Optimize frontend for mobile screens

This commit is contained in:
IRBorisov 2024-02-17 12:50:25 +03:00
parent de51d89ca6
commit 6e1460a827
12 changed files with 67 additions and 38 deletions

View File

@ -33,7 +33,11 @@ function Navigation() {
> >
<ToggleNavigationButton /> <ToggleNavigationButton />
<motion.div <motion.div
className={clsx('pl-2 pr-[0.9rem] h-[3rem]', 'flex justify-between', 'shadow-border')} className={clsx(
'pl-2 pr-[0.9rem] h-[3rem]', // prettier: split lines
'flex justify-between',
'shadow-border'
)}
initial={false} initial={false}
animate={!noNavigationAnimation ? 'open' : 'closed'} animate={!noNavigationAnimation ? 'open' : 'closed'}
variants={animateNavigation} variants={animateNavigation}

View File

@ -36,7 +36,7 @@ function ConstituentaToolbar({
}: ConstituentaToolbarProps) { }: ConstituentaToolbarProps) {
const canSave = useMemo(() => isModified && isMutable, [isModified, isMutable]); const canSave = useMemo(() => isModified && isMutable, [isModified, isMutable]);
return ( return (
<Overlay position='top-1 right-1/2 translate-x-1/2' className='flex'> <Overlay position='top-1 right-4 sm:right-1/2 sm:translate-x-1/2' className='flex'>
<MiniButton <MiniButton
title='Сохранить изменения [Ctrl + S]' title='Сохранить изменения [Ctrl + S]'
disabled={!canSave} disabled={!canSave}

View File

@ -0,0 +1,40 @@
import { LiaEdit } from 'react-icons/lia';
import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay';
import { IConstituenta } from '@/models/rsform';
interface ControlsOverlayProps {
disabled?: boolean;
constituenta?: IConstituenta;
onRename: () => void;
onEditTerm: () => void;
}
function ControlsOverlay({ disabled, constituenta, onRename, onEditTerm }: ControlsOverlayProps) {
return (
<Overlay position='top-1 left-[4.1rem]' className='flex select-none'>
<MiniButton
title={`Редактировать словоформы термина: ${constituenta?.term_forms.length ?? 0}`}
disabled={disabled}
noHover
onClick={onEditTerm}
icon={<LiaEdit size='1rem' className={!disabled ? 'clr-text-primary' : ''} />}
/>
<div className='pt-1 pl-[1.375rem] text-sm font-medium whitespace-nowrap'>
<span>Имя </span>
<span className='ml-1'>{constituenta?.alias ?? ''}</span>
</div>
<MiniButton
noHover
title='Переименовать конституенту'
disabled={disabled}
onClick={onRename}
icon={<LiaEdit size='1rem' className={!disabled ? 'clr-text-primary' : ''} />}
/>
</Overlay>
);
}
export default ControlsOverlay;

View File

@ -3,12 +3,9 @@
import clsx from 'clsx'; import clsx from 'clsx';
import { useEffect, useLayoutEffect, useState } from 'react'; import { useEffect, useLayoutEffect, useState } from 'react';
import { FiSave } from 'react-icons/fi'; import { FiSave } from 'react-icons/fi';
import { LiaEdit } from 'react-icons/lia';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import RefsInput from '@/components/RefsInput'; import RefsInput from '@/components/RefsInput';
import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay';
import SubmitButton from '@/components/ui/SubmitButton'; import SubmitButton from '@/components/ui/SubmitButton';
import TextArea from '@/components/ui/TextArea'; import TextArea from '@/components/ui/TextArea';
import { useRSForm } from '@/context/RSFormContext'; import { useRSForm } from '@/context/RSFormContext';
@ -17,6 +14,7 @@ import { classnames } from '@/utils/constants';
import { labelCstTypification } from '@/utils/labels'; import { labelCstTypification } from '@/utils/labels';
import EditorRSExpression from '../EditorRSExpression'; import EditorRSExpression from '../EditorRSExpression';
import ControlsOverlay from './ControlsOverlay';
interface FormConstituentaProps { interface FormConstituentaProps {
disabled?: boolean; disabled?: boolean;
@ -111,29 +109,10 @@ function FormConstituenta({
return ( return (
<> <>
<Overlay position='top-1 left-[4.1rem]' className='flex select-none'> <ControlsOverlay disabled={disabled} constituenta={constituenta} onEditTerm={onEditTerm} onRename={onRename} />
<MiniButton
title={`Редактировать словоформы термина: ${constituenta?.term_forms.length ?? 0}`}
disabled={disabled}
noHover
onClick={onEditTerm}
icon={<LiaEdit size='1rem' className={!disabled ? 'clr-text-primary' : ''} />}
/>
<div className='pt-1 pl-[1.375rem] text-sm font-medium whitespace-nowrap'>
<span>Имя </span>
<span className='ml-1'>{constituenta?.alias ?? ''}</span>
</div>
<MiniButton
noHover
title='Переименовать конституенту'
disabled={disabled}
onClick={onRename}
icon={<LiaEdit size='1rem' className={!disabled ? 'clr-text-primary' : ''} />}
/>
</Overlay>
<form <form
id={id} id={id}
className={clsx('mt-1 w-[47.8rem] shrink-0', 'px-4 py-1', classnames.flex_col)} className={clsx('mt-1 w-full md:w-[47.8rem] shrink-0', 'px-4 py-1', classnames.flex_col)}
onSubmit={handleSubmit} onSubmit={handleSubmit}
> >
<RefsInput <RefsInput
@ -160,7 +139,7 @@ function FormConstituenta({
/> />
<EditorRSExpression <EditorRSExpression
label='Формальное определение' label='Формальное определение'
placeholder='Родоструктурное выражение, задающее формальное определение' placeholder='Родоструктурное выражение'
value={expression} value={expression}
activeCst={constituenta} activeCst={constituenta}
showList={showList} showList={showList}
@ -172,7 +151,7 @@ function FormConstituenta({
/> />
<RefsInput <RefsInput
label='Текстовое определение' label='Текстовое определение'
placeholder='Лингвистическая интерпретация формального выражения' placeholder='Текстовый вариант формального определения'
height='3.8rem' height='3.8rem'
items={schema?.items} items={schema?.items}
value={textDefinition} value={textDefinition}

View File

@ -173,7 +173,7 @@ function EditorRSExpression({
/> />
</Overlay> </Overlay>
<Overlay position='top-[-0.5rem] right-1/2 translate-x-1/2'> <Overlay position='top-[-0.5rem] pl-[6rem] sm:pl-0 right-1/2 translate-x-1/2'>
<StatusBar <StatusBar
processing={loading} processing={loading}
isModified={isModified} isModified={isModified}

View File

@ -90,7 +90,7 @@ interface RSEditorControlsProps {
function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsProps) { function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsProps) {
return ( return (
<motion.div <motion.div
className='flex-wrap text-sm divide-solid' className='flex-wrap text-xs sm:text-sm divide-solid'
initial={false} initial={false}
animate={isOpen ? 'open' : 'closed'} animate={isOpen ? 'open' : 'closed'}
variants={animateRSControl} variants={animateRSControl}

View File

@ -19,7 +19,7 @@ function RSLocalButton({ text, title, disabled, onInsert }: RSLocalButtonProps)
data-tooltip-id={title ? globalIDs.tooltip : undefined} data-tooltip-id={title ? globalIDs.tooltip : undefined}
data-tooltip-content={title} data-tooltip-content={title}
className={clsx( className={clsx(
'w-[2rem] h-6', 'w-[1.7rem] sm:w-[2rem] h-5 sm:h-6',
'cursor-pointer disabled:cursor-default', 'cursor-pointer disabled:cursor-default',
'rounded-none', 'rounded-none',
'clr-hover clr-btn-clear', 'clr-hover clr-btn-clear',

View File

@ -19,15 +19,15 @@ function RSTokenButton({ token, disabled, onInsert }: RSTokenButtonProps) {
disabled={disabled} disabled={disabled}
onClick={() => onInsert(token)} onClick={() => onInsert(token)}
className={clsx( className={clsx(
'h-6', 'h-5 sm:h-6',
'px-1', 'px-1',
'outline-none', 'outline-none',
'clr-hover clr-btn-clear', 'clr-hover clr-btn-clear',
'font-math', 'font-math',
'cursor-pointer disabled:cursor-default', 'cursor-pointer disabled:cursor-default',
{ {
'w-[4.5rem]': label.length > 3, 'w-[3.4rem] sm:w-[4.5rem]': label.length > 3,
'w-[2.25rem]': label.length <= 3 'w-[1.7rem] sm:w-[2.25rem]': label.length <= 3
} }
)} )}
data-tooltip-id={globalIDs.tooltip} data-tooltip-id={globalIDs.tooltip}

View File

@ -1,5 +1,7 @@
'use client'; 'use client';
import clsx from 'clsx';
import InfoLibraryItem from '@/components/InfoLibraryItem'; import InfoLibraryItem from '@/components/InfoLibraryItem';
import Divider from '@/components/ui/Divider'; import Divider from '@/components/ui/Divider';
import FlexColumn from '@/components/ui/FlexColumn'; import FlexColumn from '@/components/ui/FlexColumn';
@ -50,7 +52,7 @@ function EditorRSForm({ isModified, onDestroy, setIsModified }: EditorRSFormProp
onSubmit={initiateSubmit} onSubmit={initiateSubmit}
onDestroy={onDestroy} onDestroy={onDestroy}
/> />
<div tabIndex={-1} className='flex flex-col sm:flex-row w-fit' onKeyDown={handleInput}> <div tabIndex={-1} onKeyDown={handleInput} className={clsx('flex flex-col sm:flex-row', 'sm:w-fit w-full')}>
<FlexColumn className='px-4 pb-2'> <FlexColumn className='px-4 pb-2'>
<FormRSForm <FormRSForm
disabled={!isMutable} disabled={!isMutable}

View File

@ -86,7 +86,11 @@ function FormRSForm({ id, disabled, isModified, setIsModified }: FormRSFormProps
}; };
return ( return (
<form id={id} className={clsx('mt-1 min-w-[22rem] w-[30rem]', 'py-1', classnames.flex_col)} onSubmit={handleSubmit}> <form
id={id}
className={clsx('mt-1 min-w-[22rem] w-full sm:max-w-[30rem]', 'py-1', classnames.flex_col)}
onSubmit={handleSubmit}
>
<TextInput <TextInput
required required
label='Полное название' label='Полное название'

View File

@ -11,7 +11,7 @@ function RSFormStats({ stats }: RSFormStatsProps) {
return null; return null;
} }
return ( return (
<div className='flex flex-col gap-1 px-4 mt-8 w-[16rem]'> <div className='flex flex-col gap-1 px-4 sm:mt-8 sm:w-[16rem]'>
<LabeledValue id='count_all' label='Всего конституент ' text={stats.count_all} /> <LabeledValue id='count_all' label='Всего конституент ' text={stats.count_all} />
<LabeledValue id='count_errors' label='Некорректных' text={stats.count_errors} /> <LabeledValue id='count_errors' label='Некорректных' text={stats.count_errors} />
{stats.count_property !== 0 ? ( {stats.count_property !== 0 ? (

View File

@ -167,7 +167,7 @@ function RSTabs() {
onSelect={onSelectTab} onSelect={onSelectTab}
defaultFocus defaultFocus
selectedTabClassName='clr-selected' selectedTabClassName='clr-selected'
className='flex flex-col min-w-[45rem]' className='flex flex-col min-w-fit'
> >
<TabList className={clsx('mx-auto', 'flex', 'border-b-2 border-x-2 divide-x-2')}> <TabList className={clsx('mx-auto', 'flex', 'border-b-2 border-x-2 divide-x-2')}>
<RSTabsMenu onDestroy={onDestroySchema} /> <RSTabsMenu onDestroy={onDestroySchema} />