F: Rework colors using tailwind configs

This commit is contained in:
Ivan 2024-12-16 23:51:31 +03:00
parent c7f155bba1
commit e70f7e45b9
74 changed files with 536 additions and 782 deletions

View File

@ -13,7 +13,7 @@ function ApplicationLayout() {
const { viewportHeight, mainHeight, showScroll } = useConceptOptions();
return (
<NavigationState>
<div className='min-w-[20rem] clr-app antialiased h-full max-w-[120rem] mx-auto'>
<div className='min-w-[20rem] antialiased h-full max-w-[120rem] mx-auto'>
<ConceptToaster
className='mt-[4rem] text-[14px]' // prettier: split lines
autoClose={3000}

View File

@ -5,7 +5,7 @@ import Button from '../components/ui/Button';
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
return (
<div className='flex flex-col gap-3 items-center antialiased clr-app' role='alert'>
<div className='flex flex-col gap-3 items-center antialiased' role='alert'>
<h1>Что-то пошло не так!</h1>
<Button onClick={resetErrorBoundary} text='Попробовать еще раз' />
<InfoError error={error as Error} />

View File

@ -29,7 +29,6 @@ function Navigation() {
className={clsx(
'z-navigation', // prettier: split lines
'sticky top-0 left-0 right-0',
'clr-app',
'select-none'
)}
>

View File

@ -63,6 +63,7 @@ function UserDropdown({ isOpen, hideDropdown }: UserDropdownProps) {
function handleToggleDarkMode() {
toggleDarkMode();
hideDropdown();
}
return (

View File

@ -51,7 +51,7 @@ export function ItemTypeIcon({ value, size = '1.25rem', className }: DomIconProp
case LibraryItemType.RSFORM:
return <IconRSForm size={size} className={className ?? 'clr-text-primary'} />;
case LibraryItemType.OSS:
return <IconOSS size={size} className={className ?? 'clr-text-green'} />;
return <IconOSS size={size} className={className ?? 'text-ok-600'} />;
}
}
@ -59,27 +59,27 @@ export function ItemTypeIcon({ value, size = '1.25rem', className }: DomIconProp
export function PolicyIcon({ value, size = '1.25rem', className }: DomIconProps<AccessPolicy>) {
switch (value) {
case AccessPolicy.PRIVATE:
return <IconPrivate size={size} className={className ?? 'clr-text-red'} />;
return <IconPrivate size={size} className={className ?? 'text-warn-600'} />;
case AccessPolicy.PROTECTED:
return <IconProtected size={size} className={className ?? 'clr-text-primary'} />;
case AccessPolicy.PUBLIC:
return <IconPublic size={size} className={className ?? 'clr-text-green'} />;
return <IconPublic size={size} className={className ?? 'text-ok-600'} />;
}
}
/** Icon for visibility. */
export function VisibilityIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
if (value) {
return <IconShow size={size} className={className ?? 'clr-text-green'} />;
return <IconShow size={size} className={className ?? 'text-ok-600'} />;
} else {
return <IconHide size={size} className={className ?? 'clr-text-red'} />;
return <IconHide size={size} className={className ?? 'text-warn-600'} />;
}
}
/** Icon for subfolders. */
export function SubfoldersIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
if (value) {
return <IconSubfolders size={size} className={className ?? 'clr-text-green'} />;
return <IconSubfolders size={size} className={className ?? 'text-ok-600'} />;
} else {
return <IconSubfolders size={size} className={className ?? 'clr-text-primary'} />;
}
@ -91,11 +91,11 @@ export function LocationIcon({ value, size = '1.25rem', className }: DomIconProp
case LocationHead.COMMON:
return <IconPublic size={size} className={className ?? 'clr-text-primary'} />;
case LocationHead.LIBRARY:
return <IconTemplates size={size} className={className ?? 'clr-text-red'} />;
return <IconTemplates size={size} className={className ?? 'text-warn-600'} />;
case LocationHead.PROJECTS:
return <IconBusiness size={size} className={className ?? 'clr-text-primary'} />;
case LocationHead.USER:
return <IconUser size={size} className={className ?? 'clr-text-green'} />;
return <IconUser size={size} className={className ?? 'text-ok-600'} />;
}
}
@ -153,21 +153,21 @@ export function StatusIcon({ value, size = '1.25rem', className }: DomIconProps<
export function CstTypeIcon({ value, size = '1.25rem', className }: DomIconProps<CstType>) {
switch (value) {
case CstType.BASE:
return <IconCstBaseSet size={size} className={className ?? 'clr-text-green'} />;
return <IconCstBaseSet size={size} className={className ?? 'text-ok-600'} />;
case CstType.CONSTANT:
return <IconCstConstSet size={size} className={className ?? 'clr-text-green'} />;
return <IconCstConstSet size={size} className={className ?? 'text-ok-600'} />;
case CstType.STRUCTURED:
return <IconCstStructured size={size} className={className ?? 'clr-text-green'} />;
return <IconCstStructured size={size} className={className ?? 'text-ok-600'} />;
case CstType.TERM:
return <IconCstTerm size={size} className={className ?? 'clr-text-primary'} />;
case CstType.AXIOM:
return <IconCstAxiom size={size} className={className ?? 'clr-text-red'} />;
return <IconCstAxiom size={size} className={className ?? 'text-warn-600'} />;
case CstType.FUNCTION:
return <IconCstFunction size={size} className={className ?? 'clr-text-primary'} />;
case CstType.PREDICATE:
return <IconCstPredicate size={size} className={className ?? 'clr-text-red'} />;
return <IconCstPredicate size={size} className={className ?? 'text-warn-600'} />;
case CstType.THEOREM:
return <IconCstTheorem size={size} className={className ?? 'clr-text-red'} />;
return <IconCstTheorem size={size} className={className ?? 'text-warn-600'} />;
}
}

View File

@ -13,6 +13,7 @@ import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ConstituentaID, IRSForm } from '@/models/rsform';
import { generateAlias, getCstTypePrefix, guessCstType } from '@/models/rsformAPI';
import { extractGlobals } from '@/models/rslangAPI';
import { APP_COLORS } from '@/styling/color';
import { ccBracketMatching } from './bracketMatching';
import { rsNavigation } from './clickNavigation';
@ -63,7 +64,7 @@ const RSInput = forwardRef<ReactCodeMirrorRef, RSInputProps>(
},
ref
) => {
const { darkMode, colors } = useConceptOptions();
const { darkMode } = useConceptOptions();
const internalRef = useRef<ReactCodeMirrorRef>(null);
const thisRef = !ref || typeof ref === 'function' ? internalRef : ref;
@ -73,27 +74,27 @@ const RSInput = forwardRef<ReactCodeMirrorRef, RSInputProps>(
theme: darkMode ? 'dark' : 'light',
settings: {
fontFamily: 'inherit',
background: !disabled ? colors.bgInput : colors.bgDefault,
foreground: colors.fgDefault,
selection: colors.bgHover,
caret: colors.fgDefault
background: !disabled ? APP_COLORS.bgInput : APP_COLORS.bgDefault,
foreground: APP_COLORS.fgDefault,
selection: APP_COLORS.bgHover,
caret: APP_COLORS.fgDefault
},
styles: [
{ tag: tags.name, color: colors.fgPurple, cursor: schema ? 'default' : cursor }, // GlobalID
{ tag: tags.variableName, color: colors.fgGreen }, // LocalID
{ tag: tags.propertyName, color: colors.fgTeal }, // Radical
{ tag: tags.keyword, color: colors.fgBlue }, // keywords
{ tag: tags.literal, color: colors.fgBlue }, // literals
{ tag: tags.name, color: APP_COLORS.fgPurple, cursor: schema ? 'default' : cursor }, // GlobalID
{ tag: tags.variableName, color: APP_COLORS.fgGreen }, // LocalID
{ tag: tags.propertyName, color: APP_COLORS.fgTeal }, // Radical
{ tag: tags.keyword, color: APP_COLORS.fgBlue }, // keywords
{ tag: tags.literal, color: APP_COLORS.fgBlue }, // literals
{ tag: tags.controlKeyword, fontWeight: '400' }, // R | I | D
{ tag: tags.unit, fontSize: '0.75rem' }, // indices
{ tag: tags.brace, color: colors.fgPurple, fontWeight: '600' } // braces (curly brackets)
{ tag: tags.brace, color: APP_COLORS.fgPurple, fontWeight: '600' } // braces (curly brackets)
]
});
const editorExtensions = [
EditorView.lineWrapping,
RSLanguage,
ccBracketMatching(darkMode),
ccBracketMatching(),
...(!schema || !onOpenEdit ? [] : [rsNavigation(schema, onOpenEdit)]),
...(noTooltip || !schema ? [] : [rsHoverTooltip(schema, onOpenEdit !== undefined)])
];

View File

@ -1,7 +1,7 @@
import { bracketMatching, MatchResult } from '@codemirror/language';
import { Decoration, EditorView } from '@codemirror/view';
import { bracketsDarkT, bracketsLightT } from '@/styling/color';
import { BRACKETS_THEME } from '@/styling/color';
const matchingMark = Decoration.mark({ class: 'cc-matchingBracket' });
const nonMatchingMark = Decoration.mark({ class: 'cc-nonmatchingBracket' });
@ -16,16 +16,14 @@ function bracketRender(match: MatchResult) {
return decorations;
}
const darkTheme = EditorView.baseTheme(bracketsDarkT);
const theme = EditorView.baseTheme(BRACKETS_THEME);
const lightTheme = EditorView.baseTheme(bracketsLightT);
export function ccBracketMatching(darkMode: boolean) {
export function ccBracketMatching() {
return [
bracketMatching({
renderMatch: bracketRender,
brackets: '{}[]()'
}),
darkMode ? darkTheme : lightTheme
theme
];
}

View File

@ -13,6 +13,7 @@ import { useConceptOptions } from '@/context/ConceptOptionsContext';
import DlgEditReference from '@/dialogs/DlgEditReference';
import { ReferenceType } from '@/models/language';
import { ConstituentaID, IRSForm } from '@/models/rsform';
import { APP_COLORS } from '@/styling/color';
import { CodeMirrorWrapper } from '@/utils/codemirror';
import { PARAMETER } from '@/utils/constants';
@ -91,7 +92,7 @@ const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
},
ref
) => {
const { darkMode, colors } = useConceptOptions();
const { darkMode } = useConceptOptions();
const [isFocused, setIsFocused] = useState(false);
@ -110,15 +111,15 @@ const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
theme: darkMode ? 'dark' : 'light',
settings: {
fontFamily: 'inherit',
background: !disabled ? colors.bgInput : colors.bgDefault,
foreground: colors.fgDefault,
selection: colors.bgHover,
caret: colors.fgDefault
background: !disabled ? APP_COLORS.bgInput : APP_COLORS.bgDefault,
foreground: APP_COLORS.fgDefault,
selection: APP_COLORS.bgHover,
caret: APP_COLORS.fgDefault
},
styles: [
{ tag: tags.name, color: colors.fgPurple, cursor: 'default' }, // EntityReference
{ tag: tags.literal, color: colors.fgTeal, cursor: 'default' }, // SyntacticReference
{ tag: tags.comment, color: colors.fgRed } // Error
{ tag: tags.name, color: APP_COLORS.fgPurple, cursor: 'default' }, // EntityReference
{ tag: tags.literal, color: APP_COLORS.fgTeal, cursor: 'default' }, // SyntacticReference
{ tag: tags.comment, color: APP_COLORS.fgRed } // Error
]
});
@ -127,7 +128,7 @@ const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
EditorView.contentAttributes.of({ spellcheck: 'true' }),
NaturalLanguage,
...(!schema || !onOpenEdit ? [] : [refsNavigation(schema, onOpenEdit)]),
...(schema ? [refsHoverTooltip(schema, colors, onOpenEdit !== undefined)] : [])
...(schema ? [refsHoverTooltip(schema, onOpenEdit !== undefined)] : [])
];
function handleChange(newValue: string) {

View File

@ -4,7 +4,6 @@ import { hoverTooltip } from '@codemirror/view';
import { IEntityReference, ISyntacticReference } from '@/models/language';
import { IRSForm } from '@/models/rsform';
import { IColorTheme } from '@/styling/color';
import {
domTooltipEntityReference,
domTooltipSyntacticReference,
@ -14,7 +13,7 @@ import {
import { RefEntity } from './parse/parser.terms';
export const tooltipProducer = (schema: IRSForm, colors: IColorTheme, canClick?: boolean) => {
export const tooltipProducer = (schema: IRSForm, canClick?: boolean) => {
return hoverTooltip((view, pos) => {
const parse = findReferenceAt(pos, view.state);
if (!parse) {
@ -27,7 +26,7 @@ export const tooltipProducer = (schema: IRSForm, colors: IColorTheme, canClick?:
pos: parse.start,
end: parse.end,
above: false,
create: () => domTooltipEntityReference(parse.ref as IEntityReference, cst, colors, canClick)
create: () => domTooltipEntityReference(parse.ref as IEntityReference, cst, canClick)
};
} else {
let masterText: string | undefined = undefined;
@ -54,6 +53,6 @@ export const tooltipProducer = (schema: IRSForm, colors: IColorTheme, canClick?:
});
};
export function refsHoverTooltip(schema: IRSForm, colors: IColorTheme, canClick?: boolean): Extension {
return [tooltipProducer(schema, colors, canClick)];
export function refsHoverTooltip(schema: IRSForm, canClick?: boolean): Extension {
return [tooltipProducer(schema, canClick)];
}

View File

@ -1,7 +1,7 @@
import clsx from 'clsx';
import { CstClass, IConstituenta } from '@/models/rsform';
import { colorFgCstStatus, IColorTheme } from '@/styling/color';
import { APP_COLORS, colorFgCstStatus } from '@/styling/color';
import { CProps } from '../props';
import TooltipConstituenta from './TooltipConstituenta';
@ -12,15 +12,12 @@ interface BadgeConstituentaProps extends CProps.Styling {
/** Constituenta to display. */
value: IConstituenta;
/** Color theme to use. */
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 }: BadgeConstituentaProps) {
return (
<div
id={`${prefixID}${value.id}`}
@ -33,9 +30,9 @@ function BadgeConstituenta({ value, prefixID, className, style, theme }: BadgeCo
className
)}
style={{
borderColor: colorFgCstStatus(value.status, theme),
color: colorFgCstStatus(value.status, theme),
backgroundColor: value.cst_class === CstClass.BASIC ? theme.bgGreen25 : theme.bgInput,
borderColor: colorFgCstStatus(value.status),
color: colorFgCstStatus(value.status),
backgroundColor: value.cst_class === CstClass.BASIC ? APP_COLORS.bgGreen25 : APP_COLORS.bgInput,
...style
}}
>

View File

@ -1,8 +1,7 @@
import clsx from 'clsx';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { GramData } from '@/models/language';
import { colorFgGrammeme } from '@/styling/color';
import { APP_COLORS, colorFgGrammeme } from '@/styling/color';
import { labelGrammeme } from '@/utils/labels';
interface BadgeGrammemeProps {
@ -14,7 +13,6 @@ interface BadgeGrammemeProps {
* Displays a badge with a grammeme tag.
*/
function BadgeGrammeme({ grammeme }: BadgeGrammemeProps) {
const { colors } = useConceptOptions();
return (
<div
className={clsx(
@ -24,9 +22,9 @@ function BadgeGrammeme({ grammeme }: BadgeGrammemeProps) {
'text-sm font-medium text-center whitespace-nowrap'
)}
style={{
borderColor: colorFgGrammeme(grammeme, colors),
color: colorFgGrammeme(grammeme, colors),
backgroundColor: colors.bgInput
borderColor: colorFgGrammeme(grammeme),
color: colorFgGrammeme(grammeme),
backgroundColor: APP_COLORS.bgInput
}}
>
{labelGrammeme(grammeme)}

View File

@ -1,6 +1,5 @@
import clsx from 'clsx';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { CstClass } from '@/models/rsform';
import { colorBgCstClass } from '@/styling/color';
import { prefixes } from '@/utils/constants';
@ -11,8 +10,6 @@ interface InfoCstClassProps {
}
function InfoCstClass({ header }: InfoCstClassProps) {
const { colors } = useConceptOptions();
return (
<div className='flex flex-col gap-1 mb-2 dense'>
{header ? <h1>{header}</h1> : null}
@ -21,7 +18,7 @@ function InfoCstClass({ header }: InfoCstClassProps) {
<p key={`${prefixes.cst_status_list}${index}`}>
<span
className={clsx('inline-block', 'min-w-[7rem]', 'px-1', 'border', 'text-center text-sm font-controls')}
style={{ backgroundColor: colorBgCstClass(cstClass, colors) }}
style={{ backgroundColor: colorBgCstClass(cstClass) }}
>
{labelCstClass(cstClass)}
</span>

View File

@ -1,6 +1,5 @@
import clsx from 'clsx';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ExpressionStatus } from '@/models/rsform';
import { colorBgCstStatus } from '@/styling/color';
import { prefixes } from '@/utils/constants';
@ -11,8 +10,6 @@ interface InfoCstStatusProps {
}
function InfoCstStatus({ title }: InfoCstStatusProps) {
const { colors } = useConceptOptions();
return (
<div className='flex flex-col gap-1 mb-2 dense'>
{title ? <h1>{title}</h1> : null}
@ -28,7 +25,7 @@ function InfoCstStatus({ title }: InfoCstStatusProps) {
'border',
'text-center text-sm font-controls'
)}
style={{ backgroundColor: colorBgCstStatus(status, colors) }}
style={{ backgroundColor: colorBgCstStatus(status) }}
>
{labelExpressionStatus(status)}
</span>

View File

@ -63,8 +63,7 @@ function InfoError({ error }: InfoErrorProps) {
'cc-fade-in',
'min-w-[25rem]',
'px-3 py-2 flex flex-col',
'clr-text-red',
'text-sm font-semibold',
'text-warn-600 text-sm font-semibold',
'select-text'
)}
>

View File

@ -5,10 +5,10 @@ import { useEffect, useState } from 'react';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import SearchBar from '@/components/ui/SearchBar';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { CstMatchMode } from '@/models/miscellaneous';
import { IConstituenta } from '@/models/rsform';
import { matchConstituenta } from '@/models/rsformAPI';
import { APP_COLORS } from '@/styling/color';
import { prefixes } from '@/utils/constants';
import { describeConstituenta } from '@/utils/labels';
@ -47,7 +47,6 @@ function PickConstituenta({
className,
...restProps
}: PickConstituentaProps) {
const { colors } = useConceptOptions();
const [filteredData, setFilteredData] = useState<IConstituenta[]>([]);
const [filterText, setFilterText] = useState(initialFilter);
@ -70,7 +69,7 @@ function PickConstituenta({
size: 65,
minSize: 65,
maxSize: 65,
cell: props => <BadgeConstituenta theme={colors} value={props.row.original} prefixID={prefixID} />
cell: props => <BadgeConstituenta value={props.row.original} prefixID={prefixID} />
}),
columnHelper.accessor(cst => describeFunc(cst), {
id: 'description',
@ -82,7 +81,7 @@ function PickConstituenta({
const conditionalRowStyles: IConditionalStyle<IConstituenta>[] = [
{
when: (cst: IConstituenta) => cst.id === value?.id,
style: { backgroundColor: colors.bgSelected }
style: { backgroundColor: APP_COLORS.bgSelected }
}
];

View File

@ -4,7 +4,6 @@ import clsx from 'clsx';
import { useEffect, useState } from 'react';
import DataTable, { createColumnHelper, RowSelectionState } from '@/components/ui/DataTable';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { Graph } from '@/models/Graph';
import { CstMatchMode } from '@/models/miscellaneous';
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
@ -44,7 +43,6 @@ function PickMultiConstituenta({
className,
...restProps
}: PickMultiConstituentaProps) {
const { colors } = useConceptOptions();
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
const [filtered, setFiltered] = useState<IConstituenta[]>(data);
const [filterText, setFilterText] = useState('');
@ -111,7 +109,7 @@ function PickMultiConstituenta({
id: 'alias',
header: () => <span className='pl-3'>Имя</span>,
size: 65,
cell: props => <BadgeConstituenta theme={colors} value={props.row.original} prefixID={prefixID} />
cell: props => <BadgeConstituenta value={props.row.original} prefixID={prefixID} />
}),
columnHelper.accessor(cst => describeConstituenta(cst), {
id: 'description',

View File

@ -4,11 +4,11 @@ import { useIntl } from 'react-intl';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import SearchBar from '@/components/ui/SearchBar';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useLibrary } from '@/context/LibraryContext';
import useDropdown from '@/hooks/useDropdown';
import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
import { matchLibraryItem } from '@/models/libraryAPI';
import { APP_COLORS } from '@/styling/color';
import { prefixes } from '@/utils/constants';
import { IconClose, IconFolderTree } from '../Icons';
@ -45,7 +45,6 @@ function PickSchema({
...restProps
}: PickSchemaProps) {
const intl = useIntl();
const { colors } = useConceptOptions();
const { folders } = useLibrary();
const [filterText, setFilterText] = useState(initialFilter);
@ -99,7 +98,7 @@ function PickSchema({
const conditionalRowStyles: IConditionalStyle<ILibraryItem>[] = [
{
when: (item: ILibraryItem) => item.id === value,
style: { backgroundColor: colors.bgSelected }
style: { backgroundColor: APP_COLORS.bgSelected }
}
];

View File

@ -8,10 +8,10 @@ import BadgeConstituenta from '@/components/info/BadgeConstituenta';
import SelectConstituenta from '@/components/select/SelectConstituenta';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import MiniButton from '@/components/ui/MiniButton';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ILibraryItem } from '@/models/library';
import { ICstSubstitute, IMultiSubstitution } from '@/models/oss';
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
import { APP_COLORS } from '@/styling/color';
import { errors } from '@/utils/labels';
import { IconAccept, IconPageLeft, IconPageRight, IconRemove, IconReplace } from '../Icons';
@ -46,8 +46,6 @@ function PickSubstitutions({
className,
...restProps
}: PickSubstitutionsProps) {
const { colors } = useConceptOptions();
const [leftArgument, setLeftArgument] = useState<ILibraryItem | undefined>(
schemas.length === 1 ? schemas[0] : undefined
);
@ -164,11 +162,7 @@ function PickSubstitutions({
id: 'left_alias',
size: 65,
cell: props => (
<BadgeConstituenta
theme={colors}
value={props.row.original.substitution}
prefixID={`${prefixID}_${props.row.index}_1_`}
/>
<BadgeConstituenta value={props.row.original.substitution} prefixID={`${prefixID}_${props.row.index}_1_`} />
)
}),
columnHelper.display({
@ -180,11 +174,7 @@ function PickSubstitutions({
id: 'right_alias',
size: 65,
cell: props => (
<BadgeConstituenta
theme={colors}
value={props.row.original.original}
prefixID={`${prefixID}_${props.row.index}_2_`}
/>
<BadgeConstituenta value={props.row.original.original} prefixID={`${prefixID}_${props.row.index}_2_`} />
)
}),
columnHelper.accessor(item => item.original_source.alias, {
@ -227,9 +217,7 @@ function PickSubstitutions({
const conditionalRowStyles: IConditionalStyle<IMultiSubstitution>[] = [
{
when: (item: IMultiSubstitution) => item.is_suggestion,
style: {
backgroundColor: colors.bgOrange50
}
style: { backgroundColor: APP_COLORS.bgOrange50 }
}
];

View File

@ -68,7 +68,7 @@ function Checkbox({
'border rounded-sm',
{
'clr-primary': value !== false,
'clr-app': value === false
'bg-app-100': value === false
}
)}
>

View File

@ -69,7 +69,7 @@ function CheckboxTristate({
'border rounded-sm',
{
'clr-primary': value !== false,
'clr-app': value === false
'bg-app-100': value === false
}
)}
>

View File

@ -64,7 +64,7 @@ function PaginationTools<TData>({
<input
id={id ? `${id}__page` : undefined}
title='Номер страницы. Выделите для ручного ввода'
className='w-6 text-center clr-app'
className='w-6 text-center bg-app-100'
value={table.getState().pagination.pageIndex + 1}
onChange={event => {
const page = event.target.value ? Number(event.target.value) - 1 : 0;
@ -94,7 +94,7 @@ function PaginationTools<TData>({
id={id ? `${id}__per_page` : undefined}
value={table.getState().pagination.pageSize}
onChange={handlePaginationOptionsChange}
className='mx-2 cursor-pointer clr-app'
className='mx-2 cursor-pointer bg-app-100'
>
{paginationOptions.map(pageSize => (
<option key={`${prefixes.page_size}${pageSize}`} value={pageSize}>

View File

@ -71,13 +71,9 @@ function TableBody<TData>({
<tr
key={row.id}
className={clsx(
'cc-scroll-row',
'cc-scroll-row clr-hover',
!noHeader && 'scroll-mt-[calc(2px+2rem)]',
row.getIsSelected()
? 'clr-selected clr-hover'
: index % 2 === 0
? 'clr-controls clr-hover'
: 'clr-app clr-hover'
row.getIsSelected() ? 'clr-selected' : index % 2 === 0 ? 'clr-controls' : 'bg-app-100'
)}
style={{ ...(conditionalRowStyles ? getRowStyles(row) : []) }}
>

View File

@ -22,7 +22,7 @@ function TableHeader<TData>({
}: TableHeaderProps<TData>) {
return (
<thead
className='clr-app cc-shadow-border'
className='bg-app-100 cc-shadow-border'
style={{
top: headPosition,
position: 'sticky'

View File

@ -1,6 +1,6 @@
'use client';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { APP_COLORS } from '@/styling/color';
interface LoaderProps {
/** Scale of the loader from 1 to 10. */
@ -55,11 +55,10 @@ const animatePulse = (startBig: boolean, duration: string) => {
* Displays animated loader.
*/
function Loader({ scale = 5, circular }: LoaderProps) {
const { colors } = useConceptOptions();
if (circular) {
return (
<div className='flex justify-center' aria-label='three-circles-loading' aria-busy='true' role='progressbar'>
<svg height={`${scale * 20}`} width={`${scale * 20}`} viewBox='0 0 100 100' fill={colors.bgPrimary}>
<svg height={`${scale * 20}`} width={`${scale * 20}`} viewBox='0 0 100 100' fill={APP_COLORS.bgPrimary}>
<path d='M31.6,3.5C5.9,13.6-6.6,42.7,3.5,68.4c10.1,25.7,39.2,38.3,64.9,28.1l-3.1-7.9c-21.3,8.4-45.4-2-53.8-23.3 c-8.4-21.3,2-45.4,23.3-53.8L31.6,3.5z'>
{animateRotation('2.25s')}
</path>
@ -75,7 +74,7 @@ function Loader({ scale = 5, circular }: LoaderProps) {
} else {
return (
<div className='flex justify-center' aria-busy='true' role='progressbar'>
<svg height={`${scale * 20}`} width={`${scale * 20}`} viewBox='0 0 120 30' fill={colors.bgPrimary}>
<svg height={`${scale * 20}`} width={`${scale * 20}`} viewBox='0 0 120 30' fill={APP_COLORS.bgPrimary}>
<circle cx='15' cy='15' r='16'>
{animatePulse(true, '0.8s')}
</circle>

View File

@ -95,14 +95,14 @@ function Modal({
<div className='fixed top-0 left-0 w-full h-full z-modal cursor-default'>
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'cc-modal-blur')} />
<div
className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'cc-modal-backdrop')}
className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'cc-modal-backdrop opacity-30')}
onClick={hideWindow}
/>
<div
className={clsx(
'cc-animate-modal',
'z-modal absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
'border rounded-xl clr-app'
'border rounded-xl bg-app-100'
)}
>
<Overlay position='right-2 top-2'>

View File

@ -9,9 +9,8 @@ import Select, {
StylesConfig
} from 'react-select';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import useWindowSize from '@/hooks/useWindowSize';
import { selectDarkT, selectLightT } from '@/styling/color';
import { APP_COLORS, SELECT_THEME } from '@/styling/color';
import { IconClose, IconDropArrow, IconDropArrowUp } from '../Icons';
@ -51,9 +50,7 @@ function SelectMulti<Option, Group extends GroupBase<Option> = GroupBase<Option>
noPortal,
...restProps
}: SelectMultiProps<Option, Group>) {
const { darkMode, colors } = useConceptOptions();
const size = useWindowSize();
const themeColors = !darkMode ? selectLightT : selectDarkT;
const adjustedStyles: StylesConfig<Option, true, Group> = {
container: defaultStyles => ({
@ -71,10 +68,10 @@ function SelectMulti<Option, Group extends GroupBase<Option> = GroupBase<Option>
padding: '0.25rem 0.75rem',
fontSize: '0.875rem',
lineHeight: '1.25rem',
backgroundColor: isSelected ? colors.bgSelected : styles.backgroundColor,
color: isSelected ? colors.fgSelected : styles.color,
backgroundColor: isSelected ? APP_COLORS.bgSelected : styles.backgroundColor,
color: isSelected ? APP_COLORS.fgSelected : styles.color,
borderWidth: '1px',
borderColor: colors.border
borderColor: APP_COLORS.border
}),
menuPortal: styles => ({
...styles,
@ -89,7 +86,7 @@ function SelectMulti<Option, Group extends GroupBase<Option> = GroupBase<Option>
multiValue: styles => ({
...styles,
borderRadius: '0.5rem',
backgroundColor: colors.bgSelected
backgroundColor: APP_COLORS.bgSelected
}),
dropdownIndicator: base => ({
...base,
@ -119,7 +116,7 @@ function SelectMulti<Option, Group extends GroupBase<Option> = GroupBase<Option>
},
colors: {
...theme.colors,
...themeColors
...SELECT_THEME
}
})}
menuPortalTarget={!noPortal ? document.body : null}

View File

@ -9,9 +9,8 @@ import Select, {
StylesConfig
} from 'react-select';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import useWindowSize from '@/hooks/useWindowSize';
import { selectDarkT, selectLightT } from '@/styling/color';
import { APP_COLORS, SELECT_THEME } from '@/styling/color';
import { IconClose, IconDropArrow, IconDropArrowUp } from '../Icons';
@ -53,9 +52,7 @@ function SelectSingle<Option, Group extends GroupBase<Option> = GroupBase<Option
noBorder,
...restProps
}: SelectSingleProps<Option, Group>) {
const { darkMode, colors } = useConceptOptions();
const size = useWindowSize();
const themeColors = !darkMode ? selectLightT : selectDarkT;
const adjustedStyles: StylesConfig<Option, false, Group> = {
container: defaultStyles => ({
@ -82,10 +79,10 @@ function SelectSingle<Option, Group extends GroupBase<Option> = GroupBase<Option
padding: '0.25rem 0.75rem',
fontSize: '0.875rem',
lineHeight: '1.25rem',
backgroundColor: isSelected ? colors.bgSelected : defaultStyles.backgroundColor,
color: isSelected ? colors.fgSelected : defaultStyles.color,
backgroundColor: isSelected ? APP_COLORS.bgSelected : defaultStyles.backgroundColor,
color: isSelected ? APP_COLORS.fgSelected : defaultStyles.color,
borderWidth: '1px',
borderColor: colors.border
borderColor: APP_COLORS.border
}),
input: defaultStyles => ({ ...defaultStyles }),
placeholder: defaultStyles => ({ ...defaultStyles }),
@ -117,7 +114,7 @@ function SelectSingle<Option, Group extends GroupBase<Option> = GroupBase<Option
},
colors: {
...theme.colors,
...themeColors
...SELECT_THEME
}
})}
menuPortalTarget={!noPortal ? document.body : null}

View File

@ -20,7 +20,7 @@ interface TextURLProps {
/**
* Displays a text with a clickable link.
*/
function TextURL({ text, href, title, color = 'clr-text-url', onClick }: TextURLProps) {
function TextURL({ text, href, title, color = 'text-prim-100', onClick }: TextURLProps) {
const design = `cursor-pointer hover:underline ${color}`;
if (href) {
return (

View File

@ -22,7 +22,7 @@ function ExpectedAnonymous() {
<span> | </span>
<TextURL text='Справка' href='/manuals' />
<span> | </span>
<span className='cursor-pointer hover:underline clr-text-url' onClick={logoutAndRedirect}>
<span className='cursor-pointer hover:underline text-prim-100' onClick={logoutAndRedirect}>
Выйти
</span>
</div>

View File

@ -4,7 +4,6 @@ import { createContext, useCallback, useContext, useEffect, useMemo, useState }
import Tooltip from '@/components/ui/Tooltip';
import useLocalStorage from '@/hooks/useLocalStorage';
import { darkT, IColorTheme, lightT } from '@/styling/color';
import { globals, PARAMETER, storage } from '@/utils/constants';
import { contextOutsideScope } from '@/utils/labels';
@ -12,8 +11,6 @@ interface IOptionsContext {
viewportHeight: string;
mainHeight: string;
colors: IColorTheme;
darkMode: boolean;
toggleDarkMode: () => void;
@ -60,8 +57,6 @@ export const OptionsState = ({ children }: React.PropsWithChildren) => {
const [folderMode, setFolderMode] = useLocalStorage<boolean>(storage.librarySearchFolderMode, true);
const [location, setLocation] = useLocalStorage<string>(storage.librarySearchLocation, '');
const [colors, setColors] = useState<IColorTheme>(lightT);
const [noNavigationAnimation, setNoNavigationAnimation] = useState(false);
const [noFooter, setNoFooter] = useState(false);
const [showScroll, setShowScroll] = useState(false);
@ -80,10 +75,6 @@ export const OptionsState = ({ children }: React.PropsWithChildren) => {
setDarkClass(darkMode);
}, [darkMode]);
useEffect(() => {
setColors(darkMode ? darkT : lightT);
}, [darkMode, setColors]);
const toggleNoNavigation = useCallback(() => {
if (noNavigation) {
setNoNavigationAnimation(false);
@ -109,7 +100,6 @@ export const OptionsState = ({ children }: React.PropsWithChildren) => {
const toggleDarkMode = useCallback(() => {
setDarkMode(prev => !prev);
window.location.reload();
}, [setDarkMode]);
const mainHeight = useMemo(() => {
@ -131,7 +121,6 @@ export const OptionsState = ({ children }: React.PropsWithChildren) => {
value={{
darkMode,
adminMode,
colors,
noNavigationAnimation,
noNavigation,
noFooter,

View File

@ -10,9 +10,9 @@ import PickConstituenta from '@/components/select/PickConstituenta';
import DataTable, { IConditionalStyle } from '@/components/ui/DataTable';
import MiniButton from '@/components/ui/MiniButton';
import NoData from '@/components/ui/NoData';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { IConstituenta, IRSForm } from '@/models/rsform';
import { IArgumentValue } from '@/models/rslang';
import { APP_COLORS } from '@/styling/color';
import { prefixes } from '@/utils/constants';
interface TabArgumentsProps {
@ -29,8 +29,6 @@ export interface IArgumentsState {
const argumentsHelper = createColumnHelper<IArgumentValue>();
function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
const { colors } = useConceptOptions();
const [selectedCst, setSelectedCst] = useState<IConstituenta | undefined>(undefined);
const [selectedArgument, setSelectedArgument] = useState<IArgumentValue | undefined>(undefined);
const [argumentValue, setArgumentValue] = useState('');
@ -124,7 +122,7 @@ function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
const conditionalRowStyles: IConditionalStyle<IArgumentValue>[] = [
{
when: (arg: IArgumentValue) => arg.alias === selectedArgument?.alias,
style: { backgroundColor: colors.bgSelected }
style: { backgroundColor: APP_COLORS.bgSelected }
}
];

View File

@ -119,7 +119,7 @@ function FormCreateCst({ schema, state, partialUpdate, setValidated }: FormCreat
id='dlg_cst_show_comment'
tabIndex={-1}
type='button'
className='self-start cc-label clr-text-url hover:underline'
className='self-start cc-label text-prim-100 hover:underline'
onClick={() => setForceComment(true)}
>
Добавить комментарий

View File

@ -2,9 +2,9 @@ import { ErrorData } from '@/components/info/InfoError';
import PickSubstitutions from '@/components/select/PickSubstitutions';
import TextArea from '@/components/ui/TextArea';
import DataLoader from '@/components/wrap/DataLoader';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ICstSubstitute } from '@/models/oss';
import { IRSForm } from '@/models/rsform';
import { APP_COLORS } from '@/styling/color';
import { prefixes } from '@/utils/constants';
interface TabSynthesisProps {
@ -29,7 +29,6 @@ function TabSynthesis({
setSubstitutions,
suggestions
}: TabSynthesisProps) {
const { colors } = useConceptOptions();
return (
<DataLoader isLoading={loading} error={error}>
<div className='cc-fade-in cc-column mt-3'>
@ -45,7 +44,7 @@ function TabSynthesis({
disabled
value={validationText}
rows={4}
style={{ borderColor: isCorrect ? undefined : colors.fgRed }}
style={{ borderColor: isCorrect ? undefined : APP_COLORS.fgRed }}
/>
</div>
</DataLoader>

View File

@ -6,8 +6,8 @@ import { useIntl } from 'react-intl';
import { IconRemove } from '@/components/Icons';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import MiniButton from '@/components/ui/MiniButton';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { IVersionInfo, VersionID } from '@/models/library';
import { APP_COLORS } from '@/styling/color';
interface TableVersionsProps {
processing: boolean;
@ -21,8 +21,6 @@ const columnHelper = createColumnHelper<IVersionInfo>();
function TableVersions({ processing, items, onDelete, selected, onSelect }: TableVersionsProps) {
const intl = useIntl();
const { colors } = useConceptOptions();
const columns = [
columnHelper.accessor('version', {
id: 'version',
@ -74,7 +72,7 @@ function TableVersions({ processing, items, onDelete, selected, onSelect }: Tabl
{
when: (version: IVersionInfo) => version.id === selected,
style: {
backgroundColor: colors.bgSelected
backgroundColor: APP_COLORS.bgSelected
}
}
];

View File

@ -5,7 +5,6 @@ import { ReactFlowProvider } from 'reactflow';
import Modal, { ModalProps } from '@/components/ui/Modal';
import Overlay from '@/components/ui/Overlay';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
import { SyntaxTree } from '@/models/rslang';
@ -17,7 +16,6 @@ interface DlgShowASTProps extends Pick<ModalProps, 'hideWindow'> {
}
function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
const { colors } = useConceptOptions();
const [hoverID, setHoverID] = useState<number | undefined>(undefined);
const hoverNode = syntaxTree.find(node => node.uid === hoverID);
@ -32,8 +30,7 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
>
<Overlay
position='top-2 right-1/2 translate-x-1/2'
className='px-2 py-1 rounded-2xl cc-blur max-w-[60ch] text-lg text-center'
style={{ backgroundColor: colors.bgBlur }}
className='px-2 py-1 rounded-2xl cc-blur bg-app-100 max-w-[60ch] text-lg text-center'
>
{!hoverNode || isDragging ? expression : null}
{!isDragging && hoverNode ? (

View File

@ -2,9 +2,8 @@
import { Handle, Position } from 'reactflow';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ISyntaxTreeNode } from '@/models/rslang';
import { colorBgSyntaxTree } from '@/styling/color';
import { APP_COLORS, colorBgSyntaxTree } from '@/styling/color';
import { labelSyntaxTree } from '@/utils/labels';
const FONT_SIZE_MAX = 14;
@ -25,7 +24,6 @@ interface ASTNodeInternal {
}
function ASTNode(node: ASTNodeInternal) {
const { colors } = useConceptOptions();
const label = labelSyntaxTree(node.data);
return (
@ -33,7 +31,7 @@ function ASTNode(node: ASTNodeInternal) {
<Handle type='target' position={Position.Top} style={{ opacity: 0 }} />
<div
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
style={{ backgroundColor: colorBgSyntaxTree(node.data, colors) }}
style={{ backgroundColor: colorBgSyntaxTree(node.data) }}
/>
<Handle type='source' position={Position.Bottom} style={{ opacity: 0 }} />
<div
@ -45,7 +43,7 @@ function ASTNode(node: ASTNodeInternal) {
aria-hidden='true'
style={{
WebkitTextStrokeWidth: 2,
WebkitTextStrokeColor: colors.bgDefault
WebkitTextStrokeColor: APP_COLORS.bgDefault
}}
>
{label}

View File

@ -1,17 +1,16 @@
import { SimpleBezierEdge } from 'reactflow';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { MGraphEdgeInternal } from '@/models/miscellaneous';
import { APP_COLORS } from '@/styling/color';
function CartesianEdge({ data, ...restProps }: MGraphEdgeInternal) {
const { colors } = useConceptOptions();
return (
<>
<SimpleBezierEdge
{...restProps}
label={data?.indices.join(', ')}
labelBgStyle={{ fill: colors.bgDefault }}
labelStyle={{ fill: colors.fgDefault }}
labelBgStyle={{ fill: APP_COLORS.bgDefault }}
labelStyle={{ fill: APP_COLORS.fgDefault }}
/>
</>
);

View File

@ -2,9 +2,8 @@
import { Handle, Position } from 'reactflow';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { TMGraphNode } from '@/models/TMGraph';
import { colorBgTMGraphNode } from '@/styling/color';
import { APP_COLORS, colorBgTMGraphNode } from '@/styling/color';
import { globals } from '@/utils/constants';
/**
@ -19,8 +18,6 @@ interface MGraphNodeInternal {
}
function MGraphNode(node: MGraphNodeInternal) {
const { colors } = useConceptOptions();
const tooltipText =
(node.data.annotations.length === 0 ? '' : `Конституенты: ${node.data.annotations.join(' ')}<br/>`) +
node.data.text;
@ -33,10 +30,10 @@ function MGraphNode(node: MGraphNodeInternal) {
data-tooltip-id={globals.tooltip}
data-tooltip-html={tooltipText}
style={{
backgroundColor: colorBgTMGraphNode(node.data, colors),
backgroundColor: colorBgTMGraphNode(node.data),
fontWeight: 600,
WebkitTextStrokeWidth: '0.6px',
WebkitTextStrokeColor: colors.bgDefault
WebkitTextStrokeColor: APP_COLORS.bgDefault
}}
>
{node.data.rank === 0 ? node.data.text : node.data.annotations.length > 0 ? node.data.annotations.length : ''}

View File

@ -18,6 +18,7 @@ import { useUsers } from '@/context/UsersContext';
import useLocalStorage from '@/hooks/useLocalStorage';
import useWindowSize from '@/hooks/useWindowSize';
import { ILibraryItem, LibraryItemType } from '@/models/library';
import { APP_COLORS } from '@/styling/color';
import { storage } from '@/utils/constants';
interface TableLibraryItemsProps {
@ -33,10 +34,14 @@ function TableLibraryItems({ items, resetQuery, folderMode, toggleFolderMode }:
const router = useConceptNavigation();
const intl = useIntl();
const { getUserLabel } = useUsers();
const { calculateHeight, colors } = useConceptOptions();
const { calculateHeight } = useConceptOptions();
const [itemsPerPage, setItemsPerPage] = useLocalStorage<number>(storage.libraryPagination, 50);
function handleOpenItem(item: ILibraryItem, event: CProps.EventMouse) {
const selection = window.getSelection();
if (!!selection && selection.toString().length > 0) {
return;
}
if (item.item_type === LibraryItemType.RSFORM) {
router.push(urls.schema(item.id), event.ctrlKey || event.metaKey);
} else if (item.item_type === LibraryItemType.OSS) {
@ -141,7 +146,7 @@ function TableLibraryItems({ items, resetQuery, folderMode, toggleFolderMode }:
{
when: (item: ILibraryItem) => item.item_type === LibraryItemType.OSS,
style: {
color: colors.fgGreen
color: APP_COLORS.fgGreen
}
}
];

View File

@ -96,7 +96,7 @@ export default LoginPage;
function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if (axios.isAxiosError(error) && error.response && error.response.status === 400) {
return (
<div className='text-sm select-text clr-text-red'>
<div className='text-sm select-text text-warn-600'>
На Портале отсутствует такое сочетание имени пользователя и пароля
</div>
);

View File

@ -1,7 +1,6 @@
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { APP_COLORS } from '@/styling/color';
function HelpFormulaTree() {
const { colors } = useConceptOptions();
return (
<div>
<h1>Дерево разбора выражения</h1>
@ -13,22 +12,22 @@ function HelpFormulaTree() {
<h2>Виды узлов</h2>
<li>
<span style={{ backgroundColor: colors.bgGreen }}>объявление идентификатора</span>
<span style={{ backgroundColor: APP_COLORS.bgGreen }}>объявление идентификатора</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgTeal }}>глобальный идентификатор</span>
<span style={{ backgroundColor: APP_COLORS.bgTeal }}>глобальный идентификатор</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgOrange }}>логическое выражение</span>
<span style={{ backgroundColor: APP_COLORS.bgOrange }}>логическое выражение</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgBlue }}>типизированное выражение</span>
<span style={{ backgroundColor: APP_COLORS.bgBlue }}>типизированное выражение</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgRed }}>присвоение и итерация</span>
<span style={{ backgroundColor: APP_COLORS.bgRed }}>присвоение и итерация</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgDisabled }}>составные выражения</span>
<span style={{ backgroundColor: APP_COLORS.bgDisabled }}>составные выражения</span>
</li>
</div>
);

View File

@ -17,11 +17,10 @@ import {
IconUserSearch
} from '@/components/Icons';
import LinkTopic from '@/components/ui/LinkTopic';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
import { APP_COLORS } from '@/styling/color';
function HelpLibrary() {
const { colors } = useConceptOptions();
return (
<div>
<h1>Библиотека схем</h1>
@ -33,7 +32,7 @@ function HelpLibrary() {
</p>
<li>
<span style={{ color: colors.fgGreen }}>зеленым текстом</span> выделены ОСС
<span style={{ color: APP_COLORS.fgGreen }}>зеленым текстом</span> выделены ОСС
</li>
<li>клик по строке - переход к редактированию схемы</li>
<li>Ctrl + клик по строке откроет схему в новой вкладке</li>

View File

@ -19,11 +19,10 @@ import {
IconTypeGraph
} from '@/components/Icons';
import LinkTopic from '@/components/ui/LinkTopic';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
import { APP_COLORS } from '@/styling/color';
function HelpRSEditor() {
const { colors } = useConceptOptions();
return (
<div className='dense'>
<h1>Редактор конституенты</h1>
@ -69,15 +68,15 @@ function HelpRSEditor() {
<IconChild className='inline-icon' /> отображение наследованных
</li>
<li>
<span style={{ backgroundColor: colors.bgSelected }}>текущая конституента</span>
<span style={{ backgroundColor: APP_COLORS.bgSelected }}>текущая конституента</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgGreen50 }}>
<span style={{ backgroundColor: APP_COLORS.bgGreen50 }}>
<LinkTopic text='основа' topic={HelpTopic.CC_RELATIONS} /> текущей
</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgOrange50 }}>
<span style={{ backgroundColor: APP_COLORS.bgOrange50 }}>
<LinkTopic text='порожденные' topic={HelpTopic.CC_RELATIONS} /> текущей
</span>
</li>

View File

@ -21,11 +21,10 @@ import {
} from '@/components/Icons';
import Divider from '@/components/ui/Divider';
import LinkTopic from '@/components/ui/LinkTopic';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
import { APP_COLORS } from '@/styling/color';
function HelpRSGraphTerm() {
const { colors } = useConceptOptions();
return (
<div className='flex flex-col'>
<h1>Граф термов</h1>
@ -50,7 +49,7 @@ function HelpRSGraphTerm() {
<h1>Изменение узлов</h1>
<li>Клик на конституенту выделение</li>
<li>
Alt + клик выбор <span style={{ color: colors.fgPurple }}>фокус-конституенты</span>
Alt + клик выбор <span style={{ color: APP_COLORS.fgPurple }}>фокус-конституенты</span>
</li>
<li>
<IconReset className='inline-icon' /> Esc сбросить выделение

View File

@ -1,9 +1,8 @@
import LinkTopic from '@/components/ui/LinkTopic';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
import { APP_COLORS } from '@/styling/color';
function HelpTypeGraph() {
const { colors } = useConceptOptions();
return (
<div>
<h1>Граф ступеней</h1>
@ -21,13 +20,13 @@ function HelpTypeGraph() {
<h2>Виды узлов</h2>
<li>
<span style={{ backgroundColor: colors.bgControls }}>ступень-основание</span>
<span style={{ backgroundColor: APP_COLORS.bgControls }}>ступень-основание</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgTeal }}>ступень-булеан</span>
<span style={{ backgroundColor: APP_COLORS.bgTeal }}>ступень-булеан</span>
</li>
<li>
<span style={{ backgroundColor: colors.bgOrange }}>ступень декартова произведения</span>
<span style={{ backgroundColor: APP_COLORS.bgOrange }}>ступень декартова произведения</span>
</li>
</div>
);

View File

@ -23,6 +23,7 @@ import { useOSS } from '@/context/OssContext';
import useLocalStorage from '@/hooks/useLocalStorage';
import { OssNode } from '@/models/miscellaneous';
import { OperationID } from '@/models/oss';
import { APP_COLORS } from '@/styling/color';
import { PARAMETER, storage } from '@/utils/constants';
import { errors } from '@/utils/labels';
@ -40,7 +41,7 @@ interface OssFlowProps {
}
function OssFlow({ isModified, setIsModified }: OssFlowProps) {
const { mainHeight, colors } = useConceptOptions();
const { mainHeight } = useConceptOptions();
const model = useOSS();
const controller = useOssEdit();
const flow = useReactFlow();
@ -192,7 +193,7 @@ function OssFlow({ isModified, setIsModified }: OssFlowProps) {
const nodesBounds = getNodesBounds(nodes);
const viewport = getViewportForBounds(nodesBounds, imageWidth, imageHeight, ZOOM_MIN, ZOOM_MAX);
toPng(canvas, {
backgroundColor: colors.bgDefault,
backgroundColor: APP_COLORS.bgDefault,
width: imageWidth,
height: imageHeight,
style: {

View File

@ -28,7 +28,7 @@ function NodeCore({ node }: NodeCoreProps) {
<Indicator
noPadding
title={hasFile ? 'Связанная КС' : 'Нет связанной КС'}
icon={<IconRSForm className={hasFile ? 'clr-text-green' : 'clr-text-red'} size='12px' />}
icon={<IconRSForm className={hasFile ? 'text-ok-600' : 'text-warn-600'} size='12px' />}
hideTitle={!controller.showTooltip}
/>
{node.data.operation.is_consolidation ? (

View File

@ -25,7 +25,7 @@ function PasswordChangePage() {
const [newPasswordRepeat, setNewPasswordRepeat] = useState('');
const passwordColor =
!!newPassword && !!newPasswordRepeat && newPassword !== newPasswordRepeat ? 'clr-warning' : 'clr-input';
!!newPassword && !!newPasswordRepeat && newPassword !== newPasswordRepeat ? 'bg-warn-100' : 'clr-input';
const canSubmit = !!newPassword && !!newPasswordRepeat && newPassword === newPasswordRepeat;
@ -102,7 +102,7 @@ export default PasswordChangePage;
// ====== Internals =========
function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if (axios.isAxiosError(error) && error.response && error.response.status === 404) {
return <div className='mx-auto mt-6 text-sm select-text clr-text-red'>Данная ссылка не действительна</div>;
return <div className='mx-auto mt-6 text-sm select-text text-warn-600'>Данная ссылка не действительна</div>;
} else {
return <InfoError error={error} />;
}

View File

@ -186,7 +186,7 @@ function FormConstituenta({
readOnly
label='Типизация'
value={typification}
colors='clr-app clr-text-default cursor-default'
colors='bg-transparent clr-text-default cursor-default'
/>
) : null}
{state ? (
@ -252,7 +252,7 @@ function FormConstituenta({
id='cst_disable_comment'
type='button'
tabIndex={-1}
className='self-start cc-label clr-text-url hover:underline'
className='self-start cc-label text-prim-100 hover:underline'
onClick={() => setForceComment(true)}
>
Добавить комментарий

View File

@ -33,7 +33,7 @@ function ParsingResult({ isOpen, data, disabled, onShowError }: ParsingResultPro
<p
tabIndex={-1}
key={`error-${index}`}
className={`clr-text-red break-all ${disabled ? '' : 'cursor-pointer'}`}
className={`text-warn-600 break-all ${disabled ? '' : 'cursor-pointer'}`}
onClick={disabled ? undefined : () => onShowError(error)}
>
<span className='mr-1 font-semibold underline'>

View File

@ -4,12 +4,11 @@ import clsx from 'clsx';
import { StatusIcon } from '@/components/DomainIcons';
import Loader from '@/components/ui/Loader';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ExpressionStatus } from '@/models/rsform';
import { type IConstituenta } from '@/models/rsform';
import { inferStatus } from '@/models/rsformAPI';
import { IExpressionParse, ParsingStatus } from '@/models/rslang';
import { colorStatusBar } from '@/styling/color';
import { APP_COLORS, colorStatusBar } from '@/styling/color';
import { globals } from '@/utils/constants';
import { labelExpressionStatus, prepareTooltip } from '@/utils/labels';
@ -22,7 +21,6 @@ interface StatusBarProps {
}
function StatusBar({ isModified, processing, activeCst, parseData, onAnalyze }: StatusBarProps) {
const { colors } = useConceptOptions();
const status = (() => {
if (isModified) {
return ExpressionStatus.UNKNOWN;
@ -46,7 +44,7 @@ function StatusBar({ isModified, processing, activeCst, parseData, onAnalyze }:
'focus-frame',
'transition-colors duration-500'
)}
style={{ backgroundColor: processing ? colors.bgDefault : colorStatusBar(status, colors) }}
style={{ backgroundColor: processing ? APP_COLORS.bgDefault : colorStatusBar(status) }}
data-tooltip-id={globals.tooltip}
data-tooltip-html={prepareTooltip('Проверить определение', 'Ctrl + Q')}
onClick={onAnalyze}

View File

@ -130,7 +130,7 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
<ValueIcon
dense
disabled
icon={<IconDateUpdate size='1.25rem' className='clr-text-green' />}
icon={<IconDateUpdate size='1.25rem' className='text-ok-600' />}
value={new Date(item.time_update).toLocaleString(intl.locale)}
title='Дата обновления'
/>
@ -138,7 +138,7 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
<ValueIcon
dense
disabled
icon={<IconDateCreate size='1.25rem' className='clr-text-green' />}
icon={<IconDateCreate size='1.25rem' className='text-ok-600' />}
value={new Date(item.time_create).toLocaleString(intl.locale, {
year: '2-digit',
month: '2-digit',

View File

@ -55,7 +55,7 @@ function RSFormStats({ stats, isArchive }: RSFormStatsProps) {
<ValueStats
className='col-start-1'
id='count_ok'
icon={<IconStatusOK size='1.25rem' className='clr-text-green' />}
icon={<IconStatusOK size='1.25rem' className='text-ok-600' />}
value={stats.count_all - stats.count_errors - stats.count_property - stats.count_incalculable}
title='Корректные'
/>
@ -67,13 +67,13 @@ function RSFormStats({ stats, isArchive }: RSFormStatsProps) {
/>
<ValueStats
id='count_incalculable'
icon={<IconStatusIncalculable size='1.25rem' className='clr-text-red' />}
icon={<IconStatusIncalculable size='1.25rem' className='text-warn-600' />}
value={stats.count_incalculable}
title='Невычислимые'
/>
<ValueStats
id='count_errors'
icon={<IconStatusError size='1.25rem' className='clr-text-red' />}
icon={<IconStatusError size='1.25rem' className='text-warn-600' />}
value={stats.count_errors}
title='Некорректные'
/>

View File

@ -46,7 +46,7 @@ function ToolbarItemAccess({ visible, toggleVisible, readOnly, toggleReadOnly, c
readOnly ? (
<IconImmutable size='1.25rem' className='clr-text-primary' />
) : (
<IconMutable size='1.25rem' className='clr-text-green' />
<IconMutable size='1.25rem' className='text-ok-600' />
)
}
onClick={toggleReadOnly}

View File

@ -9,7 +9,6 @@ import DataTable, { createColumnHelper, RowSelectionState, VisibilityState } fro
import NoData from '@/components/ui/NoData';
import TextContent from '@/components/ui/TextContent';
import TextURL from '@/components/ui/TextURL';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import useWindowSize from '@/hooks/useWindowSize';
import { ConstituentaID, IConstituenta } from '@/models/rsform';
import { PARAMETER, prefixes } from '@/utils/constants';
@ -46,7 +45,6 @@ function TableRSList({
onEdit,
onCreateNew
}: TableRSListProps) {
const { colors } = useConceptOptions();
const windowSize = useWindowSize();
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
@ -78,7 +76,7 @@ function TableRSList({
size: 65,
minSize: 65,
maxSize: 65,
cell: props => <BadgeConstituenta theme={colors} value={props.row.original} prefixID={prefixes.cst_list} />
cell: props => <BadgeConstituenta value={props.row.original} prefixID={prefixes.cst_list} />
}),
columnHelper.accessor(cst => labelCstTypification(cst), {
id: 'type',

View File

@ -1,6 +1,5 @@
import { IconHelp } from '@/components/Icons';
import Tooltip from '@/components/ui/Tooltip';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useLibrary } from '@/context/LibraryContext';
import { LibraryItemID } from '@/models/library';
import { IRSForm } from '@/models/rsform';
@ -12,7 +11,6 @@ interface SchemasGuideProps {
}
function SchemasGuide({ schema }: SchemasGuideProps) {
const { colors } = useConceptOptions();
const library = useLibrary();
const schemas = (() => {
@ -51,7 +49,7 @@ function SchemasGuide({ schema }: SchemasGuideProps) {
<div>
<span
className='min-w-[0.6rem] min-h-[0.6rem] border inline-block mr-1 rounded-full'
style={{ backgroundColor: colorBgSchemas(0, colors) }}
style={{ backgroundColor: colorBgSchemas(0) }}
/>
Текущая схема
</div>
@ -59,7 +57,7 @@ function SchemasGuide({ schema }: SchemasGuideProps) {
<div key={`${prefixes.schemas_list}${index}`}>
<span
className='min-w-[0.6rem] min-h-[0.6rem] border inline-block mr-1 rounded-full'
style={{ backgroundColor: colorBgSchemas(index + 1, colors) }}
style={{ backgroundColor: colorBgSchemas(index + 1) }}
/>
{alias}
</div>

View File

@ -30,7 +30,7 @@ import useLocalStorage from '@/hooks/useLocalStorage';
import { GraphColoring, GraphFilterParams } from '@/models/miscellaneous';
import { ConstituentaID, CstType, IConstituenta } from '@/models/rsform';
import { isBasicConcept } from '@/models/rsformAPI';
import { colorBgGraphNode } from '@/styling/color';
import { APP_COLORS, colorBgGraphNode } from '@/styling/color';
import { PARAMETER, storage } from '@/utils/constants';
import { errors } from '@/utils/labels';
@ -53,7 +53,7 @@ interface TGFlowProps {
}
function TGFlow({ onOpenEdit }: TGFlowProps) {
const { colors, mainHeight } = useConceptOptions();
const { mainHeight } = useConceptOptions();
const controller = useRSEdit();
const [nodes, setNodes, onNodesChange] = useNodesState([]);
const [edges, setEdges] = useEdgesState([]);
@ -137,7 +137,7 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
selected: controller.selected.includes(node.id),
position: { x: 0, y: 0 },
data: {
fill: focusCst === cst ? colors.bgPurple : colorBgGraphNode(cst, coloring, colors),
fill: focusCst === cst ? APP_COLORS.bgPurple : colorBgGraphNode(cst, coloring),
label: cst.alias,
description: !filterParams.noText ? cst.term_resolved : ''
}
@ -179,13 +179,12 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
filterParams.noText,
controller.selected,
focusCst,
coloring,
colors
coloring
]);
useEffect(() => {
setNeedReset(true);
}, [controller.schema, filterParams.noText, focusCst, coloring, colors, flow.viewportInitialized]);
}, [controller.schema, filterParams.noText, focusCst, coloring, flow.viewportInitialized]);
useEffect(() => {
if (!controller.schema || !needReset || !flow.viewportInitialized) {
@ -240,7 +239,7 @@ function TGFlow({ onOpenEdit }: TGFlowProps) {
const nodesBounds = getNodesBounds(nodes);
const viewport = getViewportForBounds(nodesBounds, imageWidth, imageHeight, ZOOM_MIN, ZOOM_MAX);
toPng(canvas, {
backgroundColor: colors.bgDefault,
backgroundColor: APP_COLORS.bgDefault,
width: imageWidth,
height: imageHeight,
style: {

View File

@ -4,8 +4,8 @@ import { useCallback } from 'react';
import { IconGraphInputs, IconGraphOutputs, IconReset } from '@/components/Icons';
import MiniButton from '@/components/ui/MiniButton';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { IConstituenta } from '@/models/rsform';
import { APP_COLORS } from '@/styling/color';
import { useRSEdit } from '../RSEditContext';
@ -27,7 +27,6 @@ function ToolbarFocusedCst({
toggleShowInputs,
toggleShowOutputs
}: ToolbarFocusedCstProps) {
const { colors } = useConceptOptions();
const controller = useRSEdit();
const resetSelection = useCallback(() => {
@ -37,7 +36,7 @@ function ToolbarFocusedCst({
return (
<div className='items-center cc-icons'>
<div className='w-[7.8rem] text-right select-none' style={{ color: colors.fgPurple }}>
<div className='w-[7.8rem] text-right select-none' style={{ color: APP_COLORS.fgPurple }}>
Фокус
<b className='px-1'> {center.alias} </b>
</div>

View File

@ -12,7 +12,7 @@ import useLocalStorage from '@/hooks/useLocalStorage';
import useWindowSize from '@/hooks/useWindowSize';
import { GraphColoring } from '@/models/miscellaneous';
import { ConstituentaID, IRSForm } from '@/models/rsform';
import { colorBgGraphNode } from '@/styling/color';
import { APP_COLORS, colorBgGraphNode } from '@/styling/color';
import { PARAMETER, prefixes, storage } from '@/utils/constants';
interface ViewHiddenProps {
@ -27,7 +27,7 @@ interface ViewHiddenProps {
}
function ViewHidden({ items, selected, toggleSelection, setFocus, schema, coloringScheme, onEdit }: ViewHiddenProps) {
const { colors, calculateHeight } = useConceptOptions();
const { calculateHeight } = useConceptOptions();
const windowSize = useWindowSize();
const localSelected = items.filter(id => selected.includes(id));
const [isFolded, setIsFolded] = useLocalStorage(storage.rsgraphFoldHidden, false);
@ -96,12 +96,12 @@ function ViewHidden({ items, selected, toggleSelection, setFocus, schema, colori
id={id}
className='min-w-[3rem] rounded-md text-center select-none'
style={{
backgroundColor: colorBgGraphNode(cst, adjustedColoring, colors),
backgroundColor: colorBgGraphNode(cst, adjustedColoring),
...(localSelected.includes(cstID)
? {
outlineWidth: '2px',
outlineStyle: cst.is_inherited ? 'dashed' : 'solid',
outlineColor: colors.fgDefault
outlineColor: APP_COLORS.fgDefault
}
: {})
}}

View File

@ -2,7 +2,7 @@
import { Handle, Position } from 'reactflow';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { APP_COLORS } from '@/styling/color';
import { truncateToLastWord } from '@/utils/utils';
const MAX_DESCRIPTION_LENGTH = 65;
@ -32,7 +32,6 @@ interface TGNodeInternal {
}
function TGNode(node: TGNodeInternal) {
const { colors } = useConceptOptions();
const description = truncateToLastWord(node.data.description, MAX_DESCRIPTION_LENGTH);
return (
@ -41,7 +40,7 @@ function TGNode(node: TGNodeInternal) {
<div
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
style={{
backgroundColor: !node.selected ? node.data.fill : colors.bgActiveSelection,
backgroundColor: !node.selected ? node.data.fill : APP_COLORS.bgActiveSelection,
fontSize: node.data.label.length > LABEL_THRESHOLD ? FONT_SIZE_MED : FONT_SIZE_MAX
}}
>
@ -49,7 +48,7 @@ function TGNode(node: TGNodeInternal) {
style={{
fontWeight: 600,
WebkitTextStrokeWidth: '0.6px',
WebkitTextStrokeColor: colors.bgDefault
WebkitTextStrokeColor: APP_COLORS.bgDefault
}}
>
{node.data.label}
@ -68,7 +67,7 @@ function TGNode(node: TGNodeInternal) {
aria-hidden='true'
style={{
WebkitTextStrokeWidth: '3px',
WebkitTextStrokeColor: colors.bgDefault
WebkitTextStrokeColor: APP_COLORS.bgDefault
}}
>
{description}

View File

@ -6,8 +6,8 @@ import BadgeConstituenta from '@/components/info/BadgeConstituenta';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import NoData from '@/components/ui/NoData';
import TextContent from '@/components/ui/TextContent';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ConstituentaID, IConstituenta } from '@/models/rsform';
import { APP_COLORS } from '@/styling/color';
import { PARAMETER, prefixes } from '@/utils/constants';
import { describeConstituenta } from '@/utils/labels';
@ -30,8 +30,6 @@ function TableSideConstituents({
onOpenEdit,
maxHeight
}: TableSideConstituentsProps) {
const { colors } = useConceptOptions();
useEffect(() => {
if (!activeCst) {
return;
@ -58,12 +56,7 @@ function TableSideConstituents({
minSize: 65,
footer: undefined,
cell: props => (
<BadgeConstituenta
className='mr-[-0.5rem]'
theme={colors}
value={props.row.original}
prefixID={prefixes.cst_side_table}
/>
<BadgeConstituenta className='mr-[-0.5rem]' value={props.row.original} prefixID={prefixes.cst_side_table} />
)
}),
columnHelper.accessor(cst => describeConstituenta(cst), {
@ -90,19 +83,19 @@ function TableSideConstituents({
{
when: (cst: IConstituenta) => !!activeCst && cst.id === activeCst?.id,
style: {
backgroundColor: colors.bgSelected
backgroundColor: APP_COLORS.bgSelected
}
},
{
when: (cst: IConstituenta) => !!activeCst && cst.spawner === activeCst?.id && cst.id !== activeCst?.id,
style: {
backgroundColor: colors.bgOrange50
backgroundColor: APP_COLORS.bgOrange50
}
},
{
when: (cst: IConstituenta) => activeCst?.id !== undefined && cst.spawn.includes(activeCst.id),
style: {
backgroundColor: colors.bgGreen50
backgroundColor: APP_COLORS.bgGreen50
}
}
];

View File

@ -175,16 +175,16 @@ function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if ('email' in error.response.data) {
return (
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
<div className='mx-auto text-sm select-text clr-text-red'>{error.response.data.email}.</div>
<div className='mx-auto text-sm select-text text-warn-600'>{error.response.data.email}.</div>
);
} else if ('username' in error.response.data) {
return (
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
<div className='mx-auto text-sm select-text clr-text-red'>{error.response.data.username}.</div>
<div className='mx-auto text-sm select-text text-warn-600'>{error.response.data.username}.</div>
);
} else {
return (
<div className='mx-auto text-sm select-text clr-text-red'>
<div className='mx-auto text-sm select-text text-warn-600'>
<PrettyJson data={error.response} />
</div>
);

View File

@ -70,7 +70,7 @@ export default RestorePasswordPage;
function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if (axios.isAxiosError(error) && error.response && error.response.status === 400) {
return (
<div className='mx-auto mt-6 text-sm select-text clr-text-red'>Данный email не используется на Портале.</div>
<div className='mx-auto mt-6 text-sm select-text text-warn-600'>Данный email не используется на Портале.</div>
);
} else {
return <InfoError error={error} />;

View File

@ -24,7 +24,7 @@ function EditorPassword() {
const [newPasswordRepeat, setNewPasswordRepeat] = useState('');
const passwordColor =
!!newPassword && !!newPasswordRepeat && newPassword !== newPasswordRepeat ? 'clr-warning' : 'clr-input';
!!newPassword && !!newPasswordRepeat && newPassword !== newPasswordRepeat ? 'bg-warn-100' : 'clr-input';
const canSubmit = !!oldPassword && !!newPassword && !!newPasswordRepeat && newPassword === newPasswordRepeat;
@ -99,7 +99,7 @@ export default EditorPassword;
// ====== Internals =========
function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if (axios.isAxiosError(error) && error.response && error.response.status === 400) {
return <div className='text-sm select-text clr-text-red'>Неверно введен старый пароль</div>;
return <div className='text-sm select-text text-warn-600'>Неверно введен старый пароль</div>;
} else {
return <InfoError error={error} />;
}

View File

@ -98,7 +98,7 @@ function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if ('email' in error.response.data) {
return (
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
<div className='text-sm select-text clr-text-red'>{error.response.data.email}.</div>
<div className='text-sm select-text text-warn-600'>{error.response.data.email}.</div>
);
}
}

View File

@ -9,221 +9,93 @@ import { ISyntaxTreeNode, TokenID } from '@/models/rslang';
import { TMGraphNode } from '@/models/TMGraph';
import { PARAMETER } from '@/utils/constants';
/**
* Represents application color theme configuration.
*/
export interface IColorTheme {
bgDefault: string;
bgBlur: string;
bgInput: string;
bgControls: string;
bgDisabled: string;
bgPrimary: string;
bgSelected: string;
bgActiveSelection: string;
bgHover: string;
bgWarning: string;
/** Semantic colors for application. */
// prettier-ignore
export const APP_COLORS = {
bgDefault: 'var(--clr-app-100)',
bgInput: 'var(--clr-app-0)',
bgControls: 'var(--clr-app-200)',
bgDisabled: 'var(--clr-app-300)',
bgPrimary: 'var(--clr-prim-200)',
bgSelected: 'var(--clr-prim-600)',
bgActiveSelection: 'var(--clr-select-node)',
bgHover: 'var(--clr-prim-800)',
bgWarning: 'var(--clr-warn-100)',
border: string;
border: 'var(--clr-app-400)',
fgDefault: string;
fgSelected: string;
fgDisabled: string;
fgWarning: string;
fgDefault: 'var(--clr-app-999)',
fgSelected: 'var(--clr-app-999)',
fgDisabled: 'var(--clr-app-800)',
fgWarning: 'var(--clr-warn-600)',
// Highlight syntax accents
bgRed: string;
bgGreen: string;
bgBlue: string;
bgPurple: string;
bgTeal: string;
bgOrange: string;
bgRed: 'var(--acc-bg-red)',
bgGreen: 'var(--acc-bg-green)',
bgBlue: 'var(--acc-bg-blue)',
bgPurple: 'var(--acc-bg-purple)',
bgTeal: 'var(--acc-bg-teal)',
bgOrange: 'var(--acc-bg-orange)',
bgGreen25: string;
bgGreen50: string;
bgOrange50: string;
bgGreen25: 'var(--acc-bg-green25)',
bgGreen50: 'var(--acc-bg-green50)',
bgOrange50: 'var(--acc-bg-orange50)',
fgRed: string;
fgGreen: string;
fgBlue: string;
fgPurple: string;
fgTeal: string;
fgOrange: string;
fgRed: 'var(--acc-fg-red)',
fgGreen: 'var(--acc-fg-green)',
fgBlue: 'var(--acc-fg-blue)',
fgPurple: 'var(--acc-fg-purple)',
fgTeal: 'var(--acc-fg-teal)',
fgOrange: 'var(--acc-fg-orange)'
}
/**
* Represents application Light theme.
* Represents Select component theme.
*/
// prettier-ignore
export const lightT: IColorTheme = {
bgDefault: 'hsl(000, 000%, 098%)', //var(--cl-bg-100)',
bgBlur: 'hsla(000, 000%, 098%, 0.8)',
bgInput: 'var(--cl-bg-120)',
bgControls: 'var(--cl-bg-80)',
bgDisabled: 'var(--cl-bg-60)',
bgPrimary: 'var(--cl-prim-bg-100)',
bgSelected: 'var(--cl-prim-bg-80)',
bgActiveSelection: 'var(--cl-teal-bg-100)',
bgHover: 'var(--cl-prim-bg-60)',
bgWarning: 'var(--cl-red-bg-100)',
export const SELECT_THEME = {
primary: APP_COLORS.bgPrimary,
primary75: APP_COLORS.bgSelected,
primary50: APP_COLORS.bgHover,
primary25: APP_COLORS.bgHover,
border: 'var(--cl-bg-40)',
danger: APP_COLORS.fgWarning,
dangerLight: APP_COLORS.bgWarning,
fgDefault: 'var(--cl-fg-100)',
fgSelected: 'var(--cl-fg-100)',
fgDisabled: 'var(--cl-fg-80)',
fgWarning: 'var(--cl-red-fg-100)',
// Highlight syntax accents
bgRed: 'hsl(000, 100%, 089%)',
bgGreen: 'hsl(100, 100%, 075%)',
bgBlue: 'hsl(235, 080%, 087%)',
bgPurple: 'hsl(274, 089%, 081%)',
bgTeal: 'hsl(192, 089%, 081%)',
bgOrange: 'hsl(028, 100%, 075%)',
bgGreen25: 'hsl(100, 100%, 096%)',
bgGreen50: 'hsl(100, 100%, 090%)',
bgOrange50: 'hsl(028, 100%, 090%)',
fgRed: 'hsl(000, 090%, 045%)',
fgGreen: 'hsl(100, 090%, 035%)',
fgBlue: 'hsl(235, 100%, 050%)',
fgPurple: 'hsl(270, 100%, 055%)',
fgTeal: 'hsl(200, 080%, 050%)',
fgOrange: 'hsl(030, 090%, 055%)'
neutral0: APP_COLORS.bgInput,
neutral5: APP_COLORS.bgDefault,
neutral10: APP_COLORS.border,
neutral20: APP_COLORS.border,
neutral30: APP_COLORS.border,
neutral40: APP_COLORS.fgDisabled,
neutral50: APP_COLORS.fgDisabled, // placeholder
neutral60: APP_COLORS.fgDefault,
neutral70: APP_COLORS.fgWarning,
neutral80: APP_COLORS.fgDefault,
neutral90: APP_COLORS.fgWarning
};
/**
* Represents application Dark theme.
* Represents Brackets highlights theme.
*/
// prettier-ignore
export const darkT: IColorTheme = {
bgDefault: 'hsl(000, 000%, 005%)', //'var(--cd-bg-100)',
bgBlur: 'hsla(000, 000%, 005%, 0.3)',
bgInput: 'var(--cd-bg-120)',
bgControls: 'var(--cd-bg-80)',
bgDisabled: 'var(--cd-bg-60)',
bgPrimary: 'var(--cd-prim-bg-100)',
bgSelected: 'var(--cd-prim-bg-80)',
bgActiveSelection: 'var(--cd-teal-bg-100)',
bgHover: 'var(--cd-prim-bg-60)',
bgWarning: 'var(--cd-red-bg-100)',
border: 'var(--cd-bg-40)',
fgDefault: 'var(--cd-fg-100)',
fgSelected: 'var(--cd-fg-100)',
fgDisabled: 'var(--cd-fg-80)',
fgWarning: 'var(--cd-red-fg-100)',
// Highlight syntax accents
bgRed: 'hsl(000, 080%, 037%)',
bgGreen: 'hsl(100, 080%, 025%)',
bgBlue: 'hsl(235, 054%, 049%)',
bgPurple: 'hsl(270, 080%, 050%)',
bgTeal: 'hsl(192, 080%, 030%)',
bgOrange: 'hsl(035, 100%, 035%)',
bgGreen25: 'hsl(100, 080%, 009%)',
bgGreen50: 'hsl(100, 080%, 017%)',
bgOrange50: 'hsl(035, 100%, 016%)',
fgRed: 'hsl(000, 080%, 045%)',
fgGreen: 'hsl(100, 080%, 035%)',
fgBlue: 'hsl(235, 100%, 080%)',
fgPurple: 'hsl(270, 100%, 080%)',
fgTeal: 'hsl(192, 100%, 045%)',
fgOrange: 'hsl(035, 100%, 050%)'
};
/**
* Represents Select component Light theme.
*/
export const selectLightT = {
primary: lightT.bgPrimary,
primary75: lightT.bgSelected,
primary50: lightT.bgHover,
primary25: lightT.bgHover,
danger: lightT.fgWarning,
dangerLight: lightT.bgWarning,
neutral0: lightT.bgInput,
neutral5: lightT.bgDefault,
neutral10: lightT.border,
neutral20: lightT.border,
neutral30: lightT.border,
neutral40: lightT.fgDisabled,
neutral50: lightT.fgDisabled, // placeholder
neutral60: lightT.fgDefault,
neutral70: lightT.fgWarning,
neutral80: lightT.fgDefault,
neutral90: lightT.fgWarning
};
/**
* Represents Select component Dark theme.
*/
export const selectDarkT = {
primary: darkT.bgPrimary,
primary75: darkT.bgSelected,
primary50: darkT.bgHover,
primary25: darkT.bgHover,
danger: darkT.fgWarning,
dangerLight: darkT.bgWarning,
neutral0: darkT.bgInput,
neutral5: darkT.bgDefault,
neutral10: darkT.border,
neutral20: darkT.border,
neutral30: darkT.border,
neutral40: darkT.fgDisabled,
neutral50: darkT.fgDisabled, // placeholder
neutral60: darkT.fgDefault,
neutral70: darkT.fgWarning,
neutral80: darkT.fgDefault,
neutral90: darkT.fgWarning
};
/**
* Represents Brackets highlights Light theme.
*/
export const bracketsLightT = {
export const BRACKETS_THEME = {
'.cc-nonmatchingBracket': {
color: lightT.fgRed,
color: APP_COLORS.fgRed,
fontWeight: 600
},
'&.cm-focused .cc-matchingBracket': {
backgroundColor: lightT.bgSelected,
color: lightT.fgSelected
}
};
/**
* Represents Brackets highlights Dark theme.
*/
export const bracketsDarkT = {
'.cc-nonmatchingBracket': {
color: darkT.fgRed,
fontWeight: 600
},
'&.cm-focused .cc-matchingBracket': {
backgroundColor: darkT.bgSelected,
color: darkT.fgSelected
backgroundColor: APP_COLORS.bgSelected,
color: APP_COLORS.fgSelected
}
};
/**
* Determines background color for {@link ISyntaxTreeNode} based on its type.
*/
export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): string {
export function colorBgSyntaxTree(node: ISyntaxTreeNode): string {
switch (node.typeID) {
case TokenID.PUNCTUATION_DEFINE:
case TokenID.PUNCTUATION_STRUCT:
case TokenID.ID_LOCAL:
return colors.bgGreen;
return APP_COLORS.bgGreen;
case TokenID.ID_GLOBAL:
case TokenID.ID_FUNCTION:
@ -232,7 +104,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case TokenID.LIT_INTEGER:
case TokenID.LIT_EMPTYSET:
case TokenID.LIT_WHOLE_NUMBERS:
return colors.bgTeal;
return APP_COLORS.bgTeal;
case TokenID.QUANTOR_UNIVERSAL:
case TokenID.QUANTOR_EXISTS:
@ -252,7 +124,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case TokenID.SUBSET_OR_EQ:
case TokenID.SUBSET:
case TokenID.NOT_SUBSET:
return colors.bgOrange;
return APP_COLORS.bgOrange;
case TokenID.NT_TUPLE:
case TokenID.NT_ENUMERATION:
@ -272,7 +144,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case TokenID.CARD:
case TokenID.BOOL:
case TokenID.DEBOOL:
return colors.bgBlue;
return APP_COLORS.bgBlue;
case TokenID.NT_FUNC_DEFINITION:
case TokenID.NT_DECLARATIVE_EXPR:
@ -284,17 +156,17 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case TokenID.NT_FUNC_CALL:
case TokenID.NT_ARGUMENTS:
case TokenID.NT_RECURSIVE_SHORT:
return colors.bgDisabled;
return APP_COLORS.bgDisabled;
case TokenID.ASSIGN:
case TokenID.ITERATE:
return colors.bgRed;
return APP_COLORS.bgRed;
}
switch (node.data.value) {
case 'Expression':
case 'Local':
return colors.bgGreen;
return APP_COLORS.bgGreen;
case 'Global':
case 'Radical':
@ -304,7 +176,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case 'Integer':
case 'EmptySet':
case 'IntegerSet':
return colors.bgTeal;
return APP_COLORS.bgTeal;
case 'Logic':
case 'Logic_predicates':
@ -331,7 +203,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case 'Function_decl':
case 'Arguments':
case 'Declaration':
return colors.bgBlue;
return APP_COLORS.bgBlue;
case 'BigPr':
case 'SmallPr':
@ -342,138 +214,138 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case 'PrefixD':
case 'PrefixI':
case 'PrefixR':
return colors.bgPurple;
return APP_COLORS.bgPurple;
case PARAMETER.errorNodeLabel:
return colors.bgRed;
return APP_COLORS.bgRed;
}
// node
return colors.bgPurple;
return APP_COLORS.bgPurple;
}
/**
* Determines background color for {@link ExpressionStatus}.
*/
export function colorBgCstStatus(status: ExpressionStatus, colors: IColorTheme): string {
export function colorBgCstStatus(status: ExpressionStatus): string {
// prettier-ignore
switch (status) {
case ExpressionStatus.VERIFIED: return colors.bgGreen;
case ExpressionStatus.INCORRECT: return colors.bgRed;
case ExpressionStatus.INCALCULABLE: return colors.bgOrange;
case ExpressionStatus.PROPERTY: return colors.bgTeal;
case ExpressionStatus.UNKNOWN: return colors.bgSelected;
case ExpressionStatus.UNDEFINED: return colors.bgBlue;
case ExpressionStatus.VERIFIED: return APP_COLORS.bgGreen;
case ExpressionStatus.INCORRECT: return APP_COLORS.bgRed;
case ExpressionStatus.INCALCULABLE: return APP_COLORS.bgOrange;
case ExpressionStatus.PROPERTY: return APP_COLORS.bgTeal;
case ExpressionStatus.UNKNOWN: return APP_COLORS.bgSelected;
case ExpressionStatus.UNDEFINED: return APP_COLORS.bgBlue;
}
}
/**
* Determines statusbar color for {@link ExpressionStatus}.
*/
export function colorStatusBar(status: ExpressionStatus, colors: IColorTheme): string {
export function colorStatusBar(status: ExpressionStatus): string {
// prettier-ignore
switch (status) {
case ExpressionStatus.VERIFIED: return colors.bgGreen50;
case ExpressionStatus.INCORRECT: return colors.bgRed;
case ExpressionStatus.INCALCULABLE: return colors.bgOrange;
case ExpressionStatus.PROPERTY: return colors.bgTeal;
case ExpressionStatus.UNKNOWN: return colors.bgSelected;
case ExpressionStatus.UNDEFINED: return colors.bgBlue;
case ExpressionStatus.VERIFIED: return APP_COLORS.bgGreen50;
case ExpressionStatus.INCORRECT: return APP_COLORS.bgRed;
case ExpressionStatus.INCALCULABLE: return APP_COLORS.bgOrange;
case ExpressionStatus.PROPERTY: return APP_COLORS.bgTeal;
case ExpressionStatus.UNKNOWN: return APP_COLORS.bgSelected;
case ExpressionStatus.UNDEFINED: return APP_COLORS.bgBlue;
}
}
/**
* Determines foreground color for {@link ExpressionStatus}.
*/
export function colorFgCstStatus(status: ExpressionStatus, colors: IColorTheme): string {
export function colorFgCstStatus(status: ExpressionStatus): string {
// prettier-ignore
switch (status) {
case ExpressionStatus.VERIFIED: return colors.fgGreen;
case ExpressionStatus.INCORRECT: return colors.fgRed;
case ExpressionStatus.INCALCULABLE: return colors.fgOrange;
case ExpressionStatus.PROPERTY: return colors.fgTeal;
case ExpressionStatus.UNKNOWN: return colors.fgBlue;
case ExpressionStatus.UNDEFINED: return colors.fgBlue;
case ExpressionStatus.VERIFIED: return APP_COLORS.fgGreen;
case ExpressionStatus.INCORRECT: return APP_COLORS.fgRed;
case ExpressionStatus.INCALCULABLE: return APP_COLORS.fgOrange;
case ExpressionStatus.PROPERTY: return APP_COLORS.fgTeal;
case ExpressionStatus.UNKNOWN: return APP_COLORS.fgBlue;
case ExpressionStatus.UNDEFINED: return APP_COLORS.fgBlue;
}
}
/**
* Determines background color for {@link IConstituenta} depending on its {@link CstClass}.
*/
export function colorBgCstClass(cstClass: CstClass, colors: IColorTheme): string {
export function colorBgCstClass(cstClass: CstClass): string {
// prettier-ignore
switch (cstClass) {
case CstClass.BASIC: return colors.bgGreen;
case CstClass.DERIVED: return colors.bgBlue;
case CstClass.STATEMENT: return colors.bgRed;
case CstClass.TEMPLATE: return colors.bgTeal;
case CstClass.BASIC: return APP_COLORS.bgGreen;
case CstClass.DERIVED: return APP_COLORS.bgBlue;
case CstClass.STATEMENT: return APP_COLORS.bgRed;
case CstClass.TEMPLATE: return APP_COLORS.bgTeal;
}
}
/**
* Determines background color for {@link IConstituenta} depending on its parent schema index.
*/
export function colorBgSchemas(schema_index: number, colors: IColorTheme): string {
export function colorBgSchemas(schema_index: number): string {
if (schema_index === 0) {
return colors.bgGreen;
return APP_COLORS.bgGreen;
}
// prettier-ignore
switch (schema_index % 4) {
case 1: return colors.bgPurple;
case 2: return colors.bgOrange;
case 3: return colors.bgTeal;
case 0: return colors.bgBlue;
case 1: return APP_COLORS.bgPurple;
case 2: return APP_COLORS.bgOrange;
case 3: return APP_COLORS.bgTeal;
case 0: return APP_COLORS.bgBlue;
}
return colors.bgBlue;
return APP_COLORS.bgBlue;
}
/**
* Determines background color for {@link GramData}.
*/
export function colorBgGrammeme(gram: GramData, colors: IColorTheme): string {
export function colorBgGrammeme(gram: GramData): string {
if (PartOfSpeech.includes(gram as Grammeme)) {
return colors.bgBlue;
return APP_COLORS.bgBlue;
}
if (NounGrams.includes(gram as Grammeme)) {
return colors.bgGreen;
return APP_COLORS.bgGreen;
}
if (VerbGrams.includes(gram as Grammeme)) {
return colors.bgTeal;
return APP_COLORS.bgTeal;
}
return colors.bgInput;
return APP_COLORS.bgInput;
}
/**
* Determines foreground color for {@link GramData}.
*/
export function colorFgGrammeme(gram: GramData, colors: IColorTheme): string {
export function colorFgGrammeme(gram: GramData): string {
if (PartOfSpeech.includes(gram as Grammeme)) {
return colors.fgBlue;
return APP_COLORS.fgBlue;
}
if (NounGrams.includes(gram as Grammeme)) {
return colors.fgGreen;
return APP_COLORS.fgGreen;
}
if (VerbGrams.includes(gram as Grammeme)) {
return colors.fgTeal;
return APP_COLORS.fgTeal;
}
if (!Object.values(Grammeme).includes(gram as Grammeme)) {
return colors.fgRed;
return APP_COLORS.fgRed;
} else {
return colors.fgPurple;
return APP_COLORS.fgPurple;
}
}
/**
* Determines graph color for {@link IConstituenta}.
*/
export function colorBgGraphNode(cst: IConstituenta, coloringScheme: GraphColoring, colors: IColorTheme): string {
export function colorBgGraphNode(cst: IConstituenta, coloringScheme: GraphColoring): string {
if (coloringScheme === 'type') {
return colorBgCstClass(cst.cst_class, colors);
return colorBgCstClass(cst.cst_class);
}
if (coloringScheme === 'status') {
return colorBgCstStatus(cst.status, colors);
return colorBgCstStatus(cst.status);
}
if (coloringScheme === 'schemas') {
return colorBgSchemas(cst.parent_schema_index, colors);
return colorBgSchemas(cst.parent_schema_index);
}
return '';
}
@ -481,12 +353,12 @@ export function colorBgGraphNode(cst: IConstituenta, coloringScheme: GraphColori
/**
* Determines m-graph color for {@link TMGraphNode}.
*/
export function colorBgTMGraphNode(node: TMGraphNode, colors: IColorTheme): string {
export function colorBgTMGraphNode(node: TMGraphNode): string {
if (node.rank === 0) {
return colors.bgControls;
return APP_COLORS.bgControls;
}
if (node.parents.length === 1) {
return colors.bgTeal;
return APP_COLORS.bgTeal;
}
return colors.bgOrange;
return APP_COLORS.bgOrange;
}

View File

@ -20,52 +20,98 @@
--duration-modal: 300ms;
--duration-fade: 300ms;
--duration-select: 100ms;
/* Light Theme */
--cl-bg-120: hsl(000, 000%, 100%);
--cl-bg-100: hsl(000, 000%, 098%);
--cl-bg-80: hsl(000, 000%, 094%);
--cl-bg-60: hsl(000, 000%, 091%);
--cl-bg-40: hsl(000, 000%, 080%);
--cl-fg-60: hsl(000, 000%, 065%);
--cl-fg-80: hsl(000, 000%, 047%);
--cl-fg-100: hsl(000, 000%, 000%);
--cl-prim-bg-100: hsl(220, 100%, 060%);
--cl-prim-bg-80: hsl(220, 080%, 092%);
--cl-prim-bg-60: hsl(190, 080%, 094%);
--cl-prim-fg-80: hsl(220, 100%, 050%);
--cl-prim-fg-100: hsl(000, 000%, 100%);
--cl-red-bg-100: hsl(000, 100%, 095%);
--cl-red-fg-100: hsl(000, 072%, 051%);
--cl-green-fg-100: hsl(120, 080%, 37%);
--cl-teal-bg-100: hsl(162, 082%, 051%);
/* Dark Theme */
--cd-bg-120: hsl(000, 000%, 005%);
--cd-bg-100: hsl(000, 000%, 009%);
--cd-bg-80: hsl(000, 000%, 015%);
--cd-bg-60: hsl(000, 000%, 022%);
--cd-bg-40: hsl(000, 000%, 035%);
--cd-fg-60: hsl(000, 000%, 055%);
--cd-fg-80: hsl(000, 000%, 080%);
--cd-fg-100: hsl(000, 000%, 093%);
--cd-prim-bg-100: hsl(267, 050%, 050%);
--cd-prim-bg-80: hsl(267, 050%, 032%);
--cd-prim-bg-60: hsl(269, 030%, 028%);
--cd-prim-fg-80: hsl(267, 070%, 070%);
--cd-prim-fg-100: hsl(000, 000%, 100%);
--cd-red-bg-100: hsl(000, 100%, 015%);
--cd-red-fg-100: hsl(000, 080%, 055%);
--cd-green-fg-100: hsl(120, 080%, 042%);
--cd-teal-bg-100: hsl(162, 082%, 041%);
}
/* Light Theme */
/* prettier-ignore */
:not(.dark):root {
--clr-app-0: hsl(000, 000%, 100%);
--clr-app-100: hsl(000, 000%, 098%);
--clr-app-200: hsl(000, 000%, 094%);
--clr-app-300: hsl(000, 000%, 091%);
--clr-app-400: hsl(000, 000%, 080%);
--clr-app-600: hsl(000, 000%, 065%);
--clr-app-800: hsl(000, 000%, 047%);
--clr-app-999: hsl(000, 000%, 000%);
--clr-prim-100: hsl(220, 100%, 050%);
--clr-prim-200: hsl(220, 100%, 060%);
--clr-prim-300: hsl(220, 100%, 070%);
--clr-prim-400: hsl(220, 100%, 080%);
--clr-prim-600: hsl(220, 080%, 092%);
--clr-prim-800: hsl(190, 080%, 094%);
--clr-prim-999: hsl(000, 000%, 100%);
--clr-warn-100: hsl(000, 100%, 095%);
--clr-warn-600: hsl(000, 072%, 051%);
--clr-ok-600: hsl(120, 080%, 37%);
--clr-select-node:hsl(162, 082%, 051%);
/* Highlight accents */
--acc-bg-red: hsl(000, 100%, 089%);
--acc-bg-green: hsl(100, 100%, 075%);
--acc-bg-blue: hsl(235, 080%, 087%);
--acc-bg-purple: hsl(274, 089%, 081%);
--acc-bg-teal: hsl(192, 089%, 081%);
--acc-bg-orange: hsl(028, 100%, 075%);
--acc-bg-green25: hsl(100, 100%, 096%);
--acc-bg-green50: hsl(100, 100%, 090%);
--acc-bg-orange50:hsl(028, 100%, 090%);
--acc-fg-red: hsl(000, 090%, 045%);
--acc-fg-green: hsl(100, 090%, 035%);
--acc-fg-blue: hsl(235, 100%, 050%);
--acc-fg-purple: hsl(270, 100%, 055%);
--acc-fg-teal: hsl(200, 080%, 050%);
--acc-fg-orange: hsl(028, 100%, 050%);
}
/* Dark Theme */
/* prettier-ignore */
.dark:root {
--clr-app-0: hsl(000, 000%, 005%);
--clr-app-100: hsl(000, 000%, 009%);
--clr-app-200: hsl(000, 000%, 015%);
--clr-app-300: hsl(000, 000%, 022%);
--clr-app-400: hsl(000, 000%, 035%);
--clr-app-600: hsl(000, 000%, 055%);
--clr-app-800: hsl(000, 000%, 080%);
--clr-app-999: hsl(000, 000%, 093%);
--clr-prim-100: hsl(267, 070%, 070%);
--clr-prim-200: hsl(267, 050%, 060%);
--clr-prim-300: hsl(267, 050%, 050%);
--clr-prim-400: hsl(267, 050%, 040%);
--clr-prim-600: hsl(267, 050%, 032%);
--clr-prim-800: hsl(269, 030%, 028%);
--clr-prim-999: hsl(000, 000%, 100%);
--clr-warn-100: hsl(000, 100%, 015%);
--clr-warn-600: hsl(000, 080%, 055%);
--clr-ok-600: hsl(120, 080%, 042%);
--clr-select-node:hsl(162, 082%, 041%);
/* Highlight accents */
--acc-bg-red: hsl(000, 080%, 037%);
--acc-bg-green: hsl(100, 080%, 025%);
--acc-bg-blue: hsl(235, 054%, 049%);
--acc-bg-purple: hsl(270, 080%, 050%);
--acc-bg-teal: hsl(192, 080%, 030%);
--acc-bg-orange: hsl(035, 100%, 035%);
--acc-bg-green25: hsl(100, 080%, 009%);
--acc-bg-green50: hsl(100, 080%, 017%);
--acc-bg-orange50:hsl(035, 100%, 016%);
--acc-fg-red: hsl(000, 080%, 045%);
--acc-fg-green: hsl(100, 080%, 035%);
--acc-fg-blue: hsl(235, 100%, 080%);
--acc-fg-purple: hsl(270, 100%, 080%);
--acc-fg-teal: hsl(192, 100%, 045%);
--acc-fg-orange: hsl(035, 100%, 050%);
}

View File

@ -6,7 +6,7 @@
:root {
/* Import overrides */
--toastify-color-dark: var(--cd-bg-60);
--toastify-color-dark: var(--clr-app-300);
}
.cm-tooltip {
@ -17,48 +17,37 @@
resize: vertical;
overflow-y: auto;
overscroll-behavior-y: contain;
border-color: var(--cl-bg-40);
.dark & {
border-color: var(--cd-bg-40);
}
@apply border rounded px-[0.375rem] py-[0.15rem];
border-color: var(--clr-app-400);
border-width: 1px;
border-radius: 0.25rem;
padding-left: 0.375rem;
padding-right: 0.375rem;
padding-top: 0.15rem;
padding-bottom: 0.15rem;
}
.cm-editor.cm-focused {
border-color: var(--cl-bg-40);
outline-color: var(--cl-prim-bg-100);
.dark & {
border-color: var(--cd-bg-40);
outline-color: var(--cd-prim-bg-100);
}
@apply outline-2 outline;
border-color: var(--clr-app-400);
outline-color: var(--clr-prim-200);
outline-style: solid;
outline-width: 2px;
}
.cm-editor .cm-placeholder {
color: var(--cl-fg-60);
@apply font-main;
.dark & {
color: var(--cd-fg-60);
}
font-family: var(--font-main);
color: var(--clr-app-600);
}
.react-flow__handle {
cursor: default !important;
border-radius: 9999px;
border-color: var(--cl-bg-40);
background-color: var(--cl-bg-120);
border-color: var(--clr-app-400);
background-color: var(--clr-app-0);
.selected & {
border-color: var(--cd-bg-40);
}
.dark & {
border-color: var(--cd-bg-40);
background-color: var(--cd-bg-120);
.selected & {
border-color: var(--cl-bg-40);
}
border-color: var(--clr-app-800);
}
}
@ -77,34 +66,20 @@
margin-right: 3px;
background-color: transparent;
color: var(--cl-fg-60);
.dark & {
color: var(--cd-fg-60);
}
color: var(--clr-app-600);
}
[class*='react-flow__node-'] {
font-size: 14px;
border: 1px solid;
background-color: var(--cl-bg-120);
color: var(--cl-fg-100);
border-color: var(--cl-bg-40);
background-color: var(--cl-bg-120);
background-color: var(--clr-app-0);
color: var(--clr-app-999);
border-color: var(--clr-app-400);
background-color: var(--clr-app-0);
&:hover:not(.selected) {
box-shadow: 0 0 0 2px var(--cl-prim-bg-80) !important;
}
.dark & {
color: var(--cd-fg-100);
border-color: var(--cd-bg-40);
background-color: var(--cd-bg-120);
&:hover:not(.selected) {
box-shadow: 0 0 0 3px var(--cd-prim-bg-80) !important;
}
box-shadow: 0 0 0 2px var(--clr-prim-600) !important;
}
}
@ -127,16 +102,8 @@
&.selected {
outline-offset: 4px;
outline-color: var(--cl-teal-bg-100);
border-color: var(--cd-bg-40);
}
.dark & {
&.selected {
outline-offset: 4px;
border-color: var(--cd-teal-bg-100);
border-color: var(--cl-bg-40);
}
outline-color: var(--clr-select-node);
border-color: var(--clr-app-800);
}
}
@ -159,15 +126,7 @@
&.selected {
outline-offset: 4px;
outline-color: var(--cl-teal-bg-100);
outline-color: var(--clr-select-node);
border-color: transparent;
}
.dark & {
&.selected {
outline-offset: 4px;
border-color: var(--cd-teal-bg-100);
border-color: transparent;
}
}
}

View File

@ -26,7 +26,7 @@ html {
hanging-punctuation: first last;
color-scheme: dark light;
/* interpolate-size: allow-keywords; */
interpolate-size: allow-keywords;
}
body {
@ -58,15 +58,9 @@ body {
line-height: var(--line-height);
font-family: var(--font-main);
color: var(--cl-fg-100);
border-color: var(--cl-bg-40);
background-color: var(--cl-bg-100);
&.dark {
color: var(--cd-fg-100);
border-color: var(--cd-bg-40);
background-color: var(--cd-bg-100);
}
color: var(--clr-app-999);
border-color: var(--clr-app-400);
background-color: var(--clr-app-100);
}
@media only screen and (max-width: 639px) {
@ -84,23 +78,14 @@ body {
}
::selection {
background: var(--cl-prim-bg-60);
.dark & {
background: var(--cd-prim-bg-60);
}
background: var(--clr-prim-800);
tr :hover& {
background: var(--cl-red-bg-100);
.dark & {
background: var(--cd-red-bg-100);
}
background: var(--clr-warn-100);
}
}
::placeholder {
color: var(--cl-fg-60);
.dark & {
color: var(--cd-fg-60);
}
color: var(--clr-app-600);
}
/* Wrapping headers */
@ -120,24 +105,35 @@ li {
text-wrap: pretty;
}
div:not(.dense) > p {
@apply [&:not(:last-child)]:mb-2;
div:not(.dense) > p:not(:last-child) {
margin-bottom: 0.5rem;
}
@layer components {
h1 {
@apply text-lg font-semibold text-center;
font-weight: 600;
font-size: 1.125rem;
line-height: 1.75rem;
text-align: center;
}
h2 {
@apply [&:not(:first-child)]:mt-2 font-semibold text-center;
[role='manuals'] & {
@apply [&:not(:first-child)]:mt-3 mb-2;
font-weight: 600;
text-align: center;
&:not(:first-child) {
:not([role='manuals']) & {
margin-top: 0.5rem;
}
[role='manuals'] & {
margin-top: 0.75rem;
margin-bottom: 0.5rem;
}
}
}
b {
@apply font-semibold;
font-weight: 600;
}
code {
@ -153,7 +149,7 @@ div:not(.dense) > p {
}
.border {
@apply rounded;
border-radius: 0.25rem;
}
.border,
@ -174,10 +170,9 @@ div:not(.dense) > p {
.divide-y,
.divide-x-2,
.divide-y-2 {
border-color: var(--cl-bg-40);
@apply divide-inherit;
.dark & {
border-color: var(--cd-bg-40);
border-color: var(--clr-app-400);
& > :not([hidden]) ~ :not([hidden]) {
border-color: inherit;
}
}

View File

@ -21,133 +21,73 @@
}
@layer components {
.clr-app,
.clr-btn-nav {
background-color: var(--cl-bg-100);
.dark & {
background-color: var(--cd-bg-100);
}
}
.clr-footer {
color: var(--cl-fg-60);
background-color: var(--cl-bg-100);
.dark & {
color: var(--cd-fg-60);
background-color: var(--cd-bg-100);
}
color: var(--clr-app-600);
background-color: var(--clr-app-100);
}
.cc-modal-backdrop {
opacity: 0.5;
background-color: var(--cl-bg-100);
.dark & {
background-color: var(--cd-bg-100);
}
background-color: var(--clr-app-100);
}
.clr-input {
background-color: var(--cl-bg-120);
background-color: var(--clr-app-0);
&:disabled {
background-color: var(--cl-bg-100);
}
.dark & {
background-color: var(--cd-bg-120);
&:disabled {
background-color: var(--cd-bg-100);
}
background-color: var(--clr-app-100);
}
}
.clr-controls,
.clr-tab,
.clr-btn-default {
background-color: var(--cl-bg-80);
.dark & {
background-color: var(--cd-bg-80);
}
background-color: var(--clr-app-200);
}
.clr-primary,
.clr-btn-primary:hover,
.clr-btn-primary:focus-visible {
@apply transition;
color: var(--cl-prim-fg-100);
background-color: var(--cl-prim-bg-100);
.dark & {
color: var(--cd-prim-fg-100);
background-color: var(--cd-prim-bg-100);
}
color: var(--clr-prim-999);
background-color: var(--clr-prim-200);
}
.clr-selected,
.clr-btn-primary {
color: var(--cl-fg-100);
background-color: var(--cl-prim-bg-80);
.dark & {
color: var(--cd-fg-100);
background-color: var(--cd-prim-bg-80);
}
color: var(--clr-app-999);
background-color: var(--clr-prim-600);
}
:is(.clr-disabled, .clr-btn-default, .clr-btn-primary):disabled {
@apply transition;
color: var(--cl-fg-80);
background-color: var(--cl-bg-60);
.dark & {
color: var(--cd-fg-80);
background-color: var(--cd-bg-60);
}
color: var(--clr-app-800);
background-color: var(--clr-app-200);
}
:is(.clr-hover, .clr-tab, .clr-btn-nav, .clr-btn-default):hover:not(:disabled) {
@apply transition;
color: var(--cl-fg-100);
background-color: var(--cl-prim-bg-60);
.dark & {
color: var(--cd-fg-100);
background-color: var(--cd-prim-bg-60);
}
color: var(--clr-app-999);
background-color: var(--clr-prim-800);
}
:is(.clr-outline, .clr-btn-primary, .focus-frame):focus-visible,
.focus-frame:has(:focus-visible) {
outline-width: 2px;
outline-style: solid;
outline-color: var(--cl-prim-bg-100);
.dark & {
outline-color: var(--cd-prim-bg-100);
}
outline-color: var(--clr-prim-200);
}
.clr-text-primary,
.clr-text-url {
color: var(--cl-prim-fg-80);
.dark & {
color: var(--cd-prim-fg-80);
}
.clr-text-primary {
color: var(--clr-prim-100);
}
.clr-text-controls,
.clr-btn-nav,
.clr-btn-clear {
color: var(--cl-fg-80);
color: var(--clr-app-800);
background-color: transparent;
&:disabled {
color: var(--cl-fg-60);
}
.dark & {
color: var(--cd-fg-80);
&:disabled {
color: var(--cd-fg-60);
}
}
}
.clr-warning {
background-color: var(--cl-red-bg-100);
.dark & {
background-color: var(--cd-red-bg-100);
color: var(--clr-app-600);
}
}
@ -155,44 +95,25 @@
input:disabled:not(::placeholder),
textarea:disabled:not(::placeholder) {
opacity: 1;
-webkit-text-fill-color: var(--cl-fg-100);
color: var(--cl-fg-100);
.dark & {
opacity: 1;
-webkit-text-fill-color: var(--cd-fg-100);
color: var(--cd-fg-100);
}
}
.clr-text-red {
color: var(--cl-red-fg-100);
.dark & {
color: var(--cd-red-fg-100);
}
}
.clr-text-green {
color: var(--cl-green-fg-100);
.dark & {
color: var(--cd-green-fg-100);
}
-webkit-text-fill-color: var(--clr-app-999);
color: var(--clr-app-999);
}
.icon-primary {
:not([disabled]) > & {
@apply clr-text-primary;
color: var(--clr-prim-100);
}
}
.icon-red {
:not([disabled]) > & {
@apply clr-text-red;
color: var(--clr-warn-600);
}
}
.icon-green {
:not([disabled]) > & {
@apply clr-text-green;
color: var(--clr-ok-600);
}
}
@ -202,15 +123,23 @@
margin-left: 0.1rem;
margin-right: 0.1rem;
transform: translate(0, -0.2rem);
@apply clr-text-primary;
color: var(--clr-prim-100);
}
.cc-tab-tools {
@apply top-[1.7rem] pt-[0.4rem] pb-1 right-1/2 translate-x-1/2;
top: 1.7rem;
right: 50%;
padding-top: 0.4rem;
transform: translate(50%, 0%);
}
.cc-label {
@apply text-sm font-medium cursor-default select-text whitespace-nowrap;
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 500;
cursor: default;
user-select: text;
white-space: nowrap;
}
.cc-column {
@ -249,7 +178,7 @@
}
.cc-shadow-border {
@apply shadow-sm shadow-[var(--cl-bg-40)] dark:shadow-[var(--cd-bg-40)];
@apply shadow-sm shadow-[var(--clr-app-400)];
}
.cc-animate-position {

View File

@ -14,8 +14,8 @@ import { parseEntityReference, parseGrammemes, parseSyntacticReference } from '@
import { IConstituenta } from '@/models/rsform';
import { isBasicConcept } from '@/models/rsformAPI';
import { SyntaxTree } from '@/models/rslang';
import { APP_COLORS, colorFgGrammeme } from '@/styling/color';
import { colorFgGrammeme, IColorTheme } from '../styling/color';
import { PARAMETER } from './constants';
import { describeConstituentaTerm, labelCstTypification, labelGrammeme } from './labels';
@ -295,7 +295,6 @@ export function domTooltipConstituenta(cst?: IConstituenta, canClick?: boolean):
export function domTooltipEntityReference(
ref: IEntityReference,
cst: IConstituenta | undefined,
colors: IColorTheme,
canClick?: boolean
): TooltipView {
const dom = document.createElement('div');
@ -329,10 +328,10 @@ export function domTooltipEntityReference(
'text-sm text-center whitespace-nowrap'
);
gram.style.borderWidth = '1px';
gram.style.borderColor = colorFgGrammeme(gramStr, colors);
gram.style.color = colorFgGrammeme(gramStr, colors);
gram.style.borderColor = colorFgGrammeme(gramStr);
gram.style.color = colorFgGrammeme(gramStr);
gram.style.fontWeight = '600';
gram.style.backgroundColor = colors.bgInput;
gram.style.backgroundColor = APP_COLORS.bgInput;
gram.innerText = labelGrammeme(gramStr);
grams.appendChild(gram);
});

View File

@ -150,7 +150,7 @@ export function tripleToggleColor(value: boolean | undefined): string {
if (value === undefined) {
return 'clr-text-controls';
}
return value ? 'clr-text-green' : 'clr-text-red';
return value ? 'text-ok-600' : 'text-warn-600';
}
/**

View File

@ -5,6 +5,37 @@ export default {
darkMode: 'class',
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
colors: {
transparent: 'transparent',
current: 'currentColor',
inherit: 'inherit',
app: {
0: 'var(--clr-app-0)',
100: 'var(--clr-app-100)',
200: 'var(--clr-app-200)',
300: 'var(--clr-app-300)',
400: 'var(--clr-app-400)',
600: 'var(--clr-app-600)',
800: 'var(--clr-app-800)',
999: 'var(--clr-app-999)'
},
prim: {
100: 'var(--clr-prim-100)',
200: 'var(--clr-prim-200)',
300: 'var(--clr-prim-300)',
400: 'var(--clr-prim-400)',
600: 'var(--clr-prim-600)',
800: 'var(--clr-prim-800)',
999: 'var(--clr-prim-999)'
},
warn: {
100: 'var(--clr-warn-100)',
600: 'var(--clr-warn-600)'
},
ok: {
600: 'var(--clr-ok-600)'
}
},
zIndex: {
bottom: '0',
topmost: '99',

View File

@ -12,7 +12,10 @@ const reactCompilerConfig = {
const inlinePackages = ['react', 'react-router', 'react-dom'];
// Rollup warnings that should not be displayed
const warningsToIgnore = [['SOURCEMAP_ERROR', "Can't resolve original location of error"]];
const warningsToIgnore = [
['SOURCEMAP_ERROR', "Can't resolve original location of error"],
['MODULE_LEVEL_DIRECTIVE', 'Module level directives cause errors when bundled']
];
// https://vitejs.dev/config/
export default ({ mode }: { mode: string }) => {