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

View File

@ -171,9 +171,9 @@ export interface IconProps {
className?: string; 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 ( return (
<svg width={size} height={size} fill='currentColor' viewBox={viewBox} {...props}> <svg width={size} height={size} fill='currentColor' className={className} viewBox={viewBox} {...props}>
{children} {children}
</svg> </svg>
); );

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,6 +2,22 @@
* Module: Utility classes for specific react components. * 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 { @utility cc-tab-tools {
z-index: var(--z-index-pop); z-index: var(--z-index-pop);
position: absolute; position: absolute;
@ -15,6 +31,7 @@
font-size: 0.875rem; font-size: 0.875rem;
line-height: 1.25rem; line-height: 1.25rem;
font-weight: 500; font-weight: 500;
cursor: default; cursor: default;
user-select: text; user-select: text;
white-space: nowrap; white-space: nowrap;

View File

@ -155,6 +155,23 @@
li::marker { li::marker {
content: '\2009'; 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 { @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 { @utility clr-hover {
&:hover:not(:disabled) { &:hover:not(:disabled) {
color: var(--clr-prim-999); 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. * Generate HTML wrapper for control description including hotkey.
*/ */
export function prepareTooltip(text: string, hotkey?: string) { export function prepareTooltip(text: string, hotkey?: string) {
return hotkey ? `<b>[${hotkey}]</b><br/>${text}` : text; return hotkey ? `<kbd>[${hotkey}]</kbd><br/>${text}` : text;
} }