F: Reworking colors and hovering pt1
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
Frontend CI / notify-failure (push) Blocked by required conditions

This commit is contained in:
Ivan 2025-06-18 16:14:41 +03:00
parent fb705249bb
commit 2013dca777
35 changed files with 149 additions and 173 deletions

View File

@ -107,7 +107,8 @@ export { BiFontFamily as IconText } from 'react-icons/bi';
export { BiFont as IconTextOff } from 'react-icons/bi';
export { TbCircleLetterM as IconTypeGraph } from 'react-icons/tb';
export { RiTreeLine as IconTree } from 'react-icons/ri';
export { FaRegKeyboard as IconControls } from 'react-icons/fa6';
export { LuKeyboard as IconKeyboard } from 'react-icons/lu';
export { LuKeyboardOff as IconKeyboardOff } from 'react-icons/lu';
export { RiLockLine as IconImmutable } from 'react-icons/ri';
export { RiLockUnlockLine as IconMutable } from 'react-icons/ri';
export { RiOpenSourceLine as IconPublic } from 'react-icons/ri';

View File

@ -8,7 +8,7 @@ export function ModalBackdrop({ onHide }: ModalBackdropProps) {
return (
<>
<div className='z-bottom fixed inset-0 backdrop-blur-[3px] opacity-50' />
<div className='z-bottom fixed inset-0 bg-popover opacity-25' onClick={onHide} />
<div className='z-bottom fixed inset-0 bg-foreground opacity-5' onClick={onHide} />
</>
);
}

View File

