F: Rework colors using tailwind configs
Some checks are pending
Frontend CI / build (22.x) (push) Waiting to run

This commit is contained in:
Ivan 2024-12-16 23:52:11 +03:00
parent b7aa8fe56a
commit 91dbd0e88f
74 changed files with 536 additions and 782 deletions

View File

@ -13,7 +13,7 @@ function ApplicationLayout() {
const { viewportHeight, mainHeight, showScroll } = useConceptOptions(); const { viewportHeight, mainHeight, showScroll } = useConceptOptions();
return ( return (
<NavigationState> <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 <ConceptToaster
className='mt-[4rem] text-[14px]' // prettier: split lines className='mt-[4rem] text-[14px]' // prettier: split lines
autoClose={3000} autoClose={3000}

View File

@ -5,7 +5,7 @@ import Button from '../components/ui/Button';
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) { function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
return ( 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> <h1>Что-то пошло не так!</h1>
<Button onClick={resetErrorBoundary} text='Попробовать еще раз' /> <Button onClick={resetErrorBoundary} text='Попробовать еще раз' />
<InfoError error={error as Error} /> <InfoError error={error as Error} />

View File

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

View File

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

View File

@ -51,7 +51,7 @@ export function ItemTypeIcon({ value, size = '1.25rem', className }: DomIconProp
case LibraryItemType.RSFORM: case LibraryItemType.RSFORM:
return <IconRSForm size={size} className={className ?? 'clr-text-primary'} />; return <IconRSForm size={size} className={className ?? 'clr-text-primary'} />;
case LibraryItemType.OSS: 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>) { export function PolicyIcon({ value, size = '1.25rem', className }: DomIconProps<AccessPolicy>) {
switch (value) { switch (value) {
case AccessPolicy.PRIVATE: case AccessPolicy.PRIVATE:
return <IconPrivate size={size} className={className ?? 'clr-text-red'} />; return <IconPrivate size={size} className={className ?? 'text-warn-600'} />;
case AccessPolicy.PROTECTED: case AccessPolicy.PROTECTED:
return <IconProtected size={size} className={className ?? 'clr-text-primary'} />; return <IconProtected size={size} className={className ?? 'clr-text-primary'} />;
case AccessPolicy.PUBLIC: case AccessPolicy.PUBLIC:
return <IconPublic size={size} className={className ?? 'clr-text-green'} />; return <IconPublic size={size} className={className ?? 'text-ok-600'} />;
} }
} }
/** Icon for visibility. */ /** Icon for visibility. */
export function VisibilityIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) { export function VisibilityIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
if (value) { if (value) {
return <IconShow size={size} className={className ?? 'clr-text-green'} />; return <IconShow size={size} className={className ?? 'text-ok-600'} />;
} else { } else {
return <IconHide size={size} className={className ?? 'clr-text-red'} />; return <IconHide size={size} className={className ?? 'text-warn-600'} />;
} }
} }
/** Icon for subfolders. */ /** Icon for subfolders. */
export function SubfoldersIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) { export function SubfoldersIcon({ value, size = '1.25rem', className }: DomIconProps<boolean>) {
if (value) { if (value) {
return <IconSubfolders size={size} className={className ?? 'clr-text-green'} />; return <IconSubfolders size={size} className={className ?? 'text-ok-600'} />;
} else { } else {
return <IconSubfolders size={size} className={className ?? 'clr-text-primary'} />; 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: case LocationHead.COMMON:
return <IconPublic size={size} className={className ?? 'clr-text-primary'} />; return <IconPublic size={size} className={className ?? 'clr-text-primary'} />;
case LocationHead.LIBRARY: case LocationHead.LIBRARY:
return <IconTemplates size={size} className={className ?? 'clr-text-red'} />; return <IconTemplates size={size} className={className ?? 'text-warn-600'} />;
case LocationHead.PROJECTS: case LocationHead.PROJECTS:
return <IconBusiness size={size} className={className ?? 'clr-text-primary'} />; return <IconBusiness size={size} className={className ?? 'clr-text-primary'} />;
case LocationHead.USER: 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>) { export function CstTypeIcon({ value, size = '1.25rem', className }: DomIconProps<CstType>) {
switch (value) { switch (value) {
case CstType.BASE: case CstType.BASE:
return <IconCstBaseSet size={size} className={className ?? 'clr-text-green'} />; return <IconCstBaseSet size={size} className={className ?? 'text-ok-600'} />;
case CstType.CONSTANT: case CstType.CONSTANT:
return <IconCstConstSet size={size} className={className ?? 'clr-text-green'} />; return <IconCstConstSet size={size} className={className ?? 'text-ok-600'} />;
case CstType.STRUCTURED: case CstType.STRUCTURED:
return <IconCstStructured size={size} className={className ?? 'clr-text-green'} />; return <IconCstStructured size={size} className={className ?? 'text-ok-600'} />;
case CstType.TERM: case CstType.TERM:
return <IconCstTerm size={size} className={className ?? 'clr-text-primary'} />; return <IconCstTerm size={size} className={className ?? 'clr-text-primary'} />;
case CstType.AXIOM: case CstType.AXIOM:
return <IconCstAxiom size={size} className={className ?? 'clr-text-red'} />; return <IconCstAxiom size={size} className={className ?? 'text-warn-600'} />;
case CstType.FUNCTION: case CstType.FUNCTION:
return <IconCstFunction size={size} className={className ?? 'clr-text-primary'} />; return <IconCstFunction size={size} className={className ?? 'clr-text-primary'} />;
case CstType.PREDICATE: case CstType.PREDICATE:
return <IconCstPredicate size={size} className={className ?? 'clr-text-red'} />; return <IconCstPredicate size={size} className={className ?? 'text-warn-600'} />;
case CstType.THEOREM: 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 { ConstituentaID, IRSForm } from '@/models/rsform';
import { generateAlias, getCstTypePrefix, guessCstType } from '@/models/rsformAPI'; import { generateAlias, getCstTypePrefix, guessCstType } from '@/models/rsformAPI';
import { extractGlobals } from '@/models/rslangAPI'; import { extractGlobals } from '@/models/rslangAPI';
import { APP_COLORS } from '@/styling/color';
import { ccBracketMatching } from './bracketMatching'; import { ccBracketMatching } from './bracketMatching';
import { rsNavigation } from './clickNavigation'; import { rsNavigation } from './clickNavigation';
@ -63,7 +64,7 @@ const RSInput = forwardRef<ReactCodeMirrorRef, RSInputProps>(
}, },
ref ref
) => { ) => {
const { darkMode, colors } = useConceptOptions(); const { darkMode } = useConceptOptions();
const internalRef = useRef<ReactCodeMirrorRef>(null); const internalRef = useRef<ReactCodeMirrorRef>(null);
const thisRef = !ref || typeof ref === 'function' ? internalRef : ref; const thisRef = !ref || typeof ref === 'function' ? internalRef : ref;
@ -73,27 +74,27 @@ const RSInput = forwardRef<ReactCodeMirrorRef, RSInputProps>(
theme: darkMode ? 'dark' : 'light', theme: darkMode ? 'dark' : 'light',
settings: { settings: {
fontFamily: 'inherit', fontFamily: 'inherit',
background: !disabled ? colors.bgInput : colors.bgDefault, background: !disabled ? APP_COLORS.bgInput : APP_COLORS.bgDefault,
foreground: colors.fgDefault, foreground: APP_COLORS.fgDefault,
selection: colors.bgHover, selection: APP_COLORS.bgHover,
caret: colors.fgDefault caret: APP_COLORS.fgDefault
}, },
styles: [ styles: [
{ tag: tags.name, color: colors.fgPurple, cursor: schema ? 'default' : cursor }, // GlobalID { tag: tags.name, color: APP_COLORS.fgPurple, cursor: schema ? 'default' : cursor }, // GlobalID
{ tag: tags.variableName, color: colors.fgGreen }, // LocalID { tag: tags.variableName, color: APP_COLORS.fgGreen }, // LocalID
{ tag: tags.propertyName, color: colors.fgTeal }, // Radical { tag: tags.propertyName, color: APP_COLORS.fgTeal }, // Radical
{ tag: tags.keyword, color: colors.fgBlue }, // keywords { tag: tags.keyword, color: APP_COLORS.fgBlue }, // keywords
{ tag: tags.literal, color: colors.fgBlue }, // literals { tag: tags.literal, color: APP_COLORS.fgBlue }, // literals
{ tag: tags.controlKeyword, fontWeight: '400' }, // R | I | D { tag: tags.controlKeyword, fontWeight: '400' }, // R | I | D
{ tag: tags.unit, fontSize: '0.75rem' }, // indices { 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 = [ const editorExtensions = [
EditorView.lineWrapping, EditorView.lineWrapping,
RSLanguage, RSLanguage,
ccBracketMatching(darkMode), ccBracketMatching(),
...(!schema || !onOpenEdit ? [] : [rsNavigation(schema, onOpenEdit)]), ...(!schema || !onOpenEdit ? [] : [rsNavigation(schema, onOpenEdit)]),
...(noTooltip || !schema ? [] : [rsHoverTooltip(schema, onOpenEdit !== undefined)]) ...(noTooltip || !schema ? [] : [rsHoverTooltip(schema, onOpenEdit !== undefined)])
]; ];

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,10 +5,10 @@ import { useEffect, useState } from 'react';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable'; import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import SearchBar from '@/components/ui/SearchBar'; import SearchBar from '@/components/ui/SearchBar';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { CstMatchMode } from '@/models/miscellaneous'; import { CstMatchMode } from '@/models/miscellaneous';
import { IConstituenta } from '@/models/rsform'; import { IConstituenta } from '@/models/rsform';
import { matchConstituenta } from '@/models/rsformAPI'; import { matchConstituenta } from '@/models/rsformAPI';
import { APP_COLORS } from '@/styling/color';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
import { describeConstituenta } from '@/utils/labels'; import { describeConstituenta } from '@/utils/labels';
@ -47,7 +47,6 @@ function PickConstituenta({
className, className,
...restProps ...restProps
}: PickConstituentaProps) { }: PickConstituentaProps) {
const { colors } = useConceptOptions();
const [filteredData, setFilteredData] = useState<IConstituenta[]>([]); const [filteredData, setFilteredData] = useState<IConstituenta[]>([]);
const [filterText, setFilterText] = useState(initialFilter); const [filterText, setFilterText] = useState(initialFilter);
@ -70,7 +69,7 @@ function PickConstituenta({
size: 65, size: 65,
minSize: 65, minSize: 65,
maxSize: 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), { columnHelper.accessor(cst => describeFunc(cst), {
id: 'description', id: 'description',
@ -82,7 +81,7 @@ function PickConstituenta({
const conditionalRowStyles: IConditionalStyle<IConstituenta>[] = [ const conditionalRowStyles: IConditionalStyle<IConstituenta>[] = [
{ {
when: (cst: IConstituenta) => cst.id === value?.id, 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 { useEffect, useState } from 'react';
import DataTable, { createColumnHelper, RowSelectionState } from '@/components/ui/DataTable'; import DataTable, { createColumnHelper, RowSelectionState } from '@/components/ui/DataTable';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { Graph } from '@/models/Graph'; import { Graph } from '@/models/Graph';
import { CstMatchMode } from '@/models/miscellaneous'; import { CstMatchMode } from '@/models/miscellaneous';
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform'; import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
@ -44,7 +43,6 @@ function PickMultiConstituenta({
className, className,
...restProps ...restProps
}: PickMultiConstituentaProps) { }: PickMultiConstituentaProps) {
const { colors } = useConceptOptions();
const [rowSelection, setRowSelection] = useState<RowSelectionState>({}); const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
const [filtered, setFiltered] = useState<IConstituenta[]>(data); const [filtered, setFiltered] = useState<IConstituenta[]>(data);
const [filterText, setFilterText] = useState(''); const [filterText, setFilterText] = useState('');
@ -111,7 +109,7 @@ function PickMultiConstituenta({
id: 'alias', id: 'alias',
header: () => <span className='pl-3'>Имя</span>, header: () => <span className='pl-3'>Имя</span>,
size: 65, 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), { columnHelper.accessor(cst => describeConstituenta(cst), {
id: 'description', id: 'description',

View File

@ -4,11 +4,11 @@ import { useIntl } from 'react-intl';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable'; import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import SearchBar from '@/components/ui/SearchBar'; import SearchBar from '@/components/ui/SearchBar';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useLibrary } from '@/context/LibraryContext'; import { useLibrary } from '@/context/LibraryContext';
import useDropdown from '@/hooks/useDropdown'; import useDropdown from '@/hooks/useDropdown';
import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library'; import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
import { matchLibraryItem } from '@/models/libraryAPI'; import { matchLibraryItem } from '@/models/libraryAPI';
import { APP_COLORS } from '@/styling/color';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
import { IconClose, IconFolderTree } from '../Icons'; import { IconClose, IconFolderTree } from '../Icons';
@ -45,7 +45,6 @@ function PickSchema({
...restProps ...restProps
}: PickSchemaProps) { }: PickSchemaProps) {
const intl = useIntl(); const intl = useIntl();
const { colors } = useConceptOptions();
const { folders } = useLibrary(); const { folders } = useLibrary();
const [filterText, setFilterText] = useState(initialFilter); const [filterText, setFilterText] = useState(initialFilter);
@ -99,7 +98,7 @@ function PickSchema({
const conditionalRowStyles: IConditionalStyle<ILibraryItem>[] = [ const conditionalRowStyles: IConditionalStyle<ILibraryItem>[] = [
{ {
when: (item: ILibraryItem) => item.id === value, 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 SelectConstituenta from '@/components/select/SelectConstituenta';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable'; import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ILibraryItem } from '@/models/library'; import { ILibraryItem } from '@/models/library';
import { ICstSubstitute, IMultiSubstitution } from '@/models/oss'; import { ICstSubstitute, IMultiSubstitution } from '@/models/oss';
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform'; import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
import { APP_COLORS } from '@/styling/color';
import { errors } from '@/utils/labels'; import { errors } from '@/utils/labels';
import { IconAccept, IconPageLeft, IconPageRight, IconRemove, IconReplace } from '../Icons'; import { IconAccept, IconPageLeft, IconPageRight, IconRemove, IconReplace } from '../Icons';
@ -46,8 +46,6 @@ function PickSubstitutions({
className, className,
...restProps ...restProps
}: PickSubstitutionsProps) { }: PickSubstitutionsProps) {
const { colors } = useConceptOptions();
const [leftArgument, setLeftArgument] = useState<ILibraryItem | undefined>( const [leftArgument, setLeftArgument] = useState<ILibraryItem | undefined>(
schemas.length === 1 ? schemas[0] : undefined schemas.length === 1 ? schemas[0] : undefined
); );
@ -164,11 +162,7 @@ function PickSubstitutions({
id: 'left_alias', id: 'left_alias',
size: 65, size: 65,
cell: props => ( cell: props => (
<BadgeConstituenta <BadgeConstituenta value={props.row.original.substitution} prefixID={`${prefixID}_${props.row.index}_1_`} />
theme={colors}
value={props.row.original.substitution}
prefixID={`${prefixID}_${props.row.index}_1_`}
/>
) )
}), }),
columnHelper.display({ columnHelper.display({
@ -180,11 +174,7 @@ function PickSubstitutions({
id: 'right_alias', id: 'right_alias',
size: 65, size: 65,
cell: props => ( cell: props => (
<BadgeConstituenta <BadgeConstituenta value={props.row.original.original} prefixID={`${prefixID}_${props.row.index}_2_`} />
theme={colors}
value={props.row.original.original}
prefixID={`${prefixID}_${props.row.index}_2_`}
/>
) )
}), }),
columnHelper.accessor(item => item.original_source.alias, { columnHelper.accessor(item => item.original_source.alias, {
@ -227,9 +217,7 @@ function PickSubstitutions({
const conditionalRowStyles: IConditionalStyle<IMultiSubstitution>[] = [ const conditionalRowStyles: IConditionalStyle<IMultiSubstitution>[] = [
{ {
when: (item: IMultiSubstitution) => item.is_suggestion, when: (item: IMultiSubstitution) => item.is_suggestion,
style: { style: { backgroundColor: APP_COLORS.bgOrange50 }
backgroundColor: colors.bgOrange50
}
} }
]; ];

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
'use client'; 'use client';
import { useConceptOptions } from '@/context/ConceptOptionsContext'; import { APP_COLORS } from '@/styling/color';
interface LoaderProps { interface LoaderProps {
/** Scale of the loader from 1 to 10. */ /** Scale of the loader from 1 to 10. */
@ -55,11 +55,10 @@ const animatePulse = (startBig: boolean, duration: string) => {
* Displays animated loader. * Displays animated loader.
*/ */
function Loader({ scale = 5, circular }: LoaderProps) { function Loader({ scale = 5, circular }: LoaderProps) {
const { colors } = useConceptOptions();
if (circular) { if (circular) {
return ( return (
<div className='flex justify-center' aria-label='three-circles-loading' aria-busy='true' role='progressbar'> <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'> <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')} {animateRotation('2.25s')}
</path> </path>
@ -75,7 +74,7 @@ function Loader({ scale = 5, circular }: LoaderProps) {
} else { } else {
return ( return (
<div className='flex justify-center' aria-busy='true' role='progressbar'> <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'> <circle cx='15' cy='15' r='16'>
{animatePulse(true, '0.8s')} {animatePulse(true, '0.8s')}
</circle> </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='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-blur')} />
<div <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} onClick={hideWindow}
/> />
<div <div
className={clsx( className={clsx(
'cc-animate-modal', 'cc-animate-modal',
'z-modal absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2', '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'> <Overlay position='right-2 top-2'>

View File

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

View File

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

View File

@ -20,7 +20,7 @@ interface TextURLProps {
/** /**
* Displays a text with a clickable link. * 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}`; const design = `cursor-pointer hover:underline ${color}`;
if (href) { if (href) {
return ( return (

View File

@ -22,7 +22,7 @@ function ExpectedAnonymous() {
<span> | </span> <span> | </span>
<TextURL text='Справка' href='/manuals' /> <TextURL text='Справка' href='/manuals' />
<span> | </span> <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> </span>
</div> </div>

View File

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

View File

@ -10,9 +10,9 @@ import PickConstituenta from '@/components/select/PickConstituenta';
import DataTable, { IConditionalStyle } from '@/components/ui/DataTable'; import DataTable, { IConditionalStyle } from '@/components/ui/DataTable';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import NoData from '@/components/ui/NoData'; import NoData from '@/components/ui/NoData';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { IConstituenta, IRSForm } from '@/models/rsform'; import { IConstituenta, IRSForm } from '@/models/rsform';
import { IArgumentValue } from '@/models/rslang'; import { IArgumentValue } from '@/models/rslang';
import { APP_COLORS } from '@/styling/color';
import { prefixes } from '@/utils/constants'; import { prefixes } from '@/utils/constants';
interface TabArgumentsProps { interface TabArgumentsProps {
@ -29,8 +29,6 @@ export interface IArgumentsState {
const argumentsHelper = createColumnHelper<IArgumentValue>(); const argumentsHelper = createColumnHelper<IArgumentValue>();
function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) { function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
const { colors } = useConceptOptions();
const [selectedCst, setSelectedCst] = useState<IConstituenta | undefined>(undefined); const [selectedCst, setSelectedCst] = useState<IConstituenta | undefined>(undefined);
const [selectedArgument, setSelectedArgument] = useState<IArgumentValue | undefined>(undefined); const [selectedArgument, setSelectedArgument] = useState<IArgumentValue | undefined>(undefined);
const [argumentValue, setArgumentValue] = useState(''); const [argumentValue, setArgumentValue] = useState('');
@ -124,7 +122,7 @@ function TabArguments({ state, schema, partialUpdate }: TabArgumentsProps) {
const conditionalRowStyles: IConditionalStyle<IArgumentValue>[] = [ const conditionalRowStyles: IConditionalStyle<IArgumentValue>[] = [
{ {
when: (arg: IArgumentValue) => arg.alias === selectedArgument?.alias, 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' id='dlg_cst_show_comment'
tabIndex={-1} tabIndex={-1}
type='button' 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)} onClick={() => setForceComment(true)}
> >
Добавить комментарий Добавить комментарий

View File

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

View File

@ -6,8 +6,8 @@ import { useIntl } from 'react-intl';
import { IconRemove } from '@/components/Icons'; import { IconRemove } from '@/components/Icons';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable'; import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { IVersionInfo, VersionID } from '@/models/library'; import { IVersionInfo, VersionID } from '@/models/library';
import { APP_COLORS } from '@/styling/color';
interface TableVersionsProps { interface TableVersionsProps {
processing: boolean; processing: boolean;
@ -21,8 +21,6 @@ const columnHelper = createColumnHelper<IVersionInfo>();
function TableVersions({ processing, items, onDelete, selected, onSelect }: TableVersionsProps) { function TableVersions({ processing, items, onDelete, selected, onSelect }: TableVersionsProps) {
const intl = useIntl(); const intl = useIntl();
const { colors } = useConceptOptions();
const columns = [ const columns = [
columnHelper.accessor('version', { columnHelper.accessor('version', {
id: 'version', id: 'version',
@ -74,7 +72,7 @@ function TableVersions({ processing, items, onDelete, selected, onSelect }: Tabl
{ {
when: (version: IVersionInfo) => version.id === selected, when: (version: IVersionInfo) => version.id === selected,
style: { 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 Modal, { ModalProps } from '@/components/ui/Modal';
import Overlay from '@/components/ui/Overlay'; import Overlay from '@/components/ui/Overlay';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { HelpTopic } from '@/models/miscellaneous'; import { HelpTopic } from '@/models/miscellaneous';
import { SyntaxTree } from '@/models/rslang'; import { SyntaxTree } from '@/models/rslang';
@ -17,7 +16,6 @@ interface DlgShowASTProps extends Pick<ModalProps, 'hideWindow'> {
} }
function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) { function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
const { colors } = useConceptOptions();
const [hoverID, setHoverID] = useState<number | undefined>(undefined); const [hoverID, setHoverID] = useState<number | undefined>(undefined);
const hoverNode = syntaxTree.find(node => node.uid === hoverID); const hoverNode = syntaxTree.find(node => node.uid === hoverID);
@ -32,8 +30,7 @@ function DlgShowAST({ hideWindow, syntaxTree, expression }: DlgShowASTProps) {
> >
<Overlay <Overlay
position='top-2 right-1/2 translate-x-1/2' 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' className='px-2 py-1 rounded-2xl cc-blur bg-app-100 max-w-[60ch] text-lg text-center'
style={{ backgroundColor: colors.bgBlur }}
> >
{!hoverNode || isDragging ? expression : null} {!hoverNode || isDragging ? expression : null}
{!isDragging && hoverNode ? ( {!isDragging && hoverNode ? (

View File

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

View File

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

View File

@ -2,9 +2,8 @@
import { Handle, Position } from 'reactflow'; import { Handle, Position } from 'reactflow';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { TMGraphNode } from '@/models/TMGraph'; import { TMGraphNode } from '@/models/TMGraph';
import { colorBgTMGraphNode } from '@/styling/color'; import { APP_COLORS, colorBgTMGraphNode } from '@/styling/color';
import { globals } from '@/utils/constants'; import { globals } from '@/utils/constants';
/** /**
@ -19,8 +18,6 @@ interface MGraphNodeInternal {
} }
function MGraphNode(node: MGraphNodeInternal) { function MGraphNode(node: MGraphNodeInternal) {
const { colors } = useConceptOptions();
const tooltipText = const tooltipText =
(node.data.annotations.length === 0 ? '' : `Конституенты: ${node.data.annotations.join(' ')}<br/>`) + (node.data.annotations.length === 0 ? '' : `Конституенты: ${node.data.annotations.join(' ')}<br/>`) +
node.data.text; node.data.text;
@ -33,10 +30,10 @@ function MGraphNode(node: MGraphNodeInternal) {
data-tooltip-id={globals.tooltip} data-tooltip-id={globals.tooltip}
data-tooltip-html={tooltipText} data-tooltip-html={tooltipText}
style={{ style={{
backgroundColor: colorBgTMGraphNode(node.data, colors), backgroundColor: colorBgTMGraphNode(node.data),
fontWeight: 600, fontWeight: 600,
WebkitTextStrokeWidth: '0.6px', 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 : ''} {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 useLocalStorage from '@/hooks/useLocalStorage';
import useWindowSize from '@/hooks/useWindowSize'; import useWindowSize from '@/hooks/useWindowSize';
import { ILibraryItem, LibraryItemType } from '@/models/library'; import { ILibraryItem, LibraryItemType } from '@/models/library';
import { APP_COLORS } from '@/styling/color';
import { storage } from '@/utils/constants'; import { storage } from '@/utils/constants';
interface TableLibraryItemsProps { interface TableLibraryItemsProps {
@ -33,10 +34,14 @@ function TableLibraryItems({ items, resetQuery, folderMode, toggleFolderMode }:
const router = useConceptNavigation(); const router = useConceptNavigation();
const intl = useIntl(); const intl = useIntl();
const { getUserLabel } = useUsers(); const { getUserLabel } = useUsers();
const { calculateHeight, colors } = useConceptOptions(); const { calculateHeight } = useConceptOptions();
const [itemsPerPage, setItemsPerPage] = useLocalStorage<number>(storage.libraryPagination, 50); const [itemsPerPage, setItemsPerPage] = useLocalStorage<number>(storage.libraryPagination, 50);
function handleOpenItem(item: ILibraryItem, event: CProps.EventMouse) { function handleOpenItem(item: ILibraryItem, event: CProps.EventMouse) {
const selection = window.getSelection();
if (!!selection && selection.toString().length > 0) {
return;
}
if (item.item_type === LibraryItemType.RSFORM) { if (item.item_type === LibraryItemType.RSFORM) {
router.push(urls.schema(item.id), event.ctrlKey || event.metaKey); router.push(urls.schema(item.id), event.ctrlKey || event.metaKey);
} else if (item.item_type === LibraryItemType.OSS) { } 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, when: (item: ILibraryItem) => item.item_type === LibraryItemType.OSS,
style: { style: {
color: colors.fgGreen color: APP_COLORS.fgGreen
} }
} }
]; ];

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@ function NodeCore({ node }: NodeCoreProps) {
<Indicator <Indicator
noPadding noPadding
title={hasFile ? 'Связанная КС' : 'Нет связанной КС'} 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} hideTitle={!controller.showTooltip}
/> />
{node.data.operation.is_consolidation ? ( {node.data.operation.is_consolidation ? (

View File

@ -25,7 +25,7 @@ function PasswordChangePage() {
const [newPasswordRepeat, setNewPasswordRepeat] = useState(''); const [newPasswordRepeat, setNewPasswordRepeat] = useState('');
const passwordColor = 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; const canSubmit = !!newPassword && !!newPasswordRepeat && newPassword === newPasswordRepeat;
@ -102,7 +102,7 @@ export default PasswordChangePage;
// ====== Internals ========= // ====== Internals =========
function ProcessError({ error }: { error: ErrorData }): React.ReactElement { function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if (axios.isAxiosError(error) && error.response && error.response.status === 404) { 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 { } else {
return <InfoError error={error} />; return <InfoError error={error} />;
} }

View File

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

View File

@ -33,7 +33,7 @@ function ParsingResult({ isOpen, data, disabled, onShowError }: ParsingResultPro
<p <p
tabIndex={-1} tabIndex={-1}
key={`error-${index}`} 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)} onClick={disabled ? undefined : () => onShowError(error)}
> >
<span className='mr-1 font-semibold underline'> <span className='mr-1 font-semibold underline'>

View File

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

View File

@ -130,7 +130,7 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
<ValueIcon <ValueIcon
dense dense
disabled 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)} value={new Date(item.time_update).toLocaleString(intl.locale)}
title='Дата обновления' title='Дата обновления'
/> />
@ -138,7 +138,7 @@ function EditorLibraryItem({ item, isModified, controller }: EditorLibraryItemPr
<ValueIcon <ValueIcon
dense dense
disabled 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, { value={new Date(item.time_create).toLocaleString(intl.locale, {
year: '2-digit', year: '2-digit',
month: '2-digit', month: '2-digit',

View File

@ -55,7 +55,7 @@ function RSFormStats({ stats, isArchive }: RSFormStatsProps) {
<ValueStats <ValueStats
className='col-start-1' className='col-start-1'
id='count_ok' 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} value={stats.count_all - stats.count_errors - stats.count_property - stats.count_incalculable}
title='Корректные' title='Корректные'
/> />
@ -67,13 +67,13 @@ function RSFormStats({ stats, isArchive }: RSFormStatsProps) {
/> />
<ValueStats <ValueStats
id='count_incalculable' 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} value={stats.count_incalculable}
title='Невычислимые' title='Невычислимые'
/> />
<ValueStats <ValueStats
id='count_errors' 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} value={stats.count_errors}
title='Некорректные' title='Некорректные'
/> />

View File

@ -46,7 +46,7 @@ function ToolbarItemAccess({ visible, toggleVisible, readOnly, toggleReadOnly, c
readOnly ? ( readOnly ? (
<IconImmutable size='1.25rem' className='clr-text-primary' /> <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} onClick={toggleReadOnly}

View File

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

View File

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

View File

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

View File

@ -4,8 +4,8 @@ import { useCallback } from 'react';
import { IconGraphInputs, IconGraphOutputs, IconReset } from '@/components/Icons'; import { IconGraphInputs, IconGraphOutputs, IconReset } from '@/components/Icons';
import MiniButton from '@/components/ui/MiniButton'; import MiniButton from '@/components/ui/MiniButton';
import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { IConstituenta } from '@/models/rsform'; import { IConstituenta } from '@/models/rsform';
import { APP_COLORS } from '@/styling/color';
import { useRSEdit } from '../RSEditContext'; import { useRSEdit } from '../RSEditContext';
@ -27,7 +27,6 @@ function ToolbarFocusedCst({
toggleShowInputs, toggleShowInputs,
toggleShowOutputs toggleShowOutputs
}: ToolbarFocusedCstProps) { }: ToolbarFocusedCstProps) {
const { colors } = useConceptOptions();
const controller = useRSEdit(); const controller = useRSEdit();
const resetSelection = useCallback(() => { const resetSelection = useCallback(() => {
@ -37,7 +36,7 @@ function ToolbarFocusedCst({
return ( return (
<div className='items-center cc-icons'> <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> <b className='px-1'> {center.alias} </b>
</div> </div>

View File

@ -12,7 +12,7 @@ import useLocalStorage from '@/hooks/useLocalStorage';
import useWindowSize from '@/hooks/useWindowSize'; import useWindowSize from '@/hooks/useWindowSize';
import { GraphColoring } from '@/models/miscellaneous'; import { GraphColoring } from '@/models/miscellaneous';
import { ConstituentaID, IRSForm } from '@/models/rsform'; 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'; import { PARAMETER, prefixes, storage } from '@/utils/constants';
interface ViewHiddenProps { interface ViewHiddenProps {
@ -27,7 +27,7 @@ interface ViewHiddenProps {
} }
function ViewHidden({ items, selected, toggleSelection, setFocus, schema, coloringScheme, onEdit }: ViewHiddenProps) { function ViewHidden({ items, selected, toggleSelection, setFocus, schema, coloringScheme, onEdit }: ViewHiddenProps) {
const { colors, calculateHeight } = useConceptOptions(); const { calculateHeight } = useConceptOptions();
const windowSize = useWindowSize(); const windowSize = useWindowSize();
const localSelected = items.filter(id => selected.includes(id)); const localSelected = items.filter(id => selected.includes(id));
const [isFolded, setIsFolded] = useLocalStorage(storage.rsgraphFoldHidden, false); const [isFolded, setIsFolded] = useLocalStorage(storage.rsgraphFoldHidden, false);
@ -96,12 +96,12 @@ function ViewHidden({ items, selected, toggleSelection, setFocus, schema, colori
id={id} id={id}
className='min-w-[3rem] rounded-md text-center select-none' className='min-w-[3rem] rounded-md text-center select-none'
style={{ style={{
backgroundColor: colorBgGraphNode(cst, adjustedColoring, colors), backgroundColor: colorBgGraphNode(cst, adjustedColoring),
...(localSelected.includes(cstID) ...(localSelected.includes(cstID)
? { ? {
outlineWidth: '2px', outlineWidth: '2px',
outlineStyle: cst.is_inherited ? 'dashed' : 'solid', 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 { Handle, Position } from 'reactflow';
import { useConceptOptions } from '@/context/ConceptOptionsContext'; import { APP_COLORS } from '@/styling/color';
import { truncateToLastWord } from '@/utils/utils'; import { truncateToLastWord } from '@/utils/utils';
const MAX_DESCRIPTION_LENGTH = 65; const MAX_DESCRIPTION_LENGTH = 65;
@ -32,7 +32,6 @@ interface TGNodeInternal {
} }
function TGNode(node: TGNodeInternal) { function TGNode(node: TGNodeInternal) {
const { colors } = useConceptOptions();
const description = truncateToLastWord(node.data.description, MAX_DESCRIPTION_LENGTH); const description = truncateToLastWord(node.data.description, MAX_DESCRIPTION_LENGTH);
return ( return (
@ -41,7 +40,7 @@ function TGNode(node: TGNodeInternal) {
<div <div
className='w-full h-full cursor-default flex items-center justify-center rounded-full' className='w-full h-full cursor-default flex items-center justify-center rounded-full'
style={{ 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 fontSize: node.data.label.length > LABEL_THRESHOLD ? FONT_SIZE_MED : FONT_SIZE_MAX
}} }}
> >
@ -49,7 +48,7 @@ function TGNode(node: TGNodeInternal) {
style={{ style={{
fontWeight: 600, fontWeight: 600,
WebkitTextStrokeWidth: '0.6px', WebkitTextStrokeWidth: '0.6px',
WebkitTextStrokeColor: colors.bgDefault WebkitTextStrokeColor: APP_COLORS.bgDefault
}} }}
> >
{node.data.label} {node.data.label}
@ -68,7 +67,7 @@ function TGNode(node: TGNodeInternal) {
aria-hidden='true' aria-hidden='true'
style={{ style={{
WebkitTextStrokeWidth: '3px', WebkitTextStrokeWidth: '3px',
WebkitTextStrokeColor: colors.bgDefault WebkitTextStrokeColor: APP_COLORS.bgDefault
}} }}
> >
{description} {description}

View File

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

View File

@ -70,7 +70,7 @@ export default RestorePasswordPage;
function ProcessError({ error }: { error: ErrorData }): React.ReactElement { function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if (axios.isAxiosError(error) && error.response && error.response.status === 400) { if (axios.isAxiosError(error) && error.response && error.response.status === 400) {
return ( 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 { } else {
return <InfoError error={error} />; return <InfoError error={error} />;

View File

@ -24,7 +24,7 @@ function EditorPassword() {
const [newPasswordRepeat, setNewPasswordRepeat] = useState(''); const [newPasswordRepeat, setNewPasswordRepeat] = useState('');
const passwordColor = 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; const canSubmit = !!oldPassword && !!newPassword && !!newPasswordRepeat && newPassword === newPasswordRepeat;
@ -99,7 +99,7 @@ export default EditorPassword;
// ====== Internals ========= // ====== Internals =========
function ProcessError({ error }: { error: ErrorData }): React.ReactElement { function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if (axios.isAxiosError(error) && error.response && error.response.status === 400) { 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 { } else {
return <InfoError error={error} />; return <InfoError error={error} />;
} }

View File

@ -98,7 +98,7 @@ function ProcessError({ error }: { error: ErrorData }): React.ReactElement {
if ('email' in error.response.data) { if ('email' in error.response.data) {
return ( return (
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access // 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 { TMGraphNode } from '@/models/TMGraph';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
/** /** Semantic colors for application. */
* Represents application color theme configuration. // prettier-ignore
*/ export const APP_COLORS = {
export interface IColorTheme { bgDefault: 'var(--clr-app-100)',
bgDefault: string; bgInput: 'var(--clr-app-0)',
bgBlur: string; bgControls: 'var(--clr-app-200)',
bgInput: string; bgDisabled: 'var(--clr-app-300)',
bgControls: string; bgPrimary: 'var(--clr-prim-200)',
bgDisabled: string; bgSelected: 'var(--clr-prim-600)',
bgPrimary: string; bgActiveSelection: 'var(--clr-select-node)',
bgSelected: string; bgHover: 'var(--clr-prim-800)',
bgActiveSelection: string; bgWarning: 'var(--clr-warn-100)',
bgHover: string;
bgWarning: string;
border: string; border: 'var(--clr-app-400)',
fgDefault: string; fgDefault: 'var(--clr-app-999)',
fgSelected: string; fgSelected: 'var(--clr-app-999)',
fgDisabled: string; fgDisabled: 'var(--clr-app-800)',
fgWarning: string; fgWarning: 'var(--clr-warn-600)',
// Highlight syntax accents bgRed: 'var(--acc-bg-red)',
bgRed: string; bgGreen: 'var(--acc-bg-green)',
bgGreen: string; bgBlue: 'var(--acc-bg-blue)',
bgBlue: string; bgPurple: 'var(--acc-bg-purple)',
bgPurple: string; bgTeal: 'var(--acc-bg-teal)',
bgTeal: string; bgOrange: 'var(--acc-bg-orange)',
bgOrange: string;
bgGreen25: string; bgGreen25: 'var(--acc-bg-green25)',
bgGreen50: string; bgGreen50: 'var(--acc-bg-green50)',
bgOrange50: string; bgOrange50: 'var(--acc-bg-orange50)',
fgRed: string; fgRed: 'var(--acc-fg-red)',
fgGreen: string; fgGreen: 'var(--acc-fg-green)',
fgBlue: string; fgBlue: 'var(--acc-fg-blue)',
fgPurple: string; fgPurple: 'var(--acc-fg-purple)',
fgTeal: string; fgTeal: 'var(--acc-fg-teal)',
fgOrange: string; fgOrange: 'var(--acc-fg-orange)'
} }
/** /**
* Represents application Light theme. * Represents Select component theme.
*/ */
// prettier-ignore export const SELECT_THEME = {
export const lightT: IColorTheme = { primary: APP_COLORS.bgPrimary,
bgDefault: 'hsl(000, 000%, 098%)', //var(--cl-bg-100)', primary75: APP_COLORS.bgSelected,
bgBlur: 'hsla(000, 000%, 098%, 0.8)', primary50: APP_COLORS.bgHover,
bgInput: 'var(--cl-bg-120)', primary25: APP_COLORS.bgHover,
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)',
border: 'var(--cl-bg-40)', danger: APP_COLORS.fgWarning,
dangerLight: APP_COLORS.bgWarning,
fgDefault: 'var(--cl-fg-100)', neutral0: APP_COLORS.bgInput,
fgSelected: 'var(--cl-fg-100)', neutral5: APP_COLORS.bgDefault,
fgDisabled: 'var(--cl-fg-80)', neutral10: APP_COLORS.border,
fgWarning: 'var(--cl-red-fg-100)', neutral20: APP_COLORS.border,
neutral30: APP_COLORS.border,
// Highlight syntax accents neutral40: APP_COLORS.fgDisabled,
bgRed: 'hsl(000, 100%, 089%)', neutral50: APP_COLORS.fgDisabled, // placeholder
bgGreen: 'hsl(100, 100%, 075%)', neutral60: APP_COLORS.fgDefault,
bgBlue: 'hsl(235, 080%, 087%)', neutral70: APP_COLORS.fgWarning,
bgPurple: 'hsl(274, 089%, 081%)', neutral80: APP_COLORS.fgDefault,
bgTeal: 'hsl(192, 089%, 081%)', neutral90: APP_COLORS.fgWarning
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%)'
}; };
/** /**
* Represents application Dark theme. * Represents Brackets highlights theme.
*/ */
// prettier-ignore export const BRACKETS_THEME = {
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 = {
'.cc-nonmatchingBracket': { '.cc-nonmatchingBracket': {
color: lightT.fgRed, color: APP_COLORS.fgRed,
fontWeight: 600 fontWeight: 600
}, },
'&.cm-focused .cc-matchingBracket': { '&.cm-focused .cc-matchingBracket': {
backgroundColor: lightT.bgSelected, backgroundColor: APP_COLORS.bgSelected,
color: lightT.fgSelected color: APP_COLORS.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
} }
}; };
/** /**
* Determines background color for {@link ISyntaxTreeNode} based on its type. * 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) { switch (node.typeID) {
case TokenID.PUNCTUATION_DEFINE: case TokenID.PUNCTUATION_DEFINE:
case TokenID.PUNCTUATION_STRUCT: case TokenID.PUNCTUATION_STRUCT:
case TokenID.ID_LOCAL: case TokenID.ID_LOCAL:
return colors.bgGreen; return APP_COLORS.bgGreen;
case TokenID.ID_GLOBAL: case TokenID.ID_GLOBAL:
case TokenID.ID_FUNCTION: case TokenID.ID_FUNCTION:
@ -232,7 +104,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case TokenID.LIT_INTEGER: case TokenID.LIT_INTEGER:
case TokenID.LIT_EMPTYSET: case TokenID.LIT_EMPTYSET:
case TokenID.LIT_WHOLE_NUMBERS: case TokenID.LIT_WHOLE_NUMBERS:
return colors.bgTeal; return APP_COLORS.bgTeal;
case TokenID.QUANTOR_UNIVERSAL: case TokenID.QUANTOR_UNIVERSAL:
case TokenID.QUANTOR_EXISTS: case TokenID.QUANTOR_EXISTS:
@ -252,7 +124,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case TokenID.SUBSET_OR_EQ: case TokenID.SUBSET_OR_EQ:
case TokenID.SUBSET: case TokenID.SUBSET:
case TokenID.NOT_SUBSET: case TokenID.NOT_SUBSET:
return colors.bgOrange; return APP_COLORS.bgOrange;
case TokenID.NT_TUPLE: case TokenID.NT_TUPLE:
case TokenID.NT_ENUMERATION: case TokenID.NT_ENUMERATION:
@ -272,7 +144,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case TokenID.CARD: case TokenID.CARD:
case TokenID.BOOL: case TokenID.BOOL:
case TokenID.DEBOOL: case TokenID.DEBOOL:
return colors.bgBlue; return APP_COLORS.bgBlue;
case TokenID.NT_FUNC_DEFINITION: case TokenID.NT_FUNC_DEFINITION:
case TokenID.NT_DECLARATIVE_EXPR: 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_FUNC_CALL:
case TokenID.NT_ARGUMENTS: case TokenID.NT_ARGUMENTS:
case TokenID.NT_RECURSIVE_SHORT: case TokenID.NT_RECURSIVE_SHORT:
return colors.bgDisabled; return APP_COLORS.bgDisabled;
case TokenID.ASSIGN: case TokenID.ASSIGN:
case TokenID.ITERATE: case TokenID.ITERATE:
return colors.bgRed; return APP_COLORS.bgRed;
} }
switch (node.data.value) { switch (node.data.value) {
case 'Expression': case 'Expression':
case 'Local': case 'Local':
return colors.bgGreen; return APP_COLORS.bgGreen;
case 'Global': case 'Global':
case 'Radical': case 'Radical':
@ -304,7 +176,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case 'Integer': case 'Integer':
case 'EmptySet': case 'EmptySet':
case 'IntegerSet': case 'IntegerSet':
return colors.bgTeal; return APP_COLORS.bgTeal;
case 'Logic': case 'Logic':
case 'Logic_predicates': case 'Logic_predicates':
@ -331,7 +203,7 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case 'Function_decl': case 'Function_decl':
case 'Arguments': case 'Arguments':
case 'Declaration': case 'Declaration':
return colors.bgBlue; return APP_COLORS.bgBlue;
case 'BigPr': case 'BigPr':
case 'SmallPr': case 'SmallPr':
@ -342,138 +214,138 @@ export function colorBgSyntaxTree(node: ISyntaxTreeNode, colors: IColorTheme): s
case 'PrefixD': case 'PrefixD':
case 'PrefixI': case 'PrefixI':
case 'PrefixR': case 'PrefixR':
return colors.bgPurple; return APP_COLORS.bgPurple;
case PARAMETER.errorNodeLabel: case PARAMETER.errorNodeLabel:
return colors.bgRed; return APP_COLORS.bgRed;
} }
// node // node
return colors.bgPurple; return APP_COLORS.bgPurple;
} }
/** /**
* Determines background color for {@link ExpressionStatus}. * Determines background color for {@link ExpressionStatus}.
*/ */
export function colorBgCstStatus(status: ExpressionStatus, colors: IColorTheme): string { export function colorBgCstStatus(status: ExpressionStatus): string {
// prettier-ignore // prettier-ignore
switch (status) { switch (status) {
case ExpressionStatus.VERIFIED: return colors.bgGreen; case ExpressionStatus.VERIFIED: return APP_COLORS.bgGreen;
case ExpressionStatus.INCORRECT: return colors.bgRed; case ExpressionStatus.INCORRECT: return APP_COLORS.bgRed;
case ExpressionStatus.INCALCULABLE: return colors.bgOrange; case ExpressionStatus.INCALCULABLE: return APP_COLORS.bgOrange;
case ExpressionStatus.PROPERTY: return colors.bgTeal; case ExpressionStatus.PROPERTY: return APP_COLORS.bgTeal;
case ExpressionStatus.UNKNOWN: return colors.bgSelected; case ExpressionStatus.UNKNOWN: return APP_COLORS.bgSelected;
case ExpressionStatus.UNDEFINED: return colors.bgBlue; case ExpressionStatus.UNDEFINED: return APP_COLORS.bgBlue;
} }
} }
/** /**
* Determines statusbar color for {@link ExpressionStatus}. * Determines statusbar color for {@link ExpressionStatus}.
*/ */
export function colorStatusBar(status: ExpressionStatus, colors: IColorTheme): string { export function colorStatusBar(status: ExpressionStatus): string {
// prettier-ignore // prettier-ignore
switch (status) { switch (status) {
case ExpressionStatus.VERIFIED: return colors.bgGreen50; case ExpressionStatus.VERIFIED: return APP_COLORS.bgGreen50;
case ExpressionStatus.INCORRECT: return colors.bgRed; case ExpressionStatus.INCORRECT: return APP_COLORS.bgRed;
case ExpressionStatus.INCALCULABLE: return colors.bgOrange; case ExpressionStatus.INCALCULABLE: return APP_COLORS.bgOrange;
case ExpressionStatus.PROPERTY: return colors.bgTeal; case ExpressionStatus.PROPERTY: return APP_COLORS.bgTeal;
case ExpressionStatus.UNKNOWN: return colors.bgSelected; case ExpressionStatus.UNKNOWN: return APP_COLORS.bgSelected;
case ExpressionStatus.UNDEFINED: return colors.bgBlue; case ExpressionStatus.UNDEFINED: return APP_COLORS.bgBlue;
} }
} }
/** /**
* Determines foreground color for {@link ExpressionStatus}. * Determines foreground color for {@link ExpressionStatus}.
*/ */
export function colorFgCstStatus(status: ExpressionStatus, colors: IColorTheme): string { export function colorFgCstStatus(status: ExpressionStatus): string {
// prettier-ignore // prettier-ignore
switch (status) { switch (status) {
case ExpressionStatus.VERIFIED: return colors.fgGreen; case ExpressionStatus.VERIFIED: return APP_COLORS.fgGreen;
case ExpressionStatus.INCORRECT: return colors.fgRed; case ExpressionStatus.INCORRECT: return APP_COLORS.fgRed;
case ExpressionStatus.INCALCULABLE: return colors.fgOrange; case ExpressionStatus.INCALCULABLE: return APP_COLORS.fgOrange;
case ExpressionStatus.PROPERTY: return colors.fgTeal; case ExpressionStatus.PROPERTY: return APP_COLORS.fgTeal;
case ExpressionStatus.UNKNOWN: return colors.fgBlue; case ExpressionStatus.UNKNOWN: return APP_COLORS.fgBlue;
case ExpressionStatus.UNDEFINED: return colors.fgBlue; case ExpressionStatus.UNDEFINED: return APP_COLORS.fgBlue;
} }
} }
/** /**
* Determines background color for {@link IConstituenta} depending on its {@link CstClass}. * 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 // prettier-ignore
switch (cstClass) { switch (cstClass) {
case CstClass.BASIC: return colors.bgGreen; case CstClass.BASIC: return APP_COLORS.bgGreen;
case CstClass.DERIVED: return colors.bgBlue; case CstClass.DERIVED: return APP_COLORS.bgBlue;
case CstClass.STATEMENT: return colors.bgRed; case CstClass.STATEMENT: return APP_COLORS.bgRed;
case CstClass.TEMPLATE: return colors.bgTeal; case CstClass.TEMPLATE: return APP_COLORS.bgTeal;
} }
} }
/** /**
* Determines background color for {@link IConstituenta} depending on its parent schema index. * 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) { if (schema_index === 0) {
return colors.bgGreen; return APP_COLORS.bgGreen;
} }
// prettier-ignore // prettier-ignore
switch (schema_index % 4) { switch (schema_index % 4) {
case 1: return colors.bgPurple; case 1: return APP_COLORS.bgPurple;
case 2: return colors.bgOrange; case 2: return APP_COLORS.bgOrange;
case 3: return colors.bgTeal; case 3: return APP_COLORS.bgTeal;
case 0: return colors.bgBlue; case 0: return APP_COLORS.bgBlue;
} }
return colors.bgBlue; return APP_COLORS.bgBlue;
} }
/** /**
* Determines background color for {@link GramData}. * 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)) { if (PartOfSpeech.includes(gram as Grammeme)) {
return colors.bgBlue; return APP_COLORS.bgBlue;
} }
if (NounGrams.includes(gram as Grammeme)) { if (NounGrams.includes(gram as Grammeme)) {
return colors.bgGreen; return APP_COLORS.bgGreen;
} }
if (VerbGrams.includes(gram as Grammeme)) { 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}. * 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)) { if (PartOfSpeech.includes(gram as Grammeme)) {
return colors.fgBlue; return APP_COLORS.fgBlue;
} }
if (NounGrams.includes(gram as Grammeme)) { if (NounGrams.includes(gram as Grammeme)) {
return colors.fgGreen; return APP_COLORS.fgGreen;
} }
if (VerbGrams.includes(gram as Grammeme)) { if (VerbGrams.includes(gram as Grammeme)) {
return colors.fgTeal; return APP_COLORS.fgTeal;
} }
if (!Object.values(Grammeme).includes(gram as Grammeme)) { if (!Object.values(Grammeme).includes(gram as Grammeme)) {
return colors.fgRed; return APP_COLORS.fgRed;
} else { } else {
return colors.fgPurple; return APP_COLORS.fgPurple;
} }
} }
/** /**
* Determines graph color for {@link IConstituenta}. * 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') { if (coloringScheme === 'type') {
return colorBgCstClass(cst.cst_class, colors); return colorBgCstClass(cst.cst_class);
} }
if (coloringScheme === 'status') { if (coloringScheme === 'status') {
return colorBgCstStatus(cst.status, colors); return colorBgCstStatus(cst.status);
} }
if (coloringScheme === 'schemas') { if (coloringScheme === 'schemas') {
return colorBgSchemas(cst.parent_schema_index, colors); return colorBgSchemas(cst.parent_schema_index);
} }
return ''; return '';
} }
@ -481,12 +353,12 @@ export function colorBgGraphNode(cst: IConstituenta, coloringScheme: GraphColori
/** /**
* Determines m-graph color for {@link TMGraphNode}. * 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) { if (node.rank === 0) {
return colors.bgControls; return APP_COLORS.bgControls;
} }
if (node.parents.length === 1) { 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-modal: 300ms;
--duration-fade: 300ms; --duration-fade: 300ms;
--duration-select: 100ms; --duration-select: 100ms;
}
/* Light Theme */
--cl-bg-120: hsl(000, 000%, 100%); /* Light Theme */
--cl-bg-100: hsl(000, 000%, 098%); /* prettier-ignore */
--cl-bg-80: hsl(000, 000%, 094%); :not(.dark):root {
--cl-bg-60: hsl(000, 000%, 091%); --clr-app-0: hsl(000, 000%, 100%);
--cl-bg-40: hsl(000, 000%, 080%); --clr-app-100: hsl(000, 000%, 098%);
--clr-app-200: hsl(000, 000%, 094%);
--cl-fg-60: hsl(000, 000%, 065%); --clr-app-300: hsl(000, 000%, 091%);
--cl-fg-80: hsl(000, 000%, 047%); --clr-app-400: hsl(000, 000%, 080%);
--cl-fg-100: hsl(000, 000%, 000%); --clr-app-600: hsl(000, 000%, 065%);
--clr-app-800: hsl(000, 000%, 047%);
--cl-prim-bg-100: hsl(220, 100%, 060%); --clr-app-999: hsl(000, 000%, 000%);
--cl-prim-bg-80: hsl(220, 080%, 092%);
--cl-prim-bg-60: hsl(190, 080%, 094%); --clr-prim-100: hsl(220, 100%, 050%);
--clr-prim-200: hsl(220, 100%, 060%);
--cl-prim-fg-80: hsl(220, 100%, 050%); --clr-prim-300: hsl(220, 100%, 070%);
--cl-prim-fg-100: hsl(000, 000%, 100%); --clr-prim-400: hsl(220, 100%, 080%);
--clr-prim-600: hsl(220, 080%, 092%);
--cl-red-bg-100: hsl(000, 100%, 095%); --clr-prim-800: hsl(190, 080%, 094%);
--cl-red-fg-100: hsl(000, 072%, 051%); --clr-prim-999: hsl(000, 000%, 100%);
--cl-green-fg-100: hsl(120, 080%, 37%);
--clr-warn-100: hsl(000, 100%, 095%);
--cl-teal-bg-100: hsl(162, 082%, 051%); --clr-warn-600: hsl(000, 072%, 051%);
/* Dark Theme */ --clr-ok-600: hsl(120, 080%, 37%);
--cd-bg-120: hsl(000, 000%, 005%);
--cd-bg-100: hsl(000, 000%, 009%); --clr-select-node:hsl(162, 082%, 051%);
--cd-bg-80: hsl(000, 000%, 015%);
--cd-bg-60: hsl(000, 000%, 022%); /* Highlight accents */
--cd-bg-40: hsl(000, 000%, 035%); --acc-bg-red: hsl(000, 100%, 089%);
--acc-bg-green: hsl(100, 100%, 075%);
--cd-fg-60: hsl(000, 000%, 055%); --acc-bg-blue: hsl(235, 080%, 087%);
--cd-fg-80: hsl(000, 000%, 080%); --acc-bg-purple: hsl(274, 089%, 081%);
--cd-fg-100: hsl(000, 000%, 093%); --acc-bg-teal: hsl(192, 089%, 081%);
--acc-bg-orange: hsl(028, 100%, 075%);
--cd-prim-bg-100: hsl(267, 050%, 050%);
--cd-prim-bg-80: hsl(267, 050%, 032%); --acc-bg-green25: hsl(100, 100%, 096%);
--cd-prim-bg-60: hsl(269, 030%, 028%); --acc-bg-green50: hsl(100, 100%, 090%);
--acc-bg-orange50:hsl(028, 100%, 090%);
--cd-prim-fg-80: hsl(267, 070%, 070%);
--cd-prim-fg-100: hsl(000, 000%, 100%); --acc-fg-red: hsl(000, 090%, 045%);
--acc-fg-green: hsl(100, 090%, 035%);
--cd-red-bg-100: hsl(000, 100%, 015%); --acc-fg-blue: hsl(235, 100%, 050%);
--cd-red-fg-100: hsl(000, 080%, 055%); --acc-fg-purple: hsl(270, 100%, 055%);
--cd-green-fg-100: hsl(120, 080%, 042%); --acc-fg-teal: hsl(200, 080%, 050%);
--acc-fg-orange: hsl(028, 100%, 050%);
--cd-teal-bg-100: hsl(162, 082%, 041%); }
/* 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 { :root {
/* Import overrides */ /* Import overrides */
--toastify-color-dark: var(--cd-bg-60); --toastify-color-dark: var(--clr-app-300);
} }
.cm-tooltip { .cm-tooltip {
@ -17,48 +17,37 @@
resize: vertical; resize: vertical;
overflow-y: auto; overflow-y: auto;
overscroll-behavior-y: contain; overscroll-behavior-y: contain;
border-color: var(--cl-bg-40);
.dark & { border-color: var(--clr-app-400);
border-color: var(--cd-bg-40); border-width: 1px;
} border-radius: 0.25rem;
@apply border rounded px-[0.375rem] py-[0.15rem];
padding-left: 0.375rem;
padding-right: 0.375rem;
padding-top: 0.15rem;
padding-bottom: 0.15rem;
} }
.cm-editor.cm-focused { .cm-editor.cm-focused {
border-color: var(--cl-bg-40); border-color: var(--clr-app-400);
outline-color: var(--cl-prim-bg-100); outline-color: var(--clr-prim-200);
.dark & { outline-style: solid;
border-color: var(--cd-bg-40); outline-width: 2px;
outline-color: var(--cd-prim-bg-100);
}
@apply outline-2 outline;
} }
.cm-editor .cm-placeholder { .cm-editor .cm-placeholder {
color: var(--cl-fg-60); font-family: var(--font-main);
@apply font-main; color: var(--clr-app-600);
.dark & {
color: var(--cd-fg-60);
}
} }
.react-flow__handle { .react-flow__handle {
cursor: default !important; cursor: default !important;
border-radius: 9999px; border-radius: 9999px;
border-color: var(--cl-bg-40); border-color: var(--clr-app-400);
background-color: var(--cl-bg-120); background-color: var(--clr-app-0);
.selected & { .selected & {
border-color: var(--cd-bg-40); border-color: var(--clr-app-800);
}
.dark & {
border-color: var(--cd-bg-40);
background-color: var(--cd-bg-120);
.selected & {
border-color: var(--cl-bg-40);
}
} }
} }
@ -77,34 +66,20 @@
margin-right: 3px; margin-right: 3px;
background-color: transparent; background-color: transparent;
color: var(--cl-fg-60); color: var(--clr-app-600);
.dark & {
color: var(--cd-fg-60);
}
} }
[class*='react-flow__node-'] { [class*='react-flow__node-'] {
font-size: 14px; font-size: 14px;
border: 1px solid; border: 1px solid;
background-color: var(--cl-bg-120); background-color: var(--clr-app-0);
color: var(--cl-fg-100); color: var(--clr-app-999);
border-color: var(--cl-bg-40); border-color: var(--clr-app-400);
background-color: var(--cl-bg-120); background-color: var(--clr-app-0);
&:hover:not(.selected) { &:hover:not(.selected) {
box-shadow: 0 0 0 2px var(--cl-prim-bg-80) !important; box-shadow: 0 0 0 2px var(--clr-prim-600) !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;
}
} }
} }
@ -127,16 +102,8 @@
&.selected { &.selected {
outline-offset: 4px; outline-offset: 4px;
outline-color: var(--cl-teal-bg-100); outline-color: var(--clr-select-node);
border-color: var(--cd-bg-40); border-color: var(--clr-app-800);
}
.dark & {
&.selected {
outline-offset: 4px;
border-color: var(--cd-teal-bg-100);
border-color: var(--cl-bg-40);
}
} }
} }
@ -159,15 +126,7 @@
&.selected { &.selected {
outline-offset: 4px; outline-offset: 4px;
outline-color: var(--cl-teal-bg-100); outline-color: var(--clr-select-node);
border-color: transparent; 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; hanging-punctuation: first last;
color-scheme: dark light; color-scheme: dark light;
/* interpolate-size: allow-keywords; */ interpolate-size: allow-keywords;
} }
body { body {
@ -58,15 +58,9 @@ body {
line-height: var(--line-height); line-height: var(--line-height);
font-family: var(--font-main); font-family: var(--font-main);
color: var(--cl-fg-100); color: var(--clr-app-999);
border-color: var(--cl-bg-40); border-color: var(--clr-app-400);
background-color: var(--cl-bg-100); background-color: var(--clr-app-100);
&.dark {
color: var(--cd-fg-100);
border-color: var(--cd-bg-40);
background-color: var(--cd-bg-100);
}
} }
@media only screen and (max-width: 639px) { @media only screen and (max-width: 639px) {
@ -84,23 +78,14 @@ body {
} }
::selection { ::selection {
background: var(--cl-prim-bg-60); background: var(--clr-prim-800);
.dark & {
background: var(--cd-prim-bg-60);
}
tr :hover& { tr :hover& {
background: var(--cl-red-bg-100); background: var(--clr-warn-100);
.dark & {
background: var(--cd-red-bg-100);
}
} }
} }
::placeholder { ::placeholder {
color: var(--cl-fg-60); color: var(--clr-app-600);
.dark & {
color: var(--cd-fg-60);
}
} }
/* Wrapping headers */ /* Wrapping headers */
@ -120,24 +105,35 @@ li {
text-wrap: pretty; text-wrap: pretty;
} }
div:not(.dense) > p { div:not(.dense) > p:not(:last-child) {
@apply [&:not(:last-child)]:mb-2; margin-bottom: 0.5rem;
} }
@layer components { @layer components {
h1 { h1 {
@apply text-lg font-semibold text-center; font-weight: 600;
font-size: 1.125rem;
line-height: 1.75rem;
text-align: center;
} }
h2 { h2 {
@apply [&:not(:first-child)]:mt-2 font-semibold text-center; font-weight: 600;
[role='manuals'] & { text-align: center;
@apply [&:not(:first-child)]:mt-3 mb-2;
&:not(:first-child) {
:not([role='manuals']) & {
margin-top: 0.5rem;
}
[role='manuals'] & {
margin-top: 0.75rem;
margin-bottom: 0.5rem;
}
} }
} }
b { b {
@apply font-semibold; font-weight: 600;
} }
code { code {
@ -153,7 +149,7 @@ div:not(.dense) > p {
} }
.border { .border {
@apply rounded; border-radius: 0.25rem;
} }
.border, .border,
@ -174,10 +170,9 @@ div:not(.dense) > p {
.divide-y, .divide-y,
.divide-x-2, .divide-x-2,
.divide-y-2 { .divide-y-2 {
border-color: var(--cl-bg-40); border-color: var(--clr-app-400);
@apply divide-inherit; & > :not([hidden]) ~ :not([hidden]) {
.dark & { border-color: inherit;
border-color: var(--cd-bg-40);
} }
} }

View File

@ -21,133 +21,73 @@
} }
@layer components { @layer components {
.clr-app,
.clr-btn-nav {
background-color: var(--cl-bg-100);
.dark & {
background-color: var(--cd-bg-100);
}
}
.clr-footer { .clr-footer {
color: var(--cl-fg-60); color: var(--clr-app-600);
background-color: var(--cl-bg-100); background-color: var(--clr-app-100);
.dark & {
color: var(--cd-fg-60);
background-color: var(--cd-bg-100);
}
} }
.cc-modal-backdrop { .cc-modal-backdrop {
opacity: 0.5; opacity: 0.5;
background-color: var(--cl-bg-100); background-color: var(--clr-app-100);
.dark & {
background-color: var(--cd-bg-100);
}
} }
.clr-input { .clr-input {
background-color: var(--cl-bg-120); background-color: var(--clr-app-0);
&:disabled { &:disabled {
background-color: var(--cl-bg-100); background-color: var(--clr-app-100);
}
.dark & {
background-color: var(--cd-bg-120);
&:disabled {
background-color: var(--cd-bg-100);
}
} }
} }
.clr-controls, .clr-controls,
.clr-tab, .clr-tab,
.clr-btn-default { .clr-btn-default {
background-color: var(--cl-bg-80); background-color: var(--clr-app-200);
.dark & {
background-color: var(--cd-bg-80);
}
} }
.clr-primary, .clr-primary,
.clr-btn-primary:hover, .clr-btn-primary:hover,
.clr-btn-primary:focus-visible { .clr-btn-primary:focus-visible {
@apply transition; @apply transition;
color: var(--cl-prim-fg-100); color: var(--clr-prim-999);
background-color: var(--cl-prim-bg-100); background-color: var(--clr-prim-200);
.dark & {
color: var(--cd-prim-fg-100);
background-color: var(--cd-prim-bg-100);
}
} }
.clr-selected, .clr-selected,
.clr-btn-primary { .clr-btn-primary {
color: var(--cl-fg-100); color: var(--clr-app-999);
background-color: var(--cl-prim-bg-80); background-color: var(--clr-prim-600);
.dark & {
color: var(--cd-fg-100);
background-color: var(--cd-prim-bg-80);
}
} }
:is(.clr-disabled, .clr-btn-default, .clr-btn-primary):disabled { :is(.clr-disabled, .clr-btn-default, .clr-btn-primary):disabled {
@apply transition; @apply transition;
color: var(--cl-fg-80); color: var(--clr-app-800);
background-color: var(--cl-bg-60); background-color: var(--clr-app-200);
.dark & {
color: var(--cd-fg-80);
background-color: var(--cd-bg-60);
}
} }
:is(.clr-hover, .clr-tab, .clr-btn-nav, .clr-btn-default):hover:not(:disabled) { :is(.clr-hover, .clr-tab, .clr-btn-nav, .clr-btn-default):hover:not(:disabled) {
@apply transition; @apply transition;
color: var(--cl-fg-100); color: var(--clr-app-999);
background-color: var(--cl-prim-bg-60); background-color: var(--clr-prim-800);
.dark & {
color: var(--cd-fg-100);
background-color: var(--cd-prim-bg-60);
}
} }
:is(.clr-outline, .clr-btn-primary, .focus-frame):focus-visible, :is(.clr-outline, .clr-btn-primary, .focus-frame):focus-visible,
.focus-frame:has(:focus-visible) { .focus-frame:has(:focus-visible) {
outline-width: 2px; outline-width: 2px;
outline-style: solid; outline-style: solid;
outline-color: var(--cl-prim-bg-100); outline-color: var(--clr-prim-200);
.dark & {
outline-color: var(--cd-prim-bg-100);
}
} }
.clr-text-primary, .clr-text-primary {
.clr-text-url { color: var(--clr-prim-100);
color: var(--cl-prim-fg-80);
.dark & {
color: var(--cd-prim-fg-80);
}
} }
.clr-text-controls, .clr-text-controls,
.clr-btn-nav, .clr-btn-nav,
.clr-btn-clear { .clr-btn-clear {
color: var(--cl-fg-80); color: var(--clr-app-800);
background-color: transparent; background-color: transparent;
&:disabled { &:disabled {
color: var(--cl-fg-60); color: var(--clr-app-600);
}
.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);
} }
} }
@ -155,44 +95,25 @@
input:disabled:not(::placeholder), input:disabled:not(::placeholder),
textarea:disabled:not(::placeholder) { textarea:disabled:not(::placeholder) {
opacity: 1; opacity: 1;
-webkit-text-fill-color: var(--cl-fg-100); -webkit-text-fill-color: var(--clr-app-999);
color: var(--cl-fg-100); color: var(--clr-app-999);
.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);
}
} }
.icon-primary { .icon-primary {
:not([disabled]) > & { :not([disabled]) > & {
@apply clr-text-primary; color: var(--clr-prim-100);
} }
} }
.icon-red { .icon-red {
:not([disabled]) > & { :not([disabled]) > & {
@apply clr-text-red; color: var(--clr-warn-600);
} }
} }
.icon-green { .icon-green {
:not([disabled]) > & { :not([disabled]) > & {
@apply clr-text-green; color: var(--clr-ok-600);
} }
} }
@ -202,15 +123,23 @@
margin-left: 0.1rem; margin-left: 0.1rem;
margin-right: 0.1rem; margin-right: 0.1rem;
transform: translate(0, -0.2rem); transform: translate(0, -0.2rem);
@apply clr-text-primary; color: var(--clr-prim-100);
} }
.cc-tab-tools { .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 { .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 { .cc-column {
@ -249,7 +178,7 @@
} }
.cc-shadow-border { .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 { .cc-animate-position {

View File

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

View File

@ -150,7 +150,7 @@ export function tripleToggleColor(value: boolean | undefined): string {
if (value === undefined) { if (value === undefined) {
return 'clr-text-controls'; 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', darkMode: 'class',
content: ['./src/**/*.{js,jsx,ts,tsx}'], content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: { 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: { zIndex: {
bottom: '0', bottom: '0',
topmost: '99', topmost: '99',

View File

@ -12,7 +12,10 @@ const reactCompilerConfig = {
const inlinePackages = ['react', 'react-router', 'react-dom']; const inlinePackages = ['react', 'react-router', 'react-dom'];
// Rollup warnings that should not be displayed // 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/ // https://vitejs.dev/config/
export default ({ mode }: { mode: string }) => { export default ({ mode }: { mode: string }) => {