F: Improve styling pt2

This commit is contained in:
Ivan 2025-03-10 16:02:53 +03:00
parent 4f9a94c933
commit 20022ea648
87 changed files with 202 additions and 345 deletions

View File

@ -25,7 +25,7 @@ export function ApplicationLayout() {
return (
<NavigationState>
<div className='min-w-80 antialiased h-full max-w-[120rem] mx-auto'>
<div className='min-w-80 antialiased h-full max-w-480 mx-auto'>
<ToasterThemed
className='text-[14px]'
style={{ marginTop: noNavigationAnimation ? '1.5rem' : '3.5rem' }}

View File

@ -1,11 +1,10 @@
import { useNavigation } from 'react-router';
import clsx from 'clsx';
import { useDebounce } from 'use-debounce';
import { Loader } from '@/components/Loader';
import { ModalBackdrop } from '@/components/Modal/ModalBackdrop';
import { PARAMETER } from '@/utils/constants';
// TODO: add animation
export function GlobalLoader() {
const navigation = useNavigation();
@ -17,16 +16,9 @@ export function GlobalLoader() {
}
return (
<div className='fixed top-0 left-0 w-full h-full z-modal cursor-default'>
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')} />
<div
className={clsx(
'px-10 mb-10',
'z-modal absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
'border rounded-xl bg-prim-100'
)}
>
<div className='cc-modal-wrapper'>
<ModalBackdrop />
<div className='cc-fade-in px-10 border rounded-xl bg-prim-100'>
<Loader scale={6} />
</div>
</div>

View File

@ -1,8 +1,7 @@
import clsx from 'clsx';
import { useMutationErrors } from '@/backend/useMutationErrors';
import { Button } from '@/components/Control';
import { DescribeError } from '@/components/InfoError';
import { ModalBackdrop } from '@/components/Modal/ModalBackdrop';
import { useEscapeKey } from '@/hooks/useEscapeKey';
import { useDialogsStore } from '@/stores/dialogs';
@ -19,18 +18,11 @@ export function MutationErrors() {
hideDialog();
return (
<div className='fixed top-0 left-0 w-full h-full z-modal cursor-default'>
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
<div className={clsx('z-navigation', 'fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')} />
<div
className={clsx(
'px-10 mb-10 py-3 flex flex-col items-center',
'z-modal absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
'border rounded-xl bg-prim-100'
)}
>
<div className='cc-modal-wrapper'>
<ModalBackdrop onHide={resetErrors} />
<div className='px-10 py-3 flex flex-col items-center border rounded-xl bg-prim-100' role='alertdialog'>
<h1 className='py-2 select-none'>Ошибка при обработке</h1>
<div className={clsx('px-3 flex flex-col', 'text-warn-600 text-sm font-semibold', 'select-text')}>
<div className='px-3 flex flex-col text-warn-600 text-sm font-semibold select-text'>
<DescribeError error={mutationErrors[0]} />
</div>
<Button onClick={resetErrors} className='w-fit' text='Закрыть' />

View File

@ -8,6 +8,7 @@ export function Logo() {
return (
<img
alt=''
aria-hidden
className='max-h-7 w-fit max-w-46'
src={size.isSmall ? '/logo_sign.svg' : !darkMode ? '/logo_full.svg' : '/logo_full_dark.svg'}
/>

View File

@ -1,9 +1,6 @@
import clsx from 'clsx';
import { IconLibrary2, IconManuals, IconNewItem2 } from '@/components/Icons';
import { useWindowSize } from '@/hooks/useWindowSize';
import { useAppLayoutStore } from '@/stores/appLayout';
import { PARAMETER } from '@/utils/constants';
import { urls } from '../urls';
@ -28,34 +25,16 @@ export function Navigation() {
router.push({ path: urls.create_schema, newTab: event.ctrlKey || event.metaKey });
return (
<nav
className={clsx(
'z-navigation', //
'sticky top-0 left-0 right-0',
'select-none',
'bg-prim-100'
)}
>
<nav className='z-navigation sticky top-0 left-0 right-0 select-none bg-prim-100'>
<ToggleNavigation />
<div
className={clsx(
'pl-2 pr-6 sm:pr-4 h-12', //
'flex',
'cc-shadow-border'
)}
className='pl-2 pr-6 sm:pr-4 h-12 flex cc-shadow-border'
style={{
willChange: 'max-height, translate',
transitionProperty: 'max-height, translate',
transitionDuration: `${PARAMETER.moveDuration}ms`,
maxHeight: noNavigationAnimation ? '0rem' : '3rem',
translate: noNavigationAnimation ? '0 -1.5rem' : '0'
}}
>
<div
tabIndex={-1}
className={clsx('flex items-center mr-auto', !size.isSmall && 'cursor-pointer')}
onClick={!size.isSmall ? navigateHome : undefined}
>
<div className='flex items-center mr-auto cursor-pointer' onClick={!size.isSmall ? navigateHome : undefined}>
<Logo />
</div>
<div className='flex gap-2 items-center'>

View File

@ -17,7 +17,7 @@ export function Divider({ vertical, margins = 'mx-2', className, ...restProps }:
return (
<div
className={clsx(
margins, //prettier: split-lines
margins, //
className,
{
'border-x': vertical,

View File

@ -3,7 +3,6 @@
import { useCallback } from 'react';
import { type Table } from '@tanstack/react-table';
import clsx from 'clsx';
import { prefixes } from '@/utils/constants';
@ -34,7 +33,7 @@ export function PaginationTools<TData>({
);
return (
<div className={clsx('flex justify-end items-center', 'my-2', 'text-sm', 'clr-text-controls', 'select-none')}>
<div className='flex justify-end items-center my-2 text-sm clr-text-controls select-none'>
<span className='mr-3'>
{`${table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1}
-

View File

@ -41,7 +41,7 @@ export function FileInput({ id, label, acceptType, title, className, style, onCh
};
return (
<div className={clsx('py-2', 'flex flex-col gap-2 items-center', className)} style={style}>
<div className={clsx('py-2 flex flex-col gap-2 items-center', className)} style={style}>
<input
id={id}
type='file'

View File

@ -109,7 +109,7 @@ export function SelectMulti<Option, Group extends GroupBase<Option> = GroupBase<
...theme,
borderRadius: 0,
spacing: {
...theme.spacing, // prettier: split-lines
...theme.spacing,
baseUnit: size.isSmall ? 2 : 4,
menuGutter: size.isSmall ? 4 : 8,
controlHeight: size.isSmall ? 28 : 38

View File

@ -107,7 +107,7 @@ export function SelectSingle<Option, Group extends GroupBase<Option> = GroupBase
...theme,
borderRadius: 0,
spacing: {
...theme.spacing, // prettier: split-lines
...theme.spacing,
baseUnit: size.isSmall ? 2 : 4,
menuGutter: 2,
controlHeight: size.isSmall ? 28 : 38

View File

@ -50,13 +50,13 @@ export function SelectTree<ItemType>({
setFolded(items.filter(item => getParent(value) !== item && getParent(getParent(value)) !== item));
}, [value, getParent, items]);
function onFoldItem(target: ItemType, showChildren: boolean) {
function onFoldItem(target: ItemType) {
setFolded(prev =>
items.filter(item => {
if (item === target) {
return !showChildren;
return !prev.includes(target);
}
if (!showChildren && (getParent(item) === target || getParent(getParent(item)) === target)) {
if (!prev.includes(target) && (getParent(item) === target || getParent(getParent(item)) === target)) {
return true;
} else {
return prev.includes(item);
@ -65,16 +65,20 @@ export function SelectTree<ItemType>({
);
}
function handleClickFold(event: React.MouseEvent<Element>, target: ItemType, showChildren: boolean) {
function handleClickFold(event: React.MouseEvent<Element>, target: ItemType) {
event.preventDefault();
event.stopPropagation();
onFoldItem(target, showChildren);
onFoldItem(target);
}
function handleSetValue(event: React.MouseEvent<Element>, target: ItemType) {
function handleClickItem(event: React.MouseEvent<Element>, target: ItemType) {
event.preventDefault();
event.stopPropagation();
onChange(target);
if (event.ctrlKey || event.metaKey) {
onFoldItem(target);
} else {
onChange(target);
}
}
return (
@ -95,7 +99,7 @@ export function SelectTree<ItemType>({
)}
data-tooltip-id={globalIDs.tooltip}
data-tooltip-html={getDescription(item)}
onClick={event => handleSetValue(event, item)}
onClick={event => handleClickItem(event, item)}
style={{
borderBottomWidth: isActive ? '1px' : '0px',
willChange: 'max-height, opacity, padding',
@ -109,11 +113,11 @@ export function SelectTree<ItemType>({
>
{foldable.has(item) ? (
<MiniButton
className={clsx('absolute left-[0.3rem]', !folded.includes(item) ? 'top-[0.4rem]' : 'top-1')}
className={clsx('absolute left-1', !folded.includes(item) ? 'top-1.5' : 'top-1')}
noPadding
noHover
icon={!folded.includes(item) ? <IconDropArrow size='1rem' /> : <IconPageRight size='1.25rem' />}
onClick={event => handleClickFold(event, item, folded.includes(item))}
onClick={event => handleClickFold(event, item)}
/>
) : null}
{getParent(item) === item ? getLabel(item) : `- ${getLabel(item).toLowerCase()}`}

View File

@ -1,19 +1,14 @@
'use client';
import clsx from 'clsx';
interface ModalBackdropProps {
onHide: () => void;
onHide?: () => void;
}
export function ModalBackdrop({ onHide }: ModalBackdropProps) {
return (
<>
<div className={clsx('z-bottom', 'fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
<div
className={clsx('z-bottom', 'fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')}
onClick={onHide}
/>
<div className='z-bottom fixed inset-0 backdrop-blur-[3px] opacity-50' />
<div className='z-bottom fixed inset-0 bg-prim-0 opacity-25' onClick={onHide} />
</>
);
}

View File

@ -87,15 +87,10 @@ export function ModalForm({
}
return (
<div className='fixed top-0 left-0 w-full h-full z-modal isolate cursor-default'>
<div className='cc-modal-wrapper'>
<ModalBackdrop onHide={handleCancel} />
<form
className={clsx(
'cc-animate-modal',
'absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
'grid',
'border rounded-xl bg-prim-100'
)}
className='cc-animate-modal grid border rounded-xl bg-prim-100'
role='dialog'
onSubmit={handleSubmit}
aria-labelledby='modal-title'

View File

@ -1,19 +1,12 @@
import clsx from 'clsx';
import { Loader } from '@/components/Loader';
import { ModalBackdrop } from './ModalBackdrop';
export function ModalLoader() {
return (
<div className='fixed top-0 left-0 w-full h-full z-modal isolate cursor-default'>
<div className={clsx('z-bottom fixed top-0 left-0', 'w-full h-full', 'backdrop-blur-[3px] opacity-50')} />
<div className={clsx('z-bottom fixed top-0 left-0', 'w-full h-full', 'bg-prim-0 opacity-25')} />
<div
className={clsx(
'cc-animate-modal p-20',
'z-modal absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
'border rounded-xl bg-prim-100'
)}
>
<div className='cc-modal-wrapper'>
<ModalBackdrop />
<div className='cc-animate-modal p-20 border rounded-xl bg-prim-100'>
<Loader circular scale={6} />
</div>
</div>

View File

@ -32,17 +32,9 @@ export function ModalView({
useEscapeKey(hideDialog);
return (
<div className='fixed top-0 left-0 w-full h-full z-modal isolate cursor-default'>
<div className='cc-modal-wrapper'>
<ModalBackdrop onHide={hideDialog} />
<div
className={clsx(
'cc-animate-modal',
'absolute bottom-1/2 left-1/2 -translate-x-1/2 translate-y-1/2',
'grid',
'border rounded-xl bg-prim-100'
)}
role='dialog'
>
<div className='cc-animate-modal grid border rounded-xl bg-prim-100' role='dialog'>
{helpTopic && !hideHelpWhen?.() ? (
<BadgeHelp
topic={helpTopic}

View File

@ -20,5 +20,5 @@ interface ValueStatsProps extends Styling, Titled {
* Displays statistics value with an icon.
*/
export function ValueStats(props: ValueStatsProps) {
return <ValueIcon dense smallThreshold={SMALL_THRESHOLD} textClassName='min-w-[1.4rem]' {...props} />;
return <ValueIcon dense smallThreshold={SMALL_THRESHOLD} textClassName='min-w-5' {...props} />;
}

View File

@ -2,7 +2,6 @@
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { urls, useConceptNavigation } from '@/app';
@ -56,11 +55,11 @@ export function LoginPage() {
}
return (
<form
className={clsx('cc-column cc-fade-in', 'w-[24rem] mx-auto', 'pt-12 pb-6 px-6')}
className='cc-column cc-fade-in w-96 mx-auto pt-12 pb-6 px-6'
onSubmit={event => void handleSubmit(onSubmit)(event)}
onChange={resetErrors}
>
<img alt='Концепт Портал' src={resources.logo} className='max-h-[2.5rem] min-w-[2.5rem] mb-3' />
<img alt='Концепт Портал' src={resources.logo} className='max-h-10 min-w-10 mb-3' />
<TextInput
id='username'
autoComplete='username'
@ -82,7 +81,7 @@ export function LoginPage() {
error={errors.password}
/>
<SubmitButton text='Войти' className='self-center w-[12rem] mt-3' loading={isPending} />
<SubmitButton text='Войти' className='self-center w-48 mt-3' loading={isPending} />
<div className='flex flex-col text-sm'>
<TextURL text='Восстановить пароль...' href='/restore-password' />
<TextURL text='Нет аккаунта? Зарегистрируйтесь...' href='/signup' />

View File

@ -1,7 +1,6 @@
'use client';
import { useState } from 'react';
import clsx from 'clsx';
import { isAxiosError } from '@/backend/apiTransport';
import { SubmitButton, TextURL } from '@/components/Control';
@ -33,11 +32,7 @@ export function Component() {
);
} else {
return (
<form
className={clsx('cc-fade-in cc-column', 'w-[24rem] mx-auto', 'px-6 mt-3')}
onSubmit={handleSubmit}
onChange={clearServerError}
>
<form className='cc-fade-in cc-column w-96 mx-auto px-6 mt-3' onSubmit={handleSubmit} onChange={clearServerError}>
<TextInput
id='email'
autoComplete='email'
@ -48,12 +43,7 @@ export function Component() {
onChange={event => setEmail(event.target.value)}
/>
<SubmitButton
text='Запросить пароль'
className='self-center w-[12rem] mt-3'
loading={isPending}
disabled={!email}
/>
<SubmitButton text='Запросить пароль' className='self-center w-48 mt-3' loading={isPending} disabled={!email} />
{serverError ? <ServerError error={serverError} /> : null}
</form>
);

View File

@ -52,7 +52,7 @@ export function BadgeHelp({ topic, padding = 'p-1', className, contentClass, sty
{...restProps}
>
<Suspense fallback={<Loader />}>
<div className='absolute right-1 text-sm top-[0.4rem] clr-input' onClick={event => event.stopPropagation()}>
<div className='absolute right-1 text-sm top-2 clr-input' onClick={event => event.stopPropagation()}>
<TextURL text='Справка...' href={`/manuals?topic=${topic}`} />
</div>
<TopicPage topic={topic} />

View File

@ -1,5 +1,3 @@
import clsx from 'clsx';
import { CstClass } from '@/features/rsform';
import { colorBgCstClass } from '@/features/rsform/colors';
import { describeCstClass, labelCstClass } from '@/features/rsform/labels';
@ -18,7 +16,7 @@ export function InfoCstClass({ header }: InfoCstClassProps) {
return (
<p key={`${prefixes.cst_status_list}${index}`}>
<span
className={clsx('inline-block', 'min-w-28', 'px-1', 'border', 'text-center text-sm font-controls')}
className='inline-block min-w-28 px-1 border text-center text-sm font-controls'
style={{ backgroundColor: colorBgCstClass(cstClass) }}
>
{labelCstClass(cstClass)}

View File

@ -21,7 +21,7 @@ export function InfoCstStatus({ title }: InfoCstStatusProps) {
<span
className={clsx(
'inline-block', //
'min-w-[7rem]',
'min-w-28',
'px-1',
'border',
'text-center text-sm font-controls'

View File

@ -69,7 +69,7 @@ export function HelpRSGraphTerm() {
<Divider margins='my-3' className='hidden sm:block' />
<div className='flex flex-col-reverse mb-3 sm:flex-row'>
<div className='sm:w-[14rem]'>
<div className='sm:w-56'>
<h1>Общие</h1>
<li>
<IconOSS className='inline-icon' /> переход к связанной <LinkTopic text='ОСС' topic={HelpTopic.CC_OSS} />
@ -88,7 +88,7 @@ export function HelpRSGraphTerm() {
<Divider vertical margins='mx-3' className='hidden sm:block' />
<div className='dense w-[21rem]'>
<div className='dense w-84'>
<h1>Выделение</h1>
<li>
<IconGraphCollapse className='inline-icon' /> все влияющие

View File

@ -67,7 +67,7 @@ export function HelpRSMenu() {
<Divider vertical margins='mx-3' />
<div className='w-[18rem]'>
<div className='w-72'>
<h2>Режимы работы</h2>
<li>
<IconAlert size='1.25rem' className='inline-icon icon-red' /> работа в анонимном режиме. Переход на страницу

View File

@ -27,7 +27,7 @@ export function ManualsPage() {
}
return (
<div className='flex mx-auto max-w-[80rem]' role='manuals' style={{ minHeight: mainHeight }}>
<div className='flex mx-auto max-w-320' role='manuals' style={{ minHeight: mainHeight }}>
<TopicsList activeTopic={activeTopic} onChangeTopic={topic => onSelectTopic(topic)} />
<ViewTopic topic={activeTopic} />
</div>

View File

@ -31,7 +31,7 @@ export function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownPro
<div
ref={menu.ref}
className={clsx(
'absolute left-0 w-54', // prettier: split-lines
'absolute left-0 w-54', //
'flex flex-col',
'z-topmost',
'text-xs sm:text-sm',
@ -59,11 +59,7 @@ export function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownPro
getParent={item => topicParent.get(item) ?? item}
getLabel={labelHelpTopic}
getDescription={describeHelpTopic}
className={clsx(
'border-r border-t rounded-none', // prettier: split-lines
'cc-scroll-y',
'bg-prim-200'
)}
className='border-r border-t rounded-none cc-scroll-y bg-prim-200'
style={{
maxHeight: treeHeight,
willChange: 'clip-path',

View File

@ -25,7 +25,7 @@ export function TopicsStatic({ activeTopic, onChangeTopic }: TopicsStaticProps)
getDescription={describeHelpTopic}
className={clsx(
'sticky top-0 left-0',
'min-w-[14.5rem] max-w-[14.5rem] sm:min-w-[12.5rem] sm:max-w-[12.5rem] md:min-w-[14.5rem] md:max-w-[14.5rem]',
'min-w-58 max-w-58 sm:min-w-50 sm:max-w-50 md:min-w-58 md:max-w-58',
'cc-scroll-y',
'self-start',
'border-x border-t rounded-none',

View File

@ -119,7 +119,7 @@ export function PickSchema({
className='mt-1'
onClick={() => locationMenu.toggle()}
/>
<Dropdown isOpen={locationMenu.isOpen} stretchLeft className='w-[20rem] h-[12.5rem]'>
<Dropdown isOpen={locationMenu.isOpen} stretchLeft className='w-80 h-50'>
<SelectLocation
value={filterLocation}
prefix={prefixes.folders_list}
@ -147,7 +147,7 @@ export function PickSchema({
columns={columns}
conditionalRowStyles={conditionalRowStyles}
noDataComponent={
<div className='cc-column dense p-3 items-center min-h-[6rem]'>
<div className='cc-column dense p-3 items-center min-h-24'>
<p>Список схем пуст</p>
<p>Измените параметры фильтра</p>
</div>

View File

@ -51,14 +51,14 @@ export function SelectLocation({ value, dense, prefix, onClick, className, style
}
return (
<div className={clsx('flex flex-col', 'cc-scroll-y', className)} style={style}>
<div className={clsx('flex flex-col cc-scroll-y', className)} style={style}>
{items.map((item, index) =>
!item.parent || !folded.includes(item.parent) ? (
<div
tabIndex={-1}
key={`${prefix}${index}`}
className={clsx(
!dense && 'min-h-[2.0825rem] sm:min-h-[2.3125rem]',
!dense && 'h-7 sm:h-8',
'pr-3 py-1 flex items-center gap-2',
'cc-scroll-row',
'clr-hover cc-animate-color',

View File

@ -35,22 +35,14 @@ export function SelectLocationContext({
}
return (
<div
ref={menu.ref}
className={clsx('relative h-full mt-[-0.25rem] ml-[-1.5rem]', 'text-right self-start', className)}
{...restProps}
>
<div ref={menu.ref} className={clsx('relative h-full -mt-1 -ml-6 text-right self-start', className)} {...restProps}>
<MiniButton
title={title}
hideTitle={menu.isOpen}
icon={<IconFolderTree size='1.25rem' className='icon-green' />}
onClick={() => menu.toggle()}
/>
<Dropdown
isOpen={menu.isOpen}
className={clsx('w-[20rem] h-[12.5rem] z-tooltip', dropdownHeight)}
margin='mt-[-0.25rem]'
>
<Dropdown isOpen={menu.isOpen} className={clsx('w-80 h-50 z-tooltip', dropdownHeight)}>
<SelectLocation
value={value}
prefix={prefixes.folders_list}

View File

@ -34,7 +34,7 @@ export function SelectVersion({ id, className, items, value, onChange, ...restPr
return (
<SelectSingle
id={id}
className={clsx('min-w-[12rem] text-ellipsis', className)}
className={clsx('min-w-48 text-ellipsis', className)}
options={options}
value={{ value: value, label: labelVersion(value, items) }}
onChange={data => onChange(data?.value ?? 'latest')}

View File

@ -40,7 +40,7 @@ export function ToolbarItemAccess({
}
return (
<div className='absolute z-bottom top-[4.5rem] right-0 w-[12rem] flex pr-2'>
<div className='absolute z-bottom top-18 right-0 w-48 flex pr-2'>
<Label text='Доступ' className='self-center select-none' />
<div className='ml-auto cc-icons'>
<SelectAccessPolicy
@ -68,7 +68,7 @@ export function ToolbarItemAccess({
onClick={toggleReadOnly}
disabled={role === UserRole.READER || isProcessing}
/>
<BadgeHelp topic={HelpTopic.ACCESS} className='mt-[0.125rem]' offset={4} />
<BadgeHelp topic={HelpTopic.ACCESS} className='mt-0.5' offset={4} />
</div>
</div>
);

View File

@ -2,7 +2,6 @@
import { Controller, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { z } from 'zod';
import { useAuthSuspense } from '@/features/auth';
@ -57,9 +56,9 @@ export function DlgChangeLocation() {
submitInvalidTooltip={`Допустимы буквы, цифры, подчерк, пробел и "!". Сегмент пути не может начинаться и заканчиваться пробелом. Общая длина (с корнем) не должна превышать ${limits.location_len}`}
canSubmit={isValid && isDirty}
onSubmit={event => void handleSubmit(onSubmit)(event)}
className={clsx('w-[35rem]', 'pb-3 px-6 flex gap-3 h-[9rem]')}
className='w-140 pb-3 px-6 flex gap-3 h-36'
>
<div className='flex flex-col gap-2 min-w-[7rem]'>
<div className='flex flex-col gap-2 min-w-28'>
<Label className='select-none' text='Корень' />
<Controller
control={control}
@ -77,11 +76,11 @@ export function DlgChangeLocation() {
control={control}
name='location'
render={({ field }) => (
<SelectLocationContext dropdownHeight='max-h-[9.2rem]' value={field.value} onChange={field.onChange} />
<SelectLocationContext dropdownHeight='max-h-36' value={field.value} onChange={field.onChange} />
)}
/>
<Controller
control={control} //
control={control}
name='location'
render={({ field }) => (
<TextArea

View File

@ -2,7 +2,6 @@
import { Controller, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { urls, useConceptNavigation } from '@/app';
import { useAuthSuspense } from '@/features/auth';
@ -69,7 +68,7 @@ export function DlgCloneLibraryItem() {
submitText='Создать'
canSubmit={isValid}
onSubmit={event => void handleSubmit(onSubmit)(event)}
className={clsx('px-6 py-2', 'cc-column', 'max-h-full w-[30rem]')}
className='px-6 py-2 cc-column h-fit w-120'
>
<TextInput
id='dlg_full_name' //
@ -77,14 +76,9 @@ export function DlgCloneLibraryItem() {
{...register('title')}
error={errors.title}
/>
<div className='flex justify-between gap-3'>
<TextInput
id='dlg_alias'
label='Сокращение'
className='w-[16rem]'
{...register('alias')}
error={errors.alias}
/>
<TextInput id='dlg_alias' label='Сокращение' className='w-64' {...register('alias')} error={errors.alias} />
<div className='flex flex-col gap-2'>
<Label text='Доступ' className='self-center select-none' />
<div className='ml-auto cc-icons'>
@ -115,7 +109,7 @@ export function DlgCloneLibraryItem() {
</div>
<div className='flex gap-3'>
<div className='flex flex-col gap-2 w-[7rem]'>
<div className='flex flex-col gap-2 w-28'>
<Label text='Корень' />
<Controller
control={control} //

View File

@ -2,7 +2,6 @@
import { Controller, useForm, useWatch } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { Checkbox, TextArea, TextInput } from '@/components/Input';
import { ModalForm } from '@/components/Modal';
@ -45,13 +44,13 @@ export function DlgCreateVersion() {
return (
<ModalForm
header='Создание версии'
className={clsx('cc-column', 'w-[30rem]', 'py-2 px-6')}
className='cc-column w-120 py-2 px-6'
canSubmit={canSubmit}
submitInvalidTooltip={errorMsg.versionTaken}
submitText='Создать'
onSubmit={event => void handleSubmit(onSubmit)(event)}
>
<TextInput id='dlg_version' {...register('version')} dense label='Версия' className='w-[16rem]' />
<TextInput id='dlg_version' {...register('version')} dense label='Версия' className='w-64' />
<TextArea id='dlg_description' {...register('description')} spellCheck label='Описание' rows={3} />
{selected.length > 0 ? (
<Controller

View File

@ -3,7 +3,6 @@
import { useRef } from 'react';
import { Controller, useForm, useWatch } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { urls, useConceptNavigation } from '@/app';
import { useAuthSuspense } from '@/features/auth';
@ -103,7 +102,7 @@ export function FormCreateItem() {
return (
<form
className={clsx('cc-fade-in cc-column', 'min-w-120 max-w-120 mx-auto', 'px-6 py-3')}
className='cc-fade-in cc-column min-w-120 max-w-120 mx-auto px-6 py-3'
onSubmit={event => void handleSubmit(onSubmit)(event)}
onChange={resetErrors}
>

View File

@ -63,7 +63,7 @@ export function TableLibraryItems({ items }: TableLibraryItemsProps) {
className={clsx('text-xs sm:text-sm cc-scroll-y h-fit border-b', { 'border-l': folderMode })}
style={{ maxHeight: tableHeight }}
noDataComponent={
<div className='cc-column dense p-3 items-center min-h-[6rem]'>
<div className='cc-column dense p-3 items-center min-h-24'>
<p>Список схем пуст</p>
<p className='flex gap-6'>
<TextURL text='Создать схему' href='/library/create' />

View File

@ -75,21 +75,12 @@ export function ToolbarSearch({ total, filtered }: ToolbarSearchProps) {
}
return (
<div
className={clsx(
'sticky top-0', //
'h-9',
'flex items-center gap-3',
'border-b',
'text-sm',
'clr-input'
)}
>
<div className={clsx('ml-3 pt-1 self-center', 'min-w-18 sm:min-w-30', 'select-none', 'whitespace-nowrap')}>
<div className='sticky top-0 h-9 flex gap-3 border-b text-sm clr-input items-center'>
<div className='ml-3 min-w-18 sm:min-w-30 select-none whitespace-nowrap'>
{filtered} из {total}
</div>
<div className='cc-icons'>
<div className='cc-icons h-full items-center'>
<MiniButton
title='Видимость'
icon={<IconItemVisibility value={true} className={tripleToggleColor(isVisible)} />}
@ -103,7 +94,7 @@ export function ToolbarSearch({ total, filtered }: ToolbarSearchProps) {
icon={<IconUserSearch size='1.25rem' className={userActive ? 'icon-green' : 'icon-primary'} />}
onClick={userMenu.toggle}
/>
<Dropdown isOpen={userMenu.isOpen} margin='mt-[0.2rem]'>
<Dropdown isOpen={userMenu.isOpen}>
<DropdownButton
text='Я - Владелец'
icon={<IconOwner size='1.25rem' className={tripleToggleColor(isOwned)} />}
@ -142,10 +133,10 @@ export function ToolbarSearch({ total, filtered }: ToolbarSearchProps) {
onChangeQuery={setQuery}
/>
{!folderMode ? (
<div ref={headMenu.ref} className='relative flex items-center h-full py-1 select-none'>
<div ref={headMenu.ref} className='relative flex items-center h-full select-none'>
<SelectorButton
transparent
className='h-full rounded-lg'
className='rounded-lg py-1'
titleHtml={(head ? describeLocationHead(head) : 'Выберите каталог') + '<br/>Ctrl + клик - Проводник'}
hideTitle={headMenu.isOpen}
icon={

View File

@ -85,7 +85,7 @@ export function ViewSideLocation({ isVisible, onRenameLocation }: ViewSideLocati
) : null}
{!!location ? (
<MiniButton
title={subfolders ? 'Вложенные папки: Вкл' : 'Вложенные папки: Выкл'} // prettier: split-lines
title={subfolders ? 'Вложенные папки: Вкл' : 'Вложенные папки: Выкл'}
icon={<IconShowSubfolders value={subfolders} />}
onClick={toggleSubfolders}
/>

View File

@ -12,7 +12,7 @@ export function OperationTooltip() {
clickable
id={globalIDs.operation_tooltip}
layer='z-topmost'
className='max-w-[35rem] dense'
className='max-w-140 dense'
style={{ maxHeight: '30rem', overflowY: 'auto' }}
hidden={!hoverOperation}
>

View File

@ -2,7 +2,6 @@
import { Controller, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { type ILibraryItem, LibraryItemType } from '@/features/library';
import { useLibrary } from '@/features/library/backend/useLibrary';
@ -55,7 +54,7 @@ export function DlgChangeInputSchema() {
header='Выбор концептуальной схемы'
submitText='Подтвердить выбор'
onSubmit={event => void handleSubmit(onSubmit)(event)}
className={clsx('w-[35rem]', 'pb-3 px-6 cc-column')}
className='w-140 pb-3 px-6 cc-column'
>
<div className='flex justify-between gap-3 items-center'>
<div className='flex gap-3'>

View File

@ -64,7 +64,7 @@ export function TabInputOperation() {
<TextInput
id='operation_alias' //
label='Сокращение'
className='w-[16rem]'
className='w-64'
{...register('item_data.alias')}
error={errors.item_data?.alias}
/>

View File

@ -29,7 +29,7 @@ export function TabSynthesisOperation() {
<TextInput
id='operation_alias'
label='Сокращение'
className='w-[16rem]'
className='w-64'
{...register('item_data.alias')}
error={errors.item_data?.alias}
/>

View File

@ -2,7 +2,6 @@
import { Controller, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
@ -44,7 +43,7 @@ export function DlgDeleteOperation() {
header='Удаление операции'
submitText='Подтвердить удаление'
onSubmit={event => void handleSubmit(onSubmit)(event)}
className={clsx('w-[35rem]', 'pb-3 px-6 cc-column', 'select-none')}
className='w-140 pb-3 px-6 cc-column select-none'
helpTopic={HelpTopic.CC_PROPAGATION}
>
<TextInput disabled dense noBorder id='operation_alias' label='Операция' value={target.alias} />

View File

@ -3,7 +3,6 @@
import { useState } from 'react';
import { Controller, useForm, useWatch } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
import { type ILibraryItem } from '@/features/library';
@ -120,7 +119,7 @@ export function DlgRelocateConstituents() {
submitText='Переместить'
canSubmit={isValid && destinationItem !== undefined}
onSubmit={event => void handleSubmit(onSubmit)(event)}
className={clsx('w-160 h-[33rem]', 'py-3 px-6')}
className='w-160 h-132 py-3 px-6'
helpTopic={HelpTopic.UI_RELOCATE_CST}
>
<div className='flex flex-col border'>

View File

@ -13,7 +13,7 @@ export function OssStats({ stats }: OssStatsProps) {
return (
<div
className={clsx(
'mt-3 md:ml-5 md:mt-8 md:w-[12rem] w-[14rem] h-min mx-auto', // prettier: split-lines
'mt-3 md:ml-5 md:mt-8 md:w-48 w-56 h-min mx-auto', //
'grid grid-cols-3 gap-1 justify-items-end'
)}
>

View File

@ -1,5 +1,3 @@
import clsx from 'clsx';
import { APP_COLORS } from '@/styling/colors';
import { colorFgGrammeme } from '../colors';
@ -17,12 +15,7 @@ interface BadgeGrammemeProps {
export function BadgeGrammeme({ grammeme }: BadgeGrammemeProps) {
return (
<div
className={clsx(
'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'
style={{
borderColor: colorFgGrammeme(grammeme),
color: colorFgGrammeme(grammeme),

View File

@ -12,12 +12,10 @@ interface InfoConstituentaProps extends React.ComponentProps<'div'> {
export function InfoConstituenta({ data, className, ...restProps }: InfoConstituentaProps) {
return (
<div className={clsx('dense min-w-[15rem] break-words', className)} {...restProps}>
<div className={clsx('dense min-w-60 break-words', className)} {...restProps}>
<h2 className='cursor-default' title={data.is_inherited ? ' наследник' : undefined}>
{data.alias}
{data.is_inherited ? (
<IconChild size='1rem' className='inline-icon translate-y-[-0.1rem] translate-x-[0.125rem]' />
) : null}
{data.is_inherited ? <IconChild size='1rem' className='inline-icon align-middle ml-1 mt-1' /> : null}
</h2>
{data.term_resolved ? (
<p>

View File

@ -93,7 +93,7 @@ export function PickConstituenta({
columns={columns}
conditionalRowStyles={conditionalRowStyles}
noDataComponent={
<NoData className='min-h-[6rem]'>
<NoData className='min-h-24'>
<p>Список конституент пуст</p>
<p>Измените параметры фильтра</p>
</NoData>

View File

@ -99,14 +99,14 @@ export function PickMultiConstituenta({
return (
<div className={clsx(noBorder ? '' : 'border', className)} {...restProps}>
<div className={clsx('px-3 flex justify-between items-center', 'clr-input', 'border-b', 'rounded-t-md')}>
<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}` : 'Конституенты'}
</div>
<SearchBar
id='dlg_constituents_search'
noBorder
className='min-w-[6rem] pr-2 grow'
className='min-w-24 pr-2 grow'
query={filterText}
onChangeQuery={setFilterText}
/>
@ -122,6 +122,7 @@ export function PickMultiConstituenta({
className='w-fit'
/>
</div>
<DataTable
id={id}
dense

View File

@ -167,7 +167,7 @@ export function PickSubstitutions({
columnHelper.accessor(item => item.substitution_source.alias, {
id: 'left_schema',
size: 100,
cell: props => <div className='min-w-[10.5rem] text-ellipsis text-left'>{props.getValue()}</div>
cell: props => <div className='min-w-43 text-ellipsis text-left'>{props.getValue()}</div>
}),
columnHelper.accessor(item => item.substitution.alias, {
id: 'left_alias',
@ -230,8 +230,8 @@ export function PickSubstitutions({
return (
<div className={clsx('flex flex-col', className)} {...restProps}>
<div className='flex items-end gap-3 justify-stretch'>
<div className='grow flex flex-col basis-1/2 gap-[0.125rem] border-x border-t clr-input rounded-t-md'>
<div className='flex items-center gap-3'>
<div className='grow flex flex-col basis-1/2 gap-1 border-x border-t clr-input rounded-t-md'>
<SelectLibraryItem
noBorder
placeholder='Выберите аргумент'
@ -241,7 +241,7 @@ export function PickSubstitutions({
/>
<SelectConstituenta noBorder items={leftItems} value={leftCst} onChange={setLeftCst} />
</div>
<div className='flex flex-col gap-1'>
<div className='flex flex-col justify-center gap-1'>
<MiniButton
title={deleteRight ? 'Заменить правую' : 'Заменить левую'}
onClick={toggleDelete}
@ -255,14 +255,14 @@ export function PickSubstitutions({
/>
<MiniButton
title='Добавить в таблицу отождествлений'
className='mb-[0.375rem] grow-0'
className='grow-0'
icon={<IconReplace size='1.5rem' className='icon-primary' />}
disabled={!leftCst || !rightCst || (leftCst === rightCst && !allowSelfSubstitution)}
onClick={addSubstitution}
/>
</div>
<div className='grow basis-1/2 flex flex-col gap-[0.125rem] border-x border-t clr-input rounded-t-md'>
<div className='grow basis-1/2 flex flex-col gap-1 border-x border-t clr-input rounded-t-md'>
<SelectLibraryItem
noBorder
placeholder='Выберите аргумент'
@ -285,7 +285,7 @@ export function PickSubstitutions({
columns={columns}
headPosition='0'
noDataComponent={
<NoData className='min-h-[2rem]'>
<NoData className='min-h-8'>
<p>Список пуст</p>
<p>Добавьте отождествление</p>
</NoData>

View File

@ -29,7 +29,7 @@ import { rsHoverTooltip } from './tooltip';
interface RSInputProps
extends Pick<
ReactCodeMirrorProps,
| 'id' // prettier: split-lines
| 'id' //
| 'height'
| 'minHeight'
| 'maxHeight'

View File

@ -1,6 +1,5 @@
import { type Extension } from '@codemirror/state';
import { hoverTooltip, type TooltipView } from '@codemirror/view';
import clsx from 'clsx';
import { labelCstTypification } from '../../labels';
import { type IConstituenta, type IRSForm } from '../../models/rsform';
@ -33,14 +32,7 @@ export function rsHoverTooltip(schema: IRSForm, canClick?: boolean): Extension {
*/
function domTooltipConstituenta(cst?: IConstituenta, canClick?: boolean): TooltipView {
const dom = document.createElement('div');
dom.className = clsx(
'max-h-[25rem] max-w-[25rem] min-w-[10rem]',
'dense',
'p-2',
'border shadow-md',
'cc-scroll-y',
'text-sm font-main'
);
dom.className = 'max-h-100 max-w-100 min-w-40 dense p-2 border shadow-md cc-scroll-y text-sm font-main';
if (!cst) {
const text = document.createElement('p');

View File

@ -60,7 +60,7 @@ const editorSetup: BasicSetupOptions = {
interface RefsInputInputProps
extends Pick<
ReactCodeMirrorProps,
| 'id' // prettier: split-lines
| 'id' //
| 'height'
| 'minHeight'
| 'maxHeight'
@ -85,7 +85,7 @@ interface RefsInputInputProps
export const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
(
{
id, // prettier: split-lines
id, //
label,
disabled,
schema,

View File

@ -65,7 +65,7 @@ export function refsHoverTooltip(schema: IRSForm, canClick?: boolean): Extension
function domTooltipEntityReference(ref: IEntityReference, cst: IConstituenta | null, canClick?: boolean): TooltipView {
const dom = document.createElement('div');
dom.className = clsx(
'max-h-[25rem] max-w-[25rem] min-w-[10rem]',
'max-h-100 max-w-100 min-w-40',
'dense',
'p-2 flex flex-col',
'border shadow-md',
@ -87,12 +87,7 @@ function domTooltipEntityReference(ref: IEntityReference, cst: IConstituenta | n
parseGrammemes(ref.form).forEach(gramStr => {
const gram = document.createElement('div');
gram.id = `tooltip-${gramStr}`;
gram.className = clsx(
'min-w-[3rem]', //
'px-1',
'border rounded-md',
'text-sm text-center whitespace-nowrap'
);
gram.className = 'min-w-12 px-1 border rounded-md text-sm text-center whitespace-nowrap';
gram.style.borderWidth = '1px';
gram.style.borderColor = colorFgGrammeme(gramStr);
gram.style.color = colorFgGrammeme(gramStr);
@ -123,7 +118,7 @@ function domTooltipSyntacticReference(
): TooltipView {
const dom = document.createElement('div');
dom.className = clsx(
'max-h-[25rem] max-w-[25rem] min-w-[10rem]',
'max-h-100 max-w-100 min-w-40',
'dense',
'p-2 flex flex-col',
'border shadow-md',

View File

@ -17,7 +17,7 @@ export function WordformButton({ text, example, grams, onSelectGrams, isSelected
tabIndex={-1}
onClick={() => onSelectGrams([...grams])}
className={clsx(
'min-w-[3.75rem] sm:min-w-[5.5rem]',
'min-w-15 sm:min-w-20',
'p-1',
'border rounded-none',
'cursor-pointer',

View File

@ -43,7 +43,7 @@ export function DlgCreateCst() {
onSubmit={event => void methods.handleSubmit(onSubmit)(event)}
submitInvalidTooltip={errorMsg.aliasInvalid}
submitText='Создать'
className='cc-column w-[35rem] max-h-[30rem] py-2 px-6'
className='cc-column w-140 max-h-120 py-2 px-6'
>
<FormProvider {...methods}>
<FormCreateCst schema={schema} />

View File

@ -43,15 +43,8 @@ export function FormCreateCst({ schema }: FormCreateCstProps) {
return (
<>
<div className='flex items-center self-center gap-3'>
<SelectCstType id='dlg_cst_type' className='w-[16rem]' value={cst_type} onChange={handleTypeChange} />
<TextInput
id='dlg_cst_alias'
dense
label='Имя'
className='w-[7rem]'
{...register('alias')}
error={errors.alias}
/>
<SelectCstType id='dlg_cst_type' className='w-64' value={cst_type} onChange={handleTypeChange} />
<TextInput id='dlg_cst_alias' dense label='Имя' className='w-28' {...register('alias')} error={errors.alias} />
<BadgeHelp topic={HelpTopic.CC_CONSTITUENTA} offset={16} contentClass='sm:max-w-160' />
</div>
@ -61,7 +54,7 @@ export function FormCreateCst({ schema }: FormCreateCstProps) {
spellCheck
label='Термин'
placeholder='Обозначение для текстовых определений'
className='max-h-[3.6rem]'
className='max-h-15'
{...register('term_raw')}
error={errors.term_raw}
/>
@ -105,7 +98,7 @@ export function FormCreateCst({ schema }: FormCreateCstProps) {
fitContent
label='Текстовое определение'
placeholder='Текстовая интерпретация формального выражения'
className='max-h-[3.6rem]'
className='max-h-15'
value={field.value}
onChange={field.onChange}
/>
@ -132,7 +125,7 @@ export function FormCreateCst({ schema }: FormCreateCstProps) {
fitContent
label={isBasic ? 'Конвенция' : 'Комментарий'}
placeholder={isBasic ? 'Договоренность об интерпретации' : 'Пояснение разработчика'}
className='max-h-[5.4rem]'
className='max-h-20'
{...register('convention')}
/>
)}

View File

@ -3,7 +3,6 @@
import { Suspense, useState } from 'react';
import { FormProvider, useForm, useWatch } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
@ -65,7 +64,7 @@ export function DlgCstTemplate() {
<ModalForm
header='Создание конституенты из шаблона'
submitText='Создать'
className='w-[43rem] h-[35rem] px-6'
className='w-172 h-140 px-6'
canSubmit={isValid}
onSubmit={event => void methods.handleSubmit(onSubmit)(event)}
helpTopic={HelpTopic.RSL_TEMPLATES}
@ -76,7 +75,7 @@ export function DlgCstTemplate() {
selectedIndex={activeTab}
onSelect={setActiveTab}
>
<TabList className={clsx('mb-3 self-center', 'flex', 'border divide-x rounded-none', 'bg-prim-200')}>
<TabList className='mb-4 self-center flex border divide-x rounded-none bg-prim-200'>
<TabLabel label='Шаблон' title='Выбор шаблона выражения' className='w-32' />
<TabLabel label='Аргументы' title='Подстановка аргументов шаблона' className='w-32' />
<TabLabel label='Конституента' title='Редактирование конституенты' className='w-32' />

View File

@ -3,7 +3,6 @@
import { useState } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';
import { createColumnHelper } from '@tanstack/react-table';
import clsx from 'clsx';
import { MiniButton } from '@/components/Control';
import { DataTable, type IConditionalStyle } from '@/components/DataTable';
@ -79,16 +78,7 @@ export function TabArguments() {
argumentsHelper.accessor(arg => arg.typification, {
id: 'type',
enableHiding: true,
cell: props => (
<div
className={clsx(
'min-w-[9.3rem] max-w-[9.3rem]', //
'text-sm break-words'
)}
>
{props.getValue()}
</div>
)
cell: props => <div className='w-36 text-sm break-words'>{props.getValue()}</div>
}),
argumentsHelper.display({
id: 'actions',
@ -120,27 +110,15 @@ export function TabArguments() {
dense
noFooter
noHeader
className={clsx(
'max-h-[5.8rem] min-h-[5.8rem]', //
'cc-scroll-y',
'text-sm',
'border',
'select-none'
)}
className='h-23 cc-scroll-y text-sm border select-none'
data={args}
columns={columns}
conditionalRowStyles={conditionalRowStyles}
noDataComponent={<NoData className='min-h-[3.6rem]'>Аргументы отсутствуют</NoData>}
noDataComponent={<NoData className='min-h-14'>Аргументы отсутствуют</NoData>}
onRowClicked={handleSelectArgument}
/>
<div
className={clsx(
'my-4', //
'flex gap-2 justify-center items-center',
'select-none'
)}
>
<div className='my-3 flex gap-2 justify-center items-center select-none'>
<span
title='Выберите аргумент из списка сверху и значение из списка снизу'
className='font-semibold text-center'
@ -181,7 +159,7 @@ export function TabArguments() {
noTooltip
id='result'
placeholder='Итоговое определение'
className='mt-[1.1rem]'
className='mt-4'
height='5.1rem'
value={definition}
/>

View File

@ -60,7 +60,7 @@ export function TabTemplate() {
<SelectSingle
noBorder
placeholder='Источник'
className='w-[12rem]'
className='w-48'
options={templateSelector}
value={templateID ? { value: templateID, label: templates.find(item => item.id == templateID)!.title } : null}
onChange={data => onChangeTemplateID(data ? data.value : null)}

View File

@ -1,7 +1,6 @@
'use client';
import { useState } from 'react';
import clsx from 'clsx';
import { Checkbox } from '@/components/Input';
import { ModalForm } from '@/components/Modal';
@ -40,7 +39,7 @@ export function DlgDeleteCst() {
header='Удаление конституент'
submitText={expandOut ? 'Удалить с зависимыми' : 'Удалить'}
onSubmit={handleSubmit}
className={clsx('cc-column', 'max-w-[60vw] min-w-[30rem]', 'px-6')}
className='cc-column max-w-[60vw] min-w-120 px-6'
>
<ListConstituents title='Выбраны к удалению' list={selected} schema={schema} prefix={prefixes.cst_delete_list} />
<ListConstituents

View File

@ -1,5 +1,3 @@
import clsx from 'clsx';
import { labelConstituenta } from '../../labels';
import { type IRSForm } from '../../models/rsform';
@ -18,7 +16,7 @@ export function ListConstituents({ list, schema, title, prefix }: ListConstituen
{title}: <b>{list.length}</b>
</p>
) : null}
<div className={clsx('h-[9rem]', 'px-3', 'cc-scroll-y', 'border', 'whitespace-nowrap')}>
<div className='h-36 px-3 cc-scroll-y border whitespace-nowrap'>
{list.map(id => {
const cst = schema.cstByID.get(id);
return cst ? <p key={`${prefix}${cst.id}`}>{labelConstituenta(cst)}</p> : null;

View File

@ -3,7 +3,6 @@
import { useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { z } from 'zod';
import { HelpTopic } from '@/features/help';
@ -102,7 +101,7 @@ export function DlgEditReference() {
canSubmit={methods.formState.isValid}
onCancel={onCancel}
onSubmit={event => void methods.handleSubmit(onSubmit)(event)}
className='w-160 px-6 h-[32rem]'
className='w-160 px-6 h-128'
helpTopic={HelpTopic.TERM_CONTROL}
>
<Tabs
@ -111,7 +110,7 @@ export function DlgEditReference() {
selectedIndex={activeTab}
onSelect={handleChangeTab}
>
<TabList className={clsx('mb-3 self-center', 'flex', 'border divide-x rounded-none', 'bg-prim-200')}>
<TabList className='mb-3 self-center flex border divide-x rounded-none bg-prim-200'>
<TabLabel title='Отсылка на термин в заданной словоформе' label={labelReferenceType(ReferenceType.ENTITY)} />
<TabLabel
title='Установление синтаксической связи с отсылкой на термин'

View File

@ -46,7 +46,7 @@ export function TabEntityReference() {
dense
label='Конституента'
placeholder='Имя'
className='w-[11rem]'
className='w-44'
{...register('entity.entity')}
/>
<TextInput

View File

@ -28,7 +28,7 @@ export function TabSyntacticReference() {
type='number'
dense
label='Смещение'
className='max-w-[10rem]'
className='max-w-40'
{...register('syntactic.offset')}
/>
<TextInput

View File

@ -1,7 +1,5 @@
'use client';
import clsx from 'clsx';
import { MiniButton } from '@/components/Control';
import { createColumnHelper, DataTable } from '@/components/DataTable';
import { IconRemove } from '@/components/Icons';
@ -37,7 +35,7 @@ export function TableWordForms({ forms, setForms, onFormSelect }: TableWordForms
size: 350,
minSize: 500,
maxSize: 500,
cell: props => <div className='min-w-[25rem]'>{props.getValue()}</div>
cell: props => <div className='min-w-100'>{props.getValue()}</div>
}),
columnHelper.accessor('grams', {
id: 'grams',
@ -65,12 +63,12 @@ export function TableWordForms({ forms, setForms, onFormSelect }: TableWordForms
dense
noFooter
noHeader
className={clsx('mb-2', 'max-h-[17.4rem] min-h-[17.4rem]', 'border', 'text-sm', 'cc-scroll-y')}
className='mb-2 max-h-70 min-h-70 border text-sm cc-scroll-y'
data={forms}
columns={columns}
headPosition='0'
noDataComponent={
<NoData className='min-h-[2rem]'>
<NoData className='min-h-8'>
<p>Список пуст</p>
<p>Добавьте словоформу</p>
</NoData>

View File

@ -26,7 +26,7 @@ export function DlgGraphParams() {
header='Настройки графа термов'
onSubmit={event => void handleSubmit(onSubmit)(event)}
submitText='Применить'
className='flex gap-6 justify-between px-6 pb-3 w-[30rem]'
className='flex gap-6 justify-between px-6 pb-3 w-120'
>
<div className='flex flex-col gap-1'>
<h1 className='mb-2'>Преобразования</h1>

View File

@ -2,7 +2,6 @@
import { useForm, useWatch } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
@ -53,12 +52,12 @@ export function DlgRenameCst() {
submitInvalidTooltip='Введите незанятое имя, соответствующее типу'
canSubmit={isValid}
onSubmit={event => void handleSubmit(onSubmit)(event)}
className={clsx('w-[30rem]', 'py-6 pr-3 pl-6 flex gap-3 justify-center items-center ')}
className='w-120 py-6 pr-3 pl-6 flex gap-3 justify-center items-center'
helpTopic={HelpTopic.CC_CONSTITUENTA}
>
<SelectCstType
id='dlg_cst_type'
className='w-[16rem]'
className='w-64'
value={cst_type}
onChange={handleChangeType}
disabled={target.is_inherited}
@ -68,7 +67,7 @@ export function DlgRenameCst() {
{...register('alias')}
dense
label='Имя'
className='w-[7rem]'
className='w-28'
/>
</ModalForm>
);

View File

@ -1,6 +1,5 @@
'use client';
import clsx from 'clsx';
import { QRCodeSVG } from 'qrcode.react';
import { ModalView } from '@/components/Modal';
@ -13,7 +12,7 @@ export interface DlgShowQRProps {
export function DlgShowQR() {
const { target } = useDialogsStore(state => state.props as DlgShowQRProps);
return (
<ModalView className={clsx('w-[25rem]', 'pb-6 pt-12 flex justify-center items-center')}>
<ModalView className='w-100 pb-6 pt-12 flex justify-center items-center'>
<div className='bg-[#ffffff] p-4 border'>
<QRCodeSVG value={target} size={256} />
</div>

View File

@ -2,7 +2,6 @@
import { Controller, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import clsx from 'clsx';
import { HelpTopic } from '@/features/help';
@ -47,7 +46,7 @@ export function DlgSubstituteCst() {
submitInvalidTooltip='Выберите две различные конституенты'
canSubmit={isValid}
onSubmit={event => void handleSubmit(onSubmit)(event)}
className={clsx('w-160', 'px-6 pb-3')}
className='w-160 px-6 pb-3'
helpTopic={HelpTopic.UI_SUBSTITUTIONS}
>
<Controller

View File

@ -44,7 +44,7 @@ export function DlgUploadRSForm() {
canSubmit={!!file}
onSubmit={handleSubmit}
submitText='Загрузить'
className='w-[25rem] px-6'
className='w-100 px-6'
>
<FileInput label='Выбрать файл' acceptType={EXTEOR_TRS_FILE} onChange={handleFile} />
<Checkbox

View File

@ -76,8 +76,8 @@ export function EditorConstituenta() {
className={clsx(
'relative',
'cc-fade-in',
'min-h-[20rem] max-w-[calc(min(100vw,95rem))] mx-auto',
'flex pt-[1.9rem]',
'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 }
)}
@ -90,7 +90,7 @@ export function EditorConstituenta() {
onSubmit={initiateSubmit}
onReset={() => setToggleReset(prev => !prev)}
/>
<div className='mx-0 md:mx-auto pt-[2rem] md:w-[48.8rem] shrink-0 xs:pt-0'>
<div className='mx-0 md:mx-auto pt-8 md:w-195 shrink-0 xs:pt-0'>
{activeCst ? (
<FormConstituenta
id={globalIDs.constituenta_editor}

View File

@ -28,7 +28,7 @@ export function EditorControls({ constituenta, disabled, onEditTerm }: EditorCon
}
return (
<div className='absolute z-pop top-0 left-[4.7rem] flex select-none'>
<div className='absolute z-pop top-0 left-19 flex select-none'>
{!disabled || isProcessing ? (
<MiniButton
title={isModified ? tooltipText.unsaved : `Редактировать словоформы термина`}
@ -40,10 +40,10 @@ export function EditorControls({ constituenta, disabled, onEditTerm }: EditorCon
) : null}
<div
className={clsx(
'pt-1 sm:pl-[1.375rem] pl-1', //
'pt-1 sm:pl-5 pl-1',
'text-sm font-medium whitespace-nowrap',
'select-text cursor-default',
disabled && !isProcessing && 'pl-[1.6rem] sm:pl-[2.8rem]'
disabled && !isProcessing && 'pl-6 sm:pl-11'
)}
>
<span>Имя </span>

View File

@ -91,7 +91,7 @@ export function RSEditorControls({ isOpen, disabled, onEdit }: RSEditorControlsP
return (
<div
className={clsx(
'max-w-[28rem] min-w-[28rem] xs:max-w-[38.5rem] xs:min-w-[38.5rem] sm:max-w-160 sm:min-w-160 md:max-w-fit mx-1 sm:mx-0',
'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',
'text-xs md:text-sm',

View File

@ -31,7 +31,7 @@ export function RSLocalButton({
data-tooltip-content={title}
data-tooltip-hidden={hideTitle}
className={clsx(
'w-[1.7rem] sm:w-[2rem] h-5 sm:h-6',
'w-7 sm:w-8 h-5 sm:h-6',
'cursor-pointer disabled:cursor-default',
'rounded-none',
'clr-hover clr-text-controls cc-animate-color',

View File

@ -27,8 +27,8 @@ export function RSTokenButton({ token, disabled, onInsert }: RSTokenButtonProps)
'font-math',
'cursor-pointer disabled:cursor-default',
{
'w-[3.7rem] md:w-[4.5rem]': label.length > 3,
'w-[1.85rem] md:w-[2.25rem]': label.length <= 3
'w-14.5 md:w-18': label.length > 3,
'w-7.25 md:w-9': label.length <= 3
}
)}
data-tooltip-id={globalIDs.tooltip}

View File

@ -38,7 +38,12 @@ export function StatusBar({ isModified, processing, activeCst, parseData, onAnal
})();
return (
<div className={clsx('absolute z-pop -top-2 right-1/2 translate-x-1/2 w-fit', 'pl-34 xs:pl-8 flex gap-1')}>
<div
className={clsx(
'absolute z-pop -top-2 right-1/2 translate-x-1/2 w-fit', //
'pl-34 xs:pl-8 flex gap-1'
)}
>
<div
tabIndex={0}
className={clsx(

View File

@ -16,7 +16,7 @@ export function ToolbarRSExpression({ disabled, showTypeGraph, showAST }: Toolba
const toggleControls = usePreferencesStore(state => state.toggleShowExpressionControls);
return (
<div className='absolute z-pop top-[-0.5rem] right-0 cc-icons'>
<div className='absolute z-pop -top-2 right-0 cc-icons'>
{!disabled || isProcessing ? (
<MiniButton
title='Отображение специальной клавиатуры'

View File

@ -36,10 +36,10 @@ export function EditorRSFormCard() {
<div
onKeyDown={handleInput}
className={clsx(
'relative',
'relative', //
'cc-fade-in',
'md:w-fit md:max-w-fit max-w-[32rem]',
'flex flex-row flex-wrap px-6 pt-[1.9rem]'
'md:w-fit md:max-w-fit max-w-128',
'flex flex-row flex-wrap px-6 pt-8'
)}
>
<ToolbarItemCard onSubmit={initiateSubmit} schema={schema} isMutable={isMutable} deleteSchema={deleteSchema} />

View File

@ -32,7 +32,7 @@ export function RSFormStats({ stats, isArchive }: RSFormStatsProps) {
return (
<div
className={clsx(
'mt-3 md:ml-5 md:mt-8 md:w-56 w-80 h-min mx-auto', // prettier: split-lines
'mt-3 md:ml-5 md:mt-8 md:w-56 w-80 h-min mx-auto', //
'grid grid-cols-4 gap-1 justify-items-end'
)}
>

View File

@ -55,7 +55,7 @@ export function ToolbarVersioning({ blockReload }: ToolbarVersioningProps) {
}
return (
<div className='absolute z-bottom top-[-0.4rem] right-[0rem] pr-2 cc-icons'>
<div className='absolute z-bottom -top-2 right-0 pr-2 cc-icons'>
{isMutable ? (
<>
<MiniButton

View File

@ -1,7 +1,5 @@
'use client';
import clsx from 'clsx';
import { TextURL } from '@/components/Control';
import { createColumnHelper, DataTable, type RowSelectionState, type VisibilityState } from '@/components/DataTable';
import { NoData, TextContent } from '@/components/View';
@ -124,7 +122,7 @@ export function TableRSList({
<DataTable
dense
noFooter
className={clsx('min-h-64', 'cc-scroll-y', 'text-sm', 'select-none')}
className='min-h-64 cc-scroll-y text-sm select-none'
style={{ maxHeight: maxHeight }}
data={items ?? []}
columns={columns}

View File

@ -74,8 +74,8 @@ export function ViewHidden({ items }: ViewHiddenProps) {
tabIndex={-1}
className={clsx(
'flex flex-wrap justify-center gap-2 py-2 -mt-2',
'text-sm',
'clr-input border-x border-b rounded-b-md',
'text-sm',
'cc-scroll-y'
)}
style={{

View File

@ -76,7 +76,7 @@ export function RSTabs({ activeID, activeTab }: RSTabsProps) {
onSelect={onSelectTab}
defaultFocus
selectedTabClassName='clr-selected'
className='relative flex flex-col mx-auto min-w-fit items-center'
className='relative flex flex-col min-w-fit items-center'
>
<TabList
className={clsx(

View File

@ -26,13 +26,10 @@ export function ViewConstituents({ isBottom, isMounted }: ViewConstituentsProps)
return (
<aside
className={clsx(
'border', // prettier: split-lines
{
'mt-9 rounded-l-md rounded-r-none h-fit overflow-visible': !isBottom,
'mt-3 mx-6 rounded-md overflow-hidden': isBottom
}
)}
className={clsx('border', {
'mt-9 rounded-l-md rounded-r-none h-fit overflow-visible': !isBottom,
'mt-3 mx-6 rounded-md overflow-hidden': isBottom
})}
style={{
willChange: 'opacity, max-width',
transitionProperty: 'opacity, max-width',

View File

@ -4,15 +4,25 @@
@import './constants.css' layer(base);
/* Uncomment to debug layering and overflow */
/* *,
*::after,
*::before {
background: hsla(135, 50%, 50%, 0.05) !important;
outline: 2px solid hotpink !important;
:focus,
:focus-visible,
:focus-within {
outline: 2px solid hotpink !important;
}
} */
@layer utilities {
*,
*::after,
*::before {
box-sizing: border-box;
/* Uncomment to debug layering and overflow */
/* background: hsla(135, 50%, 50%, 0.05); */
/* outline: 2px solid hotpink; */
}
}

View File

@ -253,3 +253,14 @@
-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;
}