F: Accessibility improvements
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run

This commit is contained in:
Ivan 2025-03-19 23:28:52 +03:00
parent f8d2928ff4
commit 575b7a29f2
18 changed files with 152 additions and 110 deletions

View File

@ -15,20 +15,13 @@ export function NavigationButton({ icon, title, hideTitle, className, style, onC
return (
<button
type='button'
tabIndex={-1}
tabIndex={1}
aria-label={title}
data-tooltip-id={!!title ? globalIDs.tooltip : undefined}
data-tooltip-hidden={hideTitle}
data-tooltip-content={title}
onClick={onClick}
className={clsx(
'p-2 flex items-center gap-1',
'cursor-pointer',
'clr-btn-nav cc-animate-color duration-500',
'rounded-xl',
'font-controls whitespace-nowrap',
className
)}
className={clsx('p-2 flex items-center gap-1', 'cc-btn-nav', 'font-controls clr-outline', className)}
style={style}
>
{icon ? icon : null}

View File

@ -171,9 +171,9 @@ export interface IconProps {
className?: string;
}
function MetaIconSVG({ viewBox, size = '1.5rem', props, children }: React.PropsWithChildren<IconSVGProps>) {
function MetaIconSVG({ viewBox, size = '1.5rem', props, className, children }: React.PropsWithChildren<IconSVGProps>) {
return (
<svg width={size} height={size} fill='currentColor' viewBox={viewBox} {...props}>
<svg width={size} height={size} fill='currentColor' className={className} viewBox={viewBox} {...props}>
{children}
</svg>
);

View File

@ -10,13 +10,13 @@ interface SubtopicsProps {
export function Subtopics({ headTopic }: SubtopicsProps) {
return (
<>
<h2>Содержание раздела</h2>
<details>
<summary className='text-center font-semibold'>Содержание раздела</summary>
{Object.values(HelpTopic)
.filter(topic => topic !== headTopic && topicParent.get(topic) === headTopic)
.map(topic => (
<TopicItem key={`${prefixes.topic_item}${topic}`} topic={topic} />
))}
</>
</details>
);
}

View File

@ -26,17 +26,22 @@ export function HelpInterface() {
интерфейса изменяются (цвет, иконка) в зависимости от доступности соответствующего функционала.
</p>
<p>
<IconHelp className='inline-icon' />
Помимо данного раздела справка предоставляется контекстно через специальную иконку{' '}
<IconHelp className='inline-icon' />
<IconHelp className='inline-icon' /> Помимо данного раздела справка предоставляется контекстно через специальную
иконку <IconHelp className='inline-icon' />
</p>
<h2>Навигация и настройки</h2>
<li>Ctrl + клик на объект навигации откроет новую вкладку</li>
<li>
<kbd>Ctrl + клик</kbd> на объект навигации откроет новую вкладку
</li>
<li>
<IconPin size='1.25rem' className='inline-icon' /> навигационную панель можно скрыть с помощью кнопки в правом
верхнем углу
</li>
<li>
<IconLightTheme className='inline-icon' />
<IconDarkTheme className='inline-icon' /> переключатели темы
</li>
<li>
<IconLogin size='1.25rem' className='inline-icon' /> вход в систему / регистрация нового пользователя
</li>
@ -44,10 +49,7 @@ export function HelpInterface() {
<IconUser2 size='1.25rem' className='inline-icon' /> меню пользователя содержит ряд настроек и переход к профилю
пользователя
</li>
<li>
<IconLightTheme className='inline-icon' />
<IconDarkTheme className='inline-icon' /> переключатели темы
</li>
<li>
<IconHelp className='inline-icon' />
<IconHelpOff className='inline-icon' /> отключение иконок контекстной справки

View File

@ -20,7 +20,8 @@ export function HelpMain() {
<LinkTopic text='Операционной схеме синтеза' topic={HelpTopic.CC_OSS} />.
</p>
<h2>Разделы Справки</h2>
<details>
<summary className='text-center font-semibold'>Разделы Справки</summary>
{[
HelpTopic.THESAURUS,
HelpTopic.INTERFACE,
@ -34,6 +35,7 @@ export function HelpMain() {
].map(topic => (
<TopicItem key={`${prefixes.topic_item}${topic}`} topic={topic} />
))}
</details>
<h2>Лицензирование и раскрытие информации</h2>
<li>Пользователи Портала сохраняют авторские права на создаваемый ими контент</li>

View File

@ -259,6 +259,10 @@ export function HelpThesaurus() {
<h2>Операция</h2>
<p>Операция выделенная часть ОСС, определяющая способ получения КС в рамках ОСС.</p>
<p>
<IconConsolidation className='inline-icon' />
{'\u2009'}Ромбовидный синтез операция, где используются КС, имеющие общих предков.
</p>
<ul>
По <b>способу получения КС выделены</b>:
@ -271,13 +275,6 @@ export function HelpThesaurus() {
{'\u2009'}синтез концептуальных схем.
</li>
</ul>
<br />
<p>
<IconConsolidation className='inline-icon' />
{'\u2009'}Ромбовидный синтез операция, где используются КС, имеющие общих предков.
</p>
</div>
);
}

View File

@ -34,8 +34,12 @@ export function HelpLibrary() {
<li>
<span className='text-(--acc-fg-green)'>зеленым текстом</span> выделены ОСС
</li>
<li>клик по строке - переход к редактированию схемы</li>
<li>Ctrl + клик по строке откроет схему в новой вкладке</li>
<li>
<kbd>клик</kbd> по строке - переход к редактированию схемы
</li>
<li>
<kbd>Ctrl + клик</kbd> по строке откроет схему в новой вкладке
</li>
<li>Фильтры атрибутов три позиции: да/нет/не применять</li>
<li>
<IconShow size='1rem' className='inline-icon' /> фильтры атрибутов применяются по клику
@ -67,9 +71,15 @@ export function HelpLibrary() {
<li>
<IconSubfolders size='1rem' className='inline-icon icon-green' /> схемы во вложенных папках
</li>
<li>клик по папке отображает справа схемы в ней</li>
<li>Ctrl + клик по папке копирует путь в буфер обмена</li>
<li>клик по иконке сворачивает/разворачивает вложенные</li>
<li>
<kbd>клик</kbd> по папке отображает справа схемы в ней
</li>
<li>
<kbd>Ctrl + клик по папке копирует путь в буфер обмена</kbd>
</li>
<li>
<kbd>клик</kbd> по иконке сворачивает/разворачивает вложенные
</li>
<li>
<IconFolderEmpty size='1rem' className='inline-icon clr-text-default' /> папка без схем
</li>

View File

@ -53,10 +53,14 @@ export function HelpOssGraph() {
<div className='sm:w-84'>
<h1>Изменение узлов</h1>
<li>Клик на операцию выделение</li>
<li>Esc сбросить выделение</li>
<li>
Двойной клик переход к связанной <LinkTopic text='КС' topic={HelpTopic.CC_SYSTEM} />
<kbd>Клик</kbd> на операцию выделение
</li>
<li>
<kbd>Esc</kbd> сбросить выделение
</li>
<li>
<kbd>Двойной клик</kbd> переход к связанной <LinkTopic text='КС' topic={HelpTopic.CC_SYSTEM} />
</li>
<li>
<IconEdit2 className='inline-icon' /> Редактирование операции
@ -65,7 +69,7 @@ export function HelpOssGraph() {
<IconNewItem className='inline-icon icon-green' /> Новая операция
</li>
<li>
<IconDestroy className='inline-icon icon-red' /> Delete удалить выбранные
<IconDestroy className='inline-icon icon-red' /> <kbd>Delete</kbd> удалить выбранные
</li>
</div>
</div>

View File

@ -34,7 +34,7 @@ export function HelpRSCard() {
<IconOSS className='inline-icon' /> переход к связанной <LinkTopic text='ОСС' topic={HelpTopic.CC_OSS} />
</li>
<li>
<IconSave className='inline-icon' /> сохранить изменения: Ctrl + S
<IconSave className='inline-icon' /> сохранить изменения: <kbd>Ctrl + S</kbd>
</li>
<li>
<IconEditor className='inline-icon' /> Редактор обладает правом редактирования

View File

@ -38,13 +38,13 @@ export function HelpRSEditor() {
<IconList className='inline-icon' /> список конституент
</li>
<li>
<IconSave className='inline-icon' /> сохранить: Ctrl + S
<IconSave className='inline-icon' /> сохранить: <kbd>Ctrl + S</kbd>
</li>
<li>
<IconReset className='inline-icon' /> сбросить изменения
</li>
<li>
<IconClone className='inline-icon icon-green' /> клонировать: Alt + V
<IconClone className='inline-icon icon-green' /> клонировать: <kbd>Alt + V</kbd>
</li>
<li>
<IconNewItem className='inline-icon icon-green' /> новая конституента
@ -58,7 +58,7 @@ export function HelpRSEditor() {
<h2>Список конституент</h2>
<li>
<IconMoveDown className='inline-icon' />
<IconMoveUp className='inline-icon' /> Alt + вверх/вниз
<IconMoveUp className='inline-icon' /> <kbd>Alt + вверх/вниз</kbd>
</li>
<li>
<IconFilter className='inline-icon' />
@ -98,14 +98,18 @@ export function HelpRSEditor() {
<IconTree className='inline-icon' /> отображение{' '}
<LinkTopic text='дерева разбора' topic={HelpTopic.UI_FORMULA_TREE} />
</li>
<li>Ctrl + Пробел вставка незанятого имени / замена проекции</li>
<li>
<kbd>Ctrl + Пробел</kbd> вставка незанятого имени / замена проекции
</li>
<h2>Термин и Текстовое определение</h2>
<li>
<IconEdit className='inline-icon' /> редактирование <LinkTopic text='Имени' topic={HelpTopic.CC_CONSTITUENTA} />{' '}
/ <LinkTopic text='Термина' topic={HelpTopic.CC_CONSTITUENTA} />
</li>
<li>Ctrl + Пробел открывает редактирование отсылок</li>
<li>
<kbd>Ctrl + Пробел</kbd> открывает редактирование отсылок
</li>
</div>
);
}

View File

@ -33,28 +33,34 @@ export function HelpRSList() {
<IconOSS className='inline-icon' /> переход к связанной <LinkTopic text='ОСС' topic={HelpTopic.CC_OSS} />
</li>
<li>
<IconReset className='inline-icon' /> сбросить выделение: ESC
<IconReset className='inline-icon' /> сбросить выделение: <kbd>ESC</kbd>
</li>
<li>Клик на строку выделение</li>
<li>Shift + клик выделение нескольких</li>
<li>Alt + клик Редактор</li>
<li>Двойной клик Редактор</li>
<li>
<kbd>Shift + клик</kbd> выделение нескольких
</li>
<li>
<kbd>Alt + клик</kbd> Редактор
</li>
<li>
<kbd>Двойной клик</kbd> Редактор
</li>
<li>
<IconMoveUp className='inline-icon' />
<IconMoveDown className='inline-icon' /> Alt + вверх/вниз перемещение
<IconMoveDown className='inline-icon' /> <kbd>Alt + вверх/вниз</kbd> перемещение
</li>
<li>
<IconClone className='inline-icon icon-green' /> клонировать выделенную: Alt + V
<IconClone className='inline-icon icon-green' /> клонировать выделенную: <kbd>Alt + V</kbd>
</li>
<li>
<IconNewItem className='inline-icon icon-green' /> новая конституента: Alt + `
<IconNewItem className='inline-icon icon-green' /> новая конституента: <kbd>Alt + `</kbd>
</li>
<li>
<IconOpenList className='inline-icon icon-green' /> быстрое добавление: Alt + 1-6,Q,W
<IconOpenList className='inline-icon icon-green' /> быстрое добавление: <kbd>Alt + 1-6,Q,W</kbd>
</li>
<li>
<IconDestroy className='inline-icon icon-red' /> удаление выделенных: Delete
<IconDestroy className='inline-icon icon-red' /> удаление выделенных: <kbd>Delete</kbd>
</li>
<Divider margins='my-2' />

View File

@ -138,7 +138,9 @@ export function ToolbarSearch({ className, total, filtered }: ToolbarSearchProps
<SelectorButton
transparent
className='rounded-lg py-1'
titleHtml={(head ? describeLocationHead(head) : 'Выберите каталог') + '<br/>Ctrl + клик - Проводник'}
titleHtml={
(head ? describeLocationHead(head) : 'Выберите каталог') + '<br/><kbd>Ctrl + клик</kbd> - Проводник'
}
hideTitle={headMenu.isOpen}
icon={
head ? (

View File

@ -101,7 +101,7 @@ function domTooltipEntityReference(ref: IEntityReference, cst: IConstituenta | n
if (canClick) {
const clickTip = document.createElement('p');
clickTip.className = 'text-center text-xs mt-1';
clickTip.innerHTML = 'Ctrl + клик для перехода</br>Ctrl + пробел для редактирования';
clickTip.innerHTML = '<kbd>Ctrl + клик</kbd> для перехода</br><kbd>Ctrl + пробел</kbd> для редактирования';
dom.appendChild(clickTip);
}
@ -146,7 +146,7 @@ function domTooltipSyntacticReference(
if (canClick) {
const clickTip = document.createElement('p');
clickTip.className = 'text-center text-xs mt-1';
clickTip.innerHTML = 'Ctrl + пробел для редактирования';
clickTip.innerHTML = '<kbd>Ctrl + пробел</kbd> для редактирования';
dom.appendChild(clickTip);
}

View File

@ -55,30 +55,30 @@ const MAIN_THIRD_ROW: TokenID[] = [
];
const SECONDARY_FIRST_ROW = [
{ text: 'μ', title: 'q' },
{ text: 'ω', title: 'w' },
{ text: 'ε', title: 'e' },
{ text: 'ρ', title: 'r' },
{ text: 'τ', title: 't' },
{ text: 'π', title: 'y' }
{ text: 'μ', hotkey: 'q' },
{ text: 'ω', hotkey: 'w' },
{ text: 'ε', hotkey: 'e' },
{ text: 'ρ', hotkey: 'r' },
{ text: 'τ', hotkey: 't' },
{ text: 'π', hotkey: 'y' }
];
const SECONDARY_SECOND_ROW = [
{ text: 'α', title: 'a' },
{ text: 'σ', title: 's' },
{ text: 'δ', title: 'd' },
{ text: 'φ', title: 'f' },
{ text: 'γ', title: 'g' },
{ text: 'λ', title: 'h' }
{ text: 'α', hotkey: 'a' },
{ text: 'σ', hotkey: 's' },
{ text: 'δ', hotkey: 'd' },
{ text: 'φ', hotkey: 'f' },
{ text: 'γ', hotkey: 'g' },
{ text: 'λ', hotkey: 'h' }
];
const SECONDARY_THIRD_ROW = [
{ text: 'ζ', title: 'z' },
{ text: 'ξ', title: 'x' },
{ text: 'ψ', title: 'c' },
{ text: 'θ', title: 'v' },
{ text: 'β', title: 'b' },
{ text: 'η', title: 'n' }
{ text: 'ζ', hotkey: 'z' },
{ text: 'ξ', hotkey: 'x' },
{ text: 'ψ', hotkey: 'c' },
{ text: 'θ', hotkey: 'v' },
{ text: 'β', hotkey: 'b' },
{ text: 'η', hotkey: 'n' }
];
interface RSEditorControlsProps {
@ -103,11 +103,11 @@ export function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsP
{MAIN_FIRST_ROW.map(token => (
<RSTokenButton key={`${prefixes.rsedit_btn}${token}`} token={token} onInsert={onEdit} disabled={disabled} />
))}
{SECONDARY_FIRST_ROW.map(({ text, title }) => (
{SECONDARY_FIRST_ROW.map(({ text, hotkey }) => (
<RSLocalButton
key={`${prefixes.rsedit_btn}${title}`}
key={`${prefixes.rsedit_btn}${hotkey}`}
text={text}
title={title}
titleHtml={`<kbd>[${hotkey}]</kbd>`}
onInsert={onEdit}
disabled={disabled}
className='hidden xs:inline'
@ -117,12 +117,12 @@ export function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsP
{MAIN_SECOND_ROW.map(token => (
<RSTokenButton key={`${prefixes.rsedit_btn}${token}`} token={token} onInsert={onEdit} disabled={disabled} />
))}
{SECONDARY_SECOND_ROW.map(({ text, title }) => (
{SECONDARY_SECOND_ROW.map(({ text, hotkey }) => (
<RSLocalButton
key={`${prefixes.rsedit_btn}${title}`}
key={`${prefixes.rsedit_btn}${hotkey}`}
className='hidden xs:inline'
text={text}
title={title}
titleHtml={`<kbd>[${hotkey}]</kbd>`}
onInsert={onEdit}
disabled={disabled}
/>
@ -131,12 +131,12 @@ export function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsP
{MAIN_THIRD_ROW.map(token => (
<RSTokenButton key={`${prefixes.rsedit_btn}${token}`} token={token} onInsert={onEdit} disabled={disabled} />
))}
{SECONDARY_THIRD_ROW.map(({ text, title }) => (
{SECONDARY_THIRD_ROW.map(({ text, hotkey }) => (
<RSLocalButton
key={`${prefixes.rsedit_btn}${title}`}
key={`${prefixes.rsedit_btn}${hotkey}`}
className='hidden xs:inline'
text={text}
title={title}
titleHtml={`<kbd>[${hotkey}]</kbd>`}
onInsert={onEdit}
disabled={disabled}
/>

View File

@ -2,6 +2,22 @@
* Module: Utility classes for specific react components.
*/
@utility cc-btn-nav {
color: var(--clr-prim-800);
border-radius: 0.75rem;
cursor: pointer;
white-space: nowrap;
transition-property: background-color;
transition-timing-function: var(--ease-bezier);
transition-duration: 500ms;
&:hover {
background-color: var(--clr-sec-100);
}
}
@utility cc-tab-tools {
z-index: var(--z-index-pop);
position: absolute;
@ -15,6 +31,7 @@
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 500;
cursor: default;
user-select: text;
white-space: nowrap;

View File

@ -155,6 +155,23 @@
li::marker {
content: '\2009';
}
summary {
cursor: pointer;
list-style: none;
}
summary::before {
font-family: var(--font-math);
padding-right: 0.5rem;
content: '+';
}
details[open] summary::before {
font-family: var(--font-math);
padding-right: 0.5rem;
content: '-';
}
}
@utility border {

View File

@ -64,18 +64,6 @@
}
}
@utility clr-btn-nav {
color: var(--clr-prim-800);
&:disabled {
color: var(--clr-prim-600);
}
&:hover:not(:disabled) {
background-color: var(--clr-sec-100);
}
}
@utility clr-hover {
&:hover:not(:disabled) {
color: var(--clr-prim-999);

View File

@ -213,5 +213,5 @@ export function removeTags(target?: string): string {
* Generate HTML wrapper for control description including hotkey.
*/
export function prepareTooltip(text: string, hotkey?: string) {
return hotkey ? `<b>[${hotkey}]</b><br/>${text}` : text;
return hotkey ? `<kbd>[${hotkey}]</kbd><br/>${text}` : text;
}