R: Simplify inline styles pt1

This commit is contained in:
Ivan 2025-03-13 01:14:47 +03:00
parent a2dd94637b
commit 503e447073
37 changed files with 106 additions and 212 deletions

View File

@ -1,5 +1,6 @@
import { Suspense } from 'react'; import { Suspense } from 'react';
import { Outlet } from 'react-router'; import { Outlet } from 'react-router';
import clsx from 'clsx';
import { ModalLoader } from '@/components/modal'; import { ModalLoader } from '@/components/modal';
import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/app-layout'; import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/app-layout';
@ -17,7 +18,6 @@ import { Navigation } from './navigation';
export function ApplicationLayout() { export function ApplicationLayout() {
const mainHeight = useMainHeight(); const mainHeight = useMainHeight();
const viewportHeight = useViewportHeight(); const viewportHeight = useViewportHeight();
const showScroll = useAppLayoutStore(state => !state.noScroll);
const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation); const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation);
const noNavigation = useAppLayoutStore(state => state.noNavigation); const noNavigation = useAppLayoutStore(state => state.noNavigation);
const noFooter = useAppLayoutStore(state => state.noFooter); const noFooter = useAppLayoutStore(state => state.noFooter);
@ -27,8 +27,7 @@ export function ApplicationLayout() {
<NavigationState> <NavigationState>
<div className='min-w-80 antialiased h-full max-w-480 mx-auto'> <div className='min-w-80 antialiased h-full max-w-480 mx-auto'>
<ToasterThemed <ToasterThemed
className='text-[14px]' className={clsx('text-[14px]', noNavigationAnimation ? 'mt-6' : 'mt-14')}
style={{ marginTop: noNavigationAnimation ? '1.5rem' : '3.5rem' }}
autoClose={3000} autoClose={3000}
draggable={false} draggable={false}
pauseOnFocusLoss={false} pauseOnFocusLoss={false}
@ -46,7 +45,7 @@ export function ApplicationLayout() {
style={{ maxHeight: viewportHeight }} style={{ maxHeight: viewportHeight }}
inert={activeDialog !== null} 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 /> <GlobalLoader />
<MutationErrors /> <MutationErrors />
<Outlet /> <Outlet />

View File

@ -1,7 +1,8 @@
import clsx from 'clsx';
import { IconLibrary2, IconManuals, IconNewItem2 } from '@/components/icons'; import { IconLibrary2, IconManuals, IconNewItem2 } from '@/components/icons';
import { useWindowSize } from '@/hooks/use-window-size'; import { useWindowSize } from '@/hooks/use-window-size';
import { useAppLayoutStore } from '@/stores/app-layout'; import { useAppLayoutStore } from '@/stores/app-layout';
import { PARAMETER } from '@/utils/constants';
import { urls } from '../urls'; 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'> <nav className='z-navigation sticky top-0 left-0 right-0 select-none bg-prim-100'>
<ToggleNavigation /> <ToggleNavigation />
<div <div
className='pl-2 pr-6 sm:pr-4 h-12 flex cc-shadow-border' className={clsx(
style={{ 'pl-2 pr-6 sm:pr-4 h-12 flex cc-shadow-border',
transitionProperty: 'max-height, translate', 'transition-[max-height,translate] ease-bezier duration-(--duration-move)',
transitionDuration: `${PARAMETER.moveDuration}ms`, noNavigationAnimation ? '-translate-y-6 max-h-0' : 'max-h-12'
transitionTimingFunction: 'ease-in-out', )}
maxHeight: noNavigationAnimation ? '0rem' : '3rem',
translate: noNavigationAnimation ? '0 -1.5rem' : '0'
}}
> >
<div className='flex items-center mr-auto cursor-pointer' onClick={!size.isSmall ? navigateHome : undefined}> <div className='flex items-center mr-auto cursor-pointer' onClick={!size.isSmall ? navigateHome : undefined}>
<Logo /> <Logo />

View File

@ -17,12 +17,9 @@ export function Divider({ vertical, margins = 'mx-2', className, ...restProps }:
return ( return (
<div <div
className={clsx( className={clsx(
margins, // vertical ? 'border-x' : 'border-y', //
className, margins,
{ className
'border-x': vertical,
'border-y': !vertical
}
)} )}
{...restProps} {...restProps}
/> />

View File

@ -26,7 +26,6 @@ export function Tooltip({
layer = 'z-tooltip', layer = 'z-tooltip',
place = 'bottom', place = 'bottom',
className, className,
style,
...restProps ...restProps
}: TooltipProps) { }: TooltipProps) {
const darkMode = usePreferencesStore(state => state.darkMode); const darkMode = usePreferencesStore(state => state.darkMode);
@ -40,6 +39,7 @@ export function Tooltip({
opacity={1} opacity={1}
className={clsx( className={clsx(
'relative', 'relative',
'py-0.5! px-2!',
'max-h-[calc(100svh-6rem)]', 'max-h-[calc(100svh-6rem)]',
'overflow-y-auto overflow-x-hidden sm:overflow-hidden overscroll-contain', 'overflow-y-auto overflow-x-hidden sm:overflow-hidden overscroll-contain',
'border shadow-md', 'border shadow-md',
@ -48,7 +48,6 @@ export function Tooltip({
className className
)} )}
classNameArrow={layer} classNameArrow={layer}
style={{ ...{ paddingTop: '2px', paddingBottom: '2px', paddingLeft: '8px', paddingRight: '8px' }, ...style }}
variant={darkMode ? 'dark' : 'light'} variant={darkMode ? 'dark' : 'light'}
place={place} place={place}
{...restProps} {...restProps}

View File

@ -43,15 +43,10 @@ export function Button({
'inline-flex gap-2 items-center justify-center', 'inline-flex gap-2 items-center justify-center',
'font-medium select-none disabled:cursor-auto', 'font-medium select-none disabled:cursor-auto',
'clr-btn-default cc-animate-color', 'clr-btn-default cc-animate-color',
{ dense ? 'px-1' : 'px-3 py-1',
'border rounded-sm': !noBorder, loading ? 'cursor-progress' : 'cursor-pointer',
'px-1': dense, noOutline ? 'outline-hidden' : 'clr-outline',
'px-3 py-1': !dense, !noBorder && 'border rounded-sm',
'cursor-progress': loading,
'cursor-pointer': !loading,
'outline-hidden': noOutline,
'clr-outline': !noOutline
},
className className
)} )}
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined} data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}

View File

@ -41,11 +41,8 @@ export function MiniButton({
'rounded-lg', 'rounded-lg',
'clr-text-controls cc-animate-color', 'clr-text-controls cc-animate-color',
'cursor-pointer disabled:cursor-auto', 'cursor-pointer disabled:cursor-auto',
{ noHover ? 'outline-hidden' : 'clr-hover',
'px-1 py-1': !noPadding, !noPadding && 'px-1 py-1',
'outline-hidden': noHover,
'clr-hover': !noHover
},
className className
)} )}
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined} data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}

View File

@ -38,10 +38,7 @@ export function SelectorButton({
'text-btn clr-text-controls', 'text-btn clr-text-controls',
'disabled:cursor-auto cursor-pointer', 'disabled:cursor-auto cursor-pointer',
'cc-animate-color', 'cc-animate-color',
{ transparent ? 'clr-hover' : 'clr-btn-default border',
'clr-hover': transparent,
'clr-btn-default border': !transparent
},
className className
)} )}
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined} data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}

