F: Improve theme switcher
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run

This commit is contained in:
Ivan 2024-12-19 18:49:08 +03:00
parent 3daa634719
commit 2cdc03db92
3 changed files with 55 additions and 29 deletions

View File

@ -1,35 +1,53 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { IconPin, IconUnpin } from '@/components/Icons'; import { IconDarkTheme, IconLightTheme, IconPin, IconUnpin } from '@/components/Icons';
import { useConceptOptions } from '@/context/ConceptOptionsContext'; import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { globals, PARAMETER } from '@/utils/constants'; import { globals, PARAMETER } from '@/utils/constants';
function ToggleNavigation() { function ToggleNavigation() {
const { noNavigationAnimation, toggleNoNavigation } = useConceptOptions(); const { noNavigationAnimation, noNavigation, toggleNoNavigation, toggleDarkMode, darkMode } = useConceptOptions();
const iconSize = !noNavigationAnimation ? '0.75rem' : '1rem';
return ( return (
<button <div
type='button'
tabIndex={-1}
className={clsx( className={clsx(
'absolute top-0 right-0 z-navigation', 'absolute top-0 right-0 z-navigation',
'min-h-[2rem] min-w-[2rem] sm:min-w-fit', 'min-h-[2rem] min-w-[2rem]',
'flex items-center justify-center', 'flex items-center justify-center gap-1',
'clr-hover', 'select-none',
'select-none' !noNavigation && 'flex-col-reverse'
)} )}
onClick={toggleNoNavigation}
data-tooltip-id={globals.tooltip}
data-tooltip-content={noNavigationAnimation ? 'Показать навигацию' : 'Скрыть навигацию'}
style={{ style={{
transitionProperty: 'height, width, background-color', transitionProperty: 'height, width, background-color',
transitionDuration: `${PARAMETER.moveDuration}ms`, transitionDuration: `${PARAMETER.moveDuration}ms`,
height: noNavigationAnimation ? '1.2rem' : '3rem', height: noNavigationAnimation ? '2rem' : '3rem',
width: noNavigationAnimation ? '3rem' : '1.2rem' width: noNavigationAnimation ? '3rem' : '2rem'
}} }}
> >
{!noNavigationAnimation ? <IconPin /> : null} {!noNavigationAnimation ? (
{noNavigationAnimation ? <IconUnpin /> : null} <button
tabIndex={-1}
type='button'
className='p-1 rounded-full'
onClick={toggleDarkMode}
data-tooltip-id={globals.tooltip}
data-tooltip-content={darkMode ? 'Тема: Темная' : 'Тема: Светлая'}
>
{darkMode ? <IconDarkTheme size='0.75rem' /> : null}
{!darkMode ? <IconLightTheme size='0.75rem' /> : null}
</button> </button>
) : null}
<button
tabIndex={-1}
type='button'
className='p-1 rounded-full'
onClick={toggleNoNavigation}
data-tooltip-id={globals.tooltip}
data-tooltip-content={noNavigationAnimation ? 'Показать навигацию' : 'Скрыть навигацию'}
>
{!noNavigationAnimation ? <IconPin size={iconSize} /> : null}
{noNavigationAnimation ? <IconUnpin size={iconSize} /> : null}
</button>
</div>
); );
} }

View File

@ -12,7 +12,6 @@ import BadgeHelp from '../info/BadgeHelp';
import { CProps } from '../props'; import { CProps } from '../props';
import Button from './Button'; import Button from './Button';
import MiniButton from './MiniButton'; import MiniButton from './MiniButton';
import Overlay from './Overlay';
export interface ModalProps extends CProps.Styling { export interface ModalProps extends CProps.Styling {
/** Title of the modal window. */ /** Title of the modal window. */
@ -105,19 +104,19 @@ function Modal({
'border rounded-xl bg-prim-100' 'border rounded-xl bg-prim-100'
)} )}
> >
<Overlay position='right-2 top-2'> {helpTopic && !hideHelpWhen?.() ? (
<div className='float-left mt-2 ml-2'>
<BadgeHelp topic={helpTopic} className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')} padding='p-0' />
</div>
) : null}
<MiniButton <MiniButton
noPadding noPadding
titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')} titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')}
icon={<IconClose size='1.25rem' />} icon={<IconClose size='1.25rem' />}
className='float-right mt-2 mr-2'
onClick={handleCancel} onClick={handleCancel}
/> />
</Overlay>
{helpTopic && !hideHelpWhen?.() ? (
<Overlay position='left-2 top-2'>
<BadgeHelp topic={helpTopic} className={clsx(PARAMETER.TOOLTIP_WIDTH, 'sm:max-w-[40rem]')} padding='p-0' />
</Overlay>
) : null}
{header ? <h1 className='px-12 py-2 select-none'>{header}</h1> : null} {header ? <h1 className='px-12 py-2 select-none'>{header}</h1> : null}

View File

@ -1,6 +1,7 @@
'use client'; 'use client';
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { flushSync } from 'react-dom';
import Tooltip from '@/components/ui/Tooltip'; import Tooltip from '@/components/ui/Tooltip';
import useLocalStorage from '@/hooks/useLocalStorage'; import useLocalStorage from '@/hooks/useLocalStorage';
@ -99,7 +100,15 @@ export const OptionsState = ({ children }: React.PropsWithChildren) => {
); );
const toggleDarkMode = useCallback(() => { const toggleDarkMode = useCallback(() => {
if (!document.startViewTransition || window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
setDarkMode(prev => !prev); setDarkMode(prev => !prev);
} else {
document.startViewTransition(() => {
flushSync(() => {
setDarkMode(prev => !prev);
});
});
}
}, [setDarkMode]); }, [setDarkMode]);
const mainHeight = useMemo(() => { const mainHeight = useMemo(() => {