mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Improve tooltips
This commit is contained in:
parent
5b1fe5527f
commit
5e91eccd68
|
@ -1,16 +1,15 @@
|
|||
import clsx from 'clsx';
|
||||
|
||||
import { CProps } from '@/components/props';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
|
||||
interface NavigationButtonProps {
|
||||
interface NavigationButtonProps extends CProps.Titled {
|
||||
text?: string;
|
||||
icon: React.ReactNode;
|
||||
title?: string;
|
||||
titleHtml?: string;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
function NavigationButton({ icon, title, titleHtml, onClick, text }: NavigationButtonProps) {
|
||||
function NavigationButton({ icon, title, titleHtml, hideTitle, onClick, text }: NavigationButtonProps) {
|
||||
return (
|
||||
<button
|
||||
type='button'
|
||||
|
@ -18,6 +17,7 @@ function NavigationButton({ icon, title, titleHtml, onClick, text }: NavigationB
|
|||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
data-tooltip-html={titleHtml}
|
||||
data-tooltip-content={title}
|
||||
data-tooltip-hidden={hideTitle}
|
||||
onClick={onClick}
|
||||
className={clsx(
|
||||
'mr-1 h-full', // prettier: split lines
|
||||
|
|
20
rsconcept/frontend/src/components/props.d.ts
vendored
20
rsconcept/frontend/src/components/props.d.ts
vendored
|
@ -2,8 +2,13 @@
|
|||
import { HTMLMotionProps } from 'framer-motion';
|
||||
|
||||
export namespace CProps {
|
||||
export type Control = {
|
||||
export type Titled = {
|
||||
title?: string;
|
||||
titleHtml?: string;
|
||||
hideTitle?: boolean;
|
||||
};
|
||||
|
||||
export type Control = Titled & {
|
||||
disabled?: boolean;
|
||||
noBorder?: boolean;
|
||||
noOutline?: boolean;
|
||||
|
@ -23,7 +28,8 @@ export namespace CProps {
|
|||
};
|
||||
|
||||
export type Div = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
||||
export type Button = Omit<
|
||||
export type Button = Titled &
|
||||
Omit<
|
||||
React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>,
|
||||
'children' | 'type'
|
||||
>;
|
||||
|
@ -31,12 +37,10 @@ export namespace CProps {
|
|||
React.DetailedHTMLProps<React.LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>,
|
||||
'children'
|
||||
>;
|
||||
export type TextArea = React.DetailedHTMLProps<
|
||||
React.TextareaHTMLAttributes<HTMLTextAreaElement>,
|
||||
HTMLTextAreaElement
|
||||
>;
|
||||
export type Input = React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
|
||||
export type TextArea = Titled &
|
||||
React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>;
|
||||
export type Input = Titled & React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
|
||||
|
||||
export type AnimatedButton = Omit<HTMLMotionProps<'button'>, 'type'>;
|
||||
export type AnimatedButton = Titled & Omit<HTMLMotionProps<'button'>, 'type'>;
|
||||
export type AnimatedDiv = HTMLMotionProps<'div'>;
|
||||
}
|
||||
|
|
|
@ -7,10 +7,8 @@ import { CProps } from '../props';
|
|||
interface ButtonProps extends CProps.Control, CProps.Colors, CProps.Button {
|
||||
text?: string;
|
||||
icon?: React.ReactNode;
|
||||
titleHtml?: string;
|
||||
|
||||
dense?: boolean;
|
||||
hideTitle?: boolean;
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
|
@ -19,10 +17,10 @@ function Button({
|
|||
icon,
|
||||
title,
|
||||
titleHtml,
|
||||
hideTitle,
|
||||
loading,
|
||||
dense,
|
||||
disabled,
|
||||
hideTitle,
|
||||
noBorder,
|
||||
noOutline,
|
||||
colors = 'clr-btn-default',
|
||||
|
|
|
@ -8,14 +8,24 @@ import { CProps } from '../props';
|
|||
|
||||
export interface CheckboxProps extends Omit<CProps.Button, 'value' | 'onClick'> {
|
||||
label?: string;
|
||||
titleHtml?: string;
|
||||
disabled?: boolean;
|
||||
|
||||
value: boolean;
|
||||
setValue?: (newValue: boolean) => void;
|
||||
}
|
||||
|
||||
function Checkbox({ id, disabled, label, title, titleHtml, className, value, setValue, ...restProps }: CheckboxProps) {
|
||||
function Checkbox({
|
||||
id,
|
||||
disabled,
|
||||
label,
|
||||
title,
|
||||
titleHtml,
|
||||
hideTitle,
|
||||
className,
|
||||
value,
|
||||
setValue,
|
||||
...restProps
|
||||
}: CheckboxProps) {
|
||||
const cursor = useMemo(() => {
|
||||
if (disabled) {
|
||||
return 'cursor-not-allowed';
|
||||
|
@ -50,6 +60,7 @@ function Checkbox({ id, disabled, label, title, titleHtml, className, value, set
|
|||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
data-tooltip-html={titleHtml}
|
||||
data-tooltip-content={title}
|
||||
data-tooltip-hidden={hideTitle}
|
||||
{...restProps}
|
||||
>
|
||||
<div
|
||||
|
|
|
@ -7,7 +7,6 @@ import { CheckboxCheckedIcon, CheckboxNullIcon } from '../Icons';
|
|||
import { CheckboxProps } from './Checkbox';
|
||||
|
||||
export interface CheckboxTristateProps extends Omit<CheckboxProps, 'value' | 'setValue'> {
|
||||
titleHtml?: string;
|
||||
value: boolean | null;
|
||||
setValue?: (newValue: boolean | null) => void;
|
||||
}
|
||||
|
@ -18,6 +17,7 @@ function CheckboxTristate({
|
|||
label,
|
||||
title,
|
||||
titleHtml,
|
||||
hideTitle,
|
||||
className,
|
||||
value,
|
||||
setValue,
|
||||
|
@ -62,6 +62,7 @@ function CheckboxTristate({
|
|||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
data-tooltip-html={titleHtml}
|
||||
data-tooltip-content={title}
|
||||
data-tooltip-hidden={hideTitle}
|
||||
{...restProps}
|
||||
>
|
||||
<div
|
||||
|
|
|
@ -8,7 +8,6 @@ import { CProps } from '../props';
|
|||
|
||||
interface DropdownButtonProps extends CProps.AnimatedButton {
|
||||
text?: string;
|
||||
titleHtml?: string;
|
||||
icon?: React.ReactNode;
|
||||
|
||||
children?: React.ReactNode;
|
||||
|
@ -20,6 +19,7 @@ function DropdownButton({
|
|||
className,
|
||||
title,
|
||||
titleHtml,
|
||||
hideTitle,
|
||||
onClick,
|
||||
children,
|
||||
...restProps
|
||||
|
@ -43,6 +43,7 @@ function DropdownButton({
|
|||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
data-tooltip-html={titleHtml}
|
||||
data-tooltip-content={title}
|
||||
data-tooltip-hidden={hideTitle}
|
||||
{...restProps}
|
||||
>
|
||||
{children ? children : null}
|
||||
|
|
|
@ -6,18 +6,16 @@ import { CProps } from '../props';
|
|||
|
||||
interface MiniButtonProps extends CProps.Button {
|
||||
icon: React.ReactNode;
|
||||
titleHtml?: string;
|
||||
noHover?: boolean;
|
||||
hideTitle?: boolean;
|
||||
}
|
||||
|
||||
function MiniButton({
|
||||
icon,
|
||||
noHover,
|
||||
hideTitle,
|
||||
tabIndex,
|
||||
title,
|
||||
titleHtml,
|
||||
hideTitle,
|
||||
className,
|
||||
...restProps
|
||||
}: MiniButtonProps) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import { BiX } from 'react-icons/bi';
|
|||
|
||||
import useEscapeKey from '@/hooks/useEscapeKey';
|
||||
import { animateModal } from '@/styling/animations';
|
||||
import { prepareTooltip } from '@/utils/labels';
|
||||
|
||||
import { CProps } from '../props';
|
||||
import Button from './Button';
|
||||
|
@ -71,7 +72,11 @@ function Modal({
|
|||
{...restProps}
|
||||
>
|
||||
<Overlay position='right-[0.3rem] top-2'>
|
||||
<MiniButton title='Закрыть диалоговое окно [ESC]' icon={<BiX size='1.25rem' />} onClick={handleCancel} />
|
||||
<MiniButton
|
||||
titleHtml={prepareTooltip('Закрыть диалоговое окно', 'ESC')}
|
||||
icon={<BiX size='1.25rem' />}
|
||||
onClick={handleCancel}
|
||||
/>
|
||||
</Overlay>
|
||||
|
||||
{header ? <h1 className='px-12 py-2 select-none'>{header}</h1> : null}
|
||||
|
|
|
@ -6,12 +6,10 @@ import { CProps } from '../props';
|
|||
|
||||
interface SelectorButtonProps extends CProps.Button {
|
||||
text?: string;
|
||||
titleHtml?: string;
|
||||
icon?: React.ReactNode;
|
||||
|
||||
colors?: string;
|
||||
transparent?: boolean;
|
||||
hideTitle?: boolean;
|
||||
}
|
||||
|
||||
function SelectorButton({
|
||||
|
|
|
@ -4,12 +4,13 @@ import { Tab as TabImpl } from 'react-tabs';
|
|||
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
|
||||
interface TabLabelProps extends Omit<TabPropsImpl, 'children'> {
|
||||
import { CProps } from '../props';
|
||||
|
||||
interface TabLabelProps extends Omit<TabPropsImpl, 'children'>, CProps.Titled {
|
||||
label?: string;
|
||||
titleHtml?: string;
|
||||
}
|
||||
|
||||
function TabLabel({ label, title, titleHtml, className, ...otherProps }: TabLabelProps) {
|
||||
function TabLabel({ label, title, titleHtml, hideTitle, className, ...otherProps }: TabLabelProps) {
|
||||
return (
|
||||
<TabImpl
|
||||
className={clsx(
|
||||
|
@ -23,6 +24,7 @@ function TabLabel({ label, title, titleHtml, className, ...otherProps }: TabLabe
|
|||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
data-tooltip-html={titleHtml}
|
||||
data-tooltip-content={title}
|
||||
data-tooltip-hidden={hideTitle}
|
||||
{...otherProps}
|
||||
>
|
||||
{label}
|
||||
|
|
|
@ -6,6 +6,7 @@ import { FiSave } from 'react-icons/fi';
|
|||
|
||||
import MiniButton from '@/components/ui/MiniButton';
|
||||
import Overlay from '@/components/ui/Overlay';
|
||||
import { prepareTooltip } from '@/utils/labels';
|
||||
|
||||
interface ConstituentaToolbarProps {
|
||||
isMutable: boolean;
|
||||
|
@ -36,7 +37,7 @@ function ConstituentaToolbar({
|
|||
return (
|
||||
<Overlay position='top-1 right-4 sm:right-1/2 sm:translate-x-1/2' className='flex'>
|
||||
<MiniButton
|
||||
title='Сохранить изменения [Ctrl + S]'
|
||||
titleHtml={prepareTooltip('Сохранить изменения', 'Ctrl + S')}
|
||||
disabled={!canSave}
|
||||
icon={<FiSave size='1.25rem' className='icon-primary' />}
|
||||
onClick={onSubmit}
|
||||
|
@ -54,7 +55,7 @@ function ConstituentaToolbar({
|
|||
icon={<BiPlusCircle size={'1.25rem'} className='icon-green' />}
|
||||
/>
|
||||
<MiniButton
|
||||
title='Клонировать конституенту [Alt + V]'
|
||||
titleHtml={prepareTooltip('Клонировать конституенту', 'Alt + V]')}
|
||||
disabled={!isMutable || isModified}
|
||||
onClick={onClone}
|
||||
icon={<BiDuplicate size='1.25rem' className='icon-green' />}
|
||||
|
@ -66,13 +67,13 @@ function ConstituentaToolbar({
|
|||
icon={<BiTrash size='1.25rem' className='icon-red' />}
|
||||
/>
|
||||
<MiniButton
|
||||
title='Переместить вверх [Alt + вверх]'
|
||||
titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')}
|
||||
icon={<BiUpvote size='1.25rem' className='icon-primary' />}
|
||||
disabled={!isMutable}
|
||||
onClick={onMoveUp}
|
||||
/>
|
||||
<MiniButton
|
||||
title='Переместить вниз [Alt + вниз]'
|
||||
titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')}
|
||||
icon={<BiDownvote size='1.25rem' className='icon-primary' />}
|
||||
disabled={!isMutable}
|
||||
onClick={onMoveDown}
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
import clsx from 'clsx';
|
||||
|
||||
import { CProps } from '@/components/props';
|
||||
import { TokenID } from '@/models/rslang';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
|
||||
interface RSLocalButtonProps {
|
||||
interface RSLocalButtonProps extends CProps.Titled {
|
||||
text: string;
|
||||
title: string;
|
||||
disabled?: boolean;
|
||||
onInsert: (token: TokenID, key?: string) => void;
|
||||
}
|
||||
|
||||
function RSLocalButton({ text, title, disabled, onInsert }: RSLocalButtonProps) {
|
||||
function RSLocalButton({ text, title, titleHtml, hideTitle, disabled, onInsert }: RSLocalButtonProps) {
|
||||
return (
|
||||
<button
|
||||
type='button'
|
||||
tabIndex={-1}
|
||||
disabled={disabled}
|
||||
data-tooltip-id={title ? globalIDs.tooltip : undefined}
|
||||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
data-tooltip-html={titleHtml}
|
||||
data-tooltip-content={title}
|
||||
data-tooltip-hidden={hideTitle}
|
||||
className={clsx(
|
||||
'w-[1.7rem] sm:w-[2rem] h-5 sm:h-6',
|
||||
'cursor-pointer disabled:cursor-default',
|
||||
|
|
|
@ -31,7 +31,7 @@ function RSTokenButton({ token, disabled, onInsert }: RSTokenButtonProps) {
|
|||
}
|
||||
)}
|
||||
data-tooltip-id={globalIDs.tooltip}
|
||||
data-tooltip-content={describeToken(token)}
|
||||
data-tooltip-html={describeToken(token)}
|
||||
>
|
||||
{label ? <span className='whitespace-nowrap'>{label}</span> : null}
|
||||
</button>
|
||||
|
|
|
@ -12,7 +12,7 @@ import { inferStatus } from '@/models/rsformAPI';
|
|||
import { IExpressionParse, ParsingStatus } from '@/models/rslang';
|
||||
import { colorBgCstStatus } from '@/styling/color';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
import { labelExpressionStatus } from '@/utils/labels';
|
||||
import { labelExpressionStatus, prepareTooltip } from '@/utils/labels';
|
||||
|
||||
import StatusIcon from './StatusIcon';
|
||||
|
||||
|
@ -49,7 +49,7 @@ function StatusBar({ isModified, processing, constituenta, parseData, onAnalyze
|
|||
)}
|
||||
style={{ backgroundColor: processing ? colors.bgDefault : colorBgCstStatus(status, colors) }}
|
||||
data-tooltip-id={globalIDs.tooltip}
|
||||
data-tooltip-content='Проверить определение [Ctrl + Q]'
|
||||
data-tooltip-html={prepareTooltip('Проверить определение', 'Ctrl + Q')}
|
||||
onClick={onAnalyze}
|
||||
>
|
||||
<AnimatePresence mode='wait'>
|
||||
|
|
|
@ -9,6 +9,7 @@ import HelpButton from '@/components/Help/HelpButton';
|
|||
import MiniButton from '@/components/ui/MiniButton';
|
||||
import Overlay from '@/components/ui/Overlay';
|
||||
import { HelpTopic } from '@/models/miscellaneous';
|
||||
import { prepareTooltip } from '@/utils/labels';
|
||||
|
||||
import { useRSEdit } from '../RSEditContext';
|
||||
|
||||
|
@ -28,7 +29,7 @@ function RSFormToolbar({ modified, anonymous, subscribed, claimable, onSubmit, o
|
|||
<Overlay position='top-1 right-1/2 translate-x-1/2' className='flex'>
|
||||
{controller.isContentEditable || controller.isProcessing ? (
|
||||
<MiniButton
|
||||
title='Сохранить изменения [Ctrl + S]'
|
||||
titleHtml={prepareTooltip('Сохранить изменения', 'Ctrl + S')}
|
||||
disabled={!canSave}
|
||||
icon={<FiSave size='1.25rem' className='icon-primary' />}
|
||||
onClick={onSubmit}
|
||||
|
@ -46,7 +47,7 @@ function RSFormToolbar({ modified, anonymous, subscribed, claimable, onSubmit, o
|
|||
/>
|
||||
{!anonymous ? (
|
||||
<MiniButton
|
||||
title={`Отслеживание ${subscribed ? 'включено' : 'выключено'}`}
|
||||
titleHtml={`Отслеживание <b>${subscribed ? 'включено' : 'выключено'}</b>`}
|
||||
disabled={controller.isProcessing}
|
||||
icon={
|
||||
subscribed ? (
|
||||
|
|
|
@ -13,7 +13,7 @@ import { HelpTopic } from '@/models/miscellaneous';
|
|||
import { CstType } from '@/models/rsform';
|
||||
import { getCstTypePrefix } from '@/models/rsformAPI';
|
||||
import { prefixes } from '@/utils/constants';
|
||||
import { getCstTypeShortcut, labelCstType } from '@/utils/labels';
|
||||
import { getCstTypeShortcut, labelCstType, prepareTooltip } from '@/utils/labels';
|
||||
|
||||
import { useRSEdit } from '../RSEditContext';
|
||||
|
||||
|
@ -29,25 +29,25 @@ function RSListToolbar({ selectedCount }: RSListToolbarProps) {
|
|||
return (
|
||||
<Overlay position='top-1 right-1/2 translate-x-1/2' className='flex items-start'>
|
||||
<MiniButton
|
||||
title='Переместить вверх [Alt + вверх]'
|
||||
titleHtml={prepareTooltip('Переместить вверх', 'Alt + вверх')}
|
||||
icon={<BiUpvote size='1.25rem' className='icon-primary' />}
|
||||
disabled={!controller.isMutable || nothingSelected}
|
||||
onClick={controller.moveUp}
|
||||
/>
|
||||
<MiniButton
|
||||
title='Переместить вниз [Alt + вниз]'
|
||||
titleHtml={prepareTooltip('Переместить вниз', 'Alt + вниз')}
|
||||
icon={<BiDownvote size='1.25rem' className='icon-primary' />}
|
||||
disabled={!controller.isMutable || nothingSelected}
|
||||
onClick={controller.moveDown}
|
||||
/>
|
||||
<MiniButton
|
||||
title='Клонировать конституенту [Alt + V]'
|
||||
titleHtml={prepareTooltip('Клонировать конституенту', 'Alt + V')}
|
||||
icon={<BiDuplicate size='1.25rem' className='icon-green' />}
|
||||
disabled={!controller.isMutable || selectedCount !== 1}
|
||||
onClick={controller.cloneCst}
|
||||
/>
|
||||
<MiniButton
|
||||
title='Добавить новую конституенту... [Alt + `]'
|
||||
titleHtml={prepareTooltip('Добавить новую конституенту...', 'Alt + `')}
|
||||
icon={<BiPlusCircle size='1.25rem' className='icon-green' />}
|
||||
disabled={!controller.isMutable}
|
||||
onClick={() => controller.createCst(undefined, false)}
|
||||
|
@ -66,13 +66,13 @@ function RSListToolbar({ selectedCount }: RSListToolbarProps) {
|
|||
key={`${prefixes.csttype_list}${typeStr}`}
|
||||
text={`${getCstTypePrefix(typeStr as CstType)}1 — ${labelCstType(typeStr as CstType)}`}
|
||||
onClick={() => controller.createCst(typeStr as CstType, true)}
|
||||
title={getCstTypeShortcut(typeStr as CstType)}
|
||||
titleHtml={getCstTypeShortcut(typeStr as CstType)}
|
||||
/>
|
||||
))}
|
||||
</Dropdown>
|
||||
</div>
|
||||
<MiniButton
|
||||
title='Удалить выбранные [Delete]'
|
||||
titleHtml={prepareTooltip('Удалить выбранные', 'Delete')}
|
||||
icon={<BiTrash size='1.25rem' className='icon-red' />}
|
||||
disabled={!controller.isMutable || nothingSelected}
|
||||
onClick={controller.deleteCst}
|
||||
|
|
|
@ -38,7 +38,7 @@ function UserTabs() {
|
|||
<div>
|
||||
<Overlay position='top-0 right-0'>
|
||||
<MiniButton
|
||||
title='Показать/Скрыть отслеживаемые схемы'
|
||||
title='Отслеживаемые схемы'
|
||||
icon={
|
||||
showSubs ? (
|
||||
<FiBell size='1.25rem' className='icon-primary' />
|
||||
|
|
|
@ -136,50 +136,50 @@ export function getCstTypeShortcut(type: CstType) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/** <b></b><br/>
|
||||
* Generates description for {@link TokenID}.
|
||||
*/
|
||||
export function describeToken(id: TokenID): string {
|
||||
// prettier-ignore
|
||||
switch (id) {
|
||||
case TokenID.BOOLEAN: return 'Булеан [Alt + E / Shift + B]';
|
||||
case TokenID.DECART: return 'Декартово произведение [Alt + Shift + E / Shift + 8]';
|
||||
case TokenID.PUNCTUATION_PL: return 'Скобки вокруг выражения [Alt + Shift + 9 ]';
|
||||
case TokenID.PUNCTUATION_SL: return 'Скобки вокруг выражения [Alt + [ ]';
|
||||
case TokenID.QUANTOR_UNIVERSAL: return 'Квантор всеобщности [`]';
|
||||
case TokenID.QUANTOR_EXISTS: return 'Квантор существования [Shift + `]';
|
||||
case TokenID.LOGIC_NOT: return 'Отрицание [Alt + `]';
|
||||
case TokenID.LOGIC_AND: return 'Конъюнкция [Alt + 3 ~ Shift + 7]';
|
||||
case TokenID.LOGIC_OR: return 'Дизъюнкция [Alt + Shift + 3]';
|
||||
case TokenID.LOGIC_IMPLICATION: return 'Импликация [Alt + 4]';
|
||||
case TokenID.LOGIC_EQUIVALENT: return 'Эквивалентность [Alt + Shift + 4]';
|
||||
case TokenID.LIT_EMPTYSET: return 'Пустое множество [Alt + X]';
|
||||
case TokenID.LIT_WHOLE_NUMBERS: return 'Целые числа [Alt + Z]';
|
||||
case TokenID.EQUAL: return 'Равенство';
|
||||
case TokenID.NOTEQUAL: return 'Неравенство [Alt + Shift + `]';
|
||||
case TokenID.GREATER_OR_EQ: return 'Больше или равно [Alt + Shift + 7]';
|
||||
case TokenID.LESSER_OR_EQ: return 'Меньше или равно [Alt + Shift + 8]';
|
||||
case TokenID.SET_IN: return 'Быть элементом (принадлежит) [Alt + 1]';
|
||||
case TokenID.SET_NOT_IN: return 'Не принадлежит [Alt + Shift + 1]';
|
||||
case TokenID.SUBSET_OR_EQ: return 'Быть частью (нестрогое подмножество) [Alt + 2]';
|
||||
case TokenID.SUBSET: return 'Строгое подмножество [Alt + 7]';
|
||||
case TokenID.NOT_SUBSET: return 'Не подмножество [Alt + Shift + 2]';
|
||||
case TokenID.SET_INTERSECTION: return 'Пересечение [Alt + A]';
|
||||
case TokenID.SET_UNION: return 'Объединение [Alt + S]';
|
||||
case TokenID.SET_MINUS: return 'Разность множеств [Alt + 5]';
|
||||
case TokenID.SET_SYMMETRIC_MINUS: return 'Симметрическая разность [Alt + Shift + 5]';
|
||||
case TokenID.NT_DECLARATIVE_EXPR: return 'Декларативная форма определения терма [Alt + D]';
|
||||
case TokenID.NT_IMPERATIVE_EXPR: return 'Императивная форма определения терма [Alt + G]';
|
||||
case TokenID.NT_RECURSIVE_FULL: return 'Рекурсивная (цикличная) форма определения терма [Alt + T]';
|
||||
case TokenID.BIGPR: return 'Большая проекция [Alt + Q]';
|
||||
case TokenID.SMALLPR: return 'Малая проекция [Alt + W]';
|
||||
case TokenID.FILTER: return 'Фильтр [Alt + F]';
|
||||
case TokenID.REDUCE: return 'Множество-сумма [Alt + R]';
|
||||
case TokenID.CARD: return 'Мощность [Alt + C]';
|
||||
case TokenID.BOOL: return 'Синглетон [Alt + B]';
|
||||
case TokenID.DEBOOL: return 'Десинглетон [Alt + V]';
|
||||
case TokenID.PUNCTUATION_ASSIGN: return 'Присвоение (императивный синтаксис) [Alt + Shift + 6]';
|
||||
case TokenID.PUNCTUATION_ITERATE: return 'Перебор элементов множества (императивный синтаксис) [Alt + 6]';
|
||||
case TokenID.BOOLEAN: return prepareTooltip('Булеан', 'Alt + E / Shift + B');
|
||||
case TokenID.DECART: return prepareTooltip('Декартово произведение', 'Alt + Shift + E / Shift + 8');
|
||||
case TokenID.PUNCTUATION_PL: return prepareTooltip('Скобки () вокруг выражения', 'Alt + Shift + 9');
|
||||
case TokenID.PUNCTUATION_SL: return prepareTooltip('Скобки [] вокруг выражения', 'Alt + [');
|
||||
case TokenID.QUANTOR_UNIVERSAL: return prepareTooltip('Квантор всеобщности', '`');
|
||||
case TokenID.QUANTOR_EXISTS: return prepareTooltip('Квантор существования', 'Shift + `');
|
||||
case TokenID.LOGIC_NOT: return prepareTooltip('Отрицание', 'Alt + `');
|
||||
case TokenID.LOGIC_AND: return prepareTooltip('Конъюнкция', 'Alt + 3 ~ Shift + 7');
|
||||
case TokenID.LOGIC_OR: return prepareTooltip('Дизъюнкция', 'Alt + Shift + 3');
|
||||
case TokenID.LOGIC_IMPLICATION: return prepareTooltip('Импликация', 'Alt + 4');
|
||||
case TokenID.LOGIC_EQUIVALENT: return prepareTooltip('Эквивалентность', 'Alt + Shift + 4');
|
||||
case TokenID.LIT_EMPTYSET: return prepareTooltip('Пустое множество', 'Alt + X');
|
||||
case TokenID.LIT_WHOLE_NUMBERS: return prepareTooltip('Целые числа', 'Alt + Z');
|
||||
case TokenID.EQUAL: return prepareTooltip('Равенство');
|
||||
case TokenID.NOTEQUAL: return prepareTooltip('Неравенство', 'Alt + Shift + `');
|
||||
case TokenID.GREATER_OR_EQ: return prepareTooltip('Больше или равно', 'Alt + Shift + 7');
|
||||
case TokenID.LESSER_OR_EQ: return prepareTooltip('Меньше или равно', 'Alt + Shift + 8');
|
||||
case TokenID.SET_IN: return prepareTooltip('Быть элементом (принадлежит)', 'Alt + 1');
|
||||
case TokenID.SET_NOT_IN: return prepareTooltip('Не принадлежит', 'Alt + Shift + 1');
|
||||
case TokenID.SUBSET_OR_EQ: return prepareTooltip('Быть частью (нестрогое подмножество)', 'Alt + 2');
|
||||
case TokenID.SUBSET: return prepareTooltip('Строгое подмножество', 'Alt + 7');
|
||||
case TokenID.NOT_SUBSET: return prepareTooltip('Не подмножество', 'Alt + Shift + 2');
|
||||
case TokenID.SET_INTERSECTION: return prepareTooltip('Пересечение', 'Alt + A');
|
||||
case TokenID.SET_UNION: return prepareTooltip('Объединение', 'Alt + S');
|
||||
case TokenID.SET_MINUS: return prepareTooltip('Разность множеств', 'Alt + 5');
|
||||
case TokenID.SET_SYMMETRIC_MINUS: return prepareTooltip('Симметрическая разность', 'Alt + Shift + 5');
|
||||
case TokenID.NT_DECLARATIVE_EXPR: return prepareTooltip('Декларативное определение', 'Alt + D');
|
||||
case TokenID.NT_IMPERATIVE_EXPR: return prepareTooltip('Императивное определение', 'Alt + G');
|
||||
case TokenID.NT_RECURSIVE_FULL: return prepareTooltip('Рекурсивное определение (цикл)', 'Alt + T');
|
||||
case TokenID.BIGPR: return prepareTooltip('Большая проекция', 'Alt + Q');
|
||||
case TokenID.SMALLPR: return prepareTooltip('Малая проекция', 'Alt + W');
|
||||
case TokenID.FILTER: return prepareTooltip('Фильтр', 'Alt + F');
|
||||
case TokenID.REDUCE: return prepareTooltip('Множество-сумма', 'Alt + R');
|
||||
case TokenID.CARD: return prepareTooltip('Мощность', 'Alt + C');
|
||||
case TokenID.BOOL: return prepareTooltip('Синглетон', 'Alt + B');
|
||||
case TokenID.DEBOOL: return prepareTooltip('Десинглетон', 'Alt + V');
|
||||
case TokenID.PUNCTUATION_ASSIGN: return prepareTooltip('Присвоение', 'Alt + Shift + 6');
|
||||
case TokenID.PUNCTUATION_ITERATE: return prepareTooltip('Перебор элементов множества', 'Alt + 6');
|
||||
}
|
||||
return `no description: ${id}`;
|
||||
}
|
||||
|
@ -743,3 +743,10 @@ export function describeAccessMode(mode: UserAccessMode): string {
|
|||
return 'Режим редактирования администратором';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate HTML wrapper for control description including hotkey.
|
||||
*/
|
||||
export function prepareTooltip(text: string, hotkey?: string) {
|
||||
return hotkey ? `<b>[${hotkey}]</b><br/>${text}` : text;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user