Components refactoring and small fixes

This commit is contained in:
IRBorisov 2023-11-05 16:31:49 +03:00
parent 6e610b5806
commit bdbf77faa2
17 changed files with 78 additions and 55 deletions

View File

@ -1,35 +1,35 @@
import { IColorsProps, IControlProps } from '../commonInterfaces'
interface ButtonProps interface ButtonProps
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className' | 'children' | 'title'| 'type'> { extends IControlProps, IColorsProps, Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className' | 'children' | 'title'| 'type'> {
text?: string text?: string
icon?: React.ReactNode icon?: React.ReactNode
tooltip?: string
dense?: boolean dense?: boolean
loading?: boolean loading?: boolean
dimensions?: string
borderClass?: string
colorClass?: string
} }
function Button({ function Button({
text, icon, tooltip, text, icon, tooltip,
dense, disabled, dense, disabled, noBorder, noOutline,
borderClass = 'border rounded', colors = 'clr-btn-default',
colorClass = 'clr-btn-default',
dimensions = 'w-fit h-fit', dimensions = 'w-fit h-fit',
loading, loading,
...props ...props
}: ButtonProps) { }: ButtonProps) {
const borderClass = noBorder ? '' : 'border rounded';
const padding = dense ? 'px-1' : 'px-3 py-2'; const padding = dense ? 'px-1' : 'px-3 py-2';
const outlineClass = noOutline ? 'outline-none': 'clr-outline';
const cursor = 'disabled:cursor-not-allowed ' + (loading ? 'cursor-progress ' : 'cursor-pointer '); const cursor = 'disabled:cursor-not-allowed ' + (loading ? 'cursor-progress ' : 'cursor-pointer ');
return ( return (
<button type='button' <button type='button'
disabled={disabled ?? loading} disabled={disabled ?? loading}
title={tooltip} title={tooltip}
className={`inline-flex items-center gap-2 align-middle justify-center select-none ${padding} ${colorClass} ${dimensions} ${borderClass} ${cursor}`} className={`inline-flex items-center gap-2 align-middle justify-center select-none ${padding} ${colors} ${outlineClass} ${borderClass} ${dimensions} ${cursor}`}
{...props} {...props}
> >
{icon && icon} {icon && icon}
{text && <span className={'font-semibold'}>{text}</span>} {text && <span className='font-semibold'>{text}</span>}
</button> </button>
); );
} }

View File

