F: Upgrade hover animations pt2
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-19 12:44:58 +03:00
parent 7df3c4b7b2
commit dd8d4fe622
39 changed files with 65 additions and 78 deletions

View File

@ -25,8 +25,12 @@ export function ToggleNavigation() {
data-tooltip-content={noNavigationAnimation ? 'Показать навигацию' : 'Скрыть навигацию'} data-tooltip-content={noNavigationAnimation ? 'Показать навигацию' : 'Скрыть навигацию'}
aria-label={noNavigationAnimation ? 'Показать навигацию' : 'Скрыть навигацию'} aria-label={noNavigationAnimation ? 'Показать навигацию' : 'Скрыть навигацию'}
> >
{!noNavigationAnimation ? <IconPin size='0.75rem' className='hover:text-primary' /> : null} {!noNavigationAnimation ? (
{noNavigationAnimation ? <IconUnpin size='0.75rem' className='hover:text-primary' /> : null} <IconPin size='0.75rem' className='hover:text-primary cc-animate-color cc-hover-pulse' />
) : null}
{noNavigationAnimation ? (
<IconUnpin size='0.75rem' className='hover:text-primary cc-animate-color cc-hover-pulse' />
) : null}
</button> </button>
{!noNavigationAnimation ? ( {!noNavigationAnimation ? (
<button <button
@ -38,8 +42,12 @@ export function ToggleNavigation() {
data-tooltip-content={darkMode ? 'Тема: Темная' : 'Тема: Светлая'} data-tooltip-content={darkMode ? 'Тема: Темная' : 'Тема: Светлая'}
aria-label={darkMode ? 'Тема: Темная' : 'Тема: Светлая'} aria-label={darkMode ? 'Тема: Темная' : 'Тема: Светлая'}
> >
{darkMode ? <IconDarkTheme size='0.75rem' className='hover:text-primary' /> : null} {darkMode ? (
{!darkMode ? <IconLightTheme size='0.75rem' className='hover:text-primary' /> : null} <IconDarkTheme size='0.75rem' className='hover:text-primary cc-animate-color cc-hover-pulse' />
) : null}
{!darkMode ? (
<IconLightTheme size='0.75rem' className='hover:text-primary cc-animate-color cc-hover-pulse' />
) : null}
</button> </button>
) : null} ) : null}
</div> </div>

View File

@ -1,8 +1,7 @@
import clsx from 'clsx';
import { globalIDs } from '@/utils/constants'; import { globalIDs } from '@/utils/constants';
import { type Button } from '../props'; import { type Button } from '../props';
import { cn } from '../utils';
interface MiniButtonProps extends Button { interface MiniButtonProps extends Button {
/** Button type. */ /** Button type. */
@ -37,11 +36,12 @@ export function MiniButton({
<button <button
type={type} type={type}
tabIndex={tabIndex ?? -1} tabIndex={tabIndex ?? -1}
className={clsx( className={cn(
'rounded-lg', 'rounded-lg',
'cc-controls cc-animate-background', 'cc-controls cc-animate-background',
'cursor-pointer disabled:cursor-auto', 'cursor-pointer disabled:cursor-auto',
noHover ? 'outline-hidden' : 'cc-hover-bg', (!tabIndex || tabIndex === -1) && 'outline-hidden',
!noHover && 'cc-hover-pulse',
!noPadding && 'px-1 py-1', !noPadding && 'px-1 py-1',
className className
)} )}

View File

@ -92,7 +92,12 @@ export function ComboBox<Option>({
hidden={hidden && !open} hidden={hidden && !open}
> >
<span className='truncate'>{value ? labelValueFunc(value) : placeholder}</span> <span className='truncate'>{value ? labelValueFunc(value) : placeholder}</span>
<ChevronDownIcon className={cn('text-muted-foreground', clearable && !!value && 'opacity-0')} /> <ChevronDownIcon
className={cn(
'text-muted-foreground cc-hover-pulse hover:text-primary',
clearable && !!value && 'opacity-0'
)}
/>
{clearable && !!value ? ( {clearable && !!value ? (
<IconRemove <IconRemove
tabIndex={-1} tabIndex={-1}

View File

@ -115,7 +115,7 @@ export function ComboMulti<Option>({
<IconRemove <IconRemove
tabIndex={-1} tabIndex={-1}
size='1rem' size='1rem'
className='cc-remove absolute pointer-events-auto right-3' className='cc-remove absolute pointer-events-auto right-3 cc-hover-pulse hover:text-primary'
onClick={handleClear} onClick={handleClear}
/> />
) : null} ) : null}

View File

@ -101,9 +101,8 @@ export function SelectTree<ItemType>({
{foldable.has(item) ? ( {foldable.has(item) ? (
<MiniButton <MiniButton
aria-label={!folded.includes(item) ? 'Свернуть' : 'Развернуть'} aria-label={!folded.includes(item) ? 'Свернуть' : 'Развернуть'}
className={clsx('absolute left-1', !folded.includes(item) ? 'top-1.5' : 'top-1')} className={clsx('absolute left-1 hover:text-primary', !folded.includes(item) ? 'top-1.5' : 'top-1')}
noPadding noPadding
noHover
icon={!folded.includes(item) ? <IconDropArrow size='1rem' /> : <IconPageRight size='1.25rem' />} icon={!folded.includes(item) ? <IconDropArrow size='1rem' /> : <IconPageRight size='1.25rem' />}
onClick={event => handleClickFold(event, item)} onClick={event => handleClickFold(event, item)}
/> />

View File

@ -46,7 +46,7 @@ function SelectTrigger({
> >
{children} {children}
<SelectPrimitive.Icon asChild> <SelectPrimitive.Icon asChild>
<ChevronDownIcon className='size-4' /> <ChevronDownIcon className='size-4 cc-hover-pulse hover:text-primary' />
</SelectPrimitive.Icon> </SelectPrimitive.Icon>
</SelectPrimitive.Trigger> </SelectPrimitive.Trigger>
); );
@ -154,7 +154,7 @@ function SelectScrollDownButton({
className={cn('flex cursor-default items-center justify-center py-1', className)} className={cn('flex cursor-default items-center justify-center py-1', className)}
{...props} {...props}
> >
<ChevronDownIcon className='size-4' /> <ChevronDownIcon className='size-4 cc-hover-pulse hover:text-primary' />
</SelectPrimitive.ScrollDownButton> </SelectPrimitive.ScrollDownButton>
); );
} }

View File

@ -57,7 +57,7 @@ export function ValueIcon({
data-tooltip-hidden={hideTitle} data-tooltip-hidden={hideTitle}
aria-label={title} aria-label={title}
> >
{onClick ? <MiniButton noHover noPadding icon={icon} onClick={onClick} disabled={disabled} /> : icon} {onClick ? <MiniButton noPadding icon={icon} onClick={onClick} disabled={disabled} /> : icon}
<span id={id}>{value}</span> <span id={id}>{value}</span>
</div> </div>
); );

View File

@ -42,7 +42,7 @@ export function BadgeHelp({ topic, padding = 'p-1', className, contentClass, sty
} }
return ( return (
<div tabIndex={-1} id={`help-${topic}`} className={cn(padding, className)} style={style}> <div tabIndex={-1} id={`help-${topic}`} className={cn(padding, className)} style={style}>
<IconHelp size='1.25rem' className='text-muted-foreground hover:text-primary' /> <IconHelp size='1.25rem' className='text-muted-foreground hover:text-primary cc-animate-color' />
<Tooltip <Tooltip
clickable clickable
anchorSelect={`#help-${topic}`} anchorSelect={`#help-${topic}`}

View File

@ -86,7 +86,6 @@ export function EditorLibraryItem({ schema, isAttachedToOSS }: EditorLibraryItem
<div className='relative flex justify-stretch sm:mb-1 max-w-120 gap-3'> <div className='relative flex justify-stretch sm:mb-1 max-w-120 gap-3'>
<MiniButton <MiniButton
title='Открыть в библиотеке' title='Открыть в библиотеке'
noHover
noPadding noPadding
icon={<IconFolderOpened size='1.25rem' className='icon-primary' />} icon={<IconFolderOpened size='1.25rem' className='icon-primary' />}
onClick={handleOpenLibrary} onClick={handleOpenLibrary}

View File

@ -30,7 +30,6 @@ export function MenuRole({ isOwned, isEditor }: MenuRoleProps) {
if (isAnonymous) { if (isAnonymous) {
return ( return (
<MiniButton <MiniButton
noHover
noPadding noPadding
titleHtml='<b>Анонимный режим</b><br />Войти в Портал' titleHtml='<b>Анонимный режим</b><br />Войти в Портал'
hideTitle={accessMenu.isOpen} hideTitle={accessMenu.isOpen}
@ -48,7 +47,7 @@ export function MenuRole({ isOwned, isEditor }: MenuRoleProps) {
noPadding noPadding
title={`Режим ${labelUserRole(role)}`} title={`Режим ${labelUserRole(role)}`}
hideTitle={accessMenu.isOpen} hideTitle={accessMenu.isOpen}
className='h-full pr-2 bg-transparent text-muted-foreground hover:text-primary' className='h-full pr-2 text-muted-foreground hover:text-primary cc-animate-color'
icon={<IconRole value={role} size='1.25rem' className='' />} icon={<IconRole value={role} size='1.25rem' className='' />}
onClick={accessMenu.toggle} onClick={accessMenu.toggle}
/> />

View File

@ -73,7 +73,6 @@ export function SelectLocation({ value, dense, prefix, onClick, className, style
{item.children.size > 0 ? ( {item.children.size > 0 ? (
<MiniButton <MiniButton
noPadding noPadding
noHover
icon={ icon={
folded.includes(item) ? ( folded.includes(item) ? (
item.filesInside ? ( item.filesInside ? (

View File

@ -48,9 +48,8 @@ export function DlgEditEditors() {
<span>Всего редакторов [{selected.length}]</span> <span>Всего редакторов [{selected.length}]</span>
<MiniButton <MiniButton
title='Очистить список' title='Очистить список'
noHover
className='py-0 align-middle' className='py-0 align-middle'
icon={<IconRemove size='1.5rem' className='cc-remove' />} icon={<IconRemove size='1.25rem' className='cc-remove' />}
onClick={() => setSelected([])} onClick={() => setSelected([])}
disabled={selected.length === 0} disabled={selected.length === 0}
/> />

View File

@ -63,7 +63,6 @@ export function TableVersions({ processing, items, onDelete, selected, onSelect
<MiniButton <MiniButton
title='Удалить версию' title='Удалить версию'
className='align-middle' className='align-middle'
noHover
noPadding noPadding
icon={<IconRemove size='1.25rem' className='cc-remove' />} icon={<IconRemove size='1.25rem' className='cc-remove' />}
onClick={event => handleDeleteVersion(event, props.row.original.id)} onClick={event => handleDeleteVersion(event, props.row.original.id)}

View File

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

View File

@ -39,10 +39,9 @@ export function useLibraryColumns() {
titleHtml='Переключение в режим Проводник' titleHtml='Переключение в режим Проводник'
aria-label='Переключатель режима Проводник' aria-label='Переключатель режима Проводник'
noPadding noPadding
noHover className='ml-2 max-h-4 -translate-y-0.5'
className='pl-2 max-h-4 -translate-y-0.5'
onClick={handleToggleFolder} onClick={handleToggleFolder}
icon={<IconFolderTree size='1.25rem' className='text-muted-foreground hover:text-primary' />} icon={<IconFolderTree size='1.25rem' className='text-primary' />}
/> />
), ),
size: 50, size: 50,

View File

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

View File

@ -98,21 +98,18 @@ export function PickContents({
<div className='flex w-fit'> <div className='flex w-fit'>
<MiniButton <MiniButton
title='Удалить' title='Удалить'
noHover
className='px-0' className='px-0'
icon={<IconRemove size='1rem' className='icon-red' />} icon={<IconRemove size='1rem' className='icon-red' />}
onClick={() => handleDelete(props.row.original)} onClick={() => handleDelete(props.row.original)}
/> />
<MiniButton <MiniButton
title='Переместить выше' title='Переместить выше'
noHover
className='px-0' className='px-0'
icon={<IconMoveUp size='1rem' className='icon-primary' />} icon={<IconMoveUp size='1rem' className='icon-primary' />}
onClick={() => handleMoveUp(props.row.original)} onClick={() => handleMoveUp(props.row.original)}
/> />
<MiniButton <MiniButton
title='Переместить ниже' title='Переместить ниже'
noHover
className='px-0' className='px-0'
icon={<IconMoveDown size='1rem' className='icon-primary' />} icon={<IconMoveDown size='1rem' className='icon-primary' />}
onClick={() => handleMoveDown(props.row.original)} onClick={() => handleMoveDown(props.row.original)}

View File

@ -82,21 +82,18 @@ export function PickMultiOperation({ rows, items, value, onChange, className, ..
<div className='flex w-fit'> <div className='flex w-fit'>
<MiniButton <MiniButton
title='Удалить' title='Удалить'
noHover
className='px-0' className='px-0'
icon={<IconRemove size='1rem' className='icon-red' />} icon={<IconRemove size='1rem' className='icon-red' />}
onClick={() => handleDelete(props.row.original.id)} onClick={() => handleDelete(props.row.original.id)}
/> />
<MiniButton <MiniButton
title='Переместить выше' title='Переместить выше'
noHover
className='px-0' className='px-0'
icon={<IconMoveUp size='1rem' className='icon-primary' />} icon={<IconMoveUp size='1rem' className='icon-primary' />}
onClick={() => handleMoveUp(props.row.original.id)} onClick={() => handleMoveUp(props.row.original.id)}
/> />
<MiniButton <MiniButton
title='Переместить ниже' title='Переместить ниже'
noHover
className='px-0' className='px-0'
icon={<IconMoveDown size='1rem' className='icon-primary' />} icon={<IconMoveDown size='1rem' className='icon-primary' />}
onClick={() => handleMoveDown(props.row.original.id)} onClick={() => handleMoveDown(props.row.original.id)}

View File

@ -61,7 +61,6 @@ export function DlgChangeInputSchema() {
<Label text='Загружаемая концептуальная схема' /> <Label text='Загружаемая концептуальная схема' />
<MiniButton <MiniButton
title='Сбросить выбор схемы' title='Сбросить выбор схемы'
noHover
noPadding noPadding
icon={<IconReset size='1.25rem' className='icon-primary' />} icon={<IconReset size='1.25rem' className='icon-primary' />}
onClick={() => setValue('input', null)} onClick={() => setValue('input', null)}

View File

@ -97,7 +97,6 @@ export function TabInputOperation() {
<Label text='Загружаемая концептуальная схема' /> <Label text='Загружаемая концептуальная схема' />
<MiniButton <MiniButton
title='Сбросить выбор схемы' title='Сбросить выбор схемы'
noHover
noPadding noPadding
icon={<IconReset size='1.25rem' className='icon-primary' />} icon={<IconReset size='1.25rem' className='icon-primary' />}
onClick={() => setValue('item_data.result', null)} onClick={() => setValue('item_data.result', null)}

View File

@ -36,7 +36,7 @@ export function MenuEditOss() {
noPadding noPadding
title='Редактирование' title='Редактирование'
hideTitle={menu.isOpen} hideTitle={menu.isOpen}
className='h-full px-3 bg-transparent text-muted-foreground hover:text-primary' className='h-full px-3 text-muted-foreground hover:text-primary cc-animate-color'
icon={<IconEdit2 size='1.25rem' />} icon={<IconEdit2 size='1.25rem' />}
onClick={menu.toggle} onClick={menu.toggle}
/> />

View File

@ -53,7 +53,7 @@ export function MenuMain() {
title='Меню' title='Меню'
hideTitle={menu.isOpen} hideTitle={menu.isOpen}
icon={<IconMenu size='1.25rem' />} icon={<IconMenu size='1.25rem' />}
className='h-full pl-2 text-muted-foreground hover:text-primary bg-transparent' className='h-full pl-2 text-muted-foreground hover:text-primary cc-animate-color'
onClick={menu.toggle} onClick={menu.toggle}
/> />
<Dropdown isOpen={menu.isOpen} margin='mt-3'> <Dropdown isOpen={menu.isOpen} margin='mt-3'>

View File

@ -196,13 +196,11 @@ export function PickSubstitutions({
<div className='max-w-fit'> <div className='max-w-fit'>
<MiniButton <MiniButton
title='Принять предложение' title='Принять предложение'
noHover
icon={<IconAccept size='1rem' className='icon-green' />} icon={<IconAccept size='1rem' className='icon-green' />}
onClick={() => handleAcceptSuggestion(props.row.original)} onClick={() => handleAcceptSuggestion(props.row.original)}
/> />
<MiniButton <MiniButton
title='Игнорировать предложение' title='Игнорировать предложение'
noHover
icon={<IconRemove size='1rem' className='icon-red' />} icon={<IconRemove size='1rem' className='icon-red' />}
onClick={() => handleDeclineSuggestion(props.row.original)} onClick={() => handleDeclineSuggestion(props.row.original)}
/> />
@ -211,7 +209,6 @@ export function PickSubstitutions({
<div className='max-w-fit'> <div className='max-w-fit'>
<MiniButton <MiniButton
title='Удалить' title='Удалить'
noHover
icon={<IconRemove size='1rem' className='icon-red' />} icon={<IconRemove size='1rem' className='icon-red' />}
onClick={() => handleDeleteSubstitution(props.row.original)} onClick={() => handleDeleteSubstitution(props.row.original)}
/> />

View File

@ -87,7 +87,6 @@ export function TabArguments() {
<MiniButton <MiniButton
title='Очистить значение' title='Очистить значение'
noPadding noPadding
noHover
className='align-middle' className='align-middle'
icon={<IconRemove size='1.25rem' className='cc-remove' />} icon={<IconRemove size='1.25rem' className='cc-remove' />}
onClick={() => handleClearArgument(props.row.original)} onClick={() => handleClearArgument(props.row.original)}
@ -129,7 +128,6 @@ export function TabArguments() {
<div className='flex'> <div className='flex'>
<MiniButton <MiniButton
title='Подставить значение аргумента' title='Подставить значение аргумента'
noHover
className='py-0' className='py-0'
icon={<IconAccept size='1.5rem' className='icon-green' />} icon={<IconAccept size='1.5rem' className='icon-green' />}
onClick={() => handleAssignArgument(selectedArgument!, argumentValue)} onClick={() => handleAssignArgument(selectedArgument!, argumentValue)}
@ -137,7 +135,6 @@ export function TabArguments() {
/> />
<MiniButton <MiniButton
title='Очистить поле' title='Очистить поле'
noHover
className='py-0' className='py-0'
onClick={handleReset} onClick={handleReset}
icon={<IconReset size='1.5rem' className='icon-primary' />} icon={<IconReset size='1.5rem' className='icon-primary' />}

View File

@ -144,14 +144,12 @@ export function DlgEditWordForms() {
<div className='flex flex-col self-center gap-1'> <div className='flex flex-col self-center gap-1'>
<MiniButton <MiniButton
title='Определить граммемы' title='Определить граммемы'
noHover
icon={<IconMoveRight size='1.25rem' className='icon-primary' />} icon={<IconMoveRight size='1.25rem' className='icon-primary' />}
onClick={handleParse} onClick={handleParse}
disabled={isProcessing || !inputText} disabled={isProcessing || !inputText}
/> />
<MiniButton <MiniButton
title='Генерировать словоформу' title='Генерировать словоформу'
noHover
icon={<IconMoveLeft size='1.25rem' className='icon-primary' />} icon={<IconMoveLeft size='1.25rem' className='icon-primary' />}
onClick={handleInflect} onClick={handleInflect}
disabled={isProcessing || inputGrams.length == 0} disabled={isProcessing || inputGrams.length == 0}
@ -169,14 +167,12 @@ export function DlgEditWordForms() {
<div className='cc-icons'> <div className='cc-icons'>
<MiniButton <MiniButton
title='Внести словоформу' title='Внести словоформу'
noHover
icon={<IconAccept size='1.5rem' className='icon-green' />} icon={<IconAccept size='1.5rem' className='icon-green' />}
onClick={handleAddForm} onClick={handleAddForm}
disabled={isProcessing || !inputText || inputGrams.length == 0} disabled={isProcessing || !inputText || inputGrams.length == 0}
/> />
<MiniButton <MiniButton
title='Генерировать стандартные словоформы' title='Генерировать стандартные словоформы'
noHover
icon={<IconMoveDown size='1.5rem' className='icon-primary' />} icon={<IconMoveDown size='1.5rem' className='icon-primary' />}
onClick={handleGenerateLexeme} onClick={handleGenerateLexeme}
disabled={isProcessing || !inputText} disabled={isProcessing || !inputText}
@ -186,7 +182,6 @@ export function DlgEditWordForms() {
<span>Заданные вручную словоформы [{forms.length}]</span> <span>Заданные вручную словоформы [{forms.length}]</span>
<MiniButton <MiniButton
title='Сбросить все словоформы' title='Сбросить все словоформы'
noHover
className='py-0 align-middle' className='py-0 align-middle'
icon={<IconRemove size='1.5rem' className='cc-remove' />} icon={<IconRemove size='1.5rem' className='cc-remove' />}
onClick={handleResetAll} onClick={handleResetAll}

View File

@ -48,7 +48,6 @@ export function TableWordForms({ forms, setForms, onFormSelect }: TableWordForms
cell: props => ( cell: props => (
<MiniButton <MiniButton
title='Удалить словоформу' title='Удалить словоформу'
noHover
noPadding noPadding
className='align-middle' className='align-middle'
icon={<IconRemove size='1.25rem' className='cc-remove' />} icon={<IconRemove size='1.25rem' className='cc-remove' />}

View File

@ -165,10 +165,9 @@ export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst,
<MiniButton <MiniButton
title={isModified ? tooltipText.unsaved : 'Редактировать словоформы термина'} title={isModified ? tooltipText.unsaved : 'Редактировать словоформы термина'}
aria-label='Редактировать словоформы термина' aria-label='Редактировать словоформы термина'
noHover
onClick={handleEditTermForms} onClick={handleEditTermForms}
className='absolute z-pop top-0 left-[calc(7ch+4px)]' className='absolute z-pop top-0 left-[calc(7ch+4px)]'
icon={<IconEdit size='1rem' className='hover:icon-primary' />} icon={<IconEdit size='1rem' className='icon-primary' />}
disabled={isModified} disabled={isModified}
/> />
) : null} ) : null}
@ -182,9 +181,8 @@ export function FormConstituenta({ disabled, id, toggleReset, schema, activeCst,
<MiniButton <MiniButton
title={isModified ? tooltipText.unsaved : 'Переименовать конституенту'} title={isModified ? tooltipText.unsaved : 'Переименовать конституенту'}
aria-label='Переименовать конституенту' aria-label='Переименовать конституенту'
noHover
onClick={handleRenameCst} onClick={handleRenameCst}
icon={<IconEdit size='1rem' className='hover:icon-primary' />} icon={<IconEdit size='1rem' className='icon-primary' />}
disabled={isModified} disabled={isModified}
/> />
) : null} ) : null}

View File

@ -151,13 +151,12 @@ export function ToolbarConstituenta({
) : null} ) : null}
<MiniButton <MiniButton
noHover
title='Отображение списка конституент' title='Отображение списка конституент'
icon={ icon={
showList ? ( showList ? (
<IconList size='1.25rem' className='hover:icon-primary' /> <IconList size='1.25rem' className='icon-primary' />
) : ( ) : (
<IconListOff size='1.25rem' className='hover:icon-primary' /> <IconListOff size='1.25rem' className='icon-primary' />
) )
} }
onClick={toggleList} onClick={toggleList}

View File

@ -24,20 +24,17 @@ export function ToolbarRSExpression({ className, disabled, showTypeGraph, showAS
<div className={clsx('cc-icons', className)}> <div className={clsx('cc-icons', className)}>
{!disabled || isProcessing ? ( {!disabled || isProcessing ? (
<MiniButton <MiniButton
noHover
title='Отображение специальной клавиатуры' title='Отображение специальной клавиатуры'
icon={<IconShowKeyboard value={showControls} size='1.25rem' className='hover:text-primary' />} icon={<IconShowKeyboard value={showControls} size='1.25rem' className='hover:text-primary' />}
onClick={toggleControls} onClick={toggleControls}
/> />
) : null} ) : null}
<MiniButton <MiniButton
noHover
title='Граф ступеней типизации' title='Граф ступеней типизации'
icon={<IconTypeGraph size='1.25rem' className='hover:text-primary' />} icon={<IconTypeGraph size='1.25rem' className='hover:text-primary' />}
onClick={showTypeGraph} onClick={showTypeGraph}
/> />
<MiniButton <MiniButton
noHover
title='Дерево разбора выражения' title='Дерево разбора выражения'
onClick={showAST} onClick={showAST}
icon={<IconTree size='1.25rem' className='hover:text-primary' />} icon={<IconTree size='1.25rem' className='hover:text-primary' />}

View File

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

View File

@ -157,8 +157,7 @@ export function ToolbarTermGraph() {
/> />
) : null} ) : null}
<MiniButton <MiniButton
noHover icon={<IconTypeGraph size='1.25rem' className='icon-primary' />}
icon={<IconTypeGraph size='1.25rem' className='hover:icon-primary' />}
title='Граф ступеней' title='Граф ступеней'
onClick={handleShowTypeGraph} onClick={handleShowTypeGraph}
/> />

View File

@ -49,7 +49,6 @@ export function ViewHidden({ items }: ViewHiddenProps) {
<MiniButton <MiniButton
className='absolute right-[calc(1rem-4px)] top-3 pointer-events-auto' className='absolute right-[calc(1rem-4px)] top-3 pointer-events-auto'
noPadding noPadding
noHover
title={!isFolded ? 'Свернуть' : 'Развернуть'} title={!isFolded ? 'Свернуть' : 'Развернуть'}
icon={!isFolded ? <IconDropArrowUp size='1rem' /> : <IconDropArrow size='1rem' />} icon={!isFolded ? <IconDropArrowUp size='1rem' /> : <IconDropArrow size='1rem' />}
onClick={toggleFolded} onClick={toggleFolded}

View File

@ -104,7 +104,6 @@ export function MenuEditSchema() {
if (isArchive) { if (isArchive) {
return ( return (
<MiniButton <MiniButton
noHover
noPadding noPadding
titleHtml='<b>Архив</b>: Редактирование запрещено<br />Перейти к актуальной версии' titleHtml='<b>Архив</b>: Редактирование запрещено<br />Перейти к актуальной версии'
hideTitle={menu.isOpen} hideTitle={menu.isOpen}
@ -122,7 +121,7 @@ export function MenuEditSchema() {
noPadding noPadding
title='Редактирование' title='Редактирование'
hideTitle={menu.isOpen} hideTitle={menu.isOpen}
className='h-full px-3 bg-transparent text-muted-foreground hover:text-primary' className='h-full px-3 text-muted-foreground hover:text-primary cc-animate-color'
icon={<IconEdit2 size='1.25rem' />} icon={<IconEdit2 size='1.25rem' />}
onClick={menu.toggle} onClick={menu.toggle}
/> />

View File

@ -134,7 +134,7 @@ export function MenuMain() {
title='Меню' title='Меню'
hideTitle={menu.isOpen} hideTitle={menu.isOpen}
icon={<IconMenu size='1.25rem' />} icon={<IconMenu size='1.25rem' />}
className='h-full pl-2 text-muted-foreground hover:text-primary bg-transparent' className='h-full pl-2 text-muted-foreground hover:text-primary cc-animate-color bg-transparent'
onClick={menu.toggle} onClick={menu.toggle}
/> />
<Dropdown isOpen={menu.isOpen} margin='mt-3'> <Dropdown isOpen={menu.isOpen} margin='mt-3'>

View File

@ -39,7 +39,6 @@ export function ConstituentsSearch({ dense }: ConstituentsSearchProps) {
<SelectGraphFilter value={filterSource} onChange={setSource} dense={dense} /> <SelectGraphFilter value={filterSource} onChange={setSource} dense={dense} />
{schema.stats.count_inherited > 0 ? ( {schema.stats.count_inherited > 0 ? (
<MiniButton <MiniButton
noHover
titleHtml={`Наследованные: <b>${includeInherited ? 'отображать' : 'скрывать'}</b>`} titleHtml={`Наследованные: <b>${includeInherited ? 'отображать' : 'скрывать'}</b>`}
aria-label={`Отображение наследованных: ${includeInherited ? 'отображать' : 'скрывать'}`} aria-label={`Отображение наследованных: ${includeInherited ? 'отображать' : 'скрывать'}`}
icon={<IconChild size='1rem' className={includeInherited ? 'icon-primary' : 'cc-controls'} />} icon={<IconChild size='1rem' className={includeInherited ? 'icon-primary' : 'cc-controls'} />}

View File

@ -32,7 +32,6 @@ export function TableUsers({ items, onDelete }: TableUsersProps) {
<MiniButton <MiniButton
title='Удалить из списка' title='Удалить из списка'
className='align-middle' className='align-middle'
noHover
noPadding noPadding
icon={<IconRemove size='1.25rem' className='cc-remove' />} icon={<IconRemove size='1.25rem' className='cc-remove' />}
onClick={() => onDelete(props.row.original.id)} onClick={() => onDelete(props.row.original.id)}

View File

@ -98,7 +98,7 @@ export function FormSignup() {
<IconHelp <IconHelp
id={globalIDs.email_tooltip} id={globalIDs.email_tooltip}
className='absolute top-0 right-0 text-muted-foreground hover:text-primary' className='absolute top-0 right-0 text-muted-foreground hover:text-primary cc-animate-color'
size='1.25rem' size='1.25rem'
/> />
<Tooltip anchorSelect={`#${globalIDs.email_tooltip}`} offset={6}> <Tooltip anchorSelect={`#${globalIDs.email_tooltip}`} offset={6}>

View File

@ -14,15 +14,8 @@
transition-duration: 500ms; transition-duration: 500ms;
&:hover { &:hover {
background-color: var(--color-accent);
color: var(--color-foreground); color: var(--color-foreground);
} }
.dark & {
&:hover {
color: var(--color-foreground);
}
}
} }
@utility cc-btn-primary { @utility cc-btn-primary {

View File

@ -26,6 +26,27 @@
} }
} }
@utility cc-hover-pulse {
&:hover:not(:disabled) {
animation: pulse-scale 1s infinite;
transition: var(--duration-move);
}
}
@keyframes pulse-scale {
0% {
transform: scale(1);
}
70% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
@utility cc-hover-text { @utility cc-hover-text {
&:hover:not(:disabled) { &:hover:not(:disabled) {
color: var(--color-foreground); color: var(--color-foreground);