@ -89,7 +89,7 @@ export function ModalForm({
<div className='cc-modal-wrapper'>
<ModalBackdrop onHide={handleCancel} />
<form
className='cc-animate-modal relative grid border rounded-xl bg-background'
className='cc-animate-modal relative grid border-2 px-1 pb-1 rounded-xl bg-background'
role='dialog'
onSubmit={handleSubmit}
aria-labelledby='modal-title'

View File

@ -6,7 +6,7 @@ export function ModalLoader() {
return (
<div className='cc-modal-wrapper'>
<ModalBackdrop />
<div className='cc-animate-modal p-20 border rounded-xl bg-background'>
<div className='cc-animate-modal p-20 border-2 rounded-xl bg-background'>
<Loader circular scale={6} />
</div>
</div>

View File

@ -39,7 +39,7 @@ export function ModalView({
return (
<div className='cc-modal-wrapper'>
<ModalBackdrop onHide={hideDialog} />
<div className='cc-animate-modal relative grid border rounded-xl bg-background' role='dialog'>
<div className='cc-animate-modal relative grid border-2 px-1 pb-1 rounded-xl bg-background' role='dialog'>
{helpTopic && !hideHelpWhen?.() ? (
<BadgeHelp
topic={helpTopic}

View File

@ -22,6 +22,7 @@ export function TabLabel({
className,
disabled,
role = 'tab',
selectedClassName = 'text-foreground! cc-selected',
...otherProps
}: TabLabelProps) {
return (
@ -29,12 +30,12 @@ export function TabLabel({
className={clsx(
'min-w-20 h-full',
'px-2 py-1 flex justify-center',
'cc-animate-color duration-select',
'cc-animate-color duration-select text-muted-foreground',
'text-sm whitespace-nowrap font-controls',
'select-none',
'outline-hidden',
!disabled && 'hover:cursor-pointer cc-hover-bg',
disabled && 'text-muted-foreground',
!disabled && 'hover:cursor-pointer cc-hover-text',
disabled && 'bg-secondary',
className
)}
tabIndex='-1'
@ -44,6 +45,7 @@ export function TabLabel({
data-tooltip-hidden={hideTitle}
role={role}
disabled={disabled}
selectedClassName={selectedClassName}
{...otherProps}
>
{label}

View File

@ -62,7 +62,7 @@ export function HelpLibrary() {
<IconFilterReset size='1rem' className='inline-icon' /> сбросить фильтры
</li>
<li>
<IconFolderTree size='1rem' className='inline-icon' /> переключение между Проводник и Поиск
<IconFolderTree size='1rem' className='inline-icon' /> переключение между Проводник и Таблица
</li>
</ul>

View File

@ -1,10 +1,10 @@
import {
IconChild,
IconClone,
IconControls,
IconDestroy,
IconEdit,
IconFilter,
IconKeyboard,
IconList,
IconMoveDown,
IconMoveUp,
@ -94,7 +94,7 @@ export function HelpRSEditor() {
<IconStatusOK className='inline-icon' /> индикатор статуса определения сверху
</li>
<li>
<IconControls className='inline-icon' /> специальная клавиатура и горячие клавиши
<IconKeyboard className='inline-icon' /> специальная клавиатура и горячие клавиши
</li>
<li>
<IconTypeGraph className='inline-icon' /> отображение{' '}

View File

@ -137,14 +137,14 @@ export function EditorLibraryItem({ schema, isAttachedToOSS }: EditorLibraryItem
<ValueIcon
title='Дата обновления'
dense
icon={<IconDateUpdate size='1.25rem' className='text-constructive' />}
icon={<IconDateUpdate size='1.25rem' />}
value={new Date(schema.time_update).toLocaleString(intl.locale)}
/>
<ValueIcon
title='Дата создания'
dense
icon={<IconDateCreate size='1.25rem' className='text-constructive' />}
icon={<IconDateCreate size='1.25rem' />}
value={new Date(schema.time_create).toLocaleString(intl.locale, {
year: '2-digit',
month: '2-digit',

View File

@ -1,21 +1,16 @@
import { UserRole } from '@/features/users';
import { IconAdmin, IconEditor, IconOwner, IconReader } from '@/components/icons';
import { type DomIconProps, IconAdmin, IconEditor, IconOwner, IconReader } from '@/components/icons';
interface IconRoleProps {
role: UserRole;
size?: string;
}
export function IconRole({ role, size = '1.25rem' }: IconRoleProps) {
switch (role) {
export function IconRole({ value, size = '1.25rem', className }: DomIconProps<UserRole>) {
switch (value) {
case UserRole.ADMIN:
return <IconAdmin size={size} className='icon-primary' />;
return <IconAdmin size={size} className={className ?? 'icon-primary'} />;
case UserRole.OWNER:
return <IconOwner size={size} className='icon-primary' />;
return <IconOwner size={size} className={className ?? 'icon-primary'} />;
case UserRole.EDITOR:
return <IconEditor size={size} className='icon-primary' />;
return <IconEditor size={size} className={className ?? 'icon-primary'} />;
case UserRole.READER:
return <IconReader size={size} className='icon-primary' />;
return <IconReader size={size} className={className ?? 'icon-primary'} />;
}
}

View File

@ -3,7 +3,7 @@ import { useAuthSuspense } from '@/features/auth';
import { useRoleStore, UserRole } from '@/features/users';
import { describeUserRole, labelUserRole } from '@/features/users/labels';
import { Button } from '@/components/control';
import { MiniButton } from '@/components/control';
import { Dropdown, DropdownButton, useDropdown } from '@/components/dropdown';
import { IconAlert } from '@/components/icons';
@ -29,13 +29,12 @@ export function MenuRole({ isOwned, isEditor }: MenuRoleProps) {
if (isAnonymous) {
return (
<Button
dense
noBorder
noOutline
<MiniButton
noHover
noPadding
titleHtml='<b>Анонимный режим</b><br />Войти в Портал'
hideTitle={accessMenu.isOpen}
className='h-full pr-2'
className='h-full pr-2 bg-transparent'
icon={<IconAlert size='1.25rem' className='icon-red' />}
onClick={() => router.push({ path: urls.login })}
/>
@ -44,44 +43,45 @@ export function MenuRole({ isOwned, isEditor }: MenuRoleProps) {
return (
<div ref={accessMenu.ref} onBlur={accessMenu.handleBlur} className='relative'>
<Button
dense
noBorder
noOutline
<MiniButton
noHover
noPadding
title={`Режим ${labelUserRole(role)}`}
hideTitle={accessMenu.isOpen}
className='h-full pr-2'
icon={<IconRole role={role} size='1.25rem' />}
className='h-full pr-2 bg-transparent text-muted-foreground hover:text-primary'
icon={<IconRole value={role} size='1.25rem' className='' />}
onClick={accessMenu.toggle}
/>
<Dropdown isOpen={accessMenu.isOpen} margin='mt-3'>
<DropdownButton
text={labelUserRole(UserRole.READER)}
title={describeUserRole(UserRole.READER)}
icon={<IconRole role={UserRole.READER} size='1rem' />}
icon={<IconRole value={UserRole.READER} size='1rem' />}
onClick={() => handleChangeMode(UserRole.READER)}
/>
<DropdownButton
text={labelUserRole(UserRole.EDITOR)}
title={describeUserRole(UserRole.EDITOR)}
icon={<IconRole role={UserRole.EDITOR} size='1rem' />}
icon={<IconRole value={UserRole.EDITOR} size='1rem' />}
onClick={() => handleChangeMode(UserRole.EDITOR)}
disabled={!isOwned && !isEditor}
/>
<DropdownButton
text={labelUserRole(UserRole.OWNER)}
title={describeUserRole(UserRole.OWNER)}
icon={<IconRole role={UserRole.OWNER} size='1rem' />}
icon={<IconRole value={UserRole.OWNER} size='1rem' />}
onClick={() => handleChangeMode(UserRole.OWNER)}
disabled={!isOwned}
/>
{user.is_staff ? (
<DropdownButton
text={labelUserRole(UserRole.ADMIN)}
title={describeUserRole(UserRole.ADMIN)}
icon={<IconRole role={UserRole.ADMIN} size='1rem' />}
icon={<IconRole value={UserRole.ADMIN} size='1rem' />}
onClick={() => handleChangeMode(UserRole.ADMIN)}
disabled={!user.is_staff}
/>
) : null}
</Dropdown>
</div>
);

View File

@ -56,9 +56,10 @@ export function LibraryPage() {
<ToolbarSearch className='top-0 h-9' total={libraryItems.length} filtered={filtered.length} />
<div className='relative flex'>
<MiniButton
noHover
title='Выгрузить в формате CSV'
className='absolute z-tooltip -top-8 right-6 hidden sm:block'
icon={<IconCSV size='1.25rem' className='icon-green' />}
icon={<IconCSV size='1.25rem' className='text-muted-foreground hover:text-constructive' />}
onClick={handleDownloadCSV}
/>

View File

@ -42,7 +42,7 @@ export function useLibraryColumns() {
noHover
className='pl-2 max-h-4 -translate-y-0.5'
onClick={handleToggleFolder}
icon={<IconFolderTree size='1.25rem' className='cc-controls' />}
icon={<IconFolderTree size='1.25rem' className='text-muted-foreground hover:text-constructive' />}
/>
),
size: 50,

View File

@ -86,8 +86,9 @@ export function ViewSideLocation({ isVisible, onRenameLocation }: ViewSideLocati
/>
) : null}
<MiniButton
title='Переключение в режим Поиск'
icon={<IconFolderTree size='1.25rem' className='icon-green' />}
noHover
title='Переключение в режим Таблица'
icon={<IconFolderTree size='1.25rem' className='text-muted-foreground hover:text-constructive' />}
onClick={toggleFolderMode}
/>
</div>

View File

@ -84,13 +84,8 @@ export function DlgCreateBlock() {
className='w-160 px-6 h-110'
helpTopic={HelpTopic.CC_OSS}
>
<Tabs
selectedTabClassName='cc-selected'
className='grid'
selectedIndex={activeTab}
onSelect={index => setActiveTab(index as TabID)}
>
<TabList className='z-pop mx-auto -mb-5 flex border divide-x rounded-none bg-secondary'>
<Tabs className='grid' selectedIndex={activeTab} onSelect={index => setActiveTab(index as TabID)}>
<TabList className='z-pop mx-auto -mb-5 flex border divide-x rounded-none'>
<TabLabel title='Основные атрибуты блока' label='Карточка' />
<TabLabel
title={`Выбор вложенных узлов: [${children_operations.length + children_blocks.length}]`}

View File

@ -100,12 +100,11 @@ export function DlgCreateOperation() {
helpTopic={HelpTopic.CC_OSS}
>
<Tabs
selectedTabClassName='cc-selected'
className='grid'
selectedIndex={activeTab}
onSelect={(index, last) => handleSelectTab(index as TabID, last as TabID)}
>
<TabList className='z-pop mx-auto -mb-5 flex border divide-x rounded-none bg-secondary'>
<TabList className='z-pop mx-auto -mb-5 flex border divide-x rounded-none'>
<TabLabel
title={describeOperationType(OperationType.INPUT)}
label={labelOperationType(OperationType.INPUT)}

View File

@ -75,13 +75,8 @@ export function DlgEditOperation() {
helpTopic={HelpTopic.UI_SUBSTITUTIONS}
hideHelpWhen={() => activeTab !== TabID.SUBSTITUTION}
>
<Tabs
selectedTabClassName='cc-selected'
className='grid'
selectedIndex={activeTab}
onSelect={index => setActiveTab(index as TabID)}
>
<TabList className='mb-3 mx-auto w-fit flex border divide-x rounded-none bg-secondary'>
<Tabs className='grid' selectedIndex={activeTab} onSelect={index => setActiveTab(index as TabID)}>
<TabList className='mb-3 mx-auto w-fit flex border divide-x rounded-none'>
<TabLabel
title='Текстовые поля' //
label='Карточка'

View File

@ -23,41 +23,36 @@ export function OssStats({ className, stats }: OssStatsProps) {
<span>Всего</span>
<span>{stats.count_all}</span>
</div>
<ValueStats
id='count_block'
title='Блоки'
icon={<IconConceptBlock size='1.25rem' className='text-primary' />}
value={stats.count_block}
/>
<ValueStats id='count_block' title='Блоки' icon={<IconConceptBlock size='1.25rem' />} value={stats.count_block} />
<ValueStats
id='count_inputs'
title='Загрузка'
icon={<IconDownload size='1.25rem' className='text-primary' />}
icon={<IconDownload size='1.25rem' />}
value={stats.count_inputs}
/>
<ValueStats
id='count_synthesis'
title='Синтез'
icon={<IconSynthesis size='1.25rem' className='text-primary' />}
icon={<IconSynthesis size='1.25rem' />}
value={stats.count_synthesis}
/>
<ValueStats
id='count_schemas'
title='Прикрепленные схемы'
icon={<IconRSForm size='1.25rem' className='text-primary' />}
icon={<IconRSForm size='1.25rem' />}
value={stats.count_schemas}
/>
<ValueStats
id='count_owned'
title='Собственные'
icon={<IconRSFormOwned size='1.25rem' className='text-primary' />}
icon={<IconRSFormOwned size='1.25rem' />}
value={stats.count_owned}
/>
<ValueStats
id='count_imported'
title='Внешние'
icon={<IconRSFormImported size='1.25rem' className='text-primary' />}
icon={<IconRSFormImported size='1.25rem' />}
value={stats.count_schemas - stats.count_owned}
/>
</div>

View File

@ -1,6 +1,6 @@
import { useAuthSuspense } from '@/features/auth';
import { Button } from '@/components/control';
import { MiniButton } from '@/components/control';
import { Dropdown, DropdownButton, useDropdown } from '@/components/dropdown';
import { IconChild, IconEdit2 } from '@/components/icons';
import { useDialogsStore } from '@/stores/dialogs';
@ -31,14 +31,13 @@ export function MenuEditOss() {
return (
<div ref={menu.ref} onBlur={menu.handleBlur} className='relative'>
<Button
dense
noBorder
noOutline
<MiniButton
noHover
noPadding
title='Редактирование'
hideTitle={menu.isOpen}
className='h-full px-2'
icon={<IconEdit2 size='1.25rem' className={isMutable ? 'icon-green' : 'icon-red'} />}
className='h-full px-3 bg-transparent text-muted-foreground hover:text-primary'
icon={<IconEdit2 size='1.25rem' />}
onClick={menu.toggle}
/>
<Dropdown isOpen={menu.isOpen} margin='mt-3'>
@ -47,7 +46,7 @@ export function MenuEditOss() {
titleHtml='Перенос конституент</br>между схемами'
aria-label='Перенос конституент между схемами'
icon={<IconChild size='1rem' className='icon-green' />}
disabled={isProcessing}
disabled={isProcessing || !isMutable}
onClick={handleRelocate}
/>
</Dropdown>

View File

@ -3,7 +3,7 @@ import { useAuthSuspense } from '@/features/auth';
import { useRoleStore, UserRole } from '@/features/users';
import { Divider } from '@/components/container';
import { Button } from '@/components/control';
import { MiniButton } from '@/components/control';
import { Dropdown, DropdownButton, useDropdown } from '@/components/dropdown';
import { IconDestroy, IconLibrary, IconMenu, IconNewItem, IconQR, IconShare } from '@/components/icons';
import { useDialogsStore } from '@/stores/dialogs';
@ -47,14 +47,13 @@ export function MenuMain() {
return (
<div ref={menu.ref} onBlur={menu.handleBlur} className='relative'>
<Button
dense
noBorder
noOutline
<MiniButton
noHover
noPadding
title='Меню'
hideTitle={menu.isOpen}
icon={<IconMenu size='1.25rem' className='cc-controls' />}
className='h-full pl-2'
icon={<IconMenu size='1.25rem' />}
className='h-full pl-2 text-muted-foreground hover:text-primary bg-transparent'
onClick={menu.toggle}
/>
<Dropdown isOpen={menu.isOpen} margin='mt-3'>

View File

@ -58,10 +58,9 @@ export function OssTabs({ activeTab }: OssTabsProps) {
selectedIndex={activeTab}
onSelect={onSelectTab}
defaultFocus
selectedTabClassName='cc-selected'
className='relative flex flex-col mx-auto min-w-fit items-center'
>
<TabList className='absolute z-sticky flex border-b-2 border-x-2 divide-x-2 bg-secondary'>
<TabList className='absolute z-sticky flex border-b-2 border-x-2 divide-x-2'>
<MenuOssTabs />
<TabLabel label='Карточка' title={schema.title ?? ''} />

View File

@ -0,0 +1,9 @@
import { type DomIconProps, IconKeyboard, IconKeyboardOff } from '@/components/icons';
export function IconShowKeyboard({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
if (value) {
return <IconKeyboard size={size} className={className} />;
} else {
return <IconKeyboardOff size={size} className={className} />;
}
}

View File

@ -76,13 +76,8 @@ export function DlgCstTemplate() {
onSubmit={event => void methods.handleSubmit(onSubmit)(event)}
helpTopic={HelpTopic.RSL_TEMPLATES}
>
<Tabs
selectedTabClassName='cc-selected'
className='grid'
selectedIndex={activeTab}
onSelect={index => setActiveTab(index as TabID)}
>
<TabList className='mb-3 mx-auto flex border divide-x rounded-none bg-secondary'>
<Tabs className='grid' selectedIndex={activeTab} onSelect={index => setActiveTab(index as TabID)}>
<TabList className='mb-3 mx-auto flex border divide-x rounded-none'>
<TabLabel label='Шаблон' title='Выбор шаблона выражения' className='w-32' />
<TabLabel label='Аргументы' title='Подстановка аргументов шаблона' className='w-32' />
<TabLabel label='Конституента' title='Редактирование конституенты' className='w-32' />

View File

@ -106,8 +106,8 @@ export function DlgEditReference() {
className='w-160 px-6 h-128'
helpTopic={HelpTopic.TERM_CONTROL}
>
<Tabs selectedTabClassName='cc-selected' className='grid' selectedIndex={activeTab} onSelect={handleChangeTab}>
<TabList className='mb-3 mx-auto flex border divide-x rounded-none bg-secondary'>
<Tabs className='grid' selectedIndex={activeTab} onSelect={handleChangeTab}>
<TabList className='mb-3 mx-auto flex border divide-x rounded-none'>
<TabLabel title='Отсылка на термин в заданной словоформе' label={labelReferenceType(ReferenceType.ENTITY)} />
<TabLabel
title='Установление синтаксической связи с отсылкой на термин'

View File

@ -58,13 +58,8 @@ export function DlgInlineSynthesis() {
canSubmit={methods.formState.isValid && sourceID !== null}
onSubmit={event => void methods.handleSubmit(onSubmit)(event)}
>
<Tabs
selectedTabClassName='cc-selected'
className='grid'
selectedIndex={activeTab}
onSelect={index => setActiveTab(index as TabID)}
>
<TabList className='mb-3 mx-auto flex border divide-x rounded-none bg-secondary'>
<Tabs className='grid' selectedIndex={activeTab} onSelect={index => setActiveTab(index as TabID)}>
<TabList className='mb-3 mx-auto flex border divide-x rounded-none'>
<TabLabel
label='Схема' //
title='Источник конституент'

View File

@ -168,7 +168,7 @@ export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst,
noHover
onClick={handleEditTermForms}
className='absolute z-pop top-0 left-[calc(7ch+4px)]'
icon={<IconEdit size='1rem' className='icon-primary' />}
icon={<IconEdit size='1rem' className='hover:icon-primary' />}
disabled={isModified}
/>
) : null}
@ -184,7 +184,7 @@ export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst,
aria-label='Переименовать конституенту'
noHover
onClick={handleRenameCst}
icon={<IconEdit size='1rem' className='icon-primary' />}
icon={<IconEdit size='1rem' className='hover:icon-primary' />}
disabled={isModified}
/>
) : null}

View File

@ -1,7 +1,9 @@
import clsx from 'clsx';
import { IconShowKeyboard } from '@/features/rsform/components/icon-show-keyboard';
import { MiniButton } from '@/components/control';
import { IconControls, IconTree, IconTypeGraph } from '@/components/icons';
import { IconTree, IconTypeGraph } from '@/components/icons';
import { usePreferencesStore } from '@/stores/preferences';
import { useMutatingRSForm } from '../../../backend/use-mutating-rsform';
@ -22,20 +24,23 @@ export function ToolbarRSExpression({ className, disabled, showTypeGraph, showAS
<div className={clsx('cc-icons', className)}>
{!disabled || isProcessing ? (
<MiniButton
noHover
title='Отображение специальной клавиатуры'
icon={<IconControls size='1.25rem' className={showControls ? 'icon-primary' : ''} />}
icon={<IconShowKeyboard value={showControls} size='1.25rem' className='hover:text-primary' />}
onClick={toggleControls}
/>
) : null}
<MiniButton
noHover
title='Граф ступеней типизации'
icon={<IconTypeGraph size='1.25rem' className='icon-primary' />}
icon={<IconTypeGraph size='1.25rem' className='hover:text-primary' />}
onClick={showTypeGraph}
/>
<MiniButton
noHover
title='Дерево разбора выражения'
onClick={showAST}
icon={<IconTree size='1.25rem' className='icon-primary' />}
icon={<IconTree size='1.25rem' className='hover:text-primary' />}
/>
</div>
);

View File

@ -39,12 +39,12 @@ export function RSFormStats({ className, stats, isArchive }: RSFormStatsProps) {
<ValueStats
id='count_owned'
title='Собственные'
icon={<IconPredecessor size='1.25rem' className='text-primary' />}
icon={<IconPredecessor size='1.25rem' />}
value={stats.count_all - stats.count_inherited}
/>
<ValueStats
id='count_inherited'
icon={<IconChild size='1.25rem' className='text-primary' />}
icon={<IconChild size='1.25rem' />}
value={stats.count_inherited}
titleHtml={isArchive ? 'Архивные схемы не хранят<br/> информацию о наследовании' : 'Наследованные'}
/>
@ -53,94 +53,91 @@ export function RSFormStats({ className, stats, isArchive }: RSFormStatsProps) {
id='count_ok'
title='Корректные'
className='col-start-1'
icon={<IconStatusOK size='1.25rem' className='text-constructive' />}
icon={<IconStatusOK size='1.25rem' />}
value={stats.count_all - stats.count_errors - stats.count_property - stats.count_incalculable}
/>
<ValueStats
id='count_property'
title='Неразмерные'
icon={<IconStatusProperty size='1.25rem' className='text-primary' />}
icon={<IconStatusProperty size='1.25rem' />}
value={stats.count_errors}
/>
<ValueStats
id='count_incalculable'
title='Невычислимые'
icon={<IconStatusIncalculable size='1.25rem' className='text-destructive' />}
icon={<IconStatusIncalculable size='1.25rem' />}
value={stats.count_incalculable}
/>
<ValueStats
id='count_errors'
title='Некорректные'
icon={<IconStatusError size='1.25rem' className='text-destructive' />}
icon={<IconStatusError size='1.25rem' className={stats.count_errors > 0 ? 'text-destructive' : undefined} />}
value={stats.count_errors}
/>
<ValueStats
id='count_base'
title='Базисные множества'
icon={<IconCstBaseSet size='1.25rem' className='cc-controls' />}
icon={<IconCstBaseSet size='1.25rem' />}
value={stats.count_base}
/>
<ValueStats
id='count_constant'
title='Константные множества'
icon={<IconCstConstSet size='1.25rem' className='cc-controls' />}
icon={<IconCstConstSet size='1.25rem' />}
value={stats.count_constant}
/>
<ValueStats
id='count_structured'
title='Родовые структуры'
icon={<IconCstStructured size='1.25rem' className='cc-controls' />}
icon={<IconCstStructured size='1.25rem' />}
value={stats.count_structured}
/>
<ValueStats
id='count_axiom'
title='Аксиомы'
icon={<IconCstAxiom size='1.25rem' className='cc-controls' />}
value={stats.count_axiom}
/>
<ValueStats id='count_axiom' title='Аксиомы' icon={<IconCstAxiom size='1.25rem' />} value={stats.count_axiom} />
<ValueStats
id='count_term'
title='Термы'
icon={<IconCstTerm size='1.25rem' className='cc-controls' />}
value={stats.count_term}
/>
<ValueStats id='count_term' title='Термы' icon={<IconCstTerm size='1.25rem' />} value={stats.count_term} />
<ValueStats
id='count_function'
title='Терм-функции'
icon={<IconCstFunction size='1.25rem' className='cc-controls' />}
icon={<IconCstFunction size='1.25rem' />}
value={stats.count_function}
/>
<ValueStats
id='count_predicate'
title='Предикат-функции'
icon={<IconCstPredicate size='1.25rem' className='cc-controls' />}
icon={<IconCstPredicate size='1.25rem' />}
value={stats.count_predicate}
/>
<ValueStats
id='count_theorem'
title='Теоремы'
icon={<IconCstTheorem size='1.25rem' className='cc-controls' />}
icon={<IconCstTheorem size='1.25rem' />}
value={stats.count_theorem}
/>
<ValueStats
id='count_text_term'
title='Термины'
icon={<IconTerminology size='1.25rem' className='text-primary' />}
icon={<IconTerminology size='1.25rem' />}
value={stats.count_text_term}
/>
<ValueStats
id='count_definition'
title='Определения'
icon={<IconDefinition size='1.25rem' className='text-primary' />}
icon={<IconDefinition size='1.25rem' />}
value={stats.count_definition}
/>
<ValueStats
id='count_convention'
title='Конвенции'
icon={<IconConvention size='1.25rem' className='text-primary' />}
icon={
<IconConvention
size='1.25rem'
className={
stats.count_convention < stats.count_structured + stats.count_base ? 'text-destructive' : undefined
}
/>
}
value={stats.count_convention}
/>
</div>

View File

@ -149,7 +149,7 @@ export function EditorRSList() {
<MiniButton
className='absolute z-pop right-4 hidden sm:block top-18'
title='Выгрузить в формате CSV'
icon={<IconCSV size='1.25rem' className='icon-green' />}
icon={<IconCSV size='1.25rem' className='text-muted-foreground hover:text-constructive' />}
onClick={handleDownloadCSV}
/>

View File

@ -2,7 +2,7 @@ import { urls, useConceptNavigation } from '@/app';
import { useAuthSuspense } from '@/features/auth';
import { Divider } from '@/components/container';
import { Button } from '@/components/control';
import { MiniButton } from '@/components/control';
import { Dropdown, DropdownButton, useDropdown } from '@/components/dropdown';
import {
IconArchive,
@ -103,13 +103,12 @@ export function MenuEditSchema() {
if (isArchive) {
return (
<Button
dense
noBorder
noOutline
<MiniButton
noHover
noPadding
titleHtml='<b>Архив</b>: Редактирование запрещено<br />Перейти к актуальной версии'
hideTitle={menu.isOpen}
className='h-full px-2'
className='h-full px-3 bg-transparent'
icon={<IconArchive size='1.25rem' className='icon-primary' />}
onClick={event => router.push({ path: urls.schema(schema.id), newTab: event.ctrlKey || event.metaKey })}
/>
@ -118,14 +117,13 @@ export function MenuEditSchema() {
return (
<div ref={menu.ref} onBlur={menu.handleBlur} className='relative'>
<Button
dense
noBorder
noOutline
<MiniButton
noHover
noPadding
title='Редактирование'
hideTitle={menu.isOpen}
className='h-full px-2'
icon={<IconEdit2 size='1.25rem' className={isContentEditable ? 'icon-green' : 'icon-red'} />}
className='h-full px-3 bg-transparent text-muted-foreground hover:text-primary'
icon={<IconEdit2 size='1.25rem' />}
onClick={menu.toggle}
/>
<Dropdown isOpen={menu.isOpen} margin='mt-3'>

View File

@ -7,7 +7,7 @@ import { AccessPolicy, LocationHead } from '@/features/library';
import { useRoleStore, UserRole } from '@/features/users';
import { Divider } from '@/components/container';
import { Button } from '@/components/control';
import { MiniButton } from '@/components/control';
import { Dropdown, DropdownButton, useDropdown } from '@/components/dropdown';
import {
IconClone,
@ -128,14 +128,13 @@ export function MenuMain() {
return (
<div ref={menu.ref} onBlur={menu.handleBlur} className='relative'>
<Button
dense
noBorder
noOutline
<MiniButton
noHover
noPadding
title='Меню'
hideTitle={menu.isOpen}
icon={<IconMenu size='1.25rem' className='cc-controls' />}
className='h-full pl-2'
icon={<IconMenu size='1.25rem' />}
className='h-full pl-2 text-muted-foreground hover:text-primary bg-transparent'
onClick={menu.toggle}
/>
<Dropdown isOpen={menu.isOpen} margin='mt-3'>

View File

@ -76,10 +76,9 @@ export function RSTabs({ activeID, activeTab }: RSTabsProps) {
selectedIndex={activeTab}
onSelect={onSelectTab}
defaultFocus
selectedTabClassName='cc-selected'
className='relative flex flex-col min-w-fit items-center'
>
<TabList className='absolute z-sticky flex border-b-2 border-x-2 divide-x-2 bg-secondary'>
<TabList className='absolute z-sticky flex border-b-2 border-x-2 divide-x-2'>
<MenuRSTabs />
<TabLabel

View File

@ -3,7 +3,7 @@
*/
@utility cc-btn-nav {
color: color-mix(in oklab, var(--color-foreground) 50%, transparent);
color: var(--color-muted-foreground);
border-radius: 0.75rem;
cursor: pointer;
@ -19,8 +19,6 @@
}
.dark & {
color: color-mix(in oklab, var(--color-foreground) 70%, transparent);
&:hover {
color: var(--color-foreground);
}

View File

@ -24,7 +24,7 @@
--clr-prim-100: oklch(098% 0 0deg);
--clr-prim-200: oklch(095% 0 0deg);
--clr-prim-400: oklch(085% 0 0deg);
--clr-prim-600: oklch(070% 0 0deg);
--clr-prim-600: oklch(065% 0 0deg);
--clr-prim-999: oklch(000% 0 0deg);
--clr-sec-0: oklch(100% 0 0deg);
@ -46,7 +46,7 @@
--acc-bg-teal: oklch(082% 0.180 210deg);
--acc-bg-orange: oklch(085% 0.130 62deg);
--acc-bg-green25: oklch(097% 0.080 138deg);
--acc-bg-green25: oklch(096% 0.070 138deg);
--acc-bg-green50: oklch(092% 0.150 138deg);
--acc-bg-orange50: oklch(090% 0.044 62deg);
@ -65,7 +65,7 @@
--clr-prim-100: oklch(022% 0 0deg);
--clr-prim-200: oklch(030% 0 0deg);
--clr-prim-400: oklch(050% 0 0deg);
--clr-prim-600: oklch(065% 0 0deg);
--clr-prim-600: oklch(070% 0 0deg);
--clr-prim-999: oklch(095% 0 0deg);
--clr-sec-0: oklch(100% 0 0deg);

View File

@ -11,7 +11,7 @@
--toastify-color-dark: var(--color-secondary);
--toastify-toast-width: 20rem;
--toastify-toast-padding: 0.75rem;
--toastify-toast-padding: 1rem;
--toastify-toast-min-height: 0;
--toastify-toast-max-height: 40rem;