@ -7,13 +7,18 @@ extends Omit<ITooltip, 'variant'> {
layer?: string layer?: string
} }
function ConceptTooltip({ className, layer, place='bottom', ...props }: ConceptTooltipProps) { function ConceptTooltip({
className,
layer='z-tooltip',
place='bottom',
...props
}: ConceptTooltipProps) {
const { darkMode } = useConceptTheme(); const { darkMode } = useConceptTheme();
return ( return (
<Tooltip <Tooltip
opacity={0.97} opacity={0.97}
className={`overflow-auto border shadow-md ${layer ?? 'z-tooltip'} ${className}`} className={`overflow-auto border shadow-md ${layer} ${className}`}
variant={(darkMode ? 'dark' : 'light')} variant={(darkMode ? 'dark' : 'light')}
place={place} place={place}
{...props} {...props}

View File

@ -8,8 +8,9 @@ interface FileInputProps
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'className' | 'title' | 'style' | 'accept' | 'type'> { extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'className' | 'title' | 'style' | 'accept' | 'type'> {
label: string label: string
tooltip?: string tooltip?: string
acceptType?: string
dimensions?: string dimensions?: string
acceptType?: string
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
} }

View File

@ -52,7 +52,7 @@ function Modal({
text={submitText} text={submitText}
tooltip={!canSubmit ? submitInvalidTooltip: ''} tooltip={!canSubmit ? submitInvalidTooltip: ''}
dimensions='min-w-[6rem] min-h-[2.6rem] w-fit h-fit' dimensions='min-w-[6rem] min-h-[2.6rem] w-fit h-fit'
colorClass='clr-btn-primary' colors='clr-btn-primary'
disabled={!canSubmit} disabled={!canSubmit}
onClick={handleSubmit} onClick={handleSubmit}
autoFocus autoFocus

View File

@ -5,14 +5,14 @@ extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className' | 'child
tooltip?: string tooltip?: string
dimensions?: string dimensions?: string
borderClass?: string borderClass?: string
colorClass?: string colors?: string
transparent?: boolean transparent?: boolean
} }
function SelectorButton({ function SelectorButton({
text, icon, tooltip, text, icon, tooltip,
colorClass = 'clr-btn-default', colors = 'clr-btn-default',
dimensions = 'w-fit h-fit', dimensions = 'w-fit h-fit',
transparent, transparent,
...props ...props
@ -21,7 +21,7 @@ function SelectorButton({
const position = `px-1 flex flex-start items-center gap-1 ${dimensions}` const position = `px-1 flex flex-start items-center gap-1 ${dimensions}`
return ( return (
<button type='button' <button type='button'
className={`text-sm small-caps ${!transparent && 'border'} ${cursor} ${position} text-btn text-controls select-none ${transparent ? 'clr-hover' : colorClass}`} className={`text-sm small-caps ${!transparent && 'border'} ${cursor} ${position} text-btn text-controls select-none ${transparent ? 'clr-hover' : colors}`}
title={tooltip} title={tooltip}
{...props} {...props}
> >

View File

@ -1,23 +1,22 @@
import { TextareaHTMLAttributes } from 'react'; import { TextareaHTMLAttributes } from 'react';
import { IColorsProps, IEditorProps } from '../commonInterfaces';
import Label from './Label'; import Label from './Label';
export interface TextAreaProps export interface TextAreaProps
extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'className' | 'title'> { extends IEditorProps, IColorsProps, Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'className' | 'title'> {
label?: string
tooltip?: string
dimensions?: string
dense?: boolean dense?: boolean
colorClass?: string
} }
function TextArea({ function TextArea({
id, label, required, tooltip, dense, id, label, required, tooltip, dense, noBorder, noOutline,
dimensions = 'w-full', dimensions = 'w-full',
colorClass = 'clr-input', colors = 'clr-input',
rows = 4, rows = 4,
...props ...props
}: TextAreaProps) { }: TextAreaProps) {
const borderClass = noBorder ? '': 'border';
const outlineClass = noOutline ? '': 'clr-outline';
return ( return (
<div className={`flex ${dense ? 'items-center gap-4 ' + dimensions : 'flex-col items-start gap-2'}`}> <div className={`flex ${dense ? 'items-center gap-4 ' + dimensions : 'flex-col items-start gap-2'}`}>
{label && {label &&
@ -27,7 +26,7 @@ function TextArea({
/>} />}
<textarea id={id} <textarea id={id}
title={tooltip} title={tooltip}
className={`px-3 py-2 leading-tight border clr-outline ${colorClass} ${dense ? 'w-full' : dimensions}`} className={`px-3 py-2 leading-tight ${outlineClass} ${borderClass} ${colors} ${dense ? 'w-full' : dimensions}`}
rows={rows} rows={rows}
required={required} required={required}
{...props} {...props}

View File

@ -1,21 +1,22 @@
import { IColorsProps, IEditorProps } from '../commonInterfaces';
import Label from './Label'; import Label from './Label';
interface TextInputProps interface TextInputProps
extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'className' | 'title'> { extends IEditorProps, IColorsProps, Omit<React.InputHTMLAttributes<HTMLInputElement>, 'className' | 'title'> {
id?: string
label?: string
tooltip?: string
dimensions?: string
colorClass?: string
dense?: boolean dense?: boolean
noBorder?: boolean allowEnter?: boolean
noOutline?: boolean }
function preventEnterCapture(event: React.KeyboardEvent<HTMLInputElement>) {
if (event.key === 'Enter') {
event.preventDefault();
}
} }
function TextInput({ function TextInput({
id, required, label, dense, tooltip, noBorder, noOutline, id, label, dense, tooltip, noBorder, noOutline, allowEnter, onKeyDown,
dimensions = 'w-full', dimensions = 'w-full',
colorClass = 'clr-input', colors = 'clr-input',
...props ...props
}: TextInputProps) { }: TextInputProps) {
const borderClass = noBorder ? '': 'border'; const borderClass = noBorder ? '': 'border';
@ -29,8 +30,9 @@ function TextInput({
/>} />}
<input id={id} <input id={id}
title={tooltip} title={tooltip}
className={`px-3 py-2 leading-tight truncate hover:text-clip ${outlineClass} ${borderClass} ${colorClass} ${dense ? 'w-full' : dimensions}`}
required={required} onKeyDown={!allowEnter && !onKeyDown ? preventEnterCapture: onKeyDown}
className={`px-3 py-2 leading-tight truncate hover:text-clip ${colors} ${outlineClass} ${borderClass} ${dense ? 'w-full' : dimensions}`}
{...props} {...props}
/> />
</div> </div>

View File

@ -0,0 +1,17 @@
// =========== Module contains interfaces for common UI elements. ==========
export interface IControlProps {
tooltip?: string
dimensions?: string
disabled?: boolean
noBorder?: boolean
noOutline?: boolean
}
export interface IEditorProps extends IControlProps {
label?: string
}
export interface IColorsProps {
colors?: string
}

View File

@ -243,7 +243,6 @@
} }
:is(.clr-outline, :is(.clr-outline,
.clr-btn-default,
.clr-btn-primary .clr-btn-primary
):focus { ):focus {
outline-width: 2px; outline-width: 2px;

View File

@ -91,18 +91,18 @@ function LoginPage() {
onSubmit={handleSubmit} onSubmit={handleSubmit}
dimensions='w-[24rem]' dimensions='w-[24rem]'
> >
<TextInput id='username' <TextInput id='username' type='text'
label='Имя пользователя' label='Имя пользователя'
required required
type='text' allowEnter
value={username} value={username}
autoFocus autoFocus
onChange={event => setUsername(event.target.value)} onChange={event => setUsername(event.target.value)}
/> />
<TextInput id='password' <TextInput id='password' type='password'
label='Пароль' label='Пароль'
required required
type='password' allowEnter
value={password} value={password}
onChange={event => setPassword(event.target.value)} onChange={event => setPassword(event.target.value)}
/> />

View File

@ -226,7 +226,7 @@ function EditorConstituenta({
dense dense
rows={1} rows={1}
value={typification} value={typification}
colorClass='clr-app' colors='clr-app'
disabled disabled
/> />
<EditorRSExpression id='expression' label='Формальное определение' <EditorRSExpression id='expression' label='Формальное определение'

View File

@ -143,9 +143,9 @@ function EditorRSExpression({
<Button <Button
tooltip='Проверить формальное определение' tooltip='Проверить формальное определение'
text='Проверить' text='Проверить'
dimensions='w-fit h-[3rem] z-pop' dimensions='w-fit h-[3rem] z-pop rounded-none'
colorClass='clr-btn-default' colors='clr-btn-default'
borderClass='rounded-none border' noOutline
onClick={() => handleCheckExpression()} onClick={() => handleCheckExpression()}
/> />
<StatusBar <StatusBar

View File

@ -81,9 +81,9 @@ function RSTabsMenu({
<Button <Button
tooltip='Действия' tooltip='Действия'
icon={<MenuIcon color='text-controls' size={5}/>} icon={<MenuIcon color='text-controls' size={5}/>}
borderClass=''
dimensions='h-full w-fit pl-2' dimensions='h-full w-fit pl-2'
style={{outlineColor: 'transparent'}} style={{outlineColor: 'transparent'}}
noBorder
dense dense
onClick={schemaMenu.toggle} onClick={schemaMenu.toggle}
tabIndex={-1} tabIndex={-1}
@ -137,11 +137,11 @@ function RSTabsMenu({
<div ref={editMenu.ref}> <div ref={editMenu.ref}>
<Button <Button
tooltip={'измнение: ' + (isEditable ? '[доступно]' : '[запрещено]')} tooltip={'измнение: ' + (isEditable ? '[доступно]' : '[запрещено]')}
borderClass=''
dimensions='h-full w-fit' dimensions='h-full w-fit'
style={{outlineColor: 'transparent'}} style={{outlineColor: 'transparent'}}
icon={<EditIcon size={5} color={isEditable ? 'text-success' : 'text-warning'}/>} icon={<EditIcon size={5} color={isEditable ? 'text-success' : 'text-warning'}/>}
dense dense
noBorder
onClick={editMenu.toggle} onClick={editMenu.toggle}
tabIndex={-1} tabIndex={-1}
/> />
@ -185,9 +185,9 @@ function RSTabsMenu({
: <NotSubscribedIcon color='text-controls' size={5}/> : <NotSubscribedIcon color='text-controls' size={5}/>
} }
dimensions='h-full w-fit pr-2' dimensions='h-full w-fit pr-2'
borderClass=''
style={{outlineColor: 'transparent'}} style={{outlineColor: 'transparent'}}
dense dense
noBorder
onClick={onToggleSubscribe} onClick={onToggleSubscribe}
tabIndex={-1} tabIndex={-1}
/> />

View File

@ -70,7 +70,7 @@ function EditorPassword() {
onChange={event => setOldPassword(event.target.value)} onChange={event => setOldPassword(event.target.value)}
/> />
<TextInput id='new_password' type='password' <TextInput id='new_password' type='password'
colorClass={passwordColor} colors={passwordColor}
label='Новый пароль' label='Новый пароль'
value={newPassword} value={newPassword}
onChange={event => { onChange={event => {
@ -78,7 +78,7 @@ function EditorPassword() {
}} }}
/> />
<TextInput id='new_password_repeat' type='password' <TextInput id='new_password_repeat' type='password'
colorClass={passwordColor} colors={passwordColor}
label='Повторите новый' label='Повторите новый'
value={newPasswordRepeat} value={newPasswordRepeat}
onChange={event => { onChange={event => {

View File

@ -1,4 +1,4 @@
// =========== Modules contains all text descriptors ========== // =========== Module contains all text descriptors. ==========
import { GramData,Grammeme, ReferenceType } from '../models/language'; import { GramData,Grammeme, ReferenceType } from '../models/language';
import { CstMatchMode, DependencyMode, HelpTopic, LibraryFilterStrategy } from '../models/miscelanious'; import { CstMatchMode, DependencyMode, HelpTopic, LibraryFilterStrategy } from '../models/miscelanious';