UI topics list refactoring

This commit is contained in:
IRBorisov 2024-05-14 19:16:04 +03:00
parent 18336cebe3
commit 22ef6b1886
9 changed files with 66 additions and 51 deletions

View File

@ -19,7 +19,7 @@ For more specific TODOs see comments in code
- User notifications on edit - consider spam prevention and change aggregation
- Static analyzer for RSForm
- Content based search in Library
- User profile: Settings
- User profile: Settings + settings persistency
- Export PDF (Items list, Graph)
- ARIA (accessibility considerations) - for now machine reading not supported

View File

@ -1,6 +1,7 @@
import { HelpTopic } from '@/models/miscellaneous';
import HelpAPI from '../man/HelpAPI';
import HelpConcept from '../man/HelpConcept';
import HelpConceptRelations from '../man/HelpConceptRelations';
import HelpConceptSystem from '../man/HelpConceptSystem';
import HelpCstAttributes from '../man/HelpCstAttributes';
@ -42,10 +43,12 @@ function InfoTopic({ topic }: InfoTopicProps) {
if (topic === HelpTopic.CST_STATUS) return <HelpCstStatus />;
if (topic === HelpTopic.CST_CLASS) return <HelpCstClass />;
if (topic === HelpTopic.RSLANG) return <HelpRSLang />;
if (topic === HelpTopic.CONCEPTUAL) return <HelpConcept />;
if (topic === HelpTopic.CC_SYSTEM) return <HelpConceptSystem />;
if (topic === HelpTopic.CC_CONSTITUENTA) return <HelpCstAttributes />;
if (topic === HelpTopic.CC_RELATIONS) return <HelpConceptRelations />;
if (topic === HelpTopic.RSLANG) return <HelpRSLang />;
if (topic === HelpTopic.RSL_TYPES) return <HelpRSLangTypes />;
if (topic === HelpTopic.RSL_CORRECT) return <HelpRSLangCorrect />;
if (topic === HelpTopic.RSL_INTERPRET) return <HelpRSLangInterpret />;

View File

@ -7,7 +7,7 @@ function HelpCstAttributes() {
// prettier-ignore
return (
<div className='dense'>
<h1>Аттрибуты конституенты</h1>
<h1>Атрибуты конституенты</h1>
<p><b>Термин</b> может быть присвоен любой конституенте. Он используется в других Терминах и в Текстовых определениях</p>
<p><b>Формальное определение</b> строится с помощью формального аппарата <TextURL text='родоструктурной экспликации' href={urls.help_topic(HelpTopic.RSLANG)}/></p>
<p><b>Типизация</b> вычисляется автоматически на основе Формального определения и отражает структуру элементов множества, задаваемого этим определением</p>

View File

@ -71,7 +71,7 @@ function TableBody<TData>({
<tr
key={row.id}
className={clsx(
'cc-table-row',
'cc-scroll-row',
!noHeader && 'scroll-mt-[calc(2px+2rem)]',
row.getIsSelected()
? 'clr-selected clr-hover'

View File

@ -10,17 +10,17 @@ import { useConceptOptions } from '@/context/OptionsContext';
import useDropdown from '@/hooks/useDropdown';
import { HelpTopic } from '@/models/miscellaneous';
import { animateSlideLeft } from '@/styling/animations';
import { prefixes } from '@/utils/constants';
import { describeHelpTopic, labelHelpTopic } from '@/utils/labels';
interface TopicsListDropDownProps {
import TopicsTree from './TopicsTree';
interface TopicsDropdownProps {
activeTopic: HelpTopic;
onChangeTopic: (newTopic: HelpTopic) => void;
}
function TopicsListDropDown({ activeTopic, onChangeTopic }: TopicsListDropDownProps) {
function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownProps) {
const menu = useDropdown();
const { noNavigation } = useConceptOptions();
const { noNavigation, calculateHeight } = useConceptOptions();
const selectTheme = useCallback(
(topic: HelpTopic) => {
@ -34,7 +34,7 @@ function TopicsListDropDown({ activeTopic, onChangeTopic }: TopicsListDropDownPr
<div
ref={menu.ref}
className={clsx(
'absolute left-0', // prettier: split-lines
'absolute left-0 w-[13rem]', // prettier: split-lines
'flex flex-col',
'z-modal-tooltip',
'text-xs sm:text-sm',
@ -51,34 +51,20 @@ function TopicsListDropDown({ activeTopic, onChangeTopic }: TopicsListDropDownPr
title='Список тем'
hideTitle={menu.isOpen}
icon={!menu.isOpen ? <IconMenuUnfold size='1.25rem' /> : <IconMenuFold size='1.25rem' />}
className='w-[3rem] h-7'
className='w-[3rem] h-7 rounded-none'
onClick={menu.toggle}
/>
<motion.div
className='border-x'
className='border divide-y rounded-none cc-scroll-y'
style={{ maxHeight: calculateHeight('4rem + 2px') }}
initial={false}
animate={menu.isOpen ? 'open' : 'closed'}
variants={animateSlideLeft}
>
{Object.values(HelpTopic).map((topic, index) => (
<div
key={`${prefixes.topic_list}${index}`}
className={clsx(
'px-3 py-1',
'border-y',
'clr-controls clr-hover',
'cursor-pointer',
activeTopic === topic && 'clr-selected'
)}
title={describeHelpTopic(topic)}
onClick={() => selectTheme(topic)}
>
{labelHelpTopic(topic)}
</div>
))}
<TopicsTree activeTopic={activeTopic} onChangeTopic={selectTheme} />
</motion.div>
</div>
);
}
export default TopicsListDropDown;
export default TopicsDropdown;

View File

@ -3,8 +3,8 @@
import useWindowSize from '@/hooks/useWindowSize';
import { HelpTopic } from '@/models/miscellaneous';
import TopicsListDropDown from './TopicsListDropdown';
import TopicsListStatic from './TopicsListStatic';
import TopicsDropdown from './TopicsDropdown';
import TopicsStatic from './TopicsStatic';
interface TopicsListProps {
activeTopic: HelpTopic;
@ -15,9 +15,9 @@ function TopicsList({ activeTopic, onChangeTopic }: TopicsListProps) {
const size = useWindowSize();
if (!size.isSmall) {
return <TopicsListStatic activeTopic={activeTopic} onChangeTopic={onChangeTopic} />;
return <TopicsStatic activeTopic={activeTopic} onChangeTopic={onChangeTopic} />;
} else {
return <TopicsListDropDown activeTopic={activeTopic} onChangeTopic={onChangeTopic} />;
return <TopicsDropdown activeTopic={activeTopic} onChangeTopic={onChangeTopic} />;
}
}

View File

@ -0,0 +1,33 @@
import clsx from 'clsx';
import { useConceptOptions } from '@/context/OptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
import TopicsTree from './TopicsTree';
interface TopicsStaticProps {
activeTopic: HelpTopic;
onChangeTopic: (newTopic: HelpTopic) => void;
}
function TopicsStatic({ activeTopic, onChangeTopic }: TopicsStaticProps) {
const { calculateHeight } = useConceptOptions();
return (
<div
className={clsx(
'sticky top-0 left-0',
'w-[14rem] cc-scroll-y',
'self-start',
'border divide-y rounded-none',
'clr-controls',
'text-xs sm:text-sm',
'select-none'
)}
style={{ maxHeight: calculateHeight('2.25rem + 2px') }}
>
<TopicsTree activeTopic={activeTopic} onChangeTopic={onChangeTopic} />
</div>
);
}
export default TopicsStatic;

View File

@ -1,33 +1,26 @@
'use client';
import clsx from 'clsx';
import { AnimatePresence } from 'framer-motion';
import { HelpTopic } from '@/models/miscellaneous';
import { prefixes } from '@/utils/constants';
import { describeHelpTopic, labelHelpTopic } from '@/utils/labels';
interface TopicsListStaticProps {
interface TopicsTreeProps {
activeTopic: HelpTopic;
onChangeTopic: (newTopic: HelpTopic) => void;
}
function TopicsListStatic({ activeTopic, onChangeTopic }: TopicsListStaticProps) {
function TopicsTree({ activeTopic, onChangeTopic }: TopicsTreeProps) {
return (
<div
className={clsx(
'sticky top-0 left-0',
'self-start',
'border-x',
'clr-controls',
'text-xs sm:text-sm',
'select-none'
)}
>
<AnimatePresence initial={false}>
{Object.values(HelpTopic).map((topic, index) => (
<div
key={`${prefixes.topic_list}${index}`}
className={clsx(
'px-3 py-1',
'border-y',
'clr-hover',
'px-3 py-1 cc-scroll-row',
'clr-controls clr-hover',
'cursor-pointer',
activeTopic === topic && 'clr-selected'
)}
@ -37,8 +30,8 @@ function TopicsListStatic({ activeTopic, onChangeTopic }: TopicsListStaticProps)
{labelHelpTopic(topic)}
</div>
))}
</div>
</AnimatePresence>
);
}
export default TopicsListStatic;
export default TopicsTree;

View File

@ -231,7 +231,7 @@
@apply flex gap-1;
}
.cc-table-row {
.cc-scroll-row {
scroll-snap-align: start;
scroll-snap-stop: always;
}