R: Improve ValueIcon component

This commit is contained in:
Ivan 2025-03-20 14:41:48 +03:00
parent 1365d27af8
commit 341db80e68
5 changed files with 49 additions and 47 deletions

View File

@ -15,15 +15,9 @@ interface ValueIconProps extends Styling, Titled {
/** Icon to display. */
icon: React.ReactNode;
/** Classname for the text. */
textClassName?: string;
/** Callback to be called when the component is clicked. */
onClick?: (event: React.MouseEvent<Element>) => void;
/** Number of symbols to display in a small size. */
smallThreshold?: number;
/** Indicates that padding should be minimal. */
dense?: boolean;
@ -39,19 +33,15 @@ export function ValueIcon({
dense,
icon,
value,
textClassName,
disabled = true,
title,
titleHtml,
hideTitle,
className,
smallThreshold,
onClick,
...restProps
}: ValueIconProps) {
// TODO: use CSS instead of threshold
// TODO: do not add button if onClick is disabled
const isSmall = !smallThreshold || String(value).length < smallThreshold;
return (
<div
className={clsx(
@ -66,11 +56,10 @@ export function ValueIcon({
data-tooltip-html={titleHtml}
data-tooltip-content={title}
data-tooltip-hidden={hideTitle}
aria-label={title}
>
<MiniButton noHover noPadding icon={icon} onClick={onClick} disabled={disabled} />
<span id={id} className={clsx({ 'text-xs': !isSmall }, textClassName)}>
{value}
</span>
{onClick ? <MiniButton noHover noPadding icon={icon} onClick={onClick} disabled={disabled} /> : icon}
<span id={id}>{value}</span>
</div>
);
}

View File

@ -1,6 +1,7 @@
import { type Styling, type Titled } from '@/components/props';
import clsx from 'clsx';
import { ValueIcon } from './value-icon';
import { type Styling, type Titled } from '@/components/props';
import { globalIDs } from '@/utils/constants';
// characters - threshold for small labels - small font
const SMALL_THRESHOLD = 3;
@ -16,9 +17,23 @@ interface ValueStatsProps extends Styling, Titled {
value: string | number;
}
/**
* Displays statistics value with an icon.
*/
export function ValueStats(props: ValueStatsProps) {
return <ValueIcon dense smallThreshold={SMALL_THRESHOLD} textClassName='min-w-5' {...props} />;
/** Displays statistics value with an icon. */
export function ValueStats({ id, icon, value, className, title, titleHtml, hideTitle, ...restProps }: ValueStatsProps) {
const isSmall = String(value).length < SMALL_THRESHOLD;
return (
<div
className={clsx('flex items-center gap-1', 'text-right', 'hover:cursor-default', className)}
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
data-tooltip-html={titleHtml}
data-tooltip-content={title}
data-tooltip-hidden={hideTitle}
aria-label={title}
{...restProps}
>
{icon}
<span id={id} className={clsx(!isSmall && 'text-xs', 'min-w-5')}>
{value}
</span>
</div>
);
}

View File

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

View File

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

View File

@ -38,9 +38,9 @@ export function RSFormStats({ className, stats, isArchive }: RSFormStatsProps) {
</div>
<ValueStats
id='count_owned'
title='Собственные'
icon={<IconPredecessor size='1.25rem' className='text-sec-600' />}
value={stats.count_all - stats.count_inherited}
title='Собственные'
/>
<ValueStats
id='count_inherited'
@ -50,98 +50,98 @@ export function RSFormStats({ className, stats, isArchive }: RSFormStatsProps) {
/>
<ValueStats
className='col-start-1'
id='count_ok'
title='Корректные'
className='col-start-1'
icon={<IconStatusOK size='1.25rem' className='text-ok-600' />}
value={stats.count_all - stats.count_errors - stats.count_property - stats.count_incalculable}
title='Корректные'
/>
<ValueStats
id='count_property'
title='Неразмерные'
icon={<IconStatusProperty size='1.25rem' className='text-sec-600' />}
value={stats.count_errors}
title='Неразмерные'
/>
<ValueStats
id='count_incalculable'
title='Невычислимые'
icon={<IconStatusIncalculable size='1.25rem' className='text-warn-600' />}
value={stats.count_incalculable}
title='Невычислимые'
/>
<ValueStats
id='count_errors'
title='Некорректные'
icon={<IconStatusError size='1.25rem' className='text-warn-600' />}
value={stats.count_errors}
title='Некорректные'
/>
<ValueStats
id='count_base'
title='Базисные множества'
icon={<IconCstBaseSet size='1.25rem' className='clr-text-controls' />}
value={stats.count_base}
title='Базисные множества'
/>
<ValueStats
id='count_constant'
title='Константные множества'
icon={<IconCstConstSet size='1.25rem' className='clr-text-controls' />}
value={stats.count_constant}
title='Константные множества'
/>
<ValueStats
id='count_structured'
title='Родовые структуры'
icon={<IconCstStructured size='1.25rem' className='clr-text-controls' />}
value={stats.count_structured}
title='Родовые структуры'
/>
<ValueStats
id='count_axiom'
title='Аксиомы'
icon={<IconCstAxiom size='1.25rem' className='clr-text-controls' />}
value={stats.count_axiom}
title='Аксиомы'
/>
<ValueStats
id='count_term'
title='Термы'
icon={<IconCstTerm size='1.25rem' className='clr-text-controls' />}
value={stats.count_term}
title='Термы'
/>
<ValueStats
id='count_function'
title='Терм-функции'
icon={<IconCstFunction size='1.25rem' className='clr-text-controls' />}
value={stats.count_function}
title='Терм-функции'
/>
<ValueStats
id='count_predicate'
title='Предикат-функции'
icon={<IconCstPredicate size='1.25rem' className='clr-text-controls' />}
value={stats.count_predicate}
title='Предикат-функции'
/>
<ValueStats
id='count_theorem'
title='Теоремы'
icon={<IconCstTheorem size='1.25rem' className='clr-text-controls' />}
value={stats.count_theorem}
title='Теоремы'
/>
<ValueStats
id='count_text_term'
title='Термины'
icon={<IconTerminology size='1.25rem' className='text-sec-600' />}
value={stats.count_text_term}
title='Термины'
/>
<ValueStats
id='count_definition'
title='Определения'
icon={<IconDefinition size='1.25rem' className='text-sec-600' />}
value={stats.count_definition}
title='Определения'
/>
<ValueStats
id='count_convention'
title='Конвенции'
icon={<IconConvention size='1.25rem' className='text-sec-600' />}
value={stats.count_convention}
title='Конвенции'
/>
</div>
);