mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Minor UI improvements and CSS refactoring
This commit is contained in:
parent
d64e4a9894
commit
ead0418564
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -108,6 +108,7 @@
|
||||||
"signup",
|
"signup",
|
||||||
"Slng",
|
"Slng",
|
||||||
"SMALLPR",
|
"SMALLPR",
|
||||||
|
"Stylesheet",
|
||||||
"tagset",
|
"tagset",
|
||||||
"tailwindcss",
|
"tailwindcss",
|
||||||
"tanstack",
|
"tanstack",
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { IoLibrary } from 'react-icons/io5';
|
||||||
import { EducationIcon } from '@/components/Icons';
|
import { EducationIcon } from '@/components/Icons';
|
||||||
import { useConceptNavigation } from '@/context/NavigationContext';
|
import { useConceptNavigation } from '@/context/NavigationContext';
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { animateNavigation } from '@/utils/animations';
|
import { animateNavigation } from '@/styling/animations';
|
||||||
|
|
||||||
import Logo from './Logo';
|
import Logo from './Logo';
|
||||||
import NavigationButton from './NavigationButton';
|
import NavigationButton from './NavigationButton';
|
||||||
|
@ -23,7 +23,14 @@ function Navigation() {
|
||||||
const navigateCreateNew = () => router.push('/library/create');
|
const navigateCreateNew = () => router.push('/library/create');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className={clsx('z-navigation', 'sticky top-0 left-0 right-0', 'clr-app', 'select-none')}>
|
<nav
|
||||||
|
className={clsx(
|
||||||
|
'z-navigation', // prettier: split lines
|
||||||
|
'sticky top-0 left-0 right-0',
|
||||||
|
'clr-app',
|
||||||
|
'select-none'
|
||||||
|
)}
|
||||||
|
>
|
||||||
<ToggleNavigationButton />
|
<ToggleNavigationButton />
|
||||||
<motion.div
|
<motion.div
|
||||||
className={clsx('pl-2 pr-[0.9rem] h-[3rem]', 'flex justify-between', 'shadow-border')}
|
className={clsx('pl-2 pr-[0.9rem] h-[3rem]', 'flex justify-between', 'shadow-border')}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { motion } from 'framer-motion';
|
||||||
import { RiPushpinFill, RiUnpinLine } from 'react-icons/ri';
|
import { RiPushpinFill, RiUnpinLine } from 'react-icons/ri';
|
||||||
|
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { animateNavigationToggle } from '@/utils/animations';
|
import { animateNavigationToggle } from '@/styling/animations';
|
||||||
|
|
||||||
function ToggleNavigationButton() {
|
function ToggleNavigationButton() {
|
||||||
const { noNavigationAnimation, toggleNoNavigation } = useConceptTheme();
|
const { noNavigationAnimation, toggleNoNavigation } = useConceptTheme();
|
||||||
|
|
22
rsconcept/frontend/src/components/AnimateFadeIn.tsx
Normal file
22
rsconcept/frontend/src/components/AnimateFadeIn.tsx
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
|
||||||
|
import { animateFadeIn } from '@/styling/animations';
|
||||||
|
|
||||||
|
import { CProps } from './props';
|
||||||
|
|
||||||
|
interface AnimateFadeInProps extends CProps.AnimatedDiv {}
|
||||||
|
|
||||||
|
function AnimateFadeIn({ children, ...restProps }: AnimateFadeInProps) {
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
initial={{ ...animateFadeIn.initial }}
|
||||||
|
animate={{ ...animateFadeIn.animate }}
|
||||||
|
exit={{ ...animateFadeIn.exit }}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AnimateFadeIn;
|
|
@ -1,9 +1,9 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import ConstituentaTooltip from '@/components/Help/ConstituentaTooltip';
|
import ConstituentaTooltip from '@/components/ConstituentaTooltip';
|
||||||
import { IConstituenta } from '@/models/rsform';
|
import { IConstituenta } from '@/models/rsform';
|
||||||
import { isMockCst } from '@/models/rsformAPI';
|
import { isMockCst } from '@/models/rsformAPI';
|
||||||
import { colorFgCstStatus, IColorTheme } from '@/utils/color';
|
import { colorFgCstStatus, IColorTheme } from '@/styling/color';
|
||||||
|
|
||||||
interface ConstituentaBadgeProps {
|
interface ConstituentaBadgeProps {
|
||||||
prefixID?: string;
|
prefixID?: string;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { prefixes } from '@/utils/constants';
|
||||||
import { describeConstituenta } from '@/utils/labels';
|
import { describeConstituenta } from '@/utils/labels';
|
||||||
|
|
||||||
import ConstituentaBadge from './ConstituentaBadge';
|
import ConstituentaBadge from './ConstituentaBadge';
|
||||||
|
import FlexColumn from './ui/FlexColumn';
|
||||||
|
|
||||||
interface ConstituentaPickerProps {
|
interface ConstituentaPickerProps {
|
||||||
prefixID?: string;
|
prefixID?: string;
|
||||||
|
@ -94,10 +95,10 @@ function ConstituentaPicker({
|
||||||
columns={columns}
|
columns={columns}
|
||||||
conditionalRowStyles={conditionalRowStyles}
|
conditionalRowStyles={conditionalRowStyles}
|
||||||
noDataComponent={
|
noDataComponent={
|
||||||
<span className='p-2 min-h-[5rem] flex flex-col justify-center text-center'>
|
<FlexColumn className='p-3 items-center min-h-[6rem]'>
|
||||||
<p>Список конституент пуст</p>
|
<p>Список конституент пуст</p>
|
||||||
<p>Измените параметры фильтра</p>
|
<p>Измените параметры фильтра</p>
|
||||||
</span>
|
</FlexColumn>
|
||||||
}
|
}
|
||||||
onRowClicked={onSelectValue}
|
onRowClicked={onSelectValue}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -14,7 +14,6 @@ import {
|
||||||
useReactTable,
|
useReactTable,
|
||||||
type VisibilityState
|
type VisibilityState
|
||||||
} from '@tanstack/react-table';
|
} from '@tanstack/react-table';
|
||||||
import clsx from 'clsx';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
@ -122,7 +121,7 @@ function DataTable<TData extends RowData>({
|
||||||
const isEmpty = tableImpl.getRowModel().rows.length === 0;
|
const isEmpty = tableImpl.getRowModel().rows.length === 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx(className)} style={style}>
|
<div className={className} style={style}>
|
||||||
<table className='w-full'>
|
<table className='w-full'>
|
||||||
{!noHeader ? (
|
{!noHeader ? (
|
||||||
<TableHeader
|
<TableHeader
|
||||||
|
|
|
@ -52,14 +52,14 @@ function TableBody<TData>({
|
||||||
style={conditionalRowStyles && getRowStyles(row)}
|
style={conditionalRowStyles && getRowStyles(row)}
|
||||||
>
|
>
|
||||||
{enableRowSelection ? (
|
{enableRowSelection ? (
|
||||||
<td key={`select-${row.id}`} className='pl-3 pr-1 border-y'>
|
<td key={`select-${row.id}`} className='pl-3 pr-1 border-y align-middle'>
|
||||||
<SelectRow row={row} />
|
<SelectRow row={row} />
|
||||||
</td>
|
</td>
|
||||||
) : null}
|
) : null}
|
||||||
{row.getVisibleCells().map((cell: Cell<TData, unknown>) => (
|
{row.getVisibleCells().map((cell: Cell<TData, unknown>) => (
|
||||||
<td
|
<td
|
||||||
key={cell.id}
|
key={cell.id}
|
||||||
className='px-2 border-y'
|
className='px-2 border-y align-middle'
|
||||||
style={{
|
style={{
|
||||||
cursor: onRowClicked || onRowDoubleClicked ? 'pointer' : 'auto',
|
cursor: onRowClicked || onRowDoubleClicked ? 'pointer' : 'auto',
|
||||||
paddingBottom: dense ? '0.25rem' : '0.5rem',
|
paddingBottom: dense ? '0.25rem' : '0.5rem',
|
||||||
|
|
|
@ -13,7 +13,7 @@ interface TableHeaderProps<TData> {
|
||||||
function TableHeader<TData>({ table, headPosition, enableRowSelection, enableSorting }: TableHeaderProps<TData>) {
|
function TableHeader<TData>({ table, headPosition, enableRowSelection, enableSorting }: TableHeaderProps<TData>) {
|
||||||
return (
|
return (
|
||||||
<thead
|
<thead
|
||||||
className={`clr-app shadow-border`}
|
className='clr-app shadow-border'
|
||||||
style={{
|
style={{
|
||||||
top: headPosition,
|
top: headPosition,
|
||||||
position: 'sticky'
|
position: 'sticky'
|
||||||
|
@ -22,7 +22,7 @@ function TableHeader<TData>({ table, headPosition, enableRowSelection, enableSor
|
||||||
{table.getHeaderGroups().map((headerGroup: HeaderGroup<TData>) => (
|
{table.getHeaderGroups().map((headerGroup: HeaderGroup<TData>) => (
|
||||||
<tr key={headerGroup.id}>
|
<tr key={headerGroup.id}>
|
||||||
{enableRowSelection ? (
|
{enableRowSelection ? (
|
||||||
<th className='pl-3 pr-1'>
|
<th className='pl-3 pr-1 align-middle'>
|
||||||
<SelectAll table={table} />
|
<SelectAll table={table} />
|
||||||
</th>
|
</th>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { GramData } from '@/models/language';
|
import { GramData } from '@/models/language';
|
||||||
import { colorFgGrammeme } from '@/utils/color';
|
import { colorFgGrammeme } from '@/styling/color';
|
||||||
import { labelGrammeme } from '@/utils/labels';
|
import { labelGrammeme } from '@/utils/labels';
|
||||||
|
|
||||||
interface GrammemeBadgeProps {
|
interface GrammemeBadgeProps {
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import { BiInfoCircle } from 'react-icons/bi';
|
import { BiInfoCircle } from 'react-icons/bi';
|
||||||
|
|
||||||
import TextURL from '@/components/ui/TextURL';
|
import TextURL from '@/components/ui/TextURL';
|
||||||
import Tooltip from '@/components/ui/Tooltip';
|
import Tooltip, { PlacesType } from '@/components/ui/Tooltip';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
|
||||||
|
import InfoTopic from '../InfoTopic';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
import InfoTopic from './InfoTopic';
|
|
||||||
|
|
||||||
interface HelpButtonProps extends CProps.Styling {
|
interface HelpButtonProps extends CProps.Styling {
|
||||||
topic: HelpTopic;
|
topic: HelpTopic;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
|
place?: PlacesType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function HelpButton({ topic, ...restProps }: HelpButtonProps) {
|
function HelpButton({ topic, ...restProps }: HelpButtonProps) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { urls } from '@/utils/constants';
|
||||||
function HelpExteor() {
|
function HelpExteor() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='flex flex-col gap-2'>
|
||||||
<h1>Экстеор</h1>
|
<h1>Экстеор</h1>
|
||||||
<p>Экстеор 4.9 — редактор текстов систем понятий эксплицированных в родах структур, используемых для создания проектов систем организационного управления. Экстеор является идейным предком Портала.</p>
|
<p>Экстеор 4.9 — редактор текстов систем понятий эксплицированных в родах структур, используемых для создания проектов систем организационного управления. Экстеор является идейным предком Портала.</p>
|
||||||
<p>Портал превосходит Экстеор в части редактирования экспликаций, но функции синтеза и вычисления интерпретации пока доступны только в Экстеоре. Также следует использовать Экстеор для выгрузки экспликаций в Word для последующей печати.</p>
|
<p>Портал превосходит Экстеор в части редактирования экспликаций, но функции синтеза и вычисления интерпретации пока доступны только в Экстеоре. Также следует использовать Экстеор для выгрузки экспликаций в Word для последующей печати.</p>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { FiBell } from 'react-icons/fi';
|
||||||
function HelpLibrary() {
|
function HelpLibrary() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return (
|
return (
|
||||||
<div className='max-w-[80rem]'>
|
<div>
|
||||||
<h1>Библиотека концептуальных схем</h1>
|
<h1>Библиотека концептуальных схем</h1>
|
||||||
<p>В библиотеки собраны различные концептуальные схемы.</p>
|
<p>В библиотеки собраны различные концептуальные схемы.</p>
|
||||||
<p>Группировка и классификации схем на данный момент не проводится.</p>
|
<p>Группировка и классификации схем на данный момент не проводится.</p>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { urls } from '@/utils/constants';
|
||||||
function HelpMain() {
|
function HelpMain() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return (
|
return (
|
||||||
<div className='max-w-[60rem]'>
|
<div>
|
||||||
<h1>Портал</h1>
|
<h1>Портал</h1>
|
||||||
<p className=''>Портал позволяет анализировать предметные области, формально записывать системы определений (концептуальные схемы) и синтезировать их с помощью математического аппарата родов структур.</p>
|
<p className=''>Портал позволяет анализировать предметные области, формально записывать системы определений (концептуальные схемы) и синтезировать их с помощью математического аппарата родов структур.</p>
|
||||||
<p className='mt-4 mb-1 text-center'><b>Основные разделы</b></p>
|
<p className='mt-4 mb-1 text-center'><b>Основные разделы</b></p>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
function HelpRSTemplates() {
|
function HelpRSTemplates() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col gap-2 pb-2 max-w-[80rem]'>
|
<div className='flex flex-col gap-2 pb-2'>
|
||||||
<h1>Банк выражений</h1>
|
<h1>Банк выражений</h1>
|
||||||
<p>Портал предоставляет быстрый доступ к часто используемым выражениям с помощью функции создания конституенты из шаблона.</p>
|
<p>Портал предоставляет быстрый доступ к часто используемым выражениям с помощью функции создания конституенты из шаблона.</p>
|
||||||
<p>Источником шаблонов является <b>Банк выражений</b>, содержащий параметризованные понятия и утверждения, сгруппированные по разделам.</p>
|
<p>Источником шаблонов является <b>Банк выражений</b>, содержащий параметризованные понятия и утверждения, сгруппированные по разделам.</p>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
function HelpTerminologyControl() {
|
function HelpTerminologyControl() {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col gap-1 max-w-[80rem]'>
|
<div className='flex flex-col gap-2'>
|
||||||
<h1>Терминологизация</h1>
|
<h1>Терминологизация</h1>
|
||||||
<p>Портал позволяет контролировать употребление терминов, привязанных к сущностям в концептуальных схемах.</p>
|
<p>Портал позволяет контролировать употребление терминов, привязанных к сущностям в концептуальных схемах.</p>
|
||||||
<p>Для этого используется механизм текстовых отсылок: <i>использование термина</i> и <i>связывание слов.</i></p>
|
<p>Для этого используется механизм текстовых отсылок: <i>использование термина</i> и <i>связывание слов.</i></p>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { IConstituenta } from '@/models/rsform';
|
import { IConstituenta } from '@/models/rsform';
|
||||||
import { labelCstTypification } from '@/utils/labels';
|
import { labelCstTypification } from '@/utils/labels';
|
||||||
|
|
||||||
interface InfoConstituentaProps extends React.HTMLAttributes<HTMLDivElement> {
|
import { CProps } from './props';
|
||||||
|
|
||||||
|
interface InfoConstituentaProps extends CProps.Div {
|
||||||
data: IConstituenta;
|
data: IConstituenta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { CstClass } from '@/models/rsform';
|
import { CstClass } from '@/models/rsform';
|
||||||
import { colorBgCstClass } from '@/utils/color';
|
import { colorBgCstClass } from '@/styling/color';
|
||||||
import { prefixes } from '@/utils/constants';
|
import { prefixes } from '@/utils/constants';
|
||||||
import { describeCstClass, labelCstClass } from '@/utils/labels';
|
import { describeCstClass, labelCstClass } from '@/utils/labels';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { ExpressionStatus } from '@/models/rsform';
|
import { ExpressionStatus } from '@/models/rsform';
|
||||||
import { colorBgCstStatus } from '@/utils/color';
|
import { colorBgCstStatus } from '@/styling/color';
|
||||||
import { prefixes } from '@/utils/constants';
|
import { prefixes } from '@/utils/constants';
|
||||||
import { describeExpressionStatus, labelExpressionStatus } from '@/utils/labels';
|
import { describeExpressionStatus, labelExpressionStatus } from '@/utils/labels';
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
|
||||||
import HelpAPI from './HelpAPI';
|
import HelpAPI from './Help/HelpAPI';
|
||||||
import HelpConstituenta from './HelpConstituenta';
|
import HelpConstituenta from './Help/HelpConstituenta';
|
||||||
import HelpExteor from './HelpExteor';
|
import HelpExteor from './Help/HelpExteor';
|
||||||
import HelpLibrary from './HelpLibrary';
|
import HelpLibrary from './Help/HelpLibrary';
|
||||||
import HelpMain from './HelpMain';
|
import HelpMain from './Help/HelpMain';
|
||||||
import HelpPrivacy from './HelpPrivacy';
|
import HelpPrivacy from './Help/HelpPrivacy';
|
||||||
import HelpRSFormItems from './HelpRSFormItems';
|
import HelpRSFormItems from './Help/HelpRSFormItems';
|
||||||
import HelpRSFormMeta from './HelpRSFormMeta';
|
import HelpRSFormMeta from './Help/HelpRSFormMeta';
|
||||||
import HelpRSLang from './HelpRSLang';
|
import HelpRSLang from './Help/HelpRSLang';
|
||||||
import HelpRSTemplates from './HelpRSTemplates';
|
import HelpRSTemplates from './Help/HelpRSTemplates';
|
||||||
import HelpTermGraph from './HelpTermGraph';
|
import HelpTermGraph from './Help/HelpTermGraph';
|
||||||
import HelpTerminologyControl from './HelpTerminologyControl';
|
import HelpTerminologyControl from './Help/HelpTerminologyControl';
|
||||||
|
|
||||||
interface InfoTopicProps {
|
interface InfoTopicProps {
|
||||||
topic: HelpTopic;
|
topic: HelpTopic;
|
|
@ -5,7 +5,7 @@ import { useMemo, useState } from 'react';
|
||||||
import { Document, Page } from 'react-pdf';
|
import { Document, Page } from 'react-pdf';
|
||||||
|
|
||||||
import useWindowSize from '@/hooks/useWindowSize';
|
import useWindowSize from '@/hooks/useWindowSize';
|
||||||
import { graphLightT } from '@/utils/color';
|
import { graphLightT } from '@/styling/color';
|
||||||
|
|
||||||
import Overlay from '../ui/Overlay';
|
import Overlay from '../ui/Overlay';
|
||||||
import PageControls from './PageControls';
|
import PageControls from './PageControls';
|
||||||
|
|
|
@ -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 '@/utils/color';
|
import { bracketsDarkT, bracketsLightT } 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' });
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
findContainedNodes,
|
findContainedNodes,
|
||||||
findEnvelopingNodes
|
findEnvelopingNodes
|
||||||
} from '@/utils/codemirror';
|
} from '@/utils/codemirror';
|
||||||
import { IColorTheme } from '@/utils/color';
|
import { IColorTheme } from '@/styling/color';
|
||||||
|
|
||||||
import { ReferenceTokens } from './parse';
|
import { ReferenceTokens } from './parse';
|
||||||
import { RefEntity, RefSyntactic } from './parse/parser.terms';
|
import { RefEntity, RefSyntactic } from './parse/parser.terms';
|
||||||
|
|
1
rsconcept/frontend/src/components/props.d.ts
vendored
1
rsconcept/frontend/src/components/props.d.ts
vendored
|
@ -38,4 +38,5 @@ export namespace CProps {
|
||||||
export type Input = React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
|
export type Input = React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
|
||||||
|
|
||||||
export type AnimatedButton = Omit<HTMLMotionProps<'button'>, 'type'>;
|
export type AnimatedButton = Omit<HTMLMotionProps<'button'>, 'type'>;
|
||||||
|
export type AnimatedDiv = HTMLMotionProps<'div'>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,13 @@ function Checkbox({ id, disabled, label, title, className, value, setValue, ...r
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
id={id}
|
id={id}
|
||||||
className={clsx('flex items-center gap-2', 'outline-none', 'text-start', cursor, className)}
|
className={clsx(
|
||||||
|
'flex items-center gap-2', // prettier: split lines
|
||||||
|
'outline-none',
|
||||||
|
'text-start',
|
||||||
|
cursor,
|
||||||
|
className
|
||||||
|
)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
data-tooltip-id={title ? globalIDs.tooltip : undefined}
|
data-tooltip-id={title ? globalIDs.tooltip : undefined}
|
||||||
|
@ -45,10 +51,14 @@ function Checkbox({ id, disabled, label, title, className, value, setValue, ...r
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={clsx('max-w-[1rem] min-w-[1rem] h-4', 'border rounded-sm', {
|
className={clsx(
|
||||||
|
'max-w-[1rem] min-w-[1rem] h-4', // prettier: split lines
|
||||||
|
'border rounded-sm',
|
||||||
|
{
|
||||||
'clr-primary': value !== false,
|
'clr-primary': value !== false,
|
||||||
'clr-app': value === false
|
'clr-app': value === false
|
||||||
})}
|
}
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{value ? (
|
{value ? (
|
||||||
<div className='mt-[1px] ml-[1px]'>
|
<div className='mt-[1px] ml-[1px]'>
|
||||||
|
|
|
@ -49,7 +49,12 @@ function CheckboxTristate({
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
id={id}
|
id={id}
|
||||||
className={clsx('flex items-center gap-2 text-start', 'outline-none', cursor, className)}
|
className={clsx(
|
||||||
|
'flex items-center gap-2 text-start', // prettier: split lines
|
||||||
|
'outline-none',
|
||||||
|
cursor,
|
||||||
|
className
|
||||||
|
)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
data-tooltip-id={title ? globalIDs.tooltip : undefined}
|
data-tooltip-id={title ? globalIDs.tooltip : undefined}
|
||||||
|
@ -57,10 +62,14 @@ function CheckboxTristate({
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={clsx('w-4 h-4', 'border rounded-sm', {
|
className={clsx(
|
||||||
|
'w-4 h-4', // prettier: split lines
|
||||||
|
'border rounded-sm',
|
||||||
|
{
|
||||||
'clr-primary': value !== false,
|
'clr-primary': value !== false,
|
||||||
'clr-app': value === false
|
'clr-app': value === false
|
||||||
})}
|
}
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{value ? (
|
{value ? (
|
||||||
<div className='mt-[1px] ml-[1px]'>
|
<div className='mt-[1px] ml-[1px]'>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
|
||||||
import { animateDropdown } from '@/utils/animations';
|
import { animateDropdown } from '@/styling/animations';
|
||||||
|
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
|
||||||
import { animateDropdownItem } from '@/utils/animations';
|
import { animateDropdownItem } from '@/styling/animations';
|
||||||
import { globalIDs } from '@/utils/constants';
|
import { globalIDs } from '@/utils/constants';
|
||||||
|
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
|
||||||
import { animateDropdownItem } from '@/utils/animations';
|
import { animateDropdownItem } from '@/styling/animations';
|
||||||
|
|
||||||
import Checkbox from './Checkbox';
|
import Checkbox from './Checkbox';
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { useRef } from 'react';
|
||||||
import { BiX } from 'react-icons/bi';
|
import { BiX } from 'react-icons/bi';
|
||||||
|
|
||||||
import useEscapeKey from '@/hooks/useEscapeKey';
|
import useEscapeKey from '@/hooks/useEscapeKey';
|
||||||
import { animateModal } from '@/utils/animations';
|
import { animateModal } from '@/styling/animations';
|
||||||
|
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useMemo } from 'react';
|
||||||
import Select, { GroupBase, Props, StylesConfig } from 'react-select';
|
import Select, { GroupBase, Props, StylesConfig } from 'react-select';
|
||||||
|
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { selectDarkT, selectLightT } from '@/utils/color';
|
import { selectDarkT, selectLightT } from '@/styling/color';
|
||||||
|
|
||||||
export interface SelectMultiProps<Option, Group extends GroupBase<Option> = GroupBase<Option>>
|
export interface SelectMultiProps<Option, Group extends GroupBase<Option> = GroupBase<Option>>
|
||||||
extends Omit<Props<Option, true, Group>, 'theme' | 'menuPortalTarget'> {
|
extends Omit<Props<Option, true, Group>, 'theme' | 'menuPortalTarget'> {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useMemo } from 'react';
|
||||||
import Select, { GroupBase, Props, StylesConfig } from 'react-select';
|
import Select, { GroupBase, Props, StylesConfig } from 'react-select';
|
||||||
|
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { selectDarkT, selectLightT } from '@/utils/color';
|
import { selectDarkT, selectLightT } from '@/styling/color';
|
||||||
|
|
||||||
interface SelectSingleProps<Option, Group extends GroupBase<Option> = GroupBase<Option>>
|
interface SelectSingleProps<Option, Group extends GroupBase<Option> = GroupBase<Option>>
|
||||||
extends Omit<Props<Option, false, Group>, 'theme' | 'menuPortalTarget'> {
|
extends Omit<Props<Option, false, Group>, 'theme' | 'menuPortalTarget'> {
|
||||||
|
|
|
@ -7,6 +7,8 @@ import { ITooltip, Tooltip as TooltipImpl } from 'react-tooltip';
|
||||||
|
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
|
|
||||||
|
export type { PlacesType } from 'react-tooltip';
|
||||||
|
|
||||||
interface TooltipProps extends Omit<ITooltip, 'variant'> {
|
interface TooltipProps extends Omit<ITooltip, 'variant'> {
|
||||||
layer?: string;
|
layer?: string;
|
||||||
text?: string;
|
text?: string;
|
||||||
|
|
|
@ -5,8 +5,8 @@ import { createContext, useCallback, useContext, useLayoutEffect, useMemo, useSt
|
||||||
|
|
||||||
import Tooltip from '@/components/ui/Tooltip';
|
import Tooltip from '@/components/ui/Tooltip';
|
||||||
import useLocalStorage from '@/hooks/useLocalStorage';
|
import useLocalStorage from '@/hooks/useLocalStorage';
|
||||||
import { animationDuration } from '@/utils/animations';
|
import { animationDuration } from '@/styling/animations';
|
||||||
import { darkT, IColorTheme, lightT } from '@/utils/color';
|
import { darkT, IColorTheme, lightT } from '@/styling/color';
|
||||||
import { globalIDs } from '@/utils/constants';
|
import { globalIDs } from '@/utils/constants';
|
||||||
|
|
||||||
interface IThemeContext {
|
interface IThemeContext {
|
||||||
|
|
|
@ -6,8 +6,8 @@ import GraphUI, { GraphEdge, GraphNode } from '@/components/GraphUI';
|
||||||
import Modal, { ModalProps } from '@/components/ui/Modal';
|
import Modal, { ModalProps } from '@/components/ui/Modal';
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { SyntaxTree } from '@/models/rslang';
|
import { SyntaxTree } from '@/models/rslang';
|
||||||
import { graphDarkT, graphLightT } from '@/utils/color';
|
import { graphDarkT, graphLightT } from '@/styling/color';
|
||||||
import { colorBgSyntaxTree } from '@/utils/color';
|
import { colorBgSyntaxTree } from '@/styling/color';
|
||||||
import { resources } from '@/utils/constants';
|
import { resources } from '@/utils/constants';
|
||||||
import { labelSyntaxTree } from '@/utils/labels';
|
import { labelSyntaxTree } from '@/utils/labels';
|
||||||
|
|
||||||
|
|
|
@ -1,361 +1,4 @@
|
||||||
@import 'react-toastify/dist/ReactToastify.css';
|
@import 'styling/setup.css';
|
||||||
|
@import 'styling/styles.css';
|
||||||
@tailwind base;
|
@import 'styling/imports.css';
|
||||||
@tailwind components;
|
@import 'styling/overrides.css';
|
||||||
@tailwind utilities;
|
|
||||||
|
|
||||||
/* prettier-ignore */
|
|
||||||
:root {
|
|
||||||
--font-ui: 'Geologica', sans-serif;
|
|
||||||
--font-main: 'Rubik', 'Noto Sans Math', 'Noto Sans Symbols 2', 'Segoe UI Symbol', sans-serif;
|
|
||||||
--font-math: 'Noto Sans Math', 'Noto Sans Symbols 2', 'Segoe UI Symbol', sans-serif;
|
|
||||||
|
|
||||||
/* Light Theme */
|
|
||||||
--cl-bg-120: hsl(000, 000%, 100%);
|
|
||||||
--cl-bg-100: hsl(000, 000%, 098%);
|
|
||||||
--cl-bg-80: hsl(000, 000%, 094%);
|
|
||||||
--cl-bg-60: hsl(000, 000%, 091%);
|
|
||||||
--cl-bg-40: hsl(000, 000%, 080%);
|
|
||||||
|
|
||||||
--cl-fg-60: hsl(000, 000%, 065%);
|
|
||||||
--cl-fg-80: hsl(000, 000%, 047%);
|
|
||||||
--cl-fg-100: hsl(000, 000%, 000%);
|
|
||||||
|
|
||||||
--cl-prim-bg-100: hsl(220, 100%, 060%);
|
|
||||||
--cl-prim-bg-80: hsl(220, 080%, 092%);
|
|
||||||
--cl-prim-bg-60: hsl(190, 080%, 094%);
|
|
||||||
|
|
||||||
--cl-prim-fg-80: hsl(220, 100%, 050%);
|
|
||||||
--cl-prim-fg-100: hsl(000, 000%, 100%);
|
|
||||||
|
|
||||||
--cl-red-bg-100: hsl(000, 100%, 095%);
|
|
||||||
--cl-red-fg-100: hsl(000, 072%, 051%);
|
|
||||||
--cl-green-fg-100: hsl(120, 080%, 37%);
|
|
||||||
|
|
||||||
/* Dark Theme */
|
|
||||||
--cd-bg-120: hsl(000, 000%, 005%);
|
|
||||||
--cd-bg-100: hsl(000, 000%, 009%);
|
|
||||||
--cd-bg-80: hsl(000, 000%, 015%);
|
|
||||||
--cd-bg-60: hsl(000, 000%, 022%);
|
|
||||||
--cd-bg-40: hsl(000, 000%, 035%);
|
|
||||||
|
|
||||||
--cd-fg-60: hsl(000, 000%, 055%);
|
|
||||||
--cd-fg-80: hsl(000, 000%, 080%);
|
|
||||||
--cd-fg-100: hsl(000, 000%, 093%);
|
|
||||||
|
|
||||||
--cd-prim-bg-100: hsl(267, 050%, 050%);
|
|
||||||
--cd-prim-bg-80: hsl(267, 050%, 032%);
|
|
||||||
--cd-prim-bg-60: hsl(269, 030%, 028%);
|
|
||||||
|
|
||||||
--cd-prim-fg-80: hsl(267, 070%, 070%);
|
|
||||||
--cd-prim-fg-100: hsl(000, 000%, 100%);
|
|
||||||
|
|
||||||
--cd-red-bg-100: hsl(000, 100%, 015%);
|
|
||||||
--cd-red-fg-100: hsl(000, 080%, 055%);
|
|
||||||
--cd-green-fg-100: hsl(120, 080%, 042%);
|
|
||||||
|
|
||||||
/* Import overrides */
|
|
||||||
--toastify-color-dark: var(--cd-bg-60);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Depth layers */
|
|
||||||
.z-bottom {
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
.z-pop {
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
:is(.z-sticky, .sticky) {
|
|
||||||
z-index: 20;
|
|
||||||
}
|
|
||||||
.z-tooltip {
|
|
||||||
z-index: 30;
|
|
||||||
}
|
|
||||||
.z-navigation {
|
|
||||||
z-index: 50;
|
|
||||||
}
|
|
||||||
.z-modal {
|
|
||||||
z-index: 60;
|
|
||||||
}
|
|
||||||
.z-modal-controls {
|
|
||||||
z-index: 70;
|
|
||||||
}
|
|
||||||
.z-modal-top {
|
|
||||||
z-index: 80;
|
|
||||||
}
|
|
||||||
.z-modal-tooltip {
|
|
||||||
z-index: 90;
|
|
||||||
}
|
|
||||||
.z-topmost {
|
|
||||||
z-index: 99;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
font-family: var(--font-main);
|
|
||||||
|
|
||||||
color: var(--cl-fg-100);
|
|
||||||
border-color: var(--cl-bg-40);
|
|
||||||
background-color: var(--cl-bg-100);
|
|
||||||
|
|
||||||
&.dark {
|
|
||||||
color: var(--cd-fg-100);
|
|
||||||
border-color: var(--cd-bg-40);
|
|
||||||
background-color: var(--cd-bg-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:focus {
|
|
||||||
outline-width: 2px;
|
|
||||||
outline-style: solid;
|
|
||||||
outline-color: transparent;
|
|
||||||
.dark & {
|
|
||||||
outline-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::selection {
|
|
||||||
background: var(--cl-prim-bg-60);
|
|
||||||
.dark & {
|
|
||||||
background: var(--cd-prim-bg-60);
|
|
||||||
}
|
|
||||||
tr :hover& {
|
|
||||||
background: var(--cl-red-bg-100);
|
|
||||||
.dark & {
|
|
||||||
background: var(--cd-red-bg-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::placeholder {
|
|
||||||
color: var(--cl-fg-60);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-fg-60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-color-scheme='dark'] {
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-color-scheme='light'] {
|
|
||||||
color-scheme: light;
|
|
||||||
}
|
|
||||||
|
|
||||||
@layer utilities {
|
|
||||||
.font-controls {
|
|
||||||
font-family: var(--font-ui);
|
|
||||||
font-weight: 600;
|
|
||||||
font-variant: small-caps;
|
|
||||||
}
|
|
||||||
.font-math {
|
|
||||||
font-family: var(--font-math);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@layer components {
|
|
||||||
h1 {
|
|
||||||
@apply text-lg font-semibold text-center;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
@apply font-semibold text-center;
|
|
||||||
}
|
|
||||||
|
|
||||||
b {
|
|
||||||
@apply font-semibold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border {
|
|
||||||
@apply rounded;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shadow-border {
|
|
||||||
@apply shadow-sm shadow-[var(--cl-bg-40)] dark:shadow-[var(--cd-bg-40)];
|
|
||||||
}
|
|
||||||
|
|
||||||
.clr-modal-backdrop {
|
|
||||||
opacity: 0.75;
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(
|
|
||||||
.clr-border,
|
|
||||||
.border,
|
|
||||||
.border-x,
|
|
||||||
.border-y,
|
|
||||||
.border-b,
|
|
||||||
.border-t,
|
|
||||||
.border-l,
|
|
||||||
.border-r,
|
|
||||||
.border-2,
|
|
||||||
.border-x-2,
|
|
||||||
.border-y-2,
|
|
||||||
.border-b-2,
|
|
||||||
.border-t-2,
|
|
||||||
.border-l-2,
|
|
||||||
.border-r-2,
|
|
||||||
.divide-x,
|
|
||||||
.divide-y,
|
|
||||||
.divide-x-2,
|
|
||||||
.divide-y-2
|
|
||||||
) {
|
|
||||||
border-color: var(--cl-bg-40);
|
|
||||||
@apply divide-inherit;
|
|
||||||
.dark & {
|
|
||||||
border-color: var(--cd-bg-40);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-app, .clr-footer, .clr-modal-backdrop, .clr-btn-nav, .clr-input:disabled) {
|
|
||||||
background-color: var(--cl-bg-100);
|
|
||||||
.dark & {
|
|
||||||
background-color: var(--cd-bg-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-input) {
|
|
||||||
background-color: var(--cl-bg-120);
|
|
||||||
.dark & {
|
|
||||||
background-color: var(--cd-bg-120);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-controls, .clr-tab, .clr-btn-default) {
|
|
||||||
background-color: var(--cl-bg-80);
|
|
||||||
.dark & {
|
|
||||||
background-color: var(--cd-bg-80);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-primary, .clr-btn-primary:hover, .clr-btn-primary:focus) {
|
|
||||||
@apply transition;
|
|
||||||
color: var(--cl-prim-fg-100);
|
|
||||||
background-color: var(--cl-prim-bg-100);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-prim-fg-100);
|
|
||||||
background-color: var(--cd-prim-bg-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-selected, .clr-btn-primary) {
|
|
||||||
color: var(--cl-fg-100);
|
|
||||||
background-color: var(--cl-prim-bg-80);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-fg-100);
|
|
||||||
background-color: var(--cd-prim-bg-80);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-disabled, .clr-btn-default, .clr-btn-primary):disabled {
|
|
||||||
@apply transition;
|
|
||||||
color: var(--cl-fg-80);
|
|
||||||
background-color: var(--cl-bg-60);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-fg-80);
|
|
||||||
background-color: var(--cd-bg-60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-hover, .clr-tab, .clr-btn-nav, .clr-btn-default):hover:not(:disabled) {
|
|
||||||
@apply transition;
|
|
||||||
color: var(--cl-fg-100);
|
|
||||||
background-color: var(--cl-prim-bg-60);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-fg-100);
|
|
||||||
background-color: var(--cd-prim-bg-60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-outline, .clr-btn-primary):focus {
|
|
||||||
outline-width: 2px;
|
|
||||||
outline-style: solid;
|
|
||||||
outline-color: var(--cl-prim-bg-100);
|
|
||||||
.dark & {
|
|
||||||
outline-color: var(--cd-prim-bg-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-text-primary, .clr-text-url) {
|
|
||||||
color: var(--cl-prim-fg-80);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-prim-fg-80);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.clr-footer {
|
|
||||||
color: var(--cl-fg-60);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-fg-60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:is(.clr-text-controls, .clr-btn-nav, .clr-btn-clear) {
|
|
||||||
color: var(--cl-fg-80);
|
|
||||||
&:disabled {
|
|
||||||
color: var(--cl-fg-60);
|
|
||||||
}
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-fg-80);
|
|
||||||
&:disabled {
|
|
||||||
color: var(--cd-fg-60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.clr-warning {
|
|
||||||
background-color: var(--cl-red-bg-100);
|
|
||||||
.dark & {
|
|
||||||
background-color: var(--cd-red-bg-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.clr-text-default {
|
|
||||||
color: var(--cl-fg-100);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-fg-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.clr-text-warning {
|
|
||||||
color: var(--cl-red-fg-100);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-red-fg-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.clr-text-success {
|
|
||||||
color: var(--cl-green-fg-100);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-green-fg-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cm-editor {
|
|
||||||
resize: vertical;
|
|
||||||
overflow-y: auto;
|
|
||||||
border-color: var(--cl-bg-40);
|
|
||||||
.dark & {
|
|
||||||
border-color: var(--cd-bg-40);
|
|
||||||
}
|
|
||||||
@apply border rounded px-[0.375rem] py-[0.15rem];
|
|
||||||
}
|
|
||||||
.cm-editor.cm-focused {
|
|
||||||
border-color: var(--cl-bg-40);
|
|
||||||
outline-color: var(--cl-prim-bg-100);
|
|
||||||
.dark & {
|
|
||||||
border-color: var(--cd-bg-40);
|
|
||||||
outline-color: var(--cd-prim-bg-100);
|
|
||||||
}
|
|
||||||
@apply outline-2 outline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cm-editor .cm-placeholder {
|
|
||||||
color: var(--cl-fg-60);
|
|
||||||
.dark & {
|
|
||||||
color: var(--cd-fg-60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.rdt_TableCell {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { useEffect, useRef, useState } from 'react';
|
||||||
import { BiDownload } from 'react-icons/bi';
|
import { BiDownload } from 'react-icons/bi';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
import AnimateFadeIn from '@/components/AnimateFadeIn';
|
||||||
import InfoError from '@/components/InfoError';
|
import InfoError from '@/components/InfoError';
|
||||||
import RequireAuth from '@/components/RequireAuth';
|
import RequireAuth from '@/components/RequireAuth';
|
||||||
import Button from '@/components/ui/Button';
|
import Button from '@/components/ui/Button';
|
||||||
|
@ -78,6 +79,7 @@ function CreateRSFormPage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<AnimateFadeIn>
|
||||||
<RequireAuth>
|
<RequireAuth>
|
||||||
<form className={clsx('px-6 py-3', classnames.flex_col)} onSubmit={handleSubmit}>
|
<form className={clsx('px-6 py-3', classnames.flex_col)} onSubmit={handleSubmit}>
|
||||||
<h1>Создание концептуальной схемы</h1>
|
<h1>Создание концептуальной схемы</h1>
|
||||||
|
@ -128,6 +130,7 @@ function CreateRSFormPage() {
|
||||||
{error ? <InfoError error={error} /> : null}
|
{error ? <InfoError error={error} /> : null}
|
||||||
</form>
|
</form>
|
||||||
</RequireAuth>
|
</RequireAuth>
|
||||||
|
</AnimateFadeIn>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,7 @@ function HomePage() {
|
||||||
}
|
}
|
||||||
}, [router, user]);
|
}, [router, user]);
|
||||||
|
|
||||||
return (
|
return <div />;
|
||||||
<div className='flex flex-col items-center justify-center px-4 py-2'>
|
|
||||||
{user?.is_staff ? (
|
|
||||||
<p>Лендинг находится в разработке. Данная страница видна только пользователям с правами администратора.</p>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default HomePage;
|
export default HomePage;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import { useCallback, useLayoutEffect, useState } from 'react';
|
import { useCallback, useLayoutEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import AnimateFadeIn from '@/components/AnimateFadeIn';
|
||||||
import InfoError from '@/components/InfoError';
|
import InfoError from '@/components/InfoError';
|
||||||
import { Loader } from '@/components/ui/Loader';
|
import { Loader } from '@/components/ui/Loader';
|
||||||
import { useAuth } from '@/context/AuthContext';
|
import { useAuth } from '@/context/AuthContext';
|
||||||
|
@ -68,7 +69,7 @@ function LibraryPage() {
|
||||||
{library.loading ? <Loader /> : null}
|
{library.loading ? <Loader /> : null}
|
||||||
{library.error ? <InfoError error={library.error} /> : null}
|
{library.error ? <InfoError error={library.error} /> : null}
|
||||||
{!library.loading && library.items ? (
|
{!library.loading && library.items ? (
|
||||||
<>
|
<AnimateFadeIn>
|
||||||
<SearchPanel
|
<SearchPanel
|
||||||
query={query}
|
query={query}
|
||||||
setQuery={setQuery}
|
setQuery={setQuery}
|
||||||
|
@ -78,7 +79,7 @@ function LibraryPage() {
|
||||||
setFilter={setFilter}
|
setFilter={setFilter}
|
||||||
/>
|
/>
|
||||||
<ViewLibrary resetQuery={resetQuery} items={items} />
|
<ViewLibrary resetQuery={resetQuery} items={items} />
|
||||||
</>
|
</AnimateFadeIn>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
import DataTable, { createColumnHelper } from '@/components/DataTable';
|
import DataTable, { createColumnHelper } from '@/components/DataTable';
|
||||||
import HelpButton from '@/components/Help/HelpButton';
|
import HelpButton from '@/components/Help/HelpButton';
|
||||||
|
import FlexColumn from '@/components/ui/FlexColumn';
|
||||||
import TextURL from '@/components/ui/TextURL';
|
import TextURL from '@/components/ui/TextURL';
|
||||||
import { useAuth } from '@/context/AuthContext';
|
import { useAuth } from '@/context/AuthContext';
|
||||||
import { useConceptNavigation } from '@/context/NavigationContext';
|
import { useConceptNavigation } from '@/context/NavigationContext';
|
||||||
|
@ -95,7 +96,7 @@ function ViewLibrary({ items, resetQuery: cleanQuery }: ViewLibraryProps) {
|
||||||
'flex gap-1'
|
'flex gap-1'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<HelpButton topic={HelpTopic.LIBRARY} className='max-w-[35rem]' offset={0} />
|
<HelpButton topic={HelpTopic.LIBRARY} className='max-w-[35rem]' offset={5} place='right-start' />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<DataTable
|
<DataTable
|
||||||
|
@ -103,13 +104,13 @@ function ViewLibrary({ items, resetQuery: cleanQuery }: ViewLibraryProps) {
|
||||||
data={items}
|
data={items}
|
||||||
headPosition='2.3rem'
|
headPosition='2.3rem'
|
||||||
noDataComponent={
|
noDataComponent={
|
||||||
<div className='p-3 text-center min-h-[6rem]'>
|
<FlexColumn className='p-3 items-center min-h-[6rem]'>
|
||||||
<p>Список схем пуст</p>
|
<p>Список схем пуст</p>
|
||||||
<p className='flex justify-center gap-6 mt-3'>
|
<p className='flex gap-6'>
|
||||||
<TextURL text='Создать схему' href='/library/create' />
|
<TextURL text='Создать схему' href='/library/create' />
|
||||||
<TextURL text='Очистить фильтр' onClick={cleanQuery} />
|
<TextURL text='Очистить фильтр' onClick={cleanQuery} />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</FlexColumn>
|
||||||
}
|
}
|
||||||
onRowClicked={handleOpenItem}
|
onRowClicked={handleOpenItem}
|
||||||
enableSorting
|
enableSorting
|
||||||
|
|
|
@ -4,6 +4,7 @@ import axios from 'axios';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import AnimateFadeIn from '@/components/AnimateFadeIn';
|
||||||
import ExpectedAnonymous from '@/components/ExpectedAnonymous';
|
import ExpectedAnonymous from '@/components/ExpectedAnonymous';
|
||||||
import InfoError, { ErrorData } from '@/components/InfoError';
|
import InfoError, { ErrorData } from '@/components/InfoError';
|
||||||
import SubmitButton from '@/components/ui/SubmitButton';
|
import SubmitButton from '@/components/ui/SubmitButton';
|
||||||
|
@ -62,6 +63,7 @@ function LoginPage() {
|
||||||
return <ExpectedAnonymous />;
|
return <ExpectedAnonymous />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
<AnimateFadeIn>
|
||||||
<form className={clsx('w-[24rem]', 'pt-12 pb-6 px-6', classnames.flex_col)} onSubmit={handleSubmit}>
|
<form className={clsx('w-[24rem]', 'pt-12 pb-6 px-6', classnames.flex_col)} onSubmit={handleSubmit}>
|
||||||
<img alt='Концепт Портал' src={resources.logo} className='max-h-[2.5rem] min-w-[2.5rem] mb-3' />
|
<img alt='Концепт Портал' src={resources.logo} className='max-h-[2.5rem] min-w-[2.5rem] mb-3' />
|
||||||
<TextInput
|
<TextInput
|
||||||
|
@ -95,6 +97,7 @@ function LoginPage() {
|
||||||
</div>
|
</div>
|
||||||
{error ? <ProcessError error={error} /> : null}
|
{error ? <ProcessError error={error} /> : null}
|
||||||
</form>
|
</form>
|
||||||
|
</AnimateFadeIn>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ function TopicsList({ activeTopic, onChangeTopic }: TopicsListProps) {
|
||||||
<div
|
<div
|
||||||
className={clsx('sticky top-0 left-0', 'min-w-[13rem] self-start', 'border-x', 'clr-controls', '', 'select-none')}
|
className={clsx('sticky top-0 left-0', 'min-w-[13rem] self-start', 'border-x', 'clr-controls', '', 'select-none')}
|
||||||
>
|
>
|
||||||
<h1 className='my-1'>Справка</h1>
|
|
||||||
{Object.values(HelpTopic).map((topic, index) => (
|
{Object.values(HelpTopic).map((topic, index) => (
|
||||||
<div
|
<div
|
||||||
key={`${prefixes.topic_list}${index}`}
|
key={`${prefixes.topic_list}${index}`}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import InfoTopic from '@/components/Help/InfoTopic';
|
import AnimateFadeIn from '@/components/AnimateFadeIn';
|
||||||
|
import InfoTopic from '@/components/InfoTopic';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
|
||||||
interface ViewTopicProps {
|
interface ViewTopicProps {
|
||||||
|
@ -7,9 +8,9 @@ interface ViewTopicProps {
|
||||||
|
|
||||||
function ViewTopic({ topic }: ViewTopicProps) {
|
function ViewTopic({ topic }: ViewTopicProps) {
|
||||||
return (
|
return (
|
||||||
<div className='px-2 py-2 mx-auto'>
|
<AnimateFadeIn key={topic} className='px-2 py-2 mx-auto'>
|
||||||
<InfoTopic topic={topic} />
|
<InfoTopic topic={topic} />
|
||||||
</div>
|
</AnimateFadeIn>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { motion } from 'framer-motion';
|
||||||
|
|
||||||
import { IExpressionParse, IRSErrorDescription } from '@/models/rslang';
|
import { IExpressionParse, IRSErrorDescription } from '@/models/rslang';
|
||||||
import { getRSErrorPrefix } from '@/models/rslangAPI';
|
import { getRSErrorPrefix } from '@/models/rslangAPI';
|
||||||
import { animateParseResults } from '@/utils/animations';
|
import { animateParseResults } from '@/styling/animations';
|
||||||
import { describeRSError } from '@/utils/labels';
|
import { describeRSError } from '@/utils/labels';
|
||||||
|
|
||||||
interface ParsingResultProps {
|
interface ParsingResultProps {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
|
||||||
import { TokenID } from '@/models/rslang';
|
import { TokenID } from '@/models/rslang';
|
||||||
import { animateRSControl } from '@/utils/animations';
|
import { animateRSControl } from '@/styling/animations';
|
||||||
import { prefixes } from '@/utils/constants';
|
import { prefixes } from '@/utils/constants';
|
||||||
|
|
||||||
import RSLocalButton from './RSLocalButton';
|
import RSLocalButton from './RSLocalButton';
|
||||||
|
|
|
@ -9,7 +9,7 @@ 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 { colorBgCstStatus } from '@/utils/color';
|
import { colorBgCstStatus } from '@/styling/color';
|
||||||
import { globalIDs } from '@/utils/constants';
|
import { globalIDs } from '@/utils/constants';
|
||||||
import { labelExpressionStatus } from '@/utils/labels';
|
import { labelExpressionStatus } from '@/utils/labels';
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,12 @@ function EditorRSList({ isMutable, onOpenEdit, onCreateCst, onDeleteCst }: Edito
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div tabIndex={-1} className='outline-none' onKeyDown={handleTableKey}>
|
<div tabIndex={-1} className='outline-none' onKeyDown={handleTableKey}>
|
||||||
|
<SelectedCounter
|
||||||
|
total={schema?.stats?.count_all ?? 0}
|
||||||
|
selected={selected.length}
|
||||||
|
position='top-[0.3rem] left-2'
|
||||||
|
/>
|
||||||
|
|
||||||
<RSListToolbar
|
<RSListToolbar
|
||||||
selectedCount={selected.length}
|
selectedCount={selected.length}
|
||||||
isMutable={isMutable}
|
isMutable={isMutable}
|
||||||
|
@ -204,7 +210,6 @@ function EditorRSList({ isMutable, onOpenEdit, onCreateCst, onDeleteCst }: Edito
|
||||||
onCreate={handleCreateCst}
|
onCreate={handleCreateCst}
|
||||||
onDelete={handleDelete}
|
onDelete={handleDelete}
|
||||||
/>
|
/>
|
||||||
<SelectedCounter total={schema?.stats?.count_all ?? 0} selected={selected.length} position='left-1 top-2' />
|
|
||||||
|
|
||||||
<div className='pt-[2.3rem] border-b' />
|
<div className='pt-[2.3rem] border-b' />
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import ConstituentaBadge from '@/components/ConstituentaBadge';
|
import ConstituentaBadge from '@/components/ConstituentaBadge';
|
||||||
import DataTable, { createColumnHelper, RowSelectionState, VisibilityState } from '@/components/DataTable';
|
import DataTable, { createColumnHelper, RowSelectionState, VisibilityState } from '@/components/DataTable';
|
||||||
|
import FlexColumn from '@/components/ui/FlexColumn';
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import useWindowSize from '@/hooks/useWindowSize';
|
import useWindowSize from '@/hooks/useWindowSize';
|
||||||
import { IConstituenta } from '@/models/rsform';
|
import { IConstituenta } from '@/models/rsform';
|
||||||
|
@ -135,12 +136,12 @@ function RSTable({ items, selected, setSelected, onEdit, onCreateNew }: RSTableP
|
||||||
rowSelection={selected}
|
rowSelection={selected}
|
||||||
onRowSelectionChange={setSelected}
|
onRowSelectionChange={setSelected}
|
||||||
noDataComponent={
|
noDataComponent={
|
||||||
<span className='flex flex-col justify-center p-2 text-center'>
|
<FlexColumn className='p-3 items-center'>
|
||||||
<p>Список пуст</p>
|
<p>Список пуст</p>
|
||||||
<p className='cursor-pointer clr-text-primary hover:underline' onClick={() => onCreateNew()}>
|
<p className='cursor-pointer clr-text-primary hover:underline' onClick={() => onCreateNew()}>
|
||||||
Создать новую конституенту
|
Создать новую конституенту
|
||||||
</p>
|
</p>
|
||||||
</span>
|
</FlexColumn>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,7 +14,7 @@ import DlgGraphParams from '@/dialogs/DlgGraphParams';
|
||||||
import useLocalStorage from '@/hooks/useLocalStorage';
|
import useLocalStorage from '@/hooks/useLocalStorage';
|
||||||
import { GraphColoringScheme, GraphFilterParams } from '@/models/miscellaneous';
|
import { GraphColoringScheme, GraphFilterParams } from '@/models/miscellaneous';
|
||||||
import { CstType, ICstCreateData } from '@/models/rsform';
|
import { CstType, ICstCreateData } from '@/models/rsform';
|
||||||
import { colorBgGraphNode } from '@/utils/color';
|
import { colorBgGraphNode } from '@/styling/color';
|
||||||
import { classnames, TIMEOUT_GRAPH_REFRESH } from '@/utils/constants';
|
import { classnames, TIMEOUT_GRAPH_REFRESH } from '@/utils/constants';
|
||||||
|
|
||||||
import GraphSidebar from './GraphSidebar';
|
import GraphSidebar from './GraphSidebar';
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useCallback, useLayoutEffect, useMemo, useRef } from 'react';
|
||||||
|
|
||||||
import GraphUI, { GraphCanvasRef, GraphEdge, GraphNode, LayoutTypes, Sphere, useSelection } from '@/components/GraphUI';
|
import GraphUI, { GraphCanvasRef, GraphEdge, GraphNode, LayoutTypes, Sphere, useSelection } from '@/components/GraphUI';
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { graphDarkT, graphLightT } from '@/utils/color';
|
import { graphDarkT, graphLightT } from '@/styling/color';
|
||||||
import { resources } from '@/utils/constants';
|
import { resources } from '@/utils/constants';
|
||||||
|
|
||||||
interface TermGraphProps {
|
interface TermGraphProps {
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import ConstituentaTooltip from '@/components/Help/ConstituentaTooltip';
|
import ConstituentaTooltip from '@/components/ConstituentaTooltip';
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { GraphColoringScheme } from '@/models/miscellaneous';
|
import { GraphColoringScheme } from '@/models/miscellaneous';
|
||||||
import { IRSForm } from '@/models/rsform';
|
import { IRSForm } from '@/models/rsform';
|
||||||
import { colorBgGraphNode } from '@/utils/color';
|
import { colorBgGraphNode } from '@/styling/color';
|
||||||
import { prefixes } from '@/utils/constants';
|
import { prefixes } from '@/utils/constants';
|
||||||
|
|
||||||
interface ViewHiddenProps {
|
interface ViewHiddenProps {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
|
||||||
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
import { TabList, TabPanel, Tabs } from 'react-tabs';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
import AnimateFadeIn from '@/components/AnimateFadeIn';
|
||||||
import InfoError, { ErrorData } from '@/components/InfoError';
|
import InfoError, { ErrorData } from '@/components/InfoError';
|
||||||
import { Loader } from '@/components/ui/Loader';
|
import { Loader } from '@/components/ui/Loader';
|
||||||
import TabLabel from '@/components/ui/TabLabel';
|
import TabLabel from '@/components/ui/TabLabel';
|
||||||
|
@ -434,6 +435,7 @@ function RSTabs() {
|
||||||
<TabLabel label='Граф термов' />
|
<TabLabel label='Граф термов' />
|
||||||
</TabList>
|
</TabList>
|
||||||
|
|
||||||
|
<AnimateFadeIn>
|
||||||
<TabPanel forceRender style={{ display: activeTab === RSTabID.CARD ? '' : 'none' }}>
|
<TabPanel forceRender style={{ display: activeTab === RSTabID.CARD ? '' : 'none' }}>
|
||||||
<EditorRSForm
|
<EditorRSForm
|
||||||
isMutable={isMutable}
|
isMutable={isMutable}
|
||||||
|
@ -479,6 +481,7 @@ function RSTabs() {
|
||||||
onDeleteCst={promptDeleteCst}
|
onDeleteCst={promptDeleteCst}
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
</AnimateFadeIn>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -125,7 +125,7 @@ function ConstituentsTable({ items, activeID, onOpenEdit, maxHeight, denseThresh
|
||||||
columnVisibility={columnVisibility}
|
columnVisibility={columnVisibility}
|
||||||
onColumnVisibilityChange={setColumnVisibility}
|
onColumnVisibilityChange={setColumnVisibility}
|
||||||
noDataComponent={
|
noDataComponent={
|
||||||
<div className={clsx('min-h-[5rem]', 'p-2', 'text-center', 'select-none')}>
|
<div className={clsx('min-h-[5rem]', 'p-3', 'text-center', 'select-none')}>
|
||||||
<p>Список конституент пуст</p>
|
<p>Список конституент пуст</p>
|
||||||
<p>Измените параметры фильтра</p>
|
<p>Измените параметры фильтра</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { useConceptTheme } from '@/context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import { IConstituenta, IRSForm } from '@/models/rsform';
|
import { IConstituenta, IRSForm } from '@/models/rsform';
|
||||||
import { animateSideView } from '@/utils/animations';
|
import { animateSideView } from '@/styling/animations';
|
||||||
|
|
||||||
import ConstituentsSearch from './ConstituentsSearch';
|
import ConstituentsSearch from './ConstituentsSearch';
|
||||||
import ConstituentsTable from './ConstituentsTable';
|
import ConstituentsTable from './ConstituentsTable';
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { useEffect, useState } from 'react';
|
||||||
import { BiInfoCircle } from 'react-icons/bi';
|
import { BiInfoCircle } from 'react-icons/bi';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
import AnimateFadeIn from '@/components/AnimateFadeIn';
|
||||||
import ExpectedAnonymous from '@/components/ExpectedAnonymous';
|
import ExpectedAnonymous from '@/components/ExpectedAnonymous';
|
||||||
import InfoError from '@/components/InfoError';
|
import InfoError from '@/components/InfoError';
|
||||||
import Button from '@/components/ui/Button';
|
import Button from '@/components/ui/Button';
|
||||||
|
@ -67,6 +68,7 @@ function RegisterPage() {
|
||||||
return <ExpectedAnonymous />;
|
return <ExpectedAnonymous />;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
<AnimateFadeIn>
|
||||||
<form className={clsx('px-6 py-3', classnames.flex_col)} onSubmit={handleSubmit}>
|
<form className={clsx('px-6 py-3', classnames.flex_col)} onSubmit={handleSubmit}>
|
||||||
<h1>Новый пользователь</h1>
|
<h1>Новый пользователь</h1>
|
||||||
<div className='flex gap-12'>
|
<div className='flex gap-12'>
|
||||||
|
@ -146,6 +148,7 @@ function RegisterPage() {
|
||||||
</div>
|
</div>
|
||||||
{error ? <InfoError error={error} /> : null}
|
{error ? <InfoError error={error} /> : null}
|
||||||
</form>
|
</form>
|
||||||
|
</AnimateFadeIn>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
|
import AnimateFadeIn from '@/components/AnimateFadeIn';
|
||||||
import TextURL from '@/components/ui/TextURL';
|
import TextURL from '@/components/ui/TextURL';
|
||||||
import { urls } from '@/utils/constants';
|
import { urls } from '@/utils/constants';
|
||||||
|
|
||||||
function RestorePasswordPage() {
|
function RestorePasswordPage() {
|
||||||
return (
|
return (
|
||||||
<div className='py-3'>
|
<AnimateFadeIn className='py-3'>
|
||||||
<p>Автоматическое восстановление пароля не доступно.</p>
|
<p>Автоматическое восстановление пароля не доступно.</p>
|
||||||
<p>
|
<p>
|
||||||
Возможно восстановление пароля через обращение на <TextURL href={urls.mail_portal} text='portal@acconcept.ru' />
|
Возможно восстановление пароля через обращение на <TextURL href={urls.mail_portal} text='portal@acconcept.ru' />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</AnimateFadeIn>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { AnimatePresence } from 'framer-motion';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { FiBell, FiBellOff } from 'react-icons/fi';
|
import { FiBell, FiBellOff } from 'react-icons/fi';
|
||||||
|
|
||||||
|
import AnimateFadeIn from '@/components/AnimateFadeIn';
|
||||||
import InfoError from '@/components/InfoError';
|
import InfoError from '@/components/InfoError';
|
||||||
import { Loader } from '@/components/ui/Loader';
|
import { Loader } from '@/components/ui/Loader';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
|
@ -32,7 +33,7 @@ function UserTabs() {
|
||||||
{loading ? <Loader /> : null}
|
{loading ? <Loader /> : null}
|
||||||
{error ? <InfoError error={error} /> : null}
|
{error ? <InfoError error={error} /> : null}
|
||||||
{user ? (
|
{user ? (
|
||||||
<div className='flex gap-6 py-2'>
|
<AnimateFadeIn className='flex gap-6 py-2'>
|
||||||
<div>
|
<div>
|
||||||
<Overlay position='top-0 right-0'>
|
<Overlay position='top-0 right-0'>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
@ -56,7 +57,7 @@ function UserTabs() {
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{subscriptions.length > 0 && showSubs ? <ViewSubscriptions items={subscriptions} /> : null}
|
{subscriptions.length > 0 && showSubs ? <ViewSubscriptions items={subscriptions} /> : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</AnimateFadeIn>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { useIntl } from 'react-intl';
|
||||||
import DataTable, { createColumnHelper } from '@/components/DataTable';
|
import DataTable, { createColumnHelper } from '@/components/DataTable';
|
||||||
import { useConceptNavigation } from '@/context/NavigationContext';
|
import { useConceptNavigation } from '@/context/NavigationContext';
|
||||||
import { ILibraryItem } from '@/models/library';
|
import { ILibraryItem } from '@/models/library';
|
||||||
import { animateSideView } from '@/utils/animations';
|
import { animateSideView } from '@/styling/animations';
|
||||||
|
|
||||||
interface ViewSubscriptionsProps {
|
interface ViewSubscriptionsProps {
|
||||||
items: ILibraryItem[];
|
items: ILibraryItem[];
|
||||||
|
|
|
@ -190,3 +190,25 @@ export const animateModal = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const animateFadeIn = {
|
||||||
|
initial: {
|
||||||
|
opacity: 0
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
type: 'tween',
|
||||||
|
ease: 'linear',
|
||||||
|
duration: 0.3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
exit: {
|
||||||
|
opacity: 0,
|
||||||
|
transition: {
|
||||||
|
type: 'tween',
|
||||||
|
ease: 'linear',
|
||||||
|
duration: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
54
rsconcept/frontend/src/styling/constants.css
Normal file
54
rsconcept/frontend/src/styling/constants.css
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
* Module: Define CSS variables.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
:root {
|
||||||
|
--font-ui: 'Geologica', sans-serif;
|
||||||
|
--font-main: 'Rubik', 'Noto Sans Math', 'Noto Sans Symbols 2', 'Segoe UI Symbol', sans-serif;
|
||||||
|
--font-math: 'Noto Sans Math', 'Noto Sans Symbols 2', 'Segoe UI Symbol', sans-serif;
|
||||||
|
|
||||||
|
/* Light Theme */
|
||||||
|
--cl-bg-120: hsl(000, 000%, 100%);
|
||||||
|
--cl-bg-100: hsl(000, 000%, 098%);
|
||||||
|
--cl-bg-80: hsl(000, 000%, 094%);
|
||||||
|
--cl-bg-60: hsl(000, 000%, 091%);
|
||||||
|
--cl-bg-40: hsl(000, 000%, 080%);
|
||||||
|
|
||||||
|
--cl-fg-60: hsl(000, 000%, 065%);
|
||||||
|
--cl-fg-80: hsl(000, 000%, 047%);
|
||||||
|
--cl-fg-100: hsl(000, 000%, 000%);
|
||||||
|
|
||||||
|
--cl-prim-bg-100: hsl(220, 100%, 060%);
|
||||||
|
--cl-prim-bg-80: hsl(220, 080%, 092%);
|
||||||
|
--cl-prim-bg-60: hsl(190, 080%, 094%);
|
||||||
|
|
||||||
|
--cl-prim-fg-80: hsl(220, 100%, 050%);
|
||||||
|
--cl-prim-fg-100: hsl(000, 000%, 100%);
|
||||||
|
|
||||||
|
--cl-red-bg-100: hsl(000, 100%, 095%);
|
||||||
|
--cl-red-fg-100: hsl(000, 072%, 051%);
|
||||||
|
--cl-green-fg-100: hsl(120, 080%, 37%);
|
||||||
|
|
||||||
|
/* Dark Theme */
|
||||||
|
--cd-bg-120: hsl(000, 000%, 005%);
|
||||||
|
--cd-bg-100: hsl(000, 000%, 009%);
|
||||||
|
--cd-bg-80: hsl(000, 000%, 015%);
|
||||||
|
--cd-bg-60: hsl(000, 000%, 022%);
|
||||||
|
--cd-bg-40: hsl(000, 000%, 035%);
|
||||||
|
|
||||||
|
--cd-fg-60: hsl(000, 000%, 055%);
|
||||||
|
--cd-fg-80: hsl(000, 000%, 080%);
|
||||||
|
--cd-fg-100: hsl(000, 000%, 093%);
|
||||||
|
|
||||||
|
--cd-prim-bg-100: hsl(267, 050%, 050%);
|
||||||
|
--cd-prim-bg-80: hsl(267, 050%, 032%);
|
||||||
|
--cd-prim-bg-60: hsl(269, 030%, 028%);
|
||||||
|
|
||||||
|
--cd-prim-fg-80: hsl(267, 070%, 070%);
|
||||||
|
--cd-prim-fg-100: hsl(000, 000%, 100%);
|
||||||
|
|
||||||
|
--cd-red-bg-100: hsl(000, 100%, 015%);
|
||||||
|
--cd-red-fg-100: hsl(000, 080%, 055%);
|
||||||
|
--cd-green-fg-100: hsl(120, 080%, 042%);
|
||||||
|
}
|
5
rsconcept/frontend/src/styling/imports.css
Normal file
5
rsconcept/frontend/src/styling/imports.css
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/**
|
||||||
|
* Module: List external styling imports.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import 'react-toastify/dist/ReactToastify.css';
|
40
rsconcept/frontend/src/styling/layers.css
Normal file
40
rsconcept/frontend/src/styling/layers.css
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/* Depth layers */
|
||||||
|
.z-bottom {
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-pop {
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.z-sticky, .sticky) {
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-tooltip {
|
||||||
|
z-index: 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-navigation {
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-modal {
|
||||||
|
z-index: 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-modal-controls {
|
||||||
|
z-index: 70;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-modal-top {
|
||||||
|
z-index: 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-modal-tooltip {
|
||||||
|
z-index: 90;
|
||||||
|
}
|
||||||
|
|
||||||
|
.z-topmost {
|
||||||
|
z-index: 99;
|
||||||
|
}
|
38
rsconcept/frontend/src/styling/overrides.css
Normal file
38
rsconcept/frontend/src/styling/overrides.css
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* Module: Override imported components CSS styling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* Import overrides */
|
||||||
|
--toastify-color-dark: var(--cd-bg-60);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-editor {
|
||||||
|
resize: vertical;
|
||||||
|
overflow-y: auto;
|
||||||
|
border-color: var(--cl-bg-40);
|
||||||
|
.dark & {
|
||||||
|
border-color: var(--cd-bg-40);
|
||||||
|
}
|
||||||
|
@apply border rounded px-[0.375rem] py-[0.15rem];
|
||||||
|
}
|
||||||
|
.cm-editor.cm-focused {
|
||||||
|
border-color: var(--cl-bg-40);
|
||||||
|
outline-color: var(--cl-prim-bg-100);
|
||||||
|
.dark & {
|
||||||
|
border-color: var(--cd-bg-40);
|
||||||
|
outline-color: var(--cd-prim-bg-100);
|
||||||
|
}
|
||||||
|
@apply outline-2 outline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-editor .cm-placeholder {
|
||||||
|
color: var(--cl-fg-60);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-fg-60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.rdt_TableCell {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
113
rsconcept/frontend/src/styling/setup.css
Normal file
113
rsconcept/frontend/src/styling/setup.css
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* Module: Basic styling setup.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import './constants.css';
|
||||||
|
@import './layers.css';
|
||||||
|
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
html {
|
||||||
|
hanging-punctuation: first last;
|
||||||
|
color-scheme: dark light;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-color-scheme='dark'] {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-color-scheme='light'] {
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Default scroll behavior */
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
:has(:target) {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
scroll-padding-top: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
font-family: var(--font-main);
|
||||||
|
|
||||||
|
color: var(--cl-fg-100);
|
||||||
|
border-color: var(--cl-bg-40);
|
||||||
|
background-color: var(--cl-bg-100);
|
||||||
|
|
||||||
|
&.dark {
|
||||||
|
color: var(--cd-fg-100);
|
||||||
|
border-color: var(--cd-bg-40);
|
||||||
|
background-color: var(--cd-bg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:focus {
|
||||||
|
outline-width: 2px;
|
||||||
|
outline-style: solid;
|
||||||
|
outline-color: transparent;
|
||||||
|
.dark & {
|
||||||
|
outline-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: var(--cl-prim-bg-60);
|
||||||
|
.dark & {
|
||||||
|
background: var(--cd-prim-bg-60);
|
||||||
|
}
|
||||||
|
tr :hover& {
|
||||||
|
background: var(--cl-red-bg-100);
|
||||||
|
.dark & {
|
||||||
|
background: var(--cd-red-bg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::placeholder {
|
||||||
|
color: var(--cl-fg-60);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-fg-60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapping headers */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Limit text lines and setup wrapping */
|
||||||
|
p,
|
||||||
|
li {
|
||||||
|
max-width: 90ch;
|
||||||
|
text-wrap: pretty;
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
h1 {
|
||||||
|
@apply text-lg font-semibold text-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@apply font-semibold text-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
@apply font-semibold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border {
|
||||||
|
@apply rounded;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadow-border {
|
||||||
|
@apply shadow-sm shadow-[var(--cl-bg-40)] dark:shadow-[var(--cd-bg-40)];
|
||||||
|
}
|
||||||
|
}
|
177
rsconcept/frontend/src/styling/styles.css
Normal file
177
rsconcept/frontend/src/styling/styles.css
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/**
|
||||||
|
* Module: Custom styling.
|
||||||
|
*/
|
||||||
|
@import './constants.css';
|
||||||
|
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
.font-controls {
|
||||||
|
font-family: var(--font-ui);
|
||||||
|
font-weight: 600;
|
||||||
|
font-variant: small-caps;
|
||||||
|
}
|
||||||
|
.font-math {
|
||||||
|
font-family: var(--font-math);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
.clr-modal-backdrop {
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(
|
||||||
|
.clr-border,
|
||||||
|
.border,
|
||||||
|
.border-x,
|
||||||
|
.border-y,
|
||||||
|
.border-b,
|
||||||
|
.border-t,
|
||||||
|
.border-l,
|
||||||
|
.border-r,
|
||||||
|
.border-2,
|
||||||
|
.border-x-2,
|
||||||
|
.border-y-2,
|
||||||
|
.border-b-2,
|
||||||
|
.border-t-2,
|
||||||
|
.border-l-2,
|
||||||
|
.border-r-2,
|
||||||
|
.divide-x,
|
||||||
|
.divide-y,
|
||||||
|
.divide-x-2,
|
||||||
|
.divide-y-2
|
||||||
|
) {
|
||||||
|
border-color: var(--cl-bg-40);
|
||||||
|
@apply divide-inherit;
|
||||||
|
.dark & {
|
||||||
|
border-color: var(--cd-bg-40);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-app, .clr-footer, .clr-modal-backdrop, .clr-btn-nav, .clr-input:disabled) {
|
||||||
|
background-color: var(--cl-bg-100);
|
||||||
|
.dark & {
|
||||||
|
background-color: var(--cd-bg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-input) {
|
||||||
|
background-color: var(--cl-bg-120);
|
||||||
|
.dark & {
|
||||||
|
background-color: var(--cd-bg-120);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-controls, .clr-tab, .clr-btn-default) {
|
||||||
|
background-color: var(--cl-bg-80);
|
||||||
|
.dark & {
|
||||||
|
background-color: var(--cd-bg-80);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-primary, .clr-btn-primary:hover, .clr-btn-primary:focus) {
|
||||||
|
@apply transition;
|
||||||
|
color: var(--cl-prim-fg-100);
|
||||||
|
background-color: var(--cl-prim-bg-100);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-prim-fg-100);
|
||||||
|
background-color: var(--cd-prim-bg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-selected, .clr-btn-primary) {
|
||||||
|
color: var(--cl-fg-100);
|
||||||
|
background-color: var(--cl-prim-bg-80);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-fg-100);
|
||||||
|
background-color: var(--cd-prim-bg-80);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-disabled, .clr-btn-default, .clr-btn-primary):disabled {
|
||||||
|
@apply transition;
|
||||||
|
color: var(--cl-fg-80);
|
||||||
|
background-color: var(--cl-bg-60);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-fg-80);
|
||||||
|
background-color: var(--cd-bg-60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-hover, .clr-tab, .clr-btn-nav, .clr-btn-default):hover:not(:disabled) {
|
||||||
|
@apply transition;
|
||||||
|
color: var(--cl-fg-100);
|
||||||
|
background-color: var(--cl-prim-bg-60);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-fg-100);
|
||||||
|
background-color: var(--cd-prim-bg-60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-outline, .clr-btn-primary):focus {
|
||||||
|
outline-width: 2px;
|
||||||
|
outline-style: solid;
|
||||||
|
outline-color: var(--cl-prim-bg-100);
|
||||||
|
.dark & {
|
||||||
|
outline-color: var(--cd-prim-bg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-text-primary, .clr-text-url) {
|
||||||
|
color: var(--cl-prim-fg-80);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-prim-fg-80);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clr-footer {
|
||||||
|
color: var(--cl-fg-60);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-fg-60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(.clr-text-controls, .clr-btn-nav, .clr-btn-clear) {
|
||||||
|
color: var(--cl-fg-80);
|
||||||
|
&:disabled {
|
||||||
|
color: var(--cl-fg-60);
|
||||||
|
}
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-fg-80);
|
||||||
|
&:disabled {
|
||||||
|
color: var(--cd-fg-60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clr-warning {
|
||||||
|
background-color: var(--cl-red-bg-100);
|
||||||
|
.dark & {
|
||||||
|
background-color: var(--cd-red-bg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clr-text-default {
|
||||||
|
color: var(--cl-fg-100);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-fg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clr-text-warning {
|
||||||
|
color: var(--cl-red-fg-100);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-red-fg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clr-text-success {
|
||||||
|
color: var(--cl-green-fg-100);
|
||||||
|
.dark & {
|
||||||
|
color: var(--cd-green-fg-100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ import { IEntityReference, ISyntacticReference } from '@/models/language';
|
||||||
import { parseGrammemes } from '@/models/languageAPI';
|
import { parseGrammemes } from '@/models/languageAPI';
|
||||||
import { IConstituenta } from '@/models/rsform';
|
import { IConstituenta } from '@/models/rsform';
|
||||||
|
|
||||||
import { colorFgGrammeme, IColorTheme } from './color';
|
import { colorFgGrammeme, IColorTheme } from '../styling/color';
|
||||||
import { describeConstituentaTerm, labelCstTypification, labelGrammeme } from './labels';
|
import { describeConstituentaTerm, labelCstTypification, labelGrammeme } from './labels';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user