mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
D: Improve TSDocs for frontend components
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run
This commit is contained in:
parent
72634e80fa
commit
c1f50d6f50
|
@ -50,6 +50,7 @@ This readme file is used mostly to document project dependencies and conventions
|
||||||
- @uiw/react-codemirror
|
- @uiw/react-codemirror
|
||||||
- @uiw/codemirror-themes
|
- @uiw/codemirror-themes
|
||||||
- @lezer/lr
|
- @lezer/lr
|
||||||
|
- @dagrejs/dagre
|
||||||
</pre>
|
</pre>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
|
|
|
@ -24,7 +24,7 @@ function UserMenu() {
|
||||||
<AnimatePresence mode='wait'>
|
<AnimatePresence mode='wait'>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<AnimateFade key='nav_user_badge_loader'>
|
<AnimateFade key='nav_user_badge_loader'>
|
||||||
<Loader circular size={3} />
|
<Loader circular scale={1.5} />
|
||||||
</AnimateFade>
|
</AnimateFade>
|
||||||
) : null}
|
) : null}
|
||||||
{!user && !loading ? (
|
{!user && !loading ? (
|
||||||
|
|
|
@ -45,6 +45,7 @@ export interface DomIconProps<RequestData> extends IconProps {
|
||||||
value: RequestData;
|
value: RequestData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for library item type. */
|
||||||
export function ItemTypeIcon({ value, size = '1.25rem', className }: DomIconProps<LibraryItemType>) {
|
export function ItemTypeIcon({ value, size = '1.25rem', className }: DomIconProps<LibraryItemType>) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case LibraryItemType.RSFORM:
|
case LibraryItemType.RSFORM:
|
||||||
|
@ -54,6 +55,7 @@ export function ItemTypeIcon({ value, size = '1.25rem', className }: DomIconProp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for access policy. */
|
||||||
export function PolicyIcon({ value, size = '1.25rem', className }: DomIconProps<AccessPolicy>) {
|
export function PolicyIcon({ value, size = '1.25rem', className }: DomIconProps<AccessPolicy>) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case AccessPolicy.PRIVATE:
|
case AccessPolicy.PRIVATE:
|
||||||
|
@ -65,6 +67,7 @@ export function PolicyIcon({ value, size = '1.25rem', className }: DomIconProps<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for visibility. */
|
||||||
export function VisibilityIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
|
export function VisibilityIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
|
||||||
if (value) {
|
if (value) {
|
||||||
return <IconShow size={size} className={className ?? 'clr-text-green'} />;
|
return <IconShow size={size} className={className ?? 'clr-text-green'} />;
|
||||||
|
@ -73,6 +76,7 @@ export function VisibilityIcon({ value, size = '1.25rem', className }: DomIconPr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for subfolders. */
|
||||||
export function SubfoldersIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
|
export function SubfoldersIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
|
||||||
if (value) {
|
if (value) {
|
||||||
return <IconSubfolders size={size} className={className ?? 'clr-text-green'} />;
|
return <IconSubfolders size={size} className={className ?? 'clr-text-green'} />;
|
||||||
|
@ -81,6 +85,7 @@ export function SubfoldersIcon({ value, size = '1.25rem', className }: DomIconPr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for location. */
|
||||||
export function LocationIcon({ value, size = '1.25rem', className }: DomIconProps<string>) {
|
export function LocationIcon({ value, size = '1.25rem', className }: DomIconProps<string>) {
|
||||||
switch (value.substring(0, 2) as LocationHead) {
|
switch (value.substring(0, 2) as LocationHead) {
|
||||||
case LocationHead.COMMON:
|
case LocationHead.COMMON:
|
||||||
|
@ -94,6 +99,7 @@ export function LocationIcon({ value, size = '1.25rem', className }: DomIconProp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for term graph dependency mode. */
|
||||||
export function DependencyIcon({ value, size = '1.25rem', className }: DomIconProps<DependencyMode>) {
|
export function DependencyIcon({ value, size = '1.25rem', className }: DomIconProps<DependencyMode>) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case DependencyMode.ALL:
|
case DependencyMode.ALL:
|
||||||
|
@ -109,6 +115,7 @@ export function DependencyIcon({ value, size = '1.25rem', className }: DomIconPr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for constituenta match mode. */
|
||||||
export function MatchModeIcon({ value, size = '1.25rem', className }: DomIconProps<CstMatchMode>) {
|
export function MatchModeIcon({ value, size = '1.25rem', className }: DomIconProps<CstMatchMode>) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case CstMatchMode.ALL:
|
case CstMatchMode.ALL:
|
||||||
|
@ -124,6 +131,7 @@ export function MatchModeIcon({ value, size = '1.25rem', className }: DomIconPro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for expression status. */
|
||||||
export function StatusIcon({ value, size = '1.25rem', className }: DomIconProps<ExpressionStatus>) {
|
export function StatusIcon({ value, size = '1.25rem', className }: DomIconProps<ExpressionStatus>) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case ExpressionStatus.VERIFIED:
|
case ExpressionStatus.VERIFIED:
|
||||||
|
@ -141,6 +149,7 @@ export function StatusIcon({ value, size = '1.25rem', className }: DomIconProps<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for constituenta type. */
|
||||||
export function CstTypeIcon({ value, size = '1.25rem', className }: DomIconProps<CstType>) {
|
export function CstTypeIcon({ value, size = '1.25rem', className }: DomIconProps<CstType>) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case CstType.BASE:
|
case CstType.BASE:
|
||||||
|
@ -162,6 +171,7 @@ export function CstTypeIcon({ value, size = '1.25rem', className }: DomIconProps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Icon for relocation direction. */
|
||||||
export function RelocateUpIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
|
export function RelocateUpIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
|
||||||
if (value) {
|
if (value) {
|
||||||
return <IconMoveUp size={size} className={className ?? 'clr-text-primary'} />;
|
return <IconMoveUp size={size} className={className ?? 'clr-text-primary'} />;
|
||||||
|
|
|
@ -7,11 +7,19 @@ import { CProps } from '../props';
|
||||||
import TooltipConstituenta from './TooltipConstituenta';
|
import TooltipConstituenta from './TooltipConstituenta';
|
||||||
|
|
||||||
interface BadgeConstituentaProps extends CProps.Styling {
|
interface BadgeConstituentaProps extends CProps.Styling {
|
||||||
|
/** Prefix for tooltip ID. */
|
||||||
prefixID?: string;
|
prefixID?: string;
|
||||||
|
|
||||||
|
/** Constituenta to display. */
|
||||||
value: IConstituenta;
|
value: IConstituenta;
|
||||||
|
|
||||||
|
/** Color theme to use. */
|
||||||
theme: IColorTheme;
|
theme: IColorTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a badge with a constituenta alias and information tooltip.
|
||||||
|
*/
|
||||||
function BadgeConstituenta({ value, prefixID, className, style, theme }: BadgeConstituentaProps) {
|
function BadgeConstituenta({ value, prefixID, className, style, theme }: BadgeConstituentaProps) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -6,9 +6,13 @@ import { colorFgGrammeme } from '@/styling/color';
|
||||||
import { labelGrammeme } from '@/utils/labels';
|
import { labelGrammeme } from '@/utils/labels';
|
||||||
|
|
||||||
interface BadgeGrammemeProps {
|
interface BadgeGrammemeProps {
|
||||||
|
/** Grammeme to display. */
|
||||||
grammeme: GramData;
|
grammeme: GramData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a badge with a grammeme tag.
|
||||||
|
*/
|
||||||
function BadgeGrammeme({ grammeme }: BadgeGrammemeProps) {
|
function BadgeGrammeme({ grammeme }: BadgeGrammemeProps) {
|
||||||
const { colors } = useConceptOptions();
|
const { colors } = useConceptOptions();
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -8,12 +8,22 @@ import { IconHelp } from '../Icons';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface BadgeHelpProps extends CProps.Styling {
|
interface BadgeHelpProps extends CProps.Styling {
|
||||||
|
/** Topic to display in a tooltip. */
|
||||||
topic: HelpTopic;
|
topic: HelpTopic;
|
||||||
|
|
||||||
|
/** Offset from the cursor to the tooltip. */
|
||||||
offset?: number;
|
offset?: number;
|
||||||
|
|
||||||
|
/** Classname for padding. */
|
||||||
padding?: string;
|
padding?: string;
|
||||||
|
|
||||||
|
/** Place of the tooltip in relation to the cursor. */
|
||||||
place?: PlacesType;
|
place?: PlacesType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display help icon with a manual page tooltip.
|
||||||
|
*/
|
||||||
function BadgeHelp({ topic, padding = 'p-1', ...restProps }: BadgeHelpProps) {
|
function BadgeHelp({ topic, padding = 'p-1', ...restProps }: BadgeHelpProps) {
|
||||||
const { showHelp } = useConceptOptions();
|
const { showHelp } = useConceptOptions();
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,13 @@ import { globals } from '@/utils/constants';
|
||||||
import { LocationIcon } from '../DomainIcons';
|
import { LocationIcon } from '../DomainIcons';
|
||||||
|
|
||||||
interface BadgeLocationProps {
|
interface BadgeLocationProps {
|
||||||
|
/** Location to display. */
|
||||||
location: string;
|
location: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays location icon with a full text tooltip.
|
||||||
|
*/
|
||||||
function BadgeLocation({ location }: BadgeLocationProps) {
|
function BadgeLocation({ location }: BadgeLocationProps) {
|
||||||
return (
|
return (
|
||||||
<div className='pl-2' data-tooltip-id={globals.tooltip} data-tooltip-content={location}>
|
<div className='pl-2' data-tooltip-id={globals.tooltip} data-tooltip-content={location}>
|
||||||
|
|
|
@ -3,10 +3,16 @@ import { IWordForm } from '@/models/language';
|
||||||
import BadgeGrammeme from './BadgeGrammeme';
|
import BadgeGrammeme from './BadgeGrammeme';
|
||||||
|
|
||||||
interface BadgeWordFormProps {
|
interface BadgeWordFormProps {
|
||||||
keyPrefix?: string;
|
/** Word form to display. */
|
||||||
form: IWordForm;
|
form: IWordForm;
|
||||||
|
|
||||||
|
/** Prefix for grammemes keys. */
|
||||||
|
keyPrefix?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a badge with grammemes of a word form.
|
||||||
|
*/
|
||||||
function BadgeWordForm({ keyPrefix, form }: BadgeWordFormProps) {
|
function BadgeWordForm({ keyPrefix, form }: BadgeWordFormProps) {
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-wrap justify-start gap-1 select-none w-fit'>
|
<div className='flex flex-wrap justify-start gap-1 select-none w-fit'>
|
||||||
|
|
|
@ -98,8 +98,8 @@ function PickConstituenta({
|
||||||
id={id ? `${id}__search` : undefined}
|
id={id ? `${id}__search` : undefined}
|
||||||
className='clr-input rounded-t-md'
|
className='clr-input rounded-t-md'
|
||||||
noBorder
|
noBorder
|
||||||
value={filterText}
|
query={filterText}
|
||||||
onChange={newValue => setFilterText(newValue)}
|
onChangeQuery={newValue => setFilterText(newValue)}
|
||||||
/>
|
/>
|
||||||
<DataTable
|
<DataTable
|
||||||
id={id}
|
id={id}
|
||||||
|
|
|
@ -132,8 +132,8 @@ function PickMultiConstituenta({
|
||||||
id='dlg_constituents_search'
|
id='dlg_constituents_search'
|
||||||
noBorder
|
noBorder
|
||||||
className='min-w-[6rem] pr-2 flex-grow'
|
className='min-w-[6rem] pr-2 flex-grow'
|
||||||
value={filterText}
|
query={filterText}
|
||||||
onChange={setFilterText}
|
onChangeQuery={setFilterText}
|
||||||
/>
|
/>
|
||||||
<ToolbarGraphSelection
|
<ToolbarGraphSelection
|
||||||
graph={foldedGraph}
|
graph={foldedGraph}
|
||||||
|
|
|
@ -129,8 +129,8 @@ function PickSchema({
|
||||||
id={id ? `${id}__search` : undefined}
|
id={id ? `${id}__search` : undefined}
|
||||||
className='clr-input flex-grow rounded-t-md'
|
className='clr-input flex-grow rounded-t-md'
|
||||||
noBorder
|
noBorder
|
||||||
value={filterText}
|
query={filterText}
|
||||||
onChange={newValue => setFilterText(newValue)}
|
onChangeQuery={newValue => setFilterText(newValue)}
|
||||||
/>
|
/>
|
||||||
<div ref={locationMenu.ref}>
|
<div ref={locationMenu.ref}>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
|
|
@ -25,45 +25,84 @@ import TableHeader from './TableHeader';
|
||||||
|
|
||||||
export { type ColumnSort, createColumnHelper, type RowSelectionState, type VisibilityState };
|
export { type ColumnSort, createColumnHelper, type RowSelectionState, type VisibilityState };
|
||||||
|
|
||||||
|
/** Style to conditionally apply to rows. */
|
||||||
export interface IConditionalStyle<TData> {
|
export interface IConditionalStyle<TData> {
|
||||||
|
/** Callback to determine if the style should be applied. */
|
||||||
when: (rowData: TData) => boolean;
|
when: (rowData: TData) => boolean;
|
||||||
|
|
||||||
|
/** Style to apply. */
|
||||||
style: React.CSSProperties;
|
style: React.CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataTableProps<TData extends RowData>
|
export interface DataTableProps<TData extends RowData>
|
||||||
extends CProps.Styling,
|
extends CProps.Styling,
|
||||||
Pick<TableOptions<TData>, 'data' | 'columns' | 'onRowSelectionChange' | 'onColumnVisibilityChange'> {
|
Pick<TableOptions<TData>, 'data' | 'columns' | 'onRowSelectionChange' | 'onColumnVisibilityChange'> {
|
||||||
|
/** Id of the component. */
|
||||||
id?: string;
|
id?: string;
|
||||||
|
|
||||||
|
/** Indicates that padding should be minimal. */
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
|
|
||||||
|
/** Number of rows to display. */
|
||||||
rows?: number;
|
rows?: number;
|
||||||
|
|
||||||
|
/** Height of the content. */
|
||||||
contentHeight?: string;
|
contentHeight?: string;
|
||||||
|
|
||||||
|
/** Top position of sticky header (0 if no other sticky elements are present). */
|
||||||
headPosition?: string;
|
headPosition?: string;
|
||||||
|
|
||||||
|
/** Disable header. */
|
||||||
noHeader?: boolean;
|
noHeader?: boolean;
|
||||||
|
|
||||||
|
/** Disable footer. */
|
||||||
noFooter?: boolean;
|
noFooter?: boolean;
|
||||||
|
|
||||||
|
/** List of styles to conditionally apply to rows. */
|
||||||
conditionalRowStyles?: IConditionalStyle<TData>[];
|
conditionalRowStyles?: IConditionalStyle<TData>[];
|
||||||
|
|
||||||
|
/** Component to display when there is no data. */
|
||||||
noDataComponent?: React.ReactNode;
|
noDataComponent?: React.ReactNode;
|
||||||
|
|
||||||
|
/** Callback to be called when a row is clicked. */
|
||||||
onRowClicked?: (rowData: TData, event: CProps.EventMouse) => void;
|
onRowClicked?: (rowData: TData, event: CProps.EventMouse) => void;
|
||||||
|
|
||||||
|
/** Callback to be called when a row is double clicked. */
|
||||||
onRowDoubleClicked?: (rowData: TData, event: CProps.EventMouse) => void;
|
onRowDoubleClicked?: (rowData: TData, event: CProps.EventMouse) => void;
|
||||||
|
|
||||||
|
/** Enable row selection. */
|
||||||
enableRowSelection?: boolean;
|
enableRowSelection?: boolean;
|
||||||
|
|
||||||
|
/** Current row selection. */
|
||||||
rowSelection?: RowSelectionState;
|
rowSelection?: RowSelectionState;
|
||||||
|
|
||||||
|
/** Enable hiding of columns. */
|
||||||
enableHiding?: boolean;
|
enableHiding?: boolean;
|
||||||
|
|
||||||
|
/** Current column visibility. */
|
||||||
columnVisibility?: VisibilityState;
|
columnVisibility?: VisibilityState;
|
||||||
|
|
||||||
|
/** Enable pagination. */
|
||||||
enablePagination?: boolean;
|
enablePagination?: boolean;
|
||||||
|
|
||||||
|
/** Number of rows per page. */
|
||||||
paginationPerPage?: number;
|
paginationPerPage?: number;
|
||||||
|
|
||||||
|
/** List of options to choose from for pagination. */
|
||||||
paginationOptions?: number[];
|
paginationOptions?: number[];
|
||||||
|
|
||||||
|
/** Callback to be called when the pagination option is changed. */
|
||||||
onChangePaginationOption?: (newValue: number) => void;
|
onChangePaginationOption?: (newValue: number) => void;
|
||||||
|
|
||||||
|
/** Enable sorting. */
|
||||||
enableSorting?: boolean;
|
enableSorting?: boolean;
|
||||||
|
|
||||||
|
/** Initial sorting. */
|
||||||
initialSorting?: ColumnSort;
|
initialSorting?: ColumnSort;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UI element: data representation as a table.
|
* Dta representation as a table.
|
||||||
*
|
*
|
||||||
* @param headPosition - Top position of sticky header (0 if no other sticky elements are present).
|
* @param headPosition - Top position of sticky header (0 if no other sticky elements are present).
|
||||||
* No sticky header if omitted
|
* No sticky header if omitted
|
||||||
|
|
|
@ -7,18 +7,24 @@ import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||||
import AnimateFade from '../wrap/AnimateFade';
|
import AnimateFade from '../wrap/AnimateFade';
|
||||||
|
|
||||||
interface LoaderProps {
|
interface LoaderProps {
|
||||||
size?: number;
|
/** Scale of the loader from 1 to 10. */
|
||||||
|
scale?: number;
|
||||||
|
|
||||||
|
/** Show a circular loader. */
|
||||||
circular?: boolean;
|
circular?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Loader({ size = 10, circular }: LoaderProps) {
|
/**
|
||||||
|
* Displays animated loader.
|
||||||
|
*/
|
||||||
|
function Loader({ scale = 5, circular }: LoaderProps) {
|
||||||
const { colors } = useConceptOptions();
|
const { colors } = useConceptOptions();
|
||||||
return (
|
return (
|
||||||
<AnimateFade noFadeIn className='flex justify-center'>
|
<AnimateFade noFadeIn className='flex justify-center'>
|
||||||
{circular ? (
|
{circular ? (
|
||||||
<ThreeCircles color={colors.bgPrimary} height={size * 10} width={size * 10} />
|
<ThreeCircles color={colors.bgPrimary} height={scale * 20} width={scale * 20} />
|
||||||
) : (
|
) : (
|
||||||
<ThreeDots color={colors.bgPrimary} height={size * 10} width={size * 10} radius={size} />
|
<ThreeDots color={colors.bgPrimary} height={scale * 20} width={scale * 20} radius={scale * 2} />
|
||||||
)}
|
)}
|
||||||
</AnimateFade>
|
</AnimateFade>
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,11 +5,19 @@ import { globals } from '@/utils/constants';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface MiniButtonProps extends CProps.Button {
|
interface MiniButtonProps extends CProps.Button {
|
||||||
|
/** Icon to display in the button. */
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
|
|
||||||
|
/** Disable hover effect. */
|
||||||
noHover?: boolean;
|
noHover?: boolean;
|
||||||
|
|
||||||
|
/** Disable padding. */
|
||||||
noPadding?: boolean;
|
noPadding?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays small transparent button with an icon.
|
||||||
|
*/
|
||||||
function MiniButton({
|
function MiniButton({
|
||||||
icon,
|
icon,
|
||||||
noHover,
|
noHover,
|
||||||
|
|
|
@ -18,23 +18,46 @@ import MiniButton from './MiniButton';
|
||||||
import Overlay from './Overlay';
|
import Overlay from './Overlay';
|
||||||
|
|
||||||
export interface ModalProps extends CProps.Styling {
|
export interface ModalProps extends CProps.Styling {
|
||||||
|
/** Title of the modal window. */
|
||||||
header?: string;
|
header?: string;
|
||||||
|
|
||||||
|
/** Text of the submit button. */
|
||||||
submitText?: string;
|
submitText?: string;
|
||||||
|
|
||||||
|
/** Tooltip for the submit button when the form is invalid. */
|
||||||
submitInvalidTooltip?: string;
|
submitInvalidTooltip?: string;
|
||||||
|
|
||||||
|
/** Indicates that form is readonly. */
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
|
||||||
|
/** Indicates that submit button is enabled. */
|
||||||
canSubmit?: boolean;
|
canSubmit?: boolean;
|
||||||
|
|
||||||
|
/** Indicates that the modal window should be scrollable. */
|
||||||
overflowVisible?: boolean;
|
overflowVisible?: boolean;
|
||||||
|
|
||||||
|
/** Callback to be called when the modal window is closed. */
|
||||||
hideWindow: () => void;
|
hideWindow: () => void;
|
||||||
|
|
||||||
|
/** Callback to be called before submit. */
|
||||||
beforeSubmit?: () => boolean;
|
beforeSubmit?: () => boolean;
|
||||||
|
|
||||||
|
/** Callback to be called after submit. */
|
||||||
onSubmit?: () => void;
|
onSubmit?: () => void;
|
||||||
|
|
||||||
|
/** Callback to be called after cancel. */
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
|
|
||||||
|
/** Help topic to be displayed in the modal window. */
|
||||||
helpTopic?: HelpTopic;
|
helpTopic?: HelpTopic;
|
||||||
|
|
||||||
|
/** Callback to determine if help should be displayed. */
|
||||||
hideHelpWhen?: () => boolean;
|
hideHelpWhen?: () => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a customizable modal window.
|
||||||
|
*/
|
||||||
function Modal({
|
function Modal({
|
||||||
children,
|
children,
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps content in a div with a centered text.
|
||||||
|
*/
|
||||||
function NoData({ className, children, ...restProps }: CProps.Div) {
|
function NoData({ className, children, ...restProps }: CProps.Div) {
|
||||||
return (
|
return (
|
||||||
<div className={clsx('p-3 flex flex-col items-center text-center select-none w-full', className)} {...restProps}>
|
<div className={clsx('p-3 flex flex-col items-center text-center select-none w-full', className)} {...restProps}>
|
||||||
|
|
|
@ -3,11 +3,19 @@ import clsx from 'clsx';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface OverlayProps extends CProps.Styling {
|
interface OverlayProps extends CProps.Styling {
|
||||||
|
/** Id of the overlay. */
|
||||||
id?: string;
|
id?: string;
|
||||||
|
|
||||||
|
/** Classnames for position of the overlay. */
|
||||||
position?: string;
|
position?: string;
|
||||||
|
|
||||||
|
/** Classname for z-index of the overlay. */
|
||||||
layer?: string;
|
layer?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a transparent overlay over the main content.
|
||||||
|
*/
|
||||||
function Overlay({
|
function Overlay({
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
|
|
|
@ -5,15 +5,26 @@ import { useMemo } from 'react';
|
||||||
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||||
import useWindowSize from '@/hooks/useWindowSize';
|
import useWindowSize from '@/hooks/useWindowSize';
|
||||||
|
|
||||||
|
/** Maximum width of the viewer. */
|
||||||
const MAXIMUM_WIDTH = 1600;
|
const MAXIMUM_WIDTH = 1600;
|
||||||
|
|
||||||
|
/** Minimum width of the viewer. */
|
||||||
const MINIMUM_WIDTH = 300;
|
const MINIMUM_WIDTH = 300;
|
||||||
|
|
||||||
interface PDFViewerProps {
|
interface PDFViewerProps {
|
||||||
|
/** PDF file to display. */
|
||||||
file?: string;
|
file?: string;
|
||||||
|
|
||||||
|
/** Offset from the left side of the window. */
|
||||||
offsetXpx?: number;
|
offsetXpx?: number;
|
||||||
|
|
||||||
|
/** Minimum width of the viewer. */
|
||||||
minWidth?: number;
|
minWidth?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a PDF file using an embedded viewer.
|
||||||
|
*/
|
||||||
function PDFViewer({ file, offsetXpx, minWidth = MINIMUM_WIDTH }: PDFViewerProps) {
|
function PDFViewer({ file, offsetXpx, minWidth = MINIMUM_WIDTH }: PDFViewerProps) {
|
||||||
const windowSize = useWindowSize();
|
const windowSize = useWindowSize();
|
||||||
const { calculateHeight } = useConceptOptions();
|
const { calculateHeight } = useConceptOptions();
|
||||||
|
|
|
@ -2,6 +2,9 @@ interface PrettyJsonProps {
|
||||||
data: unknown;
|
data: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays JSON data in a formatted string.
|
||||||
|
*/
|
||||||
function PrettyJson({ data }: PrettyJsonProps) {
|
function PrettyJson({ data }: PrettyJsonProps) {
|
||||||
return <pre>{JSON.stringify(data, null, 2)}</pre>;
|
return <pre>{JSON.stringify(data, null, 2)}</pre>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,37 @@ import Overlay from './Overlay';
|
||||||
import TextInput from './TextInput';
|
import TextInput from './TextInput';
|
||||||
|
|
||||||
interface SearchBarProps extends CProps.Styling {
|
interface SearchBarProps extends CProps.Styling {
|
||||||
value: string;
|
/** Id of the search bar. */
|
||||||
noIcon?: boolean;
|
|
||||||
id?: string;
|
id?: string;
|
||||||
|
|
||||||
|
/** Search query. */
|
||||||
|
query: string;
|
||||||
|
|
||||||
|
/** Placeholder text. */
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
onChange?: (newValue: string) => void;
|
|
||||||
|
/** Callback to be called when the search query changes. */
|
||||||
|
onChangeQuery?: (newValue: string) => void;
|
||||||
|
|
||||||
|
/** Disable search icon. */
|
||||||
|
noIcon?: boolean;
|
||||||
|
|
||||||
|
/** Disable border. */
|
||||||
noBorder?: boolean;
|
noBorder?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function SearchBar({ id, value, noIcon, onChange, noBorder, placeholder = 'Поиск', ...restProps }: SearchBarProps) {
|
/**
|
||||||
|
* Displays a search bar with a search icon and text input.
|
||||||
|
*/
|
||||||
|
function SearchBar({
|
||||||
|
id,
|
||||||
|
query,
|
||||||
|
noIcon,
|
||||||
|
onChangeQuery,
|
||||||
|
noBorder,
|
||||||
|
placeholder = 'Поиск',
|
||||||
|
...restProps
|
||||||
|
}: SearchBarProps) {
|
||||||
return (
|
return (
|
||||||
<div {...restProps}>
|
<div {...restProps}>
|
||||||
{!noIcon ? (
|
{!noIcon ? (
|
||||||
|
@ -29,8 +51,8 @@ function SearchBar({ id, value, noIcon, onChange, noBorder, placeholder = 'По
|
||||||
type='search'
|
type='search'
|
||||||
className={clsx('outline-none bg-transparent', !noIcon && 'pl-10')}
|
className={clsx('outline-none bg-transparent', !noIcon && 'pl-10')}
|
||||||
noBorder={noBorder}
|
noBorder={noBorder}
|
||||||
value={value}
|
value={query}
|
||||||
onChange={event => (onChange ? onChange(event.target.value) : undefined)}
|
onChange={event => (onChangeQuery ? onChangeQuery(event.target.value) : undefined)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -45,6 +45,9 @@ export interface SelectMultiProps<Option, Group extends GroupBase<Option> = Grou
|
||||||
noPortal?: boolean;
|
noPortal?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a multi-select component.
|
||||||
|
*/
|
||||||
function SelectMulti<Option, Group extends GroupBase<Option> = GroupBase<Option>>({
|
function SelectMulti<Option, Group extends GroupBase<Option> = GroupBase<Option>>({
|
||||||
noPortal,
|
noPortal,
|
||||||
...restProps
|
...restProps
|
||||||
|
|
|
@ -46,6 +46,9 @@ export interface SelectSingleProps<Option, Group extends GroupBase<Option> = Gro
|
||||||
noBorder?: boolean;
|
noBorder?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a single-select component.
|
||||||
|
*/
|
||||||
function SelectSingle<Option, Group extends GroupBase<Option> = GroupBase<Option>>({
|
function SelectSingle<Option, Group extends GroupBase<Option> = GroupBase<Option>>({
|
||||||
noPortal,
|
noPortal,
|
||||||
noBorder,
|
noBorder,
|
||||||
|
|
|
@ -11,22 +11,38 @@ import MiniButton from './MiniButton';
|
||||||
import Overlay from './Overlay';
|
import Overlay from './Overlay';
|
||||||
|
|
||||||
interface SelectTreeProps<ItemType> extends CProps.Styling {
|
interface SelectTreeProps<ItemType> extends CProps.Styling {
|
||||||
items: ItemType[];
|
/** Current value. */
|
||||||
value: ItemType;
|
value: ItemType;
|
||||||
setValue: (newItem: ItemType) => void;
|
|
||||||
getParent: (item: ItemType) => ItemType;
|
/** List of available items. */
|
||||||
getLabel: (item: ItemType) => string;
|
items: ItemType[];
|
||||||
getDescription: (item: ItemType) => string;
|
|
||||||
|
/** Prefix for the ids of the elements. */
|
||||||
prefix: string;
|
prefix: string;
|
||||||
|
|
||||||
|
/** Callback to be called when the value changes. */
|
||||||
|
onChangeValue: (newItem: ItemType) => void;
|
||||||
|
|
||||||
|
/** Callback providing the parent of the item. */
|
||||||
|
getParent: (item: ItemType) => ItemType;
|
||||||
|
|
||||||
|
/** Callback providing the label of the item. */
|
||||||
|
getLabel: (item: ItemType) => string;
|
||||||
|
|
||||||
|
/** Callback providing the description of the item. */
|
||||||
|
getDescription: (item: ItemType) => string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a tree of items and allows user to select one.
|
||||||
|
*/
|
||||||
function SelectTree<ItemType>({
|
function SelectTree<ItemType>({
|
||||||
items,
|
items,
|
||||||
value,
|
value,
|
||||||
getParent,
|
getParent,
|
||||||
getLabel,
|
getLabel,
|
||||||
getDescription,
|
getDescription,
|
||||||
setValue,
|
onChangeValue,
|
||||||
prefix,
|
prefix,
|
||||||
...restProps
|
...restProps
|
||||||
}: SelectTreeProps<ItemType>) {
|
}: SelectTreeProps<ItemType>) {
|
||||||
|
@ -71,9 +87,9 @@ function SelectTree<ItemType>({
|
||||||
(event: CProps.EventMouse, target: ItemType) => {
|
(event: CProps.EventMouse, target: ItemType) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
setValue(target);
|
onChangeValue(target);
|
||||||
},
|
},
|
||||||
[setValue]
|
[onChangeValue]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -5,13 +5,22 @@ import { globals } from '@/utils/constants';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface SelectorButtonProps extends CProps.Button {
|
interface SelectorButtonProps extends CProps.Button {
|
||||||
|
/** Text to display in the button. */
|
||||||
text?: string;
|
text?: string;
|
||||||
|
|
||||||
|
/** Icon to display in the button. */
|
||||||
icon?: React.ReactNode;
|
icon?: React.ReactNode;
|
||||||
|
|
||||||
|
/** Classnames for the colors of the button. */
|
||||||
colors?: string;
|
colors?: string;
|
||||||
|
|
||||||
|
/** Indicates if button background should be transparent. */
|
||||||
transparent?: boolean;
|
transparent?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a button with an icon and text that opens a dropdown menu.
|
||||||
|
*/
|
||||||
function SelectorButton({
|
function SelectorButton({
|
||||||
text,
|
text,
|
||||||
icon,
|
icon,
|
||||||
|
|
|
@ -3,11 +3,19 @@ import clsx from 'clsx';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface SubmitButtonProps extends CProps.Button {
|
interface SubmitButtonProps extends CProps.Button {
|
||||||
|
/** Text to display in the button. */
|
||||||
text?: string;
|
text?: string;
|
||||||
loading?: boolean;
|
|
||||||
|
/** Icon to display in the button. */
|
||||||
icon?: React.ReactNode;
|
icon?: React.ReactNode;
|
||||||
|
|
||||||
|
/** Indicates that loading is in progress. */
|
||||||
|
loading?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays submit type button with icon and text.
|
||||||
|
*/
|
||||||
function SubmitButton({ text = 'ОК', icon, disabled, loading, className, ...restProps }: SubmitButtonProps) {
|
function SubmitButton({ text = 'ОК', icon, disabled, loading, className, ...restProps }: SubmitButtonProps) {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -7,9 +7,13 @@ import { globals } from '@/utils/constants';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface TabLabelProps extends Omit<TabPropsImpl, 'children'>, CProps.Titled {
|
interface TabLabelProps extends Omit<TabPropsImpl, 'children'>, CProps.Titled {
|
||||||
|
/** Label to display in the tab. */
|
||||||
label?: string;
|
label?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a tab header with a label.
|
||||||
|
*/
|
||||||
function TabLabel({ label, title, titleHtml, hideTitle, className, ...otherProps }: TabLabelProps) {
|
function TabLabel({ label, title, titleHtml, hideTitle, className, ...otherProps }: TabLabelProps) {
|
||||||
return (
|
return (
|
||||||
<TabImpl
|
<TabImpl
|
||||||
|
|
|
@ -4,11 +4,19 @@ import { CProps } from '../props';
|
||||||
import Label from './Label';
|
import Label from './Label';
|
||||||
|
|
||||||
export interface TextAreaProps extends CProps.Editor, CProps.Colors, CProps.TextArea {
|
export interface TextAreaProps extends CProps.Editor, CProps.Colors, CProps.TextArea {
|
||||||
|
/** Indicates that padding should be minimal. */
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
|
|
||||||
|
/** Disable resize when content overflows. */
|
||||||
noResize?: boolean;
|
noResize?: boolean;
|
||||||
|
|
||||||
|
/** Disable resize to fit content. */
|
||||||
fitContent?: boolean;
|
fitContent?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a customizable textarea with a label.
|
||||||
|
*/
|
||||||
function TextArea({
|
function TextArea({
|
||||||
id,
|
id,
|
||||||
label,
|
label,
|
||||||
|
|
|
@ -6,11 +6,19 @@ import { truncateToLastWord } from '@/utils/utils';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
export interface TextContentProps extends CProps.Styling {
|
export interface TextContentProps extends CProps.Styling {
|
||||||
|
/** Text to display. */
|
||||||
text: string;
|
text: string;
|
||||||
|
|
||||||
|
/** Maximum number of symbols to display. */
|
||||||
maxLength?: number;
|
maxLength?: number;
|
||||||
|
|
||||||
|
/** Disable full text in a tooltip. */
|
||||||
noTooltip?: boolean;
|
noTooltip?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays text limited to a certain number of symbols.
|
||||||
|
*/
|
||||||
function TextContent({ className, text, maxLength, noTooltip, ...restProps }: TextContentProps) {
|
function TextContent({ className, text, maxLength, noTooltip, ...restProps }: TextContentProps) {
|
||||||
const truncated = maxLength ? truncateToLastWord(text, maxLength) : text;
|
const truncated = maxLength ? truncateToLastWord(text, maxLength) : text;
|
||||||
const isTruncated = maxLength && text.length > maxLength;
|
const isTruncated = maxLength && text.length > maxLength;
|
||||||
|
|
|
@ -4,7 +4,10 @@ import { CProps } from '../props';
|
||||||
import Label from './Label';
|
import Label from './Label';
|
||||||
|
|
||||||
interface TextInputProps extends CProps.Editor, CProps.Colors, CProps.Input {
|
interface TextInputProps extends CProps.Editor, CProps.Colors, CProps.Input {
|
||||||
|
/** Indicates that padding should be minimal. */
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
|
|
||||||
|
/** Capture enter key. */
|
||||||
allowEnter?: boolean;
|
allowEnter?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +17,9 @@ function preventEnterCapture(event: React.KeyboardEvent<HTMLInputElement>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a customizable input with a label.
|
||||||
|
*/
|
||||||
function TextInput({
|
function TextInput({
|
||||||
id,
|
id,
|
||||||
label,
|
label,
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
interface TextURLProps {
|
interface TextURLProps {
|
||||||
|
/** Text to display. */
|
||||||
text: string;
|
text: string;
|
||||||
|
|
||||||
|
/** Tooltip for the link. */
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
||||||
|
/** URL to link to. */
|
||||||
href?: string;
|
href?: string;
|
||||||
|
|
||||||
|
/** Color of the link. */
|
||||||
color?: string;
|
color?: string;
|
||||||
|
|
||||||
|
/** Callback to be called when the link is clicked. */
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a text with a clickable link.
|
||||||
|
*/
|
||||||
function TextURL({ text, href, title, color = 'clr-text-url', onClick }: TextURLProps) {
|
function TextURL({ text, href, title, color = 'clr-text-url', onClick }: TextURLProps) {
|
||||||
const design = `cursor-pointer hover:underline ${color}`;
|
const design = `cursor-pointer hover:underline ${color}`;
|
||||||
if (href) {
|
if (href) {
|
||||||
|
|
|
@ -10,10 +10,16 @@ import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||||
export type { PlacesType } from 'react-tooltip';
|
export type { PlacesType } from 'react-tooltip';
|
||||||
|
|
||||||
interface TooltipProps extends Omit<ITooltip, 'variant'> {
|
interface TooltipProps extends Omit<ITooltip, 'variant'> {
|
||||||
layer?: string;
|
/** Text to display in the tooltip. */
|
||||||
text?: string;
|
text?: string;
|
||||||
|
|
||||||
|
/** Classname for z-index */
|
||||||
|
layer?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays content in a tooltip container.
|
||||||
|
*/
|
||||||
function Tooltip({
|
function Tooltip({
|
||||||
text,
|
text,
|
||||||
children,
|
children,
|
||||||
|
|
|
@ -7,16 +7,34 @@ import { CProps } from '../props';
|
||||||
import MiniButton from './MiniButton';
|
import MiniButton from './MiniButton';
|
||||||
|
|
||||||
interface ValueIconProps extends CProps.Styling, CProps.Titled {
|
interface ValueIconProps extends CProps.Styling, CProps.Titled {
|
||||||
|
/** Id of the component. */
|
||||||
id?: string;
|
id?: string;
|
||||||
icon: React.ReactNode;
|
|
||||||
|
/** Value to display. */
|
||||||
value: string | number;
|
value: string | number;
|
||||||
|
|
||||||
|
/** Icon to display. */
|
||||||
|
icon: React.ReactNode;
|
||||||
|
|
||||||
|
/** Classname for the text. */
|
||||||
textClassName?: string;
|
textClassName?: string;
|
||||||
|
|
||||||
|
/** Callback to be called when the component is clicked. */
|
||||||
onClick?: (event: CProps.EventMouse) => void;
|
onClick?: (event: CProps.EventMouse) => void;
|
||||||
|
|
||||||
|
/** Number of symbols to display in a small size. */
|
||||||
smallThreshold?: number;
|
smallThreshold?: number;
|
||||||
|
|
||||||
|
/** Indicates that padding should be minimal. */
|
||||||
dense?: boolean;
|
dense?: boolean;
|
||||||
|
|
||||||
|
/** Disable interaction. */
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a value with an icon that can be clicked.
|
||||||
|
*/
|
||||||
function ValueIcon({
|
function ValueIcon({
|
||||||
id,
|
id,
|
||||||
dense,
|
dense,
|
||||||
|
|
|
@ -3,12 +3,22 @@ import clsx from 'clsx';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
interface ValueLabeledProps extends CProps.Styling {
|
interface ValueLabeledProps extends CProps.Styling {
|
||||||
|
/** Id of the component. */
|
||||||
id?: string;
|
id?: string;
|
||||||
|
|
||||||
|
/** Label to display. */
|
||||||
label: string;
|
label: string;
|
||||||
|
|
||||||
|
/** Value to display. */
|
||||||
text: string | number;
|
text: string | number;
|
||||||
|
|
||||||
|
/** Tooltip for the component. */
|
||||||
title?: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a labeled value.
|
||||||
|
*/
|
||||||
function ValueLabeled({ id, label, text, title, className, ...restProps }: ValueLabeledProps) {
|
function ValueLabeled({ id, label, text, title, className, ...restProps }: ValueLabeledProps) {
|
||||||
return (
|
return (
|
||||||
<div className={clsx('flex justify-between gap-6', className)} {...restProps}>
|
<div className={clsx('flex justify-between gap-6', className)} {...restProps}>
|
||||||
|
|
|
@ -4,11 +4,19 @@ import { CProps } from '../props';
|
||||||
import ValueIcon from './ValueIcon';
|
import ValueIcon from './ValueIcon';
|
||||||
|
|
||||||
interface ValueStatsProps extends CProps.Styling, CProps.Titled {
|
interface ValueStatsProps extends CProps.Styling, CProps.Titled {
|
||||||
|
/** Id of the component. */
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
|
/** Icon to display. */
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
|
|
||||||
|
/** Value to display. */
|
||||||
value: string | number;
|
value: string | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays statistics value with an icon.
|
||||||
|
*/
|
||||||
function ValueStats(props: ValueStatsProps) {
|
function ValueStats(props: ValueStatsProps) {
|
||||||
return <ValueIcon dense smallThreshold={PARAMETER.statSmallThreshold} textClassName='min-w-[1.4rem]' {...props} />;
|
return <ValueIcon dense smallThreshold={PARAMETER.statSmallThreshold} textClassName='min-w-[1.4rem]' {...props} />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,8 +190,8 @@ function ToolbarSearch({
|
||||||
placeholder='Поиск'
|
placeholder='Поиск'
|
||||||
noBorder
|
noBorder
|
||||||
className={clsx('min-w-[7rem] sm:min-w-[10rem] max-w-[20rem]', folderMode && 'flex-grow')}
|
className={clsx('min-w-[7rem] sm:min-w-[10rem] max-w-[20rem]', folderMode && 'flex-grow')}
|
||||||
value={query}
|
query={query}
|
||||||
onChange={onChangeQuery}
|
onChangeQuery={onChangeQuery}
|
||||||
/>
|
/>
|
||||||
{!folderMode ? (
|
{!folderMode ? (
|
||||||
<div ref={headMenu.ref} className='flex items-center h-full py-1 select-none'>
|
<div ref={headMenu.ref} className='flex items-center h-full py-1 select-none'>
|
||||||
|
@ -249,8 +249,8 @@ function ToolbarSearch({
|
||||||
noIcon
|
noIcon
|
||||||
noBorder
|
noBorder
|
||||||
className='w-[4.5rem] sm:w-[5rem] flex-grow'
|
className='w-[4.5rem] sm:w-[5rem] flex-grow'
|
||||||
value={path}
|
query={path}
|
||||||
onChange={onChangePath}
|
onChangeQuery={onChangePath}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -69,7 +69,7 @@ function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownProps) {
|
||||||
<SelectTree
|
<SelectTree
|
||||||
items={Object.values(HelpTopic).map(item => item as HelpTopic)}
|
items={Object.values(HelpTopic).map(item => item as HelpTopic)}
|
||||||
value={activeTopic}
|
value={activeTopic}
|
||||||
setValue={handleSelectTopic}
|
onChangeValue={handleSelectTopic}
|
||||||
prefix={prefixes.topic_list}
|
prefix={prefixes.topic_list}
|
||||||
getParent={item => topicParent.get(item) ?? item}
|
getParent={item => topicParent.get(item) ?? item}
|
||||||
getLabel={labelHelpTopic}
|
getLabel={labelHelpTopic}
|
||||||
|
|
|
@ -17,7 +17,7 @@ function TopicsStatic({ activeTopic, onChangeTopic }: TopicsStaticProps) {
|
||||||
<SelectTree
|
<SelectTree
|
||||||
items={Object.values(HelpTopic).map(item => item as HelpTopic)}
|
items={Object.values(HelpTopic).map(item => item as HelpTopic)}
|
||||||
value={activeTopic}
|
value={activeTopic}
|
||||||
setValue={onChangeTopic}
|
onChangeValue={onChangeTopic}
|
||||||
prefix={prefixes.topic_list}
|
prefix={prefixes.topic_list}
|
||||||
getParent={item => topicParent.get(item) ?? item}
|
getParent={item => topicParent.get(item) ?? item}
|
||||||
getLabel={labelHelpTopic}
|
getLabel={labelHelpTopic}
|
||||||
|
|
|
@ -54,7 +54,7 @@ function StatusBar({ isModified, processing, activeCst, parseData, onAnalyze }:
|
||||||
onClick={onAnalyze}
|
onClick={onAnalyze}
|
||||||
>
|
>
|
||||||
<AnimatePresence mode='wait'>
|
<AnimatePresence mode='wait'>
|
||||||
{processing ? <Loader key='status-loader' size={3} /> : null}
|
{processing ? <Loader key='status-loader' scale={3} /> : null}
|
||||||
{!processing ? (
|
{!processing ? (
|
||||||
<>
|
<>
|
||||||
<StatusIcon key='status-icon' size='1rem' value={status} />
|
<StatusIcon key='status-icon' size='1rem' value={status} />
|
||||||
|
|
|
@ -152,8 +152,8 @@ function EditorRSList({ onOpenEdit }: EditorRSListProps) {
|
||||||
id='constituents_search'
|
id='constituents_search'
|
||||||
noBorder
|
noBorder
|
||||||
className='w-[8rem]'
|
className='w-[8rem]'
|
||||||
value={filterText}
|
query={filterText}
|
||||||
onChange={setFilterText}
|
onChangeQuery={setFilterText}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -74,8 +74,8 @@ function ConstituentsSearch({ schema, activeID, activeExpression, dense, setFilt
|
||||||
id='constituents_search'
|
id='constituents_search'
|
||||||
noBorder
|
noBorder
|
||||||
className='min-w-[6rem] pr-2 flex-grow'
|
className='min-w-[6rem] pr-2 flex-grow'
|
||||||
value={filterText}
|
query={filterText}
|
||||||
onChange={setFilterText}
|
onChangeQuery={setFilterText}
|
||||||
/>
|
/>
|
||||||
{selectMatchMode}
|
{selectMatchMode}
|
||||||
{selectGraph}
|
{selectGraph}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user