View File

@ -93,11 +93,12 @@ export function TableBody<TData>({
{row.getVisibleCells().map((cell: Cell<TData, unknown>) => ( {row.getVisibleCells().map((cell: Cell<TData, unknown>) => (
<td <td
key={cell.id} key={cell.id}
className='px-2 align-middle border-y' className={clsx(
'px-2 align-middle border-y',
dense ? 'py-1' : 'py-2',
onRowClicked || onRowDoubleClicked ? 'cursor-pointer' : 'cursor-auto'
)}
style={{ 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 width: noHeader && index === 0 ? `calc(var(--col-${cell.column.id}-size) * 1px)` : undefined
}} }}
> >

View File

@ -1,6 +1,7 @@
'use no memo'; 'use no memo';
import { flexRender, type Header, type HeaderGroup, type Table } from '@tanstack/react-table'; import { flexRender, type Header, type HeaderGroup, type Table } from '@tanstack/react-table';
import clsx from 'clsx';
import { SelectAll } from './select-all'; import { SelectAll } from './select-all';
import { SortingIcon } from './sorting-icon'; import { SortingIcon } from './sorting-icon';
@ -13,13 +14,7 @@ interface TableHeaderProps<TData> {
export function TableHeader<TData>({ table, headPosition, resetLastSelected }: TableHeaderProps<TData>) { export function TableHeader<TData>({ table, headPosition, resetLastSelected }: TableHeaderProps<TData>) {
return ( return (
<thead <thead className='sticky bg-prim-100 cc-shadow-border' style={{ top: headPosition }}>
className='bg-prim-100 cc-shadow-border'
style={{
top: headPosition,
position: 'sticky'
}}
>
{table.getHeaderGroups().map((headerGroup: HeaderGroup<TData>) => ( {table.getHeaderGroups().map((headerGroup: HeaderGroup<TData>) => (
<tr key={headerGroup.id}> <tr key={headerGroup.id}>
{table.options.enableRowSelection ? ( {table.options.enableRowSelection ? (
@ -32,11 +27,11 @@ export function TableHeader<TData>({ table, headPosition, resetLastSelected }: T
key={header.id} key={header.id}
colSpan={header.colSpan} colSpan={header.colSpan}
scope='col' scope='col'
className='cc-table-header group' className={clsx(
style={{ 'cc-table-header group',
width: `calc(var(--header-${header?.id}-size) * 1px)`, table.options.enableSorting && header.column.getCanSort() ? 'cursor-pointer' : 'cursor-auto'
cursor: table.options.enableSorting && header.column.getCanSort() ? 'pointer' : 'auto' )}
}} style={{ width: `calc(var(--header-${header?.id}-size) * 1px)` }}
onClick={table.options.enableSorting ? header.column.getToggleSortingHandler() : undefined} onClick={table.options.enableSorting ? header.column.getToggleSortingHandler() : undefined}
> >
{!header.isPlaceholder ? ( {!header.isPlaceholder ? (

View File

@ -39,11 +39,7 @@ export function DropdownButton({
'text-left text-sm text-ellipsis whitespace-nowrap', 'text-left text-sm text-ellipsis whitespace-nowrap',
'disabled:clr-text-controls', 'disabled:clr-text-controls',
'cc-animate-color', 'cc-animate-color',
{ !!onClick ? 'clr-hover cursor-pointer disabled:cursor-auto' : 'clr-btn-default',
'clr-hover': onClick,
'cursor-pointer disabled:cursor-auto': onClick,
'cursor-default': !onClick
},
className className
)} )}
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined} data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}

View File

@ -1,8 +1,6 @@
import React from 'react'; import React from 'react';
import clsx from 'clsx'; import clsx from 'clsx';
import { PARAMETER } from '@/utils/constants';
import { type Styling } from '../props'; import { type Styling } from '../props';
interface DropdownProps extends Styling { interface DropdownProps extends Styling {
@ -44,24 +42,17 @@ export function Dropdown({
tabIndex={-1} tabIndex={-1}
className={clsx( className={clsx(
'z-topmost absolute', 'z-topmost absolute',
{ stretchLeft ? 'right-0' : 'left-0',
'right-0': stretchLeft, stretchTop ? 'bottom-0' : 'top-full',
'left-0': !stretchLeft,
'bottom-0': stretchTop,
'top-full': !stretchTop
},
'grid', 'grid',
'border rounded-md shadow-lg', 'border rounded-md shadow-lg',
'clr-input', 'clr-input',
'text-sm', 'text-sm',
'ease-in-out duration-(--duration-dropdown) will-change-[clip-path,transform] transition-[clip-path,transform]',
margin, margin,
className className
)} )}
style={{ style={{
willChange: 'clip-path, transform',
transitionProperty: 'clip-path, transform',
transitionDuration: `${PARAMETER.dropdownDuration}ms`,
transitionTimingFunction: 'ease-in-out',
transform: isOpen ? 'translateY(0)' : 'translateY(-10%)', transform: isOpen ? 'translateY(0)' : 'translateY(-10%)',
clipPath: isOpen ? 'inset(0% 0% 0% 0%)' : 'inset(10% 0% 90% 0%)', clipPath: isOpen ? 'inset(0% 0% 0% 0%)' : 'inset(10% 0% 90% 0%)',
...style ...style

View File

@ -33,18 +33,7 @@ export function DescribeError({ error }: { error: ErrorData }) {
<p> <p>
<b>Message:</b> {error.message} <b>Message:</b> {error.message}
</p> </p>
{error.stack && ( {error.stack && <pre className='whitespace-pre-wrap p-2 overflow-x-auto break-words'>{error.stack}</pre>}
<pre
style={{
whiteSpace: 'pre-wrap',
wordWrap: 'break-word',
padding: '6px',
overflowX: 'auto'
}}
>
{error.stack}
</pre>
)}
</div> </div>
); );
} }

View File

@ -67,10 +67,7 @@ export function CheckboxTristate({
className={clsx( className={clsx(
'w-4 h-4', // 'w-4 h-4', //
'border rounded-sm', 'border rounded-sm',
{ value === false ? 'bg-prim-100' : 'bg-sec-600 text-sec-0'
'bg-sec-600 text-sec-0': value !== false,
'bg-prim-100': value === false
}
)} )}
> >
{value ? <CheckboxChecked /> : null} {value ? <CheckboxChecked /> : null}

View File

@ -66,10 +66,7 @@ export function Checkbox({
className={clsx( className={clsx(
'w-4 h-4', // 'w-4 h-4', //
'border rounded-sm', 'border rounded-sm',
{ value === false ? 'bg-prim-100' : 'bg-sec-600 text-sec-0'
'bg-sec-600 text-sec-0': value !== false,
'bg-prim-100': value === false
}
)} )}
> >
{value ? <CheckboxChecked /> : null} {value ? <CheckboxChecked /> : null}

View File

@ -46,7 +46,7 @@ export function FileInput({ id, label, acceptType, title, className, style, onCh
id={id} id={id}
type='file' type='file'
ref={inputRef} ref={inputRef}
style={{ display: 'none' }} className='hidden'
accept={acceptType} accept={acceptType}
onChange={handleFileChange} onChange={handleFileChange}
{...restProps} {...restProps}

View File

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import clsx from 'clsx'; import clsx from 'clsx';
import { globalIDs, PARAMETER } from '@/utils/constants'; import { globalIDs } from '@/utils/constants';
import { MiniButton } from '../control'; import { MiniButton } from '../control';
import { IconDropArrow, IconPageRight } from '../icons'; import { IconDropArrow, IconPageRight } from '../icons';
@ -89,27 +89,13 @@ export function SelectTree<ItemType>({
<div <div
key={`${prefix}${index}`} key={`${prefix}${index}`}
className={clsx( className={clsx(
'relative', 'cc-tree-item cc-scroll-row clr-hover',
'pr-3 pl-6 border-b', isActive ? 'max-h-7 py-1 border-b' : 'max-h-0 opacity-0 pointer-events-none',
'cc-scroll-row', value === item && 'clr-selected'
'bg-prim-200 clr-hover cc-animate-color',
'cursor-pointer',
value === item && 'clr-selected',
!isActive && 'pointer-events-none'
)} )}
data-tooltip-id={globalIDs.tooltip} data-tooltip-id={globalIDs.tooltip}
data-tooltip-html={getDescription(item)} data-tooltip-html={getDescription(item)}
onClick={event => handleClickItem(event, 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) ? ( {foldable.has(item) ? (
<MiniButton <MiniButton

View File

@ -40,11 +40,8 @@ export function TextArea({
return ( return (
<div <div
className={clsx( className={clsx(
'w-full', 'w-full', //
{ dense ? 'flex grow items-center gap-3' : 'flex flex-col',
'flex flex-col': !dense,
'flex grow items-center gap-3': dense
},
dense && className dense && className
)} )}
> >
@ -55,16 +52,13 @@ export function TextArea({
'px-3 py-2', 'px-3 py-2',
'leading-tight', 'leading-tight',
'overflow-x-hidden overflow-y-auto', 'overflow-x-hidden overflow-y-auto',
{ !noBorder && 'border',
'field-sizing-content': fitContent, fitContent && 'field-sizing-content',
'resize-none': noResize, noResize && 'resize-none',
'border': !noBorder, transparent ? 'bg-transparent' : 'clr-input',
'grow max-w-full': dense, !noOutline && 'clr-outline',
'mt-2': !dense && !!label, dense && 'grow max-w-full',
'clr-outline': !noOutline, !dense && !!label && 'mt-2',
'bg-transparent': transparent,
'clr-input': !transparent
},
!dense && className !dense && className
)} )}
rows={rows} rows={rows}

View File

@ -42,10 +42,7 @@ export function TextInput({
return ( return (
<div <div
className={clsx( className={clsx(
{ dense ? 'flex items-center gap-3' : 'flex flex-col', //
'flex flex-col': !dense,
'flex items-center gap-3': dense
},
dense && className dense && className
)} )}
> >
@ -55,15 +52,12 @@ export function TextInput({
className={clsx( className={clsx(
'min-w-0 py-2', 'min-w-0 py-2',
'leading-tight truncate hover:text-clip', 'leading-tight truncate hover:text-clip',
{ transparent ? 'bg-transparent' : 'clr-input',
'px-3': !noBorder || !disabled, !noBorder && 'border',
'grow max-w-full': dense, !noOutline && 'clr-outline',
'mt-2': !dense && !!label, (!noBorder || !disabled) && 'px-3',
'border': !noBorder, dense && 'grow max-w-full',
'clr-outline': !noOutline, !dense && !!label && 'mt-2',
'bg-transparent': transparent,
'clr-input': !transparent
},
!dense && className !dense && className
)} )}
onKeyDown={!allowEnter && !onKeyDown ? preventEnterCapture : onKeyDown} onKeyDown={!allowEnter && !onKeyDown ? preventEnterCapture : onKeyDown}

View File

@ -124,10 +124,7 @@ export function ModalForm({
'@container/modal', '@container/modal',
'max-h-[calc(100svh-8rem)] max-w-[100svw] xs:max-w-[calc(100svw-2rem)]', 'max-h-[calc(100svh-8rem)] max-w-[100svw] xs:max-w-[calc(100svw-2rem)]',
'overscroll-contain outline-hidden', 'overscroll-contain outline-hidden',
{ overflowVisible ? 'overflow-visible' : 'overflow-auto',
'overflow-auto': !overflowVisible,
'overflow-visible': overflowVisible
},
className className
)} )}
{...restProps} {...restProps}

View File

@ -73,10 +73,7 @@ export function ModalView({
'@container/modal', '@container/modal',
'max-h-[calc(100svh-8rem)] max-w-[100svw] xs:max-w-[calc(100svw-2rem)]', 'max-h-[calc(100svh-8rem)] max-w-[100svw] xs:max-w-[calc(100svw-2rem)]',
'overscroll-contain outline-hidden', 'overscroll-contain outline-hidden',
{ overflowVisible ? 'overflow-visible' : 'overflow-auto',
'overflow-auto': !overflowVisible,
'overflow-visible': overflowVisible
},
className className
)} )}
{...restProps} {...restProps}

View File

@ -18,11 +18,9 @@ export function Indicator({ icon, title, titleHtml, hideTitle, noPadding, classN
return ( return (
<div <div
className={clsx( className={clsx(
'clr-text-controls', 'clr-text-controls', //
'outline-hidden', 'outline-hidden',
{ !noPadding && 'px-1 py-1',
'px-1 py-1': !noPadding
},
className className
)} )}
data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined} data-tooltip-id={!!title || !!titleHtml ? globalIDs.tooltip : undefined}

View File

@ -57,7 +57,7 @@ export function ValueIcon({
'flex items-center', 'flex items-center',
'text-right', 'text-right',
'hover:cursor-default', 'hover:cursor-default',
{ 'justify-between gap-6': !dense, 'gap-1': dense }, dense ? 'gap-1' : 'justify-between gap-6',
className className
)} )}
{...restProps} {...restProps}

View File

@ -7,7 +7,6 @@ import { IconHelp } from '@/components/icons';
import { Loader } from '@/components/loader'; import { Loader } from '@/components/loader';
import { type Styling } from '@/components/props'; import { type Styling } from '@/components/props';
import { usePreferencesStore } from '@/stores/preferences'; import { usePreferencesStore } from '@/stores/preferences';
import { PARAMETER } from '@/utils/constants';
import { type HelpTopic } from '../models/help-topic'; import { type HelpTopic } from '../models/help-topic';
@ -48,7 +47,7 @@ export function BadgeHelp({ topic, padding = 'p-1', className, contentClass, sty
clickable clickable
anchorSelect={`#help-${topic}`} anchorSelect={`#help-${topic}`}
layer='z-topmost' layer='z-topmost'
className={clsx(PARAMETER.TOOLTIP_WIDTH, contentClass)} className={clsx('max-w-120', contentClass)}
{...restProps} {...restProps}
> >
<Suspense fallback={<Loader />}> <Suspense fallback={<Loader />}>

View File

@ -32,14 +32,11 @@ export function TopicsDropdown({ activeTopic, onChangeTopic }: TopicsDropdownPro
ref={menu.ref} ref={menu.ref}
className={clsx( className={clsx(
'absolute left-0 w-54', // 'absolute left-0 w-54', //
noNavigation ? 'top-0' : 'top-12',
'flex flex-col', 'flex flex-col',
'z-topmost', 'z-topmost',
'text-xs sm:text-sm', 'text-xs sm:text-sm',
'select-none', 'select-none'
{
'top-0': noNavigation,
'top-12': !noNavigation
}
)} )}
> >
<Button <Button

View File

@ -60,7 +60,7 @@ export function TableLibraryItems({ items }: TableLibraryItemsProps) {
columns={columns} columns={columns}
data={items} data={items}
headPosition='0' 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 }} style={{ maxHeight: tableHeight }}
noDataComponent={ noDataComponent={
<div className='cc-column dense p-3 items-center min-h-24'> <div className='cc-column dense p-3 items-center min-h-24'>

View File

@ -107,10 +107,7 @@ export function PickMultiOperation({ rows, items, value, onChange, className, ..
]; ];
return ( return (
<div <div className={clsx('flex flex-col gap-1 border-t border-x rounded-md clr-input', className)} {...restProps}>
className={clsx('flex flex-col gap-1', ' border-t border-x rounded-md', 'clr-input', className)}
{...restProps}
>
<SelectOperation <SelectOperation
noBorder noBorder
items={nonSelectedItems} // items={nonSelectedItems} //

View File

@ -98,7 +98,7 @@ export function PickMultiConstituenta({
]; ];
return ( 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='px-3 flex justify-between items-center clr-input border-b rounded-t-md'>
<div className='w-[24ch] select-none whitespace-nowrap'> <div className='w-[24ch] select-none whitespace-nowrap'>
{items.length > 0 ? `Выбраны ${value.length} из ${items.length}` : 'Конституенты'} {items.length > 0 ? `Выбраны ${value.length} из ${items.length}` : 'Конституенты'}

View File

@ -79,7 +79,7 @@ export function EditorConstituenta() {
'min-h-80 max-w-[calc(min(100vw,95rem))] mx-auto', 'min-h-80 max-w-[calc(min(100vw,95rem))] mx-auto',
'flex pt-8', 'flex pt-8',
'overflow-y-auto overflow-x-clip', 'overflow-y-auto overflow-x-clip',
{ 'flex-col md:items-center': isNarrow } isNarrow && 'flex-col md:items-center'
)} )}
style={{ maxHeight: mainHeight }} style={{ maxHeight: mainHeight }}
onKeyDown={handleInput} onKeyDown={handleInput}

View File

@ -26,10 +26,7 @@ export function RSTokenButton({ token, disabled, onInsert }: RSTokenButtonProps)
'clr-hover clr-text-controls cc-animate-color', 'clr-hover clr-text-controls cc-animate-color',
'font-math', 'font-math',
'cursor-pointer disabled:cursor-default', 'cursor-pointer disabled:cursor-default',
{ label.length > 3 ? 'w-14.5 md:w-18' : 'w-7.25 md:w-9'
'w-14.5 md:w-18': label.length > 3,
'w-7.25 md:w-9': label.length <= 3
}
)} )}
data-tooltip-id={globalIDs.tooltip} data-tooltip-id={globalIDs.tooltip}
data-tooltip-html={describeToken(token)} data-tooltip-html={describeToken(token)}

View File

@ -1,7 +1,5 @@
'use client'; 'use client';
import clsx from 'clsx';
import { EditorLibraryItem, ToolbarItemCard } from '@/features/library/components'; import { EditorLibraryItem, ToolbarItemCard } from '@/features/library/components';
import { useModificationStore } from '@/stores/modification'; import { useModificationStore } from '@/stores/modification';
@ -35,12 +33,7 @@ export function EditorRSFormCard() {
return ( return (
<div <div
onKeyDown={handleInput} onKeyDown={handleInput}
className={clsx( className='relative cc-fade-in md:w-fit md:max-w-fit max-w-128 flex flex-row flex-wrap px-6 pt-8'
'relative', //
'cc-fade-in',
'md:w-fit md:max-w-fit max-w-128',
'flex flex-row flex-wrap px-6 pt-8'
)}
> >
<ToolbarItemCard <ToolbarItemCard
className='cc-tab-tools' className='cc-tab-tools'

View File

@ -56,7 +56,7 @@ export function ViewHidden({ items }: ViewHiddenProps) {
onClick={toggleFolded} onClick={toggleFolded}
/> />
<div className={clsx('py-2 clr-input border-x', { 'border-b rounded-b-md': isFolded })}> <div className={clsx('py-2 clr-input border-x', isFolded && 'border-b rounded-b-md')}>
<div <div
className='w-fit select-none' className='w-fit select-none'
style={{ style={{

View File

@ -6,7 +6,6 @@ import { useRoleStore, UserRole } from '@/features/users';
import { useWindowSize } from '@/hooks/use-window-size'; import { useWindowSize } from '@/hooks/use-window-size';
import { useFitHeight } from '@/stores/app-layout'; import { useFitHeight } from '@/stores/app-layout';
import { PARAMETER } from '@/utils/constants';
import { ConstituentsSearch } from './constituents-search'; import { ConstituentsSearch } from './constituents-search';
import { TableSideConstituents } from './table-side-constituents'; import { TableSideConstituents } from './table-side-constituents';
@ -29,19 +28,11 @@ export function ViewConstituents({ className, isBottom, isMounted }: ViewConstit
<aside <aside
className={clsx( className={clsx(
'border', 'border',
{ isBottom ? 'rounded-md' : 'rounded-l-md rounded-r-none',
'rounded-l-md rounded-r-none': !isBottom, isMounted ? 'max-w-full' : 'opacity-0 max-w-0',
'rounded-md': isBottom 'ease-in-out duration-1000 transition-[opacity,max-width]',
},
className 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} /> <ConstituentsSearch dense={!!windowSize.width && windowSize.width < COLUMN_DENSE_SEARCH_THRESHOLD} />
<TableSideConstituents maxHeight={listHeight} autoScroll={!isBottom} /> <TableSideConstituents maxHeight={listHeight} autoScroll={!isBottom} />

View File

@ -50,4 +50,12 @@
--breakpoint-lg: 1024px; --breakpoint-lg: 1024px;
--breakpoint-xl: 1280px; --breakpoint-xl: 1280px;
--breakpoint-2xl: 1536px; --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;
} }

View File

@ -10,9 +10,6 @@ interface AppLayoutStore {
noFooter: boolean; noFooter: boolean;
hideFooter: (value?: boolean) => void; hideFooter: (value?: boolean) => void;
noScroll: boolean;
hideScroll: (value?: boolean) => void;
} }
export const useAppLayoutStore = create<AppLayoutStore>()(set => ({ export const useAppLayoutStore = create<AppLayoutStore>()(set => ({
@ -29,10 +26,7 @@ export const useAppLayoutStore = create<AppLayoutStore>()(set => ({
}), }),
noFooter: false, noFooter: false,
hideFooter: value => set({ noFooter: value ?? true }), hideFooter: value => set({ noFooter: value ?? true })
noScroll: true,
hideScroll: value => set({ noScroll: value ?? true })
})); }));
/** Utility function that returns the height of the main area. */ /** Utility function that returns the height of the main area. */

View File

@ -15,13 +15,6 @@
--text-max-width: 75ch; --text-max-width: 75ch;
--scroll-padding: 3rem; --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 */ /* Light Theme */

View File

@ -195,7 +195,7 @@
opacity: 1; opacity: 1;
transition-property: opacity; transition-property: opacity;
transition-timing-function: var(--transition-bezier); transition-timing-function: var(--ease-bezier);
transition-duration: var(--duration-fade); transition-duration: var(--duration-fade);
@starting-style { @starting-style {
@ -205,7 +205,7 @@
@utility cc-animate-position { @utility cc-animate-position {
transition-property: transform top left bottom right margin padding; 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); transition-duration: var(--duration-move);
} }
@ -214,7 +214,7 @@
opacity: 1; opacity: 1;
transition-property: clip-path, opacity; transition-property: clip-path, opacity;
transition-timing-function: var(--transition-bezier); transition-timing-function: var(--ease-bezier);
transition-duration: var(--duration-modal); transition-duration: var(--duration-modal);
@starting-style { @starting-style {
@ -225,10 +225,23 @@
@utility cc-animate-color { @utility cc-animate-color {
transition-property: color, background-color; transition-property: color, background-color;
transition-timing-function: var(--transition-bezier); transition-timing-function: var(--ease-bezier);
transition-duration: var(--duration-select); transition-duration: var(--duration-select);
} }
@utility cc-tree-item {
position: relative;
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 { @utility cc-badge-constituenta {
width: 3rem; width: 3rem;
padding-inline: 0.25rem; padding-inline: 0.25rem;

View File

@ -31,9 +31,7 @@ export const PARAMETER = {
logicLabel: 'LOGIC', logicLabel: 'LOGIC',
errorNodeLabel: '[ERROR]', errorNodeLabel: '[ERROR]',
exteorVersion: '4.9.7', exteorVersion: '4.9.7'
TOOLTIP_WIDTH: 'max-w-120'
}; };
/** /**