mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 21:10:38 +03:00
F: Rework inline styles and improve animations
This commit is contained in:
parent
26976c806a
commit
8208adab96
|
@ -1,5 +1,6 @@
|
|||
import { Suspense } from 'react';
|
||||
import { Outlet } from 'react-router';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { ModalLoader } from '@/components/modal';
|
||||
import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/app-layout';
|
||||
|
@ -17,7 +18,6 @@ import { Navigation } from './navigation';
|
|||
export function ApplicationLayout() {
|
||||
const mainHeight = useMainHeight();
|
||||
const viewportHeight = useViewportHeight();
|
||||
const showScroll = useAppLayoutStore(state => !state.noScroll);
|
||||
const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation);
|
||||
const noNavigation = useAppLayoutStore(state => state.noNavigation);
|
||||
const noFooter = useAppLayoutStore(state => state.noFooter);
|
||||
|
@ -27,8 +27,7 @@ export function ApplicationLayout() {
|
|||
<NavigationState>
|
||||
<div className='min-w-80 antialiased h-full max-w-480 mx-auto'>
|
||||
<ToasterThemed
|
||||
className='text-[14px]'
|
||||
style={{ marginTop: noNavigationAnimation ? '1.5rem' : '3.5rem' }}
|
||||
className={clsx('text-[14px]/[20px]', noNavigationAnimation ? 'mt-6' : 'mt-14')}
|
||||
autoClose={3000}
|
||||
draggable={false}
|
||||
pauseOnFocusLoss={false}
|
||||
|
@ -46,7 +45,7 @@ export function ApplicationLayout() {
|
|||
style={{ maxHeight: viewportHeight }}
|
||||
inert={activeDialog !== null}
|
||||
>
|
||||
<main className='cc-scroll-y' style={{ overflowY: showScroll ? 'scroll' : 'auto', minHeight: mainHeight }}>
|
||||
<main className='cc-scroll-y overflow-y-auto' style={{ minHeight: mainHeight }}>
|
||||
<GlobalLoader />
|
||||
<MutationErrors />
|
||||
<Outlet />
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import clsx from 'clsx';
|
||||
|
||||
import { IconLibrary2, IconManuals, IconNewItem2 } from '@/components/icons';
|
||||
import { useWindowSize } from '@/hooks/use-window-size';
|
||||
import { useAppLayoutStore } from '@/stores/app-layout';
|
||||
import { PARAMETER } from '@/utils/constants';
|
||||
|
||||
import { urls } from '../urls';
|
||||
|
||||
|
@ -29,14 +30,11 @@ export function Navigation() {
|
|||
<nav className='z-navigation sticky top-0 left-0 right-0 select-none bg-prim-100'>
|
||||
<ToggleNavigation />
|
||||
<div
|
||||
className='pl-2 pr-6 sm:pr-4 h-12 flex cc-shadow-border'
|
||||
style={{
|
||||
transitionProperty: 'max-height, translate',
|
||||
transitionDuration: `${PARAMETER.moveDuration}ms`,
|
||||
transitionTimingFunction: 'ease-in-out',
|
||||
maxHeight: noNavigationAnimation ? '0rem' : '3rem',
|
||||
translate: noNavigationAnimation ? '0 -1.5rem' : '0'
|
||||
}}
|
||||
className={clsx(
|
||||
'pl-2 pr-6 sm:pr-4 h-12 flex cc-shadow-border',
|
||||
'transition-[max-height,translate] ease-bezier duration-(--duration-move)',
|
||||
noNavigationAnimation ? '-translate-y-6 max-h-0' : 'max-h-12'
|
||||
)}
|
||||
>
|
||||
<div className='flex items-center mr-auto cursor-pointer' onClick={!size.isSmall ? navigateHome : undefined}>
|
||||
<Logo />
|
||||
|
|
|
@ -17,12 +17,9 @@ export function Divider({ vertical, margins = 'mx-2', className, ...restProps }:
|
|||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
margins, //
|
||||
className,
|
||||
{
|
||||
'border-x': vertical,
|
||||
'border-y': !vertical
|
||||
}
|
||||
vertical ? 'border-x' : 'border-y', //
|
||||
margins,
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
/>
|
||||
|
|
|
@ -26,7 +26,6 @@ export function Tooltip({
|
|||
layer = 'z-tooltip',
|
||||
place = 'bottom',
|
||||
className,
|
||||
style,
|
||||
...restProps
|
||||
}: TooltipProps) {
|
||||
const darkMode = usePreferencesStore(state => state.darkMode);
|
||||
|
@ -40,6 +39,7 @@ export function Tooltip({
|
|||
opacity={1}
|
||||
className={clsx(
|
||||
'relative',
|
||||
'py-0.5! px-2!',
|
||||
'max-h-[calc(100svh-6rem)]',
|
||||
'overflow-y-auto overflow-x-hidden sm:overflow-hidden overscroll-contain',
|
||||
'border shadow-md',
|
||||
|
@ -48,7 +48,6 @@ export function Tooltip({
|
|||
className
|
||||
)}
|
||||
classNameArrow={layer}
|
||||
style={{ ...{ paddingTop: '2px', paddingBottom: '2px', paddingLeft: '8px', paddingRight: '8px' }, ...style }}
|
||||
variant={darkMode ? 'dark' : 'light'}
|
||||
place={place}
|
||||
{...restProps}
|
||||
|
|
|
@ -43,15 +43,10 @@ export function Button({
|
|||
'inline-flex gap-2 items-center justify-center',
|
||||
'font-medium select-none disabled:cursor-auto',
|
||||
'clr-btn-default cc-animate-color',
|
||||
{
|
||||
'border rounded-sm': !noBorder,
|
||||
'px-1': dense,
|
||||
'px-3 py-1': !dense,
|
||||
'cursor-progress': loading,
|
||||
'cursor-pointer': !loading,
|
||||
'outline-hidden': noOutline,
|
||||
'clr-outline': !noOutline
|
||||
},
|
||||
dense ? 'px-1' : 'px-3 py-1',
|
||||
loading ? 'cursor-progress' : 'cursor-pointer',
|
||||
noOutline ? 'outline-hidden' : 'clr-outline',
|
||||
!noBorder && 'border rounded-sm',
|
||||
className
|
||||
)}
|
||||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
|
|
|
@ -41,11 +41,8 @@ export function MiniButton({
|
|||
'rounded-lg',
|
||||
'clr-text-controls cc-animate-color',
|
||||
'cursor-pointer disabled:cursor-auto',
|
||||
{
|
||||
'px-1 py-1': !noPadding,
|
||||
'outline-hidden': noHover,
|
||||
'clr-hover': !noHover
|
||||
},
|
||||
noHover ? 'outline-hidden' : 'clr-hover',
|
||||
!noPadding && 'px-1 py-1',
|
||||
className
|
||||
)}
|
||||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
|
|
|
@ -38,10 +38,7 @@ export function SelectorButton({
|
|||
'text-btn clr-text-controls',
|
||||
'disabled:cursor-auto cursor-pointer',
|
||||
'cc-animate-color',
|
||||
{
|
||||
'clr-hover': transparent,
|
||||
'clr-btn-default border': !transparent
|
||||
},
|
||||
transparent ? 'clr-hover' : 'clr-btn-default border',
|
||||
className
|
||||
)}
|
||||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
|
|
|
@ -120,15 +120,15 @@ export function DataTable<TData extends RowData>({
|
|||
onRowDoubleClicked,
|
||||
noDataComponent,
|
||||
|
||||
paginationPerPage,
|
||||
paginationOptions = [10, 20, 30, 40, 50],
|
||||
|
||||
...restProps
|
||||
}: DataTableProps<TData>) {
|
||||
const [lastSelected, setLastSelected] = useState<string | null>(null);
|
||||
|
||||
const table = useDataTable({ ...restProps });
|
||||
const table = useDataTable({ paginationPerPage, ...restProps });
|
||||
|
||||
const isPaginationEnabled = typeof table.getCanNextPage === 'function';
|
||||
const isEmpty = table.getRowModel().rows.length === 0;
|
||||
|
||||
const fixedSize = useMemo(() => {
|
||||
|
@ -178,7 +178,7 @@ export function DataTable<TData extends RowData>({
|
|||
{!noFooter ? <TableFooter table={table} /> : null}
|
||||
</table>
|
||||
|
||||
{isPaginationEnabled && !isEmpty ? (
|
||||
{!!paginationPerPage && !isEmpty ? (
|
||||
<PaginationTools
|
||||
id={id ? `${id}__pagination` : undefined}
|
||||
table={table}
|
||||
|
|
|
@ -93,11 +93,12 @@ export function TableBody<TData>({
|
|||
{row.getVisibleCells().map((cell: Cell<TData, unknown>) => (
|
||||
<td
|
||||
key={cell.id}
|
||||
className='px-2 align-middle border-y'
|
||||
className={clsx(
|
||||
'px-2 align-middle border-y',
|
||||
dense ? 'py-1' : 'py-2',
|
||||
onRowClicked || onRowDoubleClicked ? 'cursor-pointer' : 'cursor-auto'
|
||||
)}
|
||||
style={{
|
||||
cursor: onRowClicked || onRowDoubleClicked ? 'pointer' : 'auto',
|
||||
paddingBottom: dense ? '0.25rem' : '0.5rem',
|
||||
paddingTop: dense ? '0.25rem' : '0.5rem',
|
||||
width: noHeader && index === 0 ? `calc(var(--col-${cell.column.id}-size) * 1px)` : undefined
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
'use no memo';
|
||||
|
||||
import { flexRender, type Header, type HeaderGroup, type Table } from '@tanstack/react-table';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { SelectAll } from './select-all';
|
||||
import { SortingIcon } from './sorting-icon';
|
||||
|
@ -13,13 +14,7 @@ interface TableHeaderProps<TData> {
|
|||
|
||||
export function TableHeader<TData>({ table, headPosition, resetLastSelected }: TableHeaderProps<TData>) {
|
||||
return (
|
||||
<thead
|
||||
className='bg-prim-100 cc-shadow-border'
|
||||
style={{
|
||||
top: headPosition,
|
||||
position: 'sticky'
|
||||
}}
|
||||
>
|
||||
<thead className='sticky bg-prim-100 cc-shadow-border' style={{ top: headPosition }}>
|
||||
{table.getHeaderGroups().map((headerGroup: HeaderGroup<TData>) => (
|
||||
<tr key={headerGroup.id}>
|
||||
{table.options.enableRowSelection ? (
|
||||
|
@ -32,11 +27,11 @@ export function TableHeader<TData>({ table, headPosition, resetLastSelected }: T
|
|||
key={header.id}
|
||||
colSpan={header.colSpan}
|
||||
scope='col'
|
||||
className='cc-table-header group'
|
||||
style={{
|
||||
width: `calc(var(--header-${header?.id}-size) * 1px)`,
|
||||
cursor: table.options.enableSorting && header.column.getCanSort() ? 'pointer' : 'auto'
|
||||
}}
|
||||
className={clsx(
|
||||
'cc-table-header group',
|
||||
table.options.enableSorting && header.column.getCanSort() ? 'cursor-pointer' : 'cursor-auto'
|
||||
)}
|
||||
style={{ width: `calc(var(--header-${header?.id}-size) * 1px)` }}
|
||||
onClick={table.options.enableSorting ? header.column.getToggleSortingHandler() : undefined}
|
||||
>
|
||||
{!header.isPlaceholder ? (
|
||||
|
|
|
@ -39,11 +39,7 @@ export function DropdownButton({
|
|||
'text-left text-sm text-ellipsis whitespace-nowrap',
|
||||
'disabled:clr-text-controls',
|
||||
'cc-animate-color',
|
||||
{
|
||||
'clr-hover': onClick,
|
||||
'cursor-pointer disabled:cursor-auto': onClick,
|
||||
'cursor-default': !onClick
|
||||
},
|
||||
!!onClick ? 'clr-hover cursor-pointer disabled:cursor-auto' : 'clr-btn-default',
|
||||
className
|
||||
)}
|
||||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { PARAMETER } from '@/utils/constants';
|
||||
|
||||
import { type Styling } from '../props';
|
||||
|
||||
interface DropdownProps extends Styling {
|
||||
|
@ -36,36 +34,19 @@ export function Dropdown({
|
|||
margin,
|
||||
className,
|
||||
children,
|
||||
style,
|
||||
...restProps
|
||||
}: React.PropsWithChildren<DropdownProps>) {
|
||||
return (
|
||||
<div
|
||||
tabIndex={-1}
|
||||
className={clsx(
|
||||
'z-topmost absolute',
|
||||
{
|
||||
'right-0': stretchLeft,
|
||||
'left-0': !stretchLeft,
|
||||
'bottom-0': stretchTop,
|
||||
'top-full': !stretchTop
|
||||
},
|
||||
'grid',
|
||||
'border rounded-md shadow-lg',
|
||||
'clr-input',
|
||||
'text-sm',
|
||||
'cc-dropdown isolate z-topmost absolute grid bg-prim-0 border rounded-md shadow-lg text-sm',
|
||||
stretchLeft ? 'right-0' : 'left-0',
|
||||
stretchTop ? 'bottom-0' : 'top-full',
|
||||
isOpen && 'open',
|
||||
margin,
|
||||
className
|
||||
)}
|
||||
style={{
|
||||
willChange: 'clip-path, transform',
|
||||
transitionProperty: 'clip-path, transform',
|
||||
transitionDuration: `${PARAMETER.dropdownDuration}ms`,
|
||||
transitionTimingFunction: 'ease-in-out',
|
||||
transform: isOpen ? 'translateY(0)' : 'translateY(-10%)',
|
||||
clipPath: isOpen ? 'inset(0% 0% 0% 0%)' : 'inset(10% 0% 90% 0%)',
|
||||
...style
|
||||
}}
|
||||
aria-hidden={!isOpen}
|
||||
{...restProps}
|
||||
>
|
||||
|
|
|
@ -33,18 +33,7 @@ export function DescribeError({ error }: { error: ErrorData }) {
|
|||
<p>
|
||||
<b>Message:</b> {error.message}
|
||||
</p>
|
||||
{error.stack && (
|
||||
<pre
|
||||
style={{
|
||||
whiteSpace: 'pre-wrap',
|
||||
wordWrap: 'break-word',
|
||||
padding: '6px',
|
||||
overflowX: 'auto'
|
||||
}}
|
||||
>
|
||||
{error.stack}
|
||||
</pre>
|
||||
)}
|
||||
{error.stack && <pre className='whitespace-pre-wrap p-2 overflow-x-auto break-words'>{error.stack}</pre>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -67,10 +67,7 @@ export function CheckboxTristate({
|
|||
className={clsx(
|
||||
'w-4 h-4', //
|
||||
'border rounded-sm',
|
||||
{
|
||||
'bg-sec-600 text-sec-0': value !== false,
|
||||
'bg-prim-100': value === false
|
||||
}
|
||||
value === false ? 'bg-prim-100' : 'bg-sec-600 text-sec-0'
|
||||
)}
|
||||
>
|
||||
{value ? <CheckboxChecked /> : null}
|
||||
|
|
|
@ -66,10 +66,7 @@ export function Checkbox({
|
|||
className={clsx(
|
||||
'w-4 h-4', //
|
||||
'border rounded-sm',
|
||||
{
|
||||
'bg-sec-600 text-sec-0': value !== false,
|
||||
'bg-prim-100': value === false
|
||||
}
|
||||
value === false ? 'bg-prim-100' : 'bg-sec-600 text-sec-0'
|
||||
)}
|
||||
>
|
||||
{value ? <CheckboxChecked /> : null}
|
||||
|
|
|
@ -46,7 +46,7 @@ export function FileInput({ id, label, acceptType, title, className, style, onCh
|
|||
id={id}
|
||||
type='file'
|
||||
ref={inputRef}
|
||||
style={{ display: 'none' }}
|
||||
className='hidden'
|
||||
accept={acceptType}
|
||||
onChange={handleFileChange}
|
||||
{...restProps}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { globalIDs, PARAMETER } from '@/utils/constants';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
|
||||
import { MiniButton } from '../control';
|
||||
import { IconDropArrow, IconPageRight } from '../icons';
|
||||
|
@ -89,27 +89,13 @@ export function SelectTree<ItemType>({
|
|||
<div
|
||||
key={`${prefix}${index}`}
|
||||
className={clsx(
|
||||
'relative',
|
||||
'pr-3 pl-6 border-b',
|
||||
'cc-scroll-row',
|
||||
'bg-prim-200 clr-hover cc-animate-color',
|
||||
'cursor-pointer',
|
||||
value === item && 'clr-selected',
|
||||
!isActive && 'pointer-events-none'
|
||||
'cc-tree-item relative cc-scroll-row clr-hover',
|
||||
isActive ? 'max-h-7 py-1 border-b' : 'max-h-0 opacity-0 pointer-events-none',
|
||||
value === item && 'clr-selected'
|
||||
)}
|
||||
data-tooltip-id={globalIDs.tooltip}
|
||||
data-tooltip-html={getDescription(item)}
|
||||
onClick={event => handleClickItem(event, item)}
|
||||
style={{
|
||||
borderBottomWidth: isActive ? '1px' : '0px',
|
||||
willChange: 'max-height, opacity, padding',
|
||||
transitionProperty: 'max-height, opacity, padding',
|
||||
transitionDuration: `${PARAMETER.moveDuration}ms`,
|
||||
paddingTop: isActive ? '0.25rem' : '0',
|
||||
paddingBottom: isActive ? '0.25rem' : '0',
|
||||
maxHeight: isActive ? '1.75rem' : '0',
|
||||
opacity: isActive ? '1' : '0'
|
||||
}}
|
||||
>
|
||||
{foldable.has(item) ? (
|
||||
<MiniButton
|
||||
|
|
|
@ -40,11 +40,8 @@ export function TextArea({
|
|||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'w-full',
|
||||
{
|
||||
'flex flex-col': !dense,
|
||||
'flex grow items-center gap-3': dense
|
||||
},
|
||||
'w-full', //
|
||||
dense ? 'flex grow items-center gap-3' : 'flex flex-col',
|
||||
dense && className
|
||||
)}
|
||||
>
|
||||
|
@ -55,16 +52,13 @@ export function TextArea({
|
|||
'px-3 py-2',
|
||||
'leading-tight',
|
||||
'overflow-x-hidden overflow-y-auto',
|
||||
{
|
||||
'field-sizing-content': fitContent,
|
||||
'resize-none': noResize,
|
||||
'border': !noBorder,
|
||||
'grow max-w-full': dense,
|
||||
'mt-2': !dense && !!label,
|
||||
'clr-outline': !noOutline,
|
||||
'bg-transparent': transparent,
|
||||
'clr-input': !transparent
|
||||
},
|
||||
!noBorder && 'border',
|
||||
fitContent && 'field-sizing-content',
|
||||
noResize && 'resize-none',
|
||||
transparent ? 'bg-transparent' : 'clr-input',
|
||||
!noOutline && 'clr-outline',
|
||||
dense && 'grow max-w-full',
|
||||
!dense && !!label && 'mt-2',
|
||||
!dense && className
|
||||
)}
|
||||
rows={rows}
|
||||
|
|
|
@ -42,10 +42,7 @@ export function TextInput({
|
|||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
{
|
||||
'flex flex-col': !dense,
|
||||
'flex items-center gap-3': dense
|
||||
},
|
||||
dense ? 'flex items-center gap-3' : 'flex flex-col', //
|
||||
dense && className
|
||||
)}
|
||||
>
|
||||
|
@ -55,15 +52,12 @@ export function TextInput({
|
|||
className={clsx(
|
||||
'min-w-0 py-2',
|
||||
'leading-tight truncate hover:text-clip',
|
||||
{
|
||||
'px-3': !noBorder || !disabled,
|
||||
'grow max-w-full': dense,
|
||||
'mt-2': !dense && !!label,
|
||||
'border': !noBorder,
|
||||
'clr-outline': !noOutline,
|
||||
'bg-transparent': transparent,
|
||||
'clr-input': !transparent
|
||||
},
|
||||
transparent ? 'bg-transparent' : 'clr-input',
|
||||
!noBorder && 'border',
|
||||
!noOutline && 'clr-outline',
|
||||
(!noBorder || !disabled) && 'px-3',
|
||||
dense && 'grow max-w-full',
|
||||
!dense && !!label && 'mt-2',
|
||||
!dense && className
|
||||
)}
|
||||
onKeyDown={!allowEnter && !onKeyDown ? preventEnterCapture : onKeyDown}
|
||||
|
|
|
@ -124,10 +124,7 @@ export function ModalForm({
|
|||
'@container/modal',
|
||||
'max-h-[calc(100svh-8rem)] max-w-[100svw] xs:max-w-[calc(100svw-2rem)]',
|
||||
'overscroll-contain outline-hidden',
|
||||
{
|
||||
'overflow-auto': !overflowVisible,
|
||||
'overflow-visible': overflowVisible
|
||||
},
|
||||
overflowVisible ? 'overflow-visible' : 'overflow-auto',
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
|
|
|
@ -61,7 +61,7 @@ export function ModalView({
|
|||
<h1
|
||||
className={clsx(
|
||||
'px-12 py-2 select-none',
|
||||
fullScreen && 'z-pop absolute top-0 right-1/2 translate-x-1/2 cc-blur bg-prim-100/90 rounded-2xl'
|
||||
fullScreen && 'z-pop absolute top-0 right-1/2 translate-x-1/2 backdrop-blur-xs bg-prim-100/90 rounded-2xl'
|
||||
)}
|
||||
>
|
||||
{header}
|
||||
|
@ -73,10 +73,7 @@ export function ModalView({
|
|||
'@container/modal',
|
||||
'max-h-[calc(100svh-8rem)] max-w-[100svw] xs:max-w-[calc(100svw-2rem)]',
|
||||
'overscroll-contain outline-hidden',
|
||||
{
|
||||
'overflow-auto': !overflowVisible,
|
||||
'overflow-visible': overflowVisible
|
||||
},
|
||||
overflowVisible ? 'overflow-visible' : 'overflow-auto',
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
|
@ -90,12 +87,12 @@ export function ModalView({
|
|||
aria-label='Закрыть'
|
||||
className={clsx(
|
||||
'my-2 mx-auto text-sm min-w-28',
|
||||
fullScreen && 'z-pop absolute bottom-0 right-1/2 translate-x-1/2 cc-blur'
|
||||
fullScreen && 'z-pop absolute bottom-0 right-1/2 translate-x-1/2'
|
||||
)}
|
||||
onClick={hideDialog}
|
||||
/>
|
||||
) : (
|
||||
<div className='z-pop absolute bottom-0 right-1/2 translate-x-1/2 bg-prim-100/90 cc-blur p-3 rounded-xl'>
|
||||
<div className='z-pop absolute bottom-0 right-1/2 translate-x-1/2 p-3 rounded-xl bg-prim-100/90 backdrop-blur-xs'>
|
||||
{' '}
|
||||
<Button text='Закрыть' aria-label='Закрыть' className='text-sm min-w-28' onClick={hideDialog} />
|
||||
</div>
|
||||
|
|
|
@ -18,9 +18,8 @@ export function EmbedYoutube({ videoID, pxHeight, pxWidth }: EmbedYoutubeProps)
|
|||
}
|
||||
return (
|
||||
<div
|
||||
className='relative'
|
||||
className='relative h-0'
|
||||
style={{
|
||||
height: 0,
|
||||
paddingBottom: `${pxHeight}px`,
|
||||
paddingLeft: `${pxWidth}px`
|
||||
}}
|
||||
|
|
|
@ -18,11 +18,9 @@ export function Indicator({ icon, title, titleHtml, hideTitle, noPadding, classN
|
|||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'clr-text-controls',
|
||||
'clr-text-controls', //
|
||||
'outline-hidden',
|
||||
{
|
||||
'px-1 py-1': !noPadding
|
||||
},
|
||||
!noPadding && 'px-1 py-1',
|
||||
className
|
||||
)}
|
||||
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}
|
||||
|
|
|
@ -57,7 +57,7 @@ export function ValueIcon({
|
|||
'flex items-center',
|
||||
'text-right',
|
||||
'hover:cursor-default',
|
||||
{ 'justify-between gap-6': !dense, 'gap-1': dense },
|
||||
dense ? 'gap-1' : 'justify-between gap-6',
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
|
|
|
@ -7,7 +7,6 @@ import { IconHelp } from '@/components/icons';
|
|||
import { Loader } from '@/components/loader';
|
||||
import { type Styling } from '@/components/props';
|
||||
import { usePreferencesStore } from '@/stores/preferences';
|
||||
import { PARAMETER } from '@/utils/constants';
|
||||
|
||||
import { type HelpTopic } from '../models/help-topic';
|
||||
|
||||
|
@ -48,7 +47,7 @@ export function BadgeHelp({ topic, padding = 'p-1', className, contentClass, sty
|
|||
clickable
|
||||
anchorSelect={`#help-${topic}`}
|
||||
layer='z-topmost'
|
||||
className={clsx(PARAMETER.TOOLTIP_WIDTH, contentClass)}
|
||||
className={clsx('max-w-120', contentClass)}
|
||||
{...restProps}
|
||||
>
|
||||
<Suspense fallback={<Loader />}>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { APP_COLORS } from '@/styling/colors';
|
||||
|
||||
export function HelpFormulaTree() {
|
||||
return (
|
||||
<div>
|
||||
|
@ -12,22 +10,22 @@ export function HelpFormulaTree() {
|
|||
|
||||
<h2>Виды узлов</h2>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgGreen }}>объявление идентификатора</span>
|
||||
<span className='bg-(--acc-bg-green)'>объявление идентификатора</span>
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgTeal }}>глобальный идентификатор</span>
|
||||
<span className='bg-(--acc-bg-teal)'>глобальный идентификатор</span>
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgOrange }}>логическое выражение</span>
|
||||
<span className='bg-(--acc-bg-orange)'>логическое выражение</span>
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgBlue }}>типизированное выражение</span>
|
||||
<span className='bg-(--acc-bg-blue)'>типизированное выражение</span>
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgRed }}>присвоение и итерация</span>
|
||||
<span className='bg-(--acc-bg-red)'>присвоение и итерация</span>
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgDisabled }}>составные выражения</span>
|
||||
<span className='bg-prim-300'>составные выражения</span>
|
||||
</li>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
IconSubfolders,
|
||||
IconUserSearch
|
||||
} from '@/components/icons';
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
|
||||
import { LinkTopic } from '../../components/link-topic';
|
||||
import { HelpTopic } from '../../models/help-topic';
|
||||
|
@ -33,7 +32,7 @@ export function HelpLibrary() {
|
|||
</p>
|
||||
|
||||
<li>
|
||||
<span style={{ color: APP_COLORS.fgGreen }}>зеленым текстом</span> выделены ОСС
|
||||
<span className='text-(--acc-fg-green)'>зеленым текстом</span> выделены ОСС
|
||||
</li>
|
||||
<li>клик по строке - переход к редактированию схемы</li>
|
||||
<li>Ctrl + клик по строке откроет схему в новой вкладке</li>
|
||||
|
|
|
@ -18,7 +18,6 @@ import {
|
|||
IconTree,
|
||||
IconTypeGraph
|
||||
} from '@/components/icons';
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
|
||||
import { LinkTopic } from '../../components/link-topic';
|
||||
import { HelpTopic } from '../../models/help-topic';
|
||||
|
@ -69,15 +68,15 @@ export function HelpRSEditor() {
|
|||
<IconChild className='inline-icon' /> отображение наследованных
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgSelected }}>текущая конституента</span>
|
||||
<span className='bg-sec-200'>текущая конституента</span>
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgGreen50 }}>
|
||||
<span className='bg-(--acc-bg-green50)'>
|
||||
<LinkTopic text='основа' topic={HelpTopic.CC_RELATIONS} /> текущей
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgOrange50 }}>
|
||||
<span className='bg-(--acc-bg-orange50)'>
|
||||
<LinkTopic text='порожденные' topic={HelpTopic.CC_RELATIONS} /> текущей
|
||||
</span>
|
||||
</li>
|
||||
|
|
|
@ -19,7 +19,6 @@ import {
|
|||
IconText,
|
||||
IconTypeGraph
|
||||
} from '@/components/icons';
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
|
||||
import { LinkTopic } from '../../components/link-topic';
|
||||
import { HelpTopic } from '../../models/help-topic';
|
||||
|
@ -49,7 +48,7 @@ export function HelpRSGraphTerm() {
|
|||
<h1>Изменение узлов</h1>
|
||||
<li>Клик на узел – выделение</li>
|
||||
<li>
|
||||
Левый клик – выбор <span style={{ color: APP_COLORS.fgPurple }}>фокус-конституенты</span>
|
||||
Левый клик – выбор <span className='text-(--acc-fg-purple)'>фокус-конституенты</span>
|
||||
</li>
|
||||
<li>
|
||||
<IconReset className='inline-icon' /> Esc – сбросить выделение
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { APP_COLORS } from '@/styling/colors';
|
||||
|
||||
import { LinkTopic } from '../../components/link-topic';
|
||||
import { HelpTopic } from '../../models/help-topic';
|
||||
|
||||
|
@ -21,13 +19,13 @@ export function HelpTypeGraph() {
|
|||
|
||||
<h2>Виды узлов</h2>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgControls }}>ступень-основание</span>
|
||||
<span className='bg-prim-200'>ступень-основание</span>
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgTeal }}>ступень-булеан</span>
|
||||
<span className='bg-(--acc-bg-teal)'>ступень-булеан</span>
|
||||
</li>
|
||||
<li>
|
||||
<span style={{ backgroundColor: APP_COLORS.bgOrange }}>ступень декартова произведения</span>
|
||||
<span className='bg-(--acc-bg-orange)'>ступень декартова произведения</span>
|
||||
</li>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -7,7 +7,7 @@ import { useDropdown } from '@/components/dropdown';
|
|||
import { IconMenuFold, IconMenuUnfold } from '@/components/icons';
|
||||
import { SelectTree } from '@/components/input';
|
||||
import { useAppLayoutStore, useFitHeight } from '@/stores/app-layout';
|
||||
import { PARAMETER, prefixes } from '@/utils/constants';
|
||||
import { prefixes } from '@/utils/constants';
|
||||
|
||||
import { describeHelpTopic, labelHelpTopic } from '../../labels';
|
||||
import { HelpTopic, topicParent } from '../../models/help-topic';
|
||||
|
@ -32,14 +32,11 @@ export function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownPro
|
|||
ref={menu.ref}
|
||||
className={clsx(
|
||||
'absolute left-0 w-54', //
|
||||
noNavigation ? 'top-0' : 'top-12',
|
||||
'flex flex-col',
|
||||
'z-topmost',
|
||||
'text-xs sm:text-sm',
|
||||
'select-none',
|
||||
{
|
||||
'top-0': noNavigation,
|
||||
'top-12': !noNavigation
|
||||
}
|
||||
'select-none'
|
||||
)}
|
||||
>
|
||||
<Button
|
||||
|
@ -59,14 +56,11 @@ export function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownPro
|
|||
getParent={item => topicParent.get(item) ?? item}
|
||||
getLabel={labelHelpTopic}
|
||||
getDescription={describeHelpTopic}
|
||||
className='border-r border-t rounded-none cc-scroll-y bg-prim-200'
|
||||
style={{
|
||||
maxHeight: treeHeight,
|
||||
willChange: 'clip-path',
|
||||
transitionProperty: 'clip-path',
|
||||
transitionDuration: `${PARAMETER.moveDuration}ms`,
|
||||
clipPath: menu.isOpen ? 'inset(0% 0% 0% 0%)' : 'inset(0% 100% 0% 0%)'
|
||||
}}
|
||||
className={clsx(
|
||||
'cc-topic-dropdown border-r border-t rounded-none cc-scroll-y bg-prim-200',
|
||||
menu.isOpen && 'open'
|
||||
)}
|
||||
style={{ maxHeight: treeHeight }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -113,7 +113,8 @@ export function FormCreateItem() {
|
|||
id='schema_file'
|
||||
ref={inputRef}
|
||||
type='file'
|
||||
style={{ display: 'none' }}
|
||||
aria-hidden
|
||||
className='hidden'
|
||||
accept={EXTEOR_TRS_FILE}
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
|
|
|
@ -60,7 +60,7 @@ export function TableLibraryItems({ items }: TableLibraryItemsProps) {
|
|||
columns={columns}
|
||||
data={items}
|
||||
headPosition='0'
|
||||
className={clsx('cc-scroll-y h-fit text-xs sm:text-sm border-b', { 'border-l': folderMode })}
|
||||
className={clsx('cc-scroll-y h-fit text-xs sm:text-sm border-b', folderMode && 'border-l')}
|
||||
style={{ maxHeight: tableHeight }}
|
||||
noDataComponent={
|
||||
<div className='cc-column dense p-3 items-center min-h-24'>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { toast } from 'react-toastify';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { useAuthSuspense } from '@/features/auth';
|
||||
import { HelpTopic } from '@/features/help';
|
||||
|
@ -6,9 +7,8 @@ import { BadgeHelp } from '@/features/help/components';
|
|||
|
||||
import { MiniButton } from '@/components/control';
|
||||
import { IconFolderEdit, IconFolderTree } from '@/components/icons';
|
||||
import { useWindowSize } from '@/hooks/use-window-size';
|
||||
import { useFitHeight } from '@/stores/app-layout';
|
||||
import { PARAMETER, prefixes } from '@/utils/constants';
|
||||
import { prefixes } from '@/utils/constants';
|
||||
import { infoMsg } from '@/utils/labels';
|
||||
|
||||
import { useLibrary } from '../../backend/use-library';
|
||||
|
@ -25,7 +25,6 @@ interface ViewSideLocationProps {
|
|||
export function ViewSideLocation({ isVisible, onRenameLocation }: ViewSideLocationProps) {
|
||||
const { user, isAnonymous } = useAuthSuspense();
|
||||
const { items } = useLibrary();
|
||||
const { isSmall } = useWindowSize();
|
||||
|
||||
const location = useLibrarySearchStore(state => state.location);
|
||||
const setLocation = useLibrarySearchStore(state => state.setLocation);
|
||||
|
@ -62,15 +61,10 @@ export function ViewSideLocation({ isVisible, onRenameLocation }: ViewSideLocati
|
|||
|
||||
return (
|
||||
<div
|
||||
className='max-w-40 sm:max-w-60 flex flex-col text:xs sm:text-sm select-none'
|
||||
style={{
|
||||
transitionProperty: 'width, min-width, opacity',
|
||||
transitionDuration: `${PARAMETER.moveDuration}ms`,
|
||||
transitionTimingFunction: 'ease-out',
|
||||
minWidth: isVisible ? (isSmall ? '10rem' : '15rem') : '0',
|
||||
width: isVisible ? '100%' : '0',
|
||||
opacity: isVisible ? 1 : 0
|
||||
}}
|
||||
className={clsx(
|
||||
'max-w-40 sm:max-w-60 flex flex-col text:xs sm:text-sm select-none cc-side-location',
|
||||
isVisible && 'open min-w-[10rem] sm:min-w-[15rem]'
|
||||
)}
|
||||
>
|
||||
<div className='h-8 flex justify-between items-center pr-1 pl-0.5'>
|
||||
<BadgeHelp topic={HelpTopic.UI_LIBRARY} contentClass='text-sm' offset={5} place='right-start' />
|
||||
|
|
|
@ -74,7 +74,7 @@ export function InfoOperation({ operation }: InfoOperationProps) {
|
|||
dense
|
||||
noHeader
|
||||
noFooter
|
||||
className='text-sm border select-none mb-2'
|
||||
className='text-sm border-x select-none mb-2'
|
||||
data={operation.substitutions}
|
||||
columns={columns}
|
||||
/>
|
||||
|
|
|
@ -12,8 +12,7 @@ export function OperationTooltip() {
|
|||
clickable
|
||||
id={globalIDs.operation_tooltip}
|
||||
layer='z-topmost'
|
||||
className='max-w-140 dense'
|
||||
style={{ maxHeight: '30rem', overflowY: 'auto' }}
|
||||
className='max-w-140 dense max-h-120! overflow-y-auto!'
|
||||
hidden={!hoverOperation}
|
||||
>
|
||||
{hoverOperation ? <InfoOperation operation={hoverOperation} /> : null}
|
||||
|
|
|
@ -107,10 +107,7 @@ export function PickMultiOperation({ rows, items, value, onChange, className, ..
|
|||
];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx('flex flex-col gap-1', ' border-t border-x rounded-md', 'clr-input', className)}
|
||||
{...restProps}
|
||||
>
|
||||
<div className={clsx('flex flex-col gap-1 border-t border-x rounded-md clr-input', className)} {...restProps}>
|
||||
<SelectOperation
|
||||
noBorder
|
||||
items={nonSelectedItems} //
|
||||
|
|
|
@ -7,7 +7,6 @@ import { PickSubstitutions } from '@/features/rsform/components';
|
|||
|
||||
import { TextArea } from '@/components/input';
|
||||
import { useDialogsStore } from '@/stores/dialogs';
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
|
||||
import { type IOperationUpdateDTO } from '../../backend/types';
|
||||
import { SubstitutionValidator } from '../../models/oss-api';
|
||||
|
@ -45,12 +44,7 @@ export function TabSynthesis() {
|
|||
)}
|
||||
/>
|
||||
|
||||
<TextArea
|
||||
disabled
|
||||
value={validator.msg}
|
||||
rows={4}
|
||||
style={{ borderColor: isCorrect ? undefined : APP_COLORS.fgRed, borderWidth: isCorrect ? undefined : '2px' }}
|
||||
/>
|
||||
<TextArea disabled value={validator.msg} rows={4} className={isCorrect ? '' : 'border-(--acc-fg-red) border-2'} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { IconConsolidation, IconRSForm } from '@/components/icons';
|
||||
import { Indicator } from '@/components/view';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
|
@ -52,13 +54,10 @@ export function NodeCore({ node }: NodeCoreProps) {
|
|||
) : null}
|
||||
|
||||
<div
|
||||
className='text-center line-clamp-2'
|
||||
style={{
|
||||
fontSize: longLabel ? '12px' : '14px',
|
||||
lineHeight: longLabel ? '16px' : '20px',
|
||||
paddingLeft: '4px',
|
||||
paddingRight: longLabel ? '10px' : '4px'
|
||||
}}
|
||||
className={clsx(
|
||||
'text-center line-clamp-2 pl-[4px]',
|
||||
longLabel ? 'text-[12px]/[16px] pr-[10px]' : 'text-[14px]/[20px] pr-[4px]'
|
||||
)}
|
||||
>
|
||||
{node.data.label}
|
||||
</div>
|
||||
|
|
|
@ -131,8 +131,7 @@ export function ToolbarOssGraph({
|
|||
className={clsx(
|
||||
'flex flex-col items-center pt-1',
|
||||
'rounded-b-2xl',
|
||||
'cc-blur',
|
||||
'hover:bg-prim-100 hover:bg-opacity-50',
|
||||
'hover:bg-prim-100 hover:bg-opacity-50 backdrop-blur-xs',
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { APP_COLORS } from '@/styling/colors';
|
||||
|
||||
import { colorFgGrammeme } from '../colors';
|
||||
import { labelGrammeme } from '../labels';
|
||||
import { type GramData } from '../models/language';
|
||||
|
@ -15,11 +13,10 @@ interface BadgeGrammemeProps {
|
|||
export function BadgeGrammeme({ grammeme }: BadgeGrammemeProps) {
|
||||
return (
|
||||
<div
|
||||
className='min-w-12 px-1 border rounded-md text-sm font-medium text-center whitespace-nowrap'
|
||||
className='min-w-12 px-1 border rounded-md text-sm font-medium text-center whitespace-nowrap bg-prim-0'
|
||||
style={{
|
||||
borderColor: colorFgGrammeme(grammeme),
|
||||
color: colorFgGrammeme(grammeme),
|
||||
backgroundColor: APP_COLORS.bgInput
|
||||
color: colorFgGrammeme(grammeme)
|
||||
}}
|
||||
>
|
||||
{labelGrammeme(grammeme)}
|
||||
|
|
|
@ -98,7 +98,7 @@ export function PickMultiConstituenta({
|
|||
];
|
||||
|
||||
return (
|
||||
<div className={clsx(noBorder ? '' : 'border', className)} {...restProps}>
|
||||
<div className={clsx(!noBorder && 'border', className)} {...restProps}>
|
||||
<div className='px-3 flex justify-between items-center clr-input border-b rounded-t-md'>
|
||||
<div className='w-[24ch] select-none whitespace-nowrap'>
|
||||
{items.length > 0 ? `Выбраны ${value.length} из ${items.length}` : 'Конституенты'}
|
||||
|
|
|
@ -35,7 +35,7 @@ export function DlgShowAST() {
|
|||
className={clsx(
|
||||
'absolute z-pop top-2 right-1/2 translate-x-1/2 max-w-[60ch]',
|
||||
'px-2 rounded-2xl',
|
||||
'cc-blur bg-prim-100/90',
|
||||
'backdrop-blur-xs bg-prim-100/90',
|
||||
'text-lg text-center'
|
||||
)}
|
||||
>
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
'use client';
|
||||
|
||||
import { Handle, Position } from 'reactflow';
|
||||
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { colorBgSyntaxTree } from '../../../colors';
|
||||
import { labelSyntaxTree } from '../../../labels';
|
||||
import { type ISyntaxTreeNode } from '../../../models/rslang';
|
||||
|
||||
const FONT_SIZE_MAX = 14;
|
||||
const FONT_SIZE_MED = 12;
|
||||
|
||||
const LABEL_THRESHOLD = 3;
|
||||
|
||||
/**
|
||||
|
@ -30,24 +26,20 @@ export function ASTNode(node: ASTNodeInternal) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Handle type='target' position={Position.Top} style={{ opacity: 0 }} />
|
||||
<Handle type='target' position={Position.Top} className='opacity-0' />
|
||||
<div
|
||||
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
|
||||
style={{ backgroundColor: colorBgSyntaxTree(node.data) }}
|
||||
/>
|
||||
<Handle type='source' position={Position.Bottom} style={{ opacity: 0 }} />
|
||||
<Handle type='source' position={Position.Bottom} className='opacity-0' />
|
||||
<div
|
||||
className='font-math mt-1 w-fit text-center translate-x-[calc(-50%+20px)]'
|
||||
style={{ fontSize: label.length > LABEL_THRESHOLD ? FONT_SIZE_MED : FONT_SIZE_MAX }}
|
||||
className={clsx(
|
||||
'font-math mt-1 w-fit text-center translate-x-[calc(-50%+20px)]',
|
||||
label.length > LABEL_THRESHOLD ? 'text-[12px]/[16px]' : 'text-[14px]/[20px]'
|
||||
)}
|
||||
>
|
||||
<div className='absolute top-0 left-0 text-center w-full'>{label}</div>
|
||||
<div
|
||||
aria-hidden='true'
|
||||
style={{
|
||||
WebkitTextStrokeWidth: 2,
|
||||
WebkitTextStrokeColor: APP_COLORS.bgDefault
|
||||
}}
|
||||
>
|
||||
<div aria-hidden className='cc-ast-label-outline'>
|
||||
{label}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import { Handle, Position } from 'reactflow';
|
||||
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
|
||||
import { colorBgTMGraphNode } from '../../../colors';
|
||||
|
@ -26,21 +25,16 @@ export function MGraphNode(node: MGraphNodeInternal) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Handle type='source' position={Position.Top} style={{ opacity: 0 }} />
|
||||
<Handle type='source' position={Position.Top} className='opacity-0' />
|
||||
<div
|
||||
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
|
||||
className='cc-node-label w-full h-full cursor-default flex items-center justify-center rounded-full'
|
||||
data-tooltip-id={globalIDs.tooltip}
|
||||
data-tooltip-html={tooltipText}
|
||||
style={{
|
||||
backgroundColor: colorBgTMGraphNode(node.data),
|
||||
fontWeight: 600,
|
||||
WebkitTextStrokeWidth: '0.6px',
|
||||
WebkitTextStrokeColor: APP_COLORS.bgDefault
|
||||
}}
|
||||
style={{ backgroundColor: colorBgTMGraphNode(node.data) }}
|
||||
>
|
||||
{node.data.rank === 0 ? node.data.text : node.data.annotations.length > 0 ? node.data.annotations.length : ''}
|
||||
</div>
|
||||
<Handle type='target' position={Position.Bottom} style={{ opacity: 0 }} />
|
||||
<Handle type='target' position={Position.Bottom} className='opacity-0' />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ export function EditorConstituenta() {
|
|||
'min-h-80 max-w-[calc(min(100vw,95rem))] mx-auto',
|
||||
'flex pt-8',
|
||||
'overflow-y-auto overflow-x-clip',
|
||||
{ 'flex-col md:items-center': isNarrow }
|
||||
isNarrow && 'flex-col md:items-center'
|
||||
)}
|
||||
style={{ maxHeight: mainHeight }}
|
||||
onKeyDown={handleInput}
|
||||
|
|
|
@ -80,7 +80,7 @@ export function ToolbarConstituenta({
|
|||
}
|
||||
|
||||
return (
|
||||
<div className={clsx('px-1 rounded-b-2xl cc-blur cc-icons cc-animate-position outline-hidden', className)}>
|
||||
<div className={clsx('px-1 rounded-b-2xl backdrop-blur-xs cc-icons cc-animate-position outline-hidden', className)}>
|
||||
{schema.oss.length > 0 ? (
|
||||
<MiniSelectorOSS
|
||||
items={schema.oss}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import clsx from 'clsx';
|
||||
|
||||
import { type IExpressionParseDTO, type IRSErrorDescription } from '../../../backend/types';
|
||||
import { describeRSError } from '../../../labels';
|
||||
import { getRSErrorPrefix } from '../../../models/rslang-api';
|
||||
|
@ -14,17 +16,7 @@ export function ParsingResult({ isOpen, data, disabled, onShowError }: ParsingRe
|
|||
const warningsCount = data ? data.errors.length - errorCount : 0;
|
||||
|
||||
return (
|
||||
<div
|
||||
tabIndex={-1}
|
||||
className='text-sm border dense cc-scroll-y transition-all duration-300'
|
||||
style={{
|
||||
clipPath: isOpen ? 'inset(0% 0% 0% 0%)' : 'inset(0% 0% 100% 0%)',
|
||||
marginTop: isOpen ? '0.75rem' : '0rem',
|
||||
padding: isOpen ? '0.25rem 0.5rem 0.25rem 0.5rem' : '0rem 0rem 0rem 0rem',
|
||||
borderWidth: isOpen ? '1px' : '0px',
|
||||
height: isOpen ? '4.5rem' : '0rem'
|
||||
}}
|
||||
>
|
||||
<div tabIndex={-1} className={clsx('cc-parsing-result text-sm border dense cc-scroll-y', isOpen && 'open')}>
|
||||
<p>
|
||||
Ошибок: <b>{errorCount}</b> | Предупреждений: <b>{warningsCount}</b>
|
||||
</p>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import clsx from 'clsx';
|
||||
|
||||
import { PARAMETER, prefixes } from '@/utils/constants';
|
||||
import { prefixes } from '@/utils/constants';
|
||||
|
||||
import { TokenID } from '../../../backend/types';
|
||||
|
||||
|
@ -91,19 +91,14 @@ export function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsP
|
|||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'cc-rs-edit-controls',
|
||||
'max-w-112 min-w-112 xs:max-w-154 xs:min-w-154 sm:max-w-160 sm:min-w-160 md:max-w-fit mx-1 sm:mx-0',
|
||||
'flex-wrap',
|
||||
'divide-solid',
|
||||
'flex flex-wrap',
|
||||
'text-xs md:text-sm',
|
||||
'select-none'
|
||||
'select-none',
|
||||
isOpen && 'open'
|
||||
)}
|
||||
style={{
|
||||
clipPath: isOpen ? 'inset(0% 0% 0% 0%)' : 'inset(0% 0% 100% 0%)',
|
||||
marginTop: isOpen ? '0.25rem' : '0rem',
|
||||
transitionProperty: 'max-height',
|
||||
transitionDuration: `${PARAMETER.moveDuration}ms`,
|
||||
maxHeight: isOpen ? '4.5rem' : '0rem'
|
||||
}}
|
||||
aria-hidden={!isOpen}
|
||||
>
|
||||
{MAIN_FIRST_ROW.map(token => (
|
||||
<RSTokenButton key={`${prefixes.rsedit_btn}${token}`} token={token} onInsert={onEdit} disabled={disabled} />
|
||||
|
|
|
@ -26,10 +26,7 @@ export function RSTokenButton({ token, disabled, onInsert }: RSTokenButtonProps)
|
|||
'clr-hover clr-text-controls cc-animate-color',
|
||||
'font-math',
|
||||
'cursor-pointer disabled:cursor-default',
|
||||
{
|
||||
'w-14.5 md:w-18': label.length > 3,
|
||||
'w-7.25 md:w-9': label.length <= 3
|
||||
}
|
||||
label.length > 3 ? 'w-14.5 md:w-18' : 'w-7.25 md:w-9'
|
||||
)}
|
||||
data-tooltip-id={globalIDs.tooltip}
|
||||
data-tooltip-html={describeToken(token)}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { EditorLibraryItem, ToolbarItemCard } from '@/features/library/components';
|
||||
|
||||
import { useModificationStore } from '@/stores/modification';
|
||||
|
@ -35,12 +33,7 @@ export function EditorRSFormCard() {
|
|||
return (
|
||||
<div
|
||||
onKeyDown={handleInput}
|
||||
className={clsx(
|
||||
'relative', //
|
||||
'cc-fade-in',
|
||||
'md:w-fit md:max-w-fit max-w-128',
|
||||
'flex flex-row flex-wrap px-6 pt-8'
|
||||
)}
|
||||
className='relative cc-fade-in md:w-fit md:max-w-fit max-w-128 flex flex-row flex-wrap px-6 pt-8'
|
||||
>
|
||||
<ToolbarItemCard
|
||||
className='cc-tab-tools'
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
'use client';
|
||||
|
||||
import { Handle, Position } from 'reactflow';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
|
@ -13,10 +14,6 @@ import { useRSEdit } from '../../rsedit-context';
|
|||
const DESCRIPTION_THRESHOLD = 15;
|
||||
const LABEL_THRESHOLD = 3;
|
||||
|
||||
const FONT_SIZE_MAX = 14;
|
||||
const FONT_SIZE_MED = 12;
|
||||
const FONT_SIZE_MIN = 10;
|
||||
|
||||
/**
|
||||
* Represents graph AST node internal data.
|
||||
*/
|
||||
|
@ -52,18 +49,19 @@ export function TGNode(node: TGNodeInternal) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Handle type='target' position={Position.Top} style={{ opacity: 0 }} />
|
||||
<Handle type='target' position={Position.Top} className='opacity-0' />
|
||||
<div
|
||||
className='w-full h-full cursor-default flex items-center justify-center rounded-full'
|
||||
className={clsx(
|
||||
'w-full h-full cursor-default flex items-center justify-center rounded-full',
|
||||
isFocused && 'border-2 border-sec-200',
|
||||
label.length > LABEL_THRESHOLD ? 'text-[12px]/[16px]' : 'text-[14px]/[20px]'
|
||||
)}
|
||||
style={{
|
||||
backgroundColor: node.selected
|
||||
? APP_COLORS.bgActiveSelection
|
||||
: isFocused
|
||||
? APP_COLORS.bgPurple
|
||||
: colorBgGraphNode(node.data, coloring),
|
||||
fontSize: label.length > LABEL_THRESHOLD ? FONT_SIZE_MED : FONT_SIZE_MAX,
|
||||
borderWidth: isFocused ? '2px' : '0px',
|
||||
borderColor: isFocused ? APP_COLORS.bgSelected : 'transparent'
|
||||
: colorBgGraphNode(node.data, coloring)
|
||||
}}
|
||||
data-tooltip-id={globalIDs.tooltip}
|
||||
data-tooltip-html={describeCstNode(node.data)}
|
||||
|
@ -71,37 +69,22 @@ export function TGNode(node: TGNodeInternal) {
|
|||
onContextMenu={handleContextMenu}
|
||||
onDoubleClick={handleDoubleClick}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontWeight: 600,
|
||||
WebkitTextStrokeWidth: '0.6px',
|
||||
WebkitTextStrokeColor: APP_COLORS.bgDefault
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
<div className='cc-node-label'>{label}</div>
|
||||
</div>
|
||||
<Handle type='source' position={Position.Bottom} style={{ opacity: 0 }} />
|
||||
<Handle type='source' position={Position.Bottom} className='opacity-0' />
|
||||
{description ? (
|
||||
<div
|
||||
className='mt-1 w-[150px] px-1 text-center translate-x-[calc(-50%+20px)]'
|
||||
style={{
|
||||
fontSize: description.length > DESCRIPTION_THRESHOLD ? FONT_SIZE_MIN : FONT_SIZE_MED
|
||||
}}
|
||||
className={clsx(
|
||||
'mt-1 w-[150px] px-1 text-center translate-x-[calc(-50%+20px)]',
|
||||
description.length > DESCRIPTION_THRESHOLD ? 'text-[10px]/[12px]' : 'text-[12px]/[16px]'
|
||||
)}
|
||||
onContextMenu={handleContextMenu}
|
||||
onDoubleClick={handleDoubleClick}
|
||||
>
|
||||
<div className='absolute top-0 px-1 left-0 text-center w-full line-clamp-3 hover:line-clamp-none'>
|
||||
{description}
|
||||
</div>
|
||||
<div
|
||||
aria-hidden='true'
|
||||
className='line-clamp-3 hover:line-clamp-none'
|
||||
style={{
|
||||
WebkitTextStrokeWidth: '3px',
|
||||
WebkitTextStrokeColor: APP_COLORS.bgDefault
|
||||
}}
|
||||
>
|
||||
<div aria-hidden className='line-clamp-3 hover:line-clamp-none cc-text-outline'>
|
||||
{description}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -163,7 +163,7 @@ export function TGFlow() {
|
|||
|
||||
return (
|
||||
<div className='cc-fade-in relative' tabIndex={-1} onKeyDown={handleKeyDown}>
|
||||
<div className='cc-tab-tools flex flex-col items-center rounded-b-2xl cc-blur'>
|
||||
<div className='cc-tab-tools flex flex-col items-center rounded-b-2xl backdrop-blur-xs'>
|
||||
<ToolbarTermGraph />
|
||||
<ToolbarFocusedCst />
|
||||
{!focusCst ? (
|
||||
|
@ -181,7 +181,7 @@ export function TGFlow() {
|
|||
</div>
|
||||
|
||||
<div className='absolute z-pop top-18 sm:top-16 left-2 sm:left-3 w-54 flex flex-col pointer-events-none'>
|
||||
<span className='px-2 pb-1 select-none whitespace-nowrap cc-blur rounded-xl'>
|
||||
<span className='px-2 pb-1 select-none whitespace-nowrap backdrop-blur-xs rounded-xl'>
|
||||
Выбор {selected.length} из {schema.stats?.count_all ?? 0}
|
||||
</span>
|
||||
<GraphSelectors />
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import { MiniButton } from '@/components/control';
|
||||
import { IconGraphInputs, IconGraphOutputs, IconReset } from '@/components/icons';
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
|
||||
import { useTermGraphStore } from '../../../stores/term-graph';
|
||||
import { useRSEdit } from '../rsedit-context';
|
||||
|
@ -37,7 +36,7 @@ export function ToolbarFocusedCst() {
|
|||
|
||||
return (
|
||||
<div className='flex items-center cc-icons'>
|
||||
<div className='w-31 mt-0.5 text-right select-none' style={{ color: APP_COLORS.fgPurple }}>
|
||||
<div className='w-31 mt-0.5 text-right select-none color-(--acc-fg-purple)'>
|
||||
<span>
|
||||
Фокус
|
||||
<b className='pr-1'> {focusCst.alias} </b>
|
||||
|
|
|
@ -6,8 +6,7 @@ import { MiniButton } from '@/components/control';
|
|||
import { IconDropArrow, IconDropArrowUp } from '@/components/icons';
|
||||
import { useWindowSize } from '@/hooks/use-window-size';
|
||||
import { useFitHeight } from '@/stores/app-layout';
|
||||
import { APP_COLORS } from '@/styling/colors';
|
||||
import { globalIDs, PARAMETER, prefixes } from '@/utils/constants';
|
||||
import { globalIDs, prefixes } from '@/utils/constants';
|
||||
|
||||
import { colorBgGraphNode } from '../../../colors';
|
||||
import { type IConstituenta } from '../../../models/rsform';
|
||||
|
@ -56,16 +55,8 @@ export function ViewHidden({ items }: ViewHiddenProps) {
|
|||
onClick={toggleFolded}
|
||||
/>
|
||||
|
||||
<div className={clsx('py-2 clr-input border-x', { 'border-b rounded-b-md': isFolded })}>
|
||||
<div
|
||||
className='w-fit select-none'
|
||||
style={{
|
||||
transitionProperty: 'translate',
|
||||
transitionDuration: `${PARAMETER.fastAnimation}ms`,
|
||||
transitionTimingFunction: 'ease-out',
|
||||
translate: isFolded ? '0.75rem' : 'calc(6.5rem - 50%)'
|
||||
}}
|
||||
>
|
||||
<div className={clsx('py-2 clr-input border-x', isFolded && 'border-b rounded-b-md')}>
|
||||
<div className={clsx('w-fit select-none cc-view-hidden-header', !isFolded && 'open')}>
|
||||
{`Скрытые [${localSelected.length} | ${items.length}]`}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -73,19 +64,14 @@ export function ViewHidden({ items }: ViewHiddenProps) {
|
|||
<div
|
||||
tabIndex={-1}
|
||||
className={clsx(
|
||||
'flex flex-wrap justify-center gap-2 py-2 -mt-2',
|
||||
'clr-input border-x border-b rounded-b-md',
|
||||
'cc-view-hidden-list flex flex-wrap gap-2 justify-center py-2 -mt-2',
|
||||
'border-x border-b rounded-b-md bg-prim-0',
|
||||
'text-sm',
|
||||
'cc-scroll-y'
|
||||
'cc-scroll-y',
|
||||
!isFolded && 'open'
|
||||
)}
|
||||
style={{
|
||||
pointerEvents: isFolded ? 'none' : 'auto',
|
||||
maxHeight: hiddenHeight,
|
||||
transitionProperty: 'clip-path',
|
||||
transitionDuration: `${PARAMETER.fastAnimation}ms`,
|
||||
transitionTimingFunction: 'ease-out',
|
||||
clipPath: isFolded ? 'inset(10% 0% 90% 0%)' : 'inset(0% 0% 0% 0%)'
|
||||
}}
|
||||
aria-hidden={isFolded}
|
||||
style={{ maxHeight: hiddenHeight }}
|
||||
>
|
||||
{items.map(cstID => {
|
||||
const cst = schema.cstByID.get(cstID)!;
|
||||
|
@ -93,17 +79,12 @@ export function ViewHidden({ items }: ViewHiddenProps) {
|
|||
<button
|
||||
key={`${prefixes.cst_hidden_list}${cst.alias}`}
|
||||
type='button'
|
||||
className='w-12 rounded-md text-center select-none'
|
||||
style={{
|
||||
backgroundColor: colorBgGraphNode(cst, coloring),
|
||||
...(localSelected.includes(cstID)
|
||||
? {
|
||||
outlineWidth: '2px',
|
||||
outlineStyle: cst.is_inherited ? 'dashed' : 'solid',
|
||||
outlineColor: APP_COLORS.fgDefault
|
||||
}
|
||||
: {})
|
||||
}}
|
||||
className={clsx(
|
||||
'cc-view-hidden-item w-12 rounded-md text-center select-none',
|
||||
localSelected.includes(cstID) && 'selected',
|
||||
cst.is_inherited && 'inherited'
|
||||
)}
|
||||
style={{ backgroundColor: colorBgGraphNode(cst, coloring) }}
|
||||
onClick={event => handleClick(event, cstID)}
|
||||
onContextMenu={event => handleContextMenu(event, cst)}
|
||||
onDoubleClick={() => navigateCst(cstID)}
|
||||
|
|
|
@ -6,7 +6,6 @@ import { useRoleStore, UserRole } from '@/features/users';
|
|||
|
||||
import { useWindowSize } from '@/hooks/use-window-size';
|
||||
import { useFitHeight } from '@/stores/app-layout';
|
||||
import { PARAMETER } from '@/utils/constants';
|
||||
|
||||
import { ConstituentsSearch } from './constituents-search';
|
||||
import { TableSideConstituents } from './table-side-constituents';
|
||||
|
@ -29,19 +28,11 @@ export function ViewConstituents({ className, isBottom, isMounted }: ViewConstit
|
|||
<aside
|
||||
className={clsx(
|
||||
'border',
|
||||
{
|
||||
'rounded-l-md rounded-r-none': !isBottom,
|
||||
'rounded-md': isBottom
|
||||
},
|
||||
isBottom ? 'rounded-md' : 'rounded-l-md rounded-r-none',
|
||||
isMounted ? 'max-w-full' : 'opacity-0 max-w-0',
|
||||
'ease-in-out duration-1000 transition-[opacity,max-width]',
|
||||
className
|
||||
)}
|
||||
style={{
|
||||
transitionProperty: 'opacity, max-width',
|
||||
transitionDuration: `${2 * PARAMETER.moveDuration}ms`,
|
||||
transitionTimingFunction: 'ease-in-out',
|
||||
opacity: isMounted ? 1 : 0,
|
||||
maxWidth: isMounted ? '100%' : '0'
|
||||
}}
|
||||
>
|
||||
<ConstituentsSearch dense={!!windowSize.width && windowSize.width < COLUMN_DENSE_SEARCH_THRESHOLD} />
|
||||
<TableSideConstituents maxHeight={listHeight} autoScroll={!isBottom} />
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
@import './styling/setup.css';
|
||||
@import './styling/overrides.css';
|
||||
@import './styling/styles.css';
|
||||
@import './styling/utilities.css';
|
||||
@import './styling/components.css';
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
|
@ -50,4 +51,12 @@
|
|||
--breakpoint-lg: 1024px;
|
||||
--breakpoint-xl: 1280px;
|
||||
--breakpoint-2xl: 1536px;
|
||||
|
||||
--ease-bezier: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
--duration-move: 500ms;
|
||||
--duration-modal: 300ms;
|
||||
--duration-fade: 300ms;
|
||||
--duration-dropdown: 200ms;
|
||||
--duration-select: 100ms;
|
||||
}
|
||||
|
|
|
@ -10,9 +10,6 @@ interface AppLayoutStore {
|
|||
|
||||
noFooter: boolean;
|
||||
hideFooter: (value?: boolean) => void;
|
||||
|
||||
noScroll: boolean;
|
||||
hideScroll: (value?: boolean) => void;
|
||||
}
|
||||
|
||||
export const useAppLayoutStore = create<AppLayoutStore>()(set => ({
|
||||
|
@ -29,10 +26,7 @@ export const useAppLayoutStore = create<AppLayoutStore>()(set => ({
|
|||
}),
|
||||
|
||||
noFooter: false,
|
||||
hideFooter: value => set({ noFooter: value ?? true }),
|
||||
|
||||
noScroll: true,
|
||||
hideScroll: value => set({ noScroll: value ?? true })
|
||||
hideFooter: value => set({ noFooter: value ?? true })
|
||||
}));
|
||||
|
||||
/** Utility function that returns the height of the main area. */
|
||||
|
|
202
rsconcept/frontend/src/styling/components.css
Normal file
202
rsconcept/frontend/src/styling/components.css
Normal file
|
@ -0,0 +1,202 @@
|
|||
/**
|
||||
* Module: Utility classes for specific react components.
|
||||
*/
|
||||
|
||||
@utility cc-tab-tools {
|
||||
z-index: var(--z-index-pop);
|
||||
position: absolute;
|
||||
top: 1.7rem;
|
||||
right: 50%;
|
||||
padding-top: 0.4rem;
|
||||
transform: translate(50%, 0%);
|
||||
}
|
||||
|
||||
@utility cc-label {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
font-weight: 500;
|
||||
cursor: default;
|
||||
user-select: text;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@utility cc-tree-item {
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 0.75rem;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
will-change: max-height, opacity, padding, border;
|
||||
transition-property: max-height, opacity, padding, border, color, background-color;
|
||||
transition-timing-function: var(--ease-bezier);
|
||||
transition-duration: var(--duration-dropdown);
|
||||
}
|
||||
|
||||
@utility cc-badge-constituenta {
|
||||
width: 3rem;
|
||||
padding-inline: 0.25rem;
|
||||
|
||||
border-width: 1px;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@utility cc-table-header {
|
||||
text-align: start;
|
||||
padding: 0.5rem;
|
||||
|
||||
font-size: var(--text-xs);
|
||||
line-height: var(--tw-leading, var(--text-xs--line-height));
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@utility cc-modal-wrapper {
|
||||
isolation: isolate;
|
||||
z-index: var(--z-index-modal);
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@utility cc-node-label {
|
||||
font-weight: 600;
|
||||
-webkit-text-stroke-width: 0.6px;
|
||||
-webkit-text-stroke-color: var(--clr-prim-100);
|
||||
}
|
||||
|
||||
@utility cc-text-outline {
|
||||
-webkit-text-stroke-width: 3px;
|
||||
-webkit-text-stroke-color: var(--clr-prim-100);
|
||||
}
|
||||
|
||||
@utility cc-ast-label-outline {
|
||||
-webkit-text-stroke-width: 2px;
|
||||
-webkit-text-stroke-color: var(--clr-prim-100);
|
||||
}
|
||||
|
||||
@utility cc-dropdown {
|
||||
transition-property: clip-path, transform;
|
||||
transition-duration: var(--duration-dropdown);
|
||||
transition-timing-function: var(--ease-in-out);
|
||||
|
||||
transform: translateY(-10%);
|
||||
clip-path: inset(10% 0% 90% 0%);
|
||||
|
||||
&.open {
|
||||
transform: translateY(0);
|
||||
clip-path: inset(0% 0% 0% 0%);
|
||||
}
|
||||
}
|
||||
|
||||
@utility cc-side-location {
|
||||
transition-property: width, min-width, opacity;
|
||||
transition-duration: var(--duration-move);
|
||||
transition-timing-function: var(--ease-bezier);
|
||||
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
min-width: 0;
|
||||
|
||||
&.open {
|
||||
opacity: 1;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@utility cc-view-hidden-header {
|
||||
transition-property: transform;
|
||||
transition-duration: var(--duration-dropdown);
|
||||
transition-timing-function: var(--ease-out);
|
||||
|
||||
transform: translateX(0.75rem);
|
||||
|
||||
&.open {
|
||||
transform: translateX(calc(6.5rem - 50%));
|
||||
}
|
||||
}
|
||||
|
||||
@utility cc-view-hidden-list {
|
||||
transition-property: clip-path;
|
||||
transition-duration: var(--duration-dropdown);
|
||||
transition-timing-function: var(--ease-out);
|
||||
|
||||
clip-path: inset(10% 0% 90% 0%);
|
||||
pointer-events: none;
|
||||
|
||||
&.open {
|
||||
clip-path: inset(0% 0% 0% 0%);
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@utility cc-view-hidden-item {
|
||||
outline-width: 0px;
|
||||
outline-color: transparent;
|
||||
|
||||
&.selected {
|
||||
outline-width: 2px;
|
||||
outline-color: var(--clr-prim-999);
|
||||
outline-style: solid;
|
||||
}
|
||||
&.inherited {
|
||||
outline-style: dashed;
|
||||
}
|
||||
}
|
||||
|
||||
@utility cc-rs-edit-controls {
|
||||
transition-property: max-height;
|
||||
transition-duration: var(--duration-move);
|
||||
transition-timing-function: var(--ease-in-out);
|
||||
|
||||
clip-path: inset(0% 0% 100% 0%);
|
||||
max-height: 0;
|
||||
margin-top: 0;
|
||||
|
||||
&.open {
|
||||
clip-path: inset(0% 0% 0% 0%);
|
||||
max-height: 4.5rem;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@utility cc-parsing-result {
|
||||
transition-property: clip-path, padding, margin, border, height;
|
||||
transition-duration: var(--duration-move);
|
||||
transition-timing-function: var(--ease-in-out);
|
||||
|
||||
clip-path: inset(0% 0% 100% 0%);
|
||||
height: 0;
|
||||
margin-top: 0;
|
||||
padding: 0;
|
||||
border-width: 0;
|
||||
|
||||
&.open {
|
||||
clip-path: inset(0% 0% 0% 0%);
|
||||
height: 4.5rem;
|
||||
margin-top: 0.75rem;
|
||||
padding: 0.25rem 0.5rem 0.25rem 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@utility cc-topic-dropdown {
|
||||
will-change: clip-path;
|
||||
transition-property: clip-path;
|
||||
transition-duration: var(--duration-move);
|
||||
transition-timing-function: var(--ease-in-out);
|
||||
|
||||
clip-path: inset(0% 100% 0% 0%);
|
||||
|
||||
&.open {
|
||||
clip-path: inset(0% 0% 0% 0%);
|
||||
}
|
||||
}
|
|
@ -15,13 +15,6 @@
|
|||
|
||||
--text-max-width: 75ch;
|
||||
--scroll-padding: 3rem;
|
||||
|
||||
--duration-move: 500ms;
|
||||
--duration-modal: 300ms;
|
||||
--duration-fade: 300ms;
|
||||
--duration-select: 100ms;
|
||||
|
||||
--transition-bezier: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* Light Theme */
|
||||
|
|
|
@ -169,7 +169,3 @@
|
|||
@utility border {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
@utility sticky {
|
||||
z-index: 20;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
/**
|
||||
* Module: Utility classes for stlye features.
|
||||
*/
|
||||
|
||||
@utility font-main {
|
||||
font-family: var(--font-main);
|
||||
}
|
||||
|
@ -143,24 +147,6 @@
|
|||
color: var(--clr-sec-800);
|
||||
}
|
||||
|
||||
@utility cc-tab-tools {
|
||||
z-index: var(--z-index-pop);
|
||||
position: absolute;
|
||||
top: 1.7rem;
|
||||
right: 50%;
|
||||
padding-top: 0.4rem;
|
||||
transform: translate(50%, 0%);
|
||||
}
|
||||
|
||||
@utility cc-label {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
font-weight: 500;
|
||||
cursor: default;
|
||||
user-select: text;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@utility cc-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -183,10 +169,6 @@
|
|||
scroll-snap-type: y mandatory;
|
||||
}
|
||||
|
||||
@utility cc-blur {
|
||||
backdrop-filter: blur(3px);
|
||||
}
|
||||
|
||||
@utility cc-shadow-border {
|
||||
box-shadow: 0 1px 2px 0 var(--clr-prim-400);
|
||||
}
|
||||
|
@ -195,7 +177,7 @@
|
|||
opacity: 1;
|
||||
|
||||
transition-property: opacity;
|
||||
transition-timing-function: var(--transition-bezier);
|
||||
transition-timing-function: var(--ease-bezier);
|
||||
transition-duration: var(--duration-fade);
|
||||
|
||||
@starting-style {
|
||||
|
@ -205,7 +187,7 @@
|
|||
|
||||
@utility cc-animate-position {
|
||||
transition-property: transform top left bottom right margin padding;
|
||||
transition-timing-function: var(--transition-bezier);
|
||||
transition-timing-function: var(--ease-bezier);
|
||||
transition-duration: var(--duration-move);
|
||||
}
|
||||
|
||||
|
@ -214,7 +196,7 @@
|
|||
opacity: 1;
|
||||
|
||||
transition-property: clip-path, opacity;
|
||||
transition-timing-function: var(--transition-bezier);
|
||||
transition-timing-function: var(--ease-bezier);
|
||||
transition-duration: var(--duration-modal);
|
||||
|
||||
@starting-style {
|
||||
|
@ -225,46 +207,10 @@
|
|||
|
||||
@utility cc-animate-color {
|
||||
transition-property: color, background-color;
|
||||
transition-timing-function: var(--transition-bezier);
|
||||
transition-timing-function: var(--ease-bezier);
|
||||
transition-duration: var(--duration-select);
|
||||
}
|
||||
|
||||
@utility cc-badge-constituenta {
|
||||
width: 3rem;
|
||||
padding-inline: 0.25rem;
|
||||
|
||||
border-width: 1px;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@utility cc-table-header {
|
||||
text-align: start;
|
||||
padding: 0.5rem;
|
||||
|
||||
font-size: var(--text-xs);
|
||||
line-height: var(--tw-leading, var(--text-xs--line-height));
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@utility cc-modal-wrapper {
|
||||
isolation: isolate;
|
||||
z-index: var(--z-index-modal);
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@utility cc-mask-sides {
|
||||
--mask-border-size: 2rem;
|
||||
|
|
@ -7,33 +7,25 @@
|
|||
*/
|
||||
export const PARAMETER = {
|
||||
smallScreen: 640, // == tailwind:sm
|
||||
smallTreeNodes: 50, // amount of nodes threshold for size increase for large graphs
|
||||
|
||||
minimalTimeout: 10, // milliseconds delay for fast updates
|
||||
refreshTimeout: 100, // milliseconds delay for post-refresh actions
|
||||
notificationDelay: 300, // milliseconds delay for notifications
|
||||
minimalTimeout: 10, // milliseconds delay for fast updates
|
||||
zoomDuration: 500, // milliseconds animation duration
|
||||
moveDuration: 500, // milliseconds - duration of move animation
|
||||
dropdownDuration: 200, // milliseconds - duration of dropdown animation
|
||||
navigationDuration: 300, // milliseconds navigation duration
|
||||
navigationPopupDelay: 300, // milliseconds delay for navigation popup
|
||||
graphPopupDelay: 500, // milliseconds delay for graph popup selections
|
||||
graphRefreshDelay: 10, // milliseconds delay for graph viewpoint reset
|
||||
|
||||
fastAnimation: 200, // milliseconds - duration of fast animation
|
||||
fadeDuration: 300, // milliseconds - duration of fade animation
|
||||
moveDuration: 500, // milliseconds - duration of move animation
|
||||
|
||||
ossImageWidth: 1280, // pixels - size of OSS image
|
||||
ossImageHeight: 960, // pixels - size of OSS image
|
||||
|
||||
graphHandleSize: 3, // pixels - size of graph connection handle
|
||||
graphNodeRadius: 20, // pixels - radius of graph node
|
||||
graphNodePadding: 5, // pixels - padding of graph node
|
||||
graphNodeRadius: 20, // pixels - radius of graph node
|
||||
|
||||
logicLabel: 'LOGIC',
|
||||
errorNodeLabel: '[ERROR]',
|
||||
exteorVersion: '4.9.7',
|
||||
|
||||
TOOLTIP_WIDTH: 'max-w-120'
|
||||
exteorVersion: '4.9.7'
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue
Block a user