Skip to content

Commit

Permalink
Рефакторинг EventsModal, фикс отображения на светлой теме (#114)
Browse files Browse the repository at this point in the history
Заменил на универсальный компонент Modal.
Все useEffect поменял на useLayoutEffect чтобы не дёргалось
Параметры теперь видны и на светлой теме

Co-authored-by: Mikhail Chekan <chekoopa@mail.ru>
  • Loading branch information
bryzZz and chekoopa authored Dec 6, 2023
1 parent 7d07656 commit e07f19e
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 75 deletions.
4 changes: 1 addition & 3 deletions src/renderer/src/components/DiagramEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export const DiagramEditor: React.FC<DiagramEditorProps> = ({ manager, editor, s
<DiagramContextMenu {...contextMenu} />
<StateNameModal {...stateName} />

{editor !== null ? (
{editor && (
<CreateEventsModal
editor={editor}
manager={manager}
Expand All @@ -175,8 +175,6 @@ export const DiagramEditor: React.FC<DiagramEditorProps> = ({ manager, editor, s
onClose={closeEventsModal}
onSubmit={handleCreateEventsModal}
/>
) : (
''
)}

{isModalOpen ? (
Expand Down
122 changes: 53 additions & 69 deletions src/renderer/src/components/EventsModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import React, { useEffect, useState } from 'react';

import ReactModal, { Props } from 'react-modal';
import React, { useLayoutEffect, useState } from 'react';

import './Modal/style.css';
import { Select, SelectOption } from '@renderer/components/UI';
Expand All @@ -10,6 +8,7 @@ import { State } from '@renderer/lib/drawable/State';
import { Action, Event } from '@renderer/types/diagram';
import { ArgumentProto } from '@renderer/types/platform';

import { Modal } from './Modal';
import { WithHint } from './WithHint';

import { EventSelection } from '../lib/drawable/Events';
Expand All @@ -25,13 +24,11 @@ interface FormPreset {
argForm: ArgForm;
}

interface EventsModalProps extends Props {
editor: CanvasEditor | null;
interface EventsModalProps {
editor: CanvasEditor;
manager: EditorManager;
isData: { state: State; event: EventSelection; click: boolean } | undefined;
isOpen: boolean;
cancelLabel?: string;
submitLabel?: string;
onSubmit: (data: EventsModalResult) => void;
onClose: () => void;
}
Expand All @@ -43,17 +40,16 @@ export interface EventsModalResult {
}

export const CreateEventsModal: React.FC<EventsModalProps> = ({
cancelLabel,
submitLabel,
onSubmit,
onClose,
editor,
manager,
...props
isData,
isOpen,
}) => {
const componentsData = manager.useData('elements.components');
const machine = editor!.container.machineController;
const isEditingEvent = props.isData?.event.actionIdx === null;
const machine = editor.container.machineController;
const isEditingEvent = isData?.event.actionIdx === null;

const compoEntry = (idx: string) => {
const proto = machine.platform.getComponent(idx);
Expand Down Expand Up @@ -132,7 +128,7 @@ export const CreateEventsModal: React.FC<EventsModalProps> = ({

const [methods, setMethods] = useState<SelectOption | null>(optionsMethods[0]);

useEffect(() => {
useLayoutEffect(() => {
if (!isChanged) return;
if (optionsMethods.length > 0) {
setMethods(optionsMethods[0]);
Expand All @@ -159,7 +155,7 @@ export const CreateEventsModal: React.FC<EventsModalProps> = ({
return argForm;
};

useEffect(() => {
useLayoutEffect(() => {
if (!isChanged) return;
setArgSet({});
if (methods) {
Expand All @@ -169,9 +165,9 @@ export const CreateEventsModal: React.FC<EventsModalProps> = ({
}
}, [methods]);

const tryGetData: () => FormPreset | undefined = () => {
if (props.isData) {
const d = props.isData;
const tryGetData = (): FormPreset | undefined => {
if (isData) {
const d = isData;
if (d.event.eventIdx >= 0) {
const evs = d.state.eventBox.data[d.event.eventIdx];
if (evs) {
Expand Down Expand Up @@ -208,30 +204,28 @@ export const CreateEventsModal: React.FC<EventsModalProps> = ({
const name = entry.name;
const data = argSet[entry.name] ?? '';
return (
<>
<label className="mx-1 flex flex-col">
{name}
<input
className="w-[250px] max-w-[250px] rounded border bg-transparent px-2 py-1 outline-none transition-colors placeholder:font-normal"
value={data}
name={name}
onChange={(e) => handleInputChange(e)}
/>
</label>
</>
<label key={name} className="mx-1 flex flex-col">
{name}
<input
className="w-[250px] rounded border border-border-primary bg-transparent px-2 py-1 text-text-primary outline-none"
value={data}
name={name}
onChange={(e) => handleInputChange(e)}
/>
</label>
);
});

const handleInputChange = (e) => {
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newSet = { ...argSet };
newSet[e.target.name] = e.target.value;
setArgSet(newSet);
};

const [isChanged, setIsChanged] = useState(false);
const [wasOpen, setWasOpen] = useState(false);
useEffect(() => {
if (!wasOpen && props.isOpen) {
useLayoutEffect(() => {
if (!wasOpen && isOpen) {
const d: FormPreset | undefined = tryGetData();
if (d) {
setComponents(d.compo);
Expand All @@ -243,10 +237,10 @@ export const CreateEventsModal: React.FC<EventsModalProps> = ({
}
setIsChanged(false);
}
setWasOpen(props.isOpen);
}, [props.isOpen]);
setWasOpen(isOpen);
}, [isOpen]);

const handleSubmit = (ev) => {
const handleSubmit = (ev: React.FormEvent) => {
ev.preventDefault();

if (!methods) {
Expand All @@ -255,7 +249,7 @@ export const CreateEventsModal: React.FC<EventsModalProps> = ({

// FIXME: очень некорректное дублирование, его нужно снять
const data = {
id: props.isData,
id: isData,
trigger: {
component: components.value,
method: methods.value,
Expand All @@ -276,42 +270,32 @@ export const CreateEventsModal: React.FC<EventsModalProps> = ({
};

return (
<ReactModal
{...props}
className="absolute left-1/2 top-12 w-full max-w-sm -translate-x-1/2 rounded-lg bg-bg-primary p-6 outline-none"
overlayClassName="bg-[rgba(0,0,0,0.6)] z-[60] fixed inset-0 backdrop-blur"
<Modal
title={`Выберите ${isEditingEvent ? 'событие' : 'действие'}`}
onSubmit={handleSubmit}
submitDisabled={!methods}
className="max-w-sm"
overlayClassName="z-[60]"
isOpen={isOpen}
onRequestClose={onClose}
>
<div className="relative mb-3 justify-between border-b border-border-primary pb-1">
<h1 className="text-2xl font-bold">Выберите {isEditingEvent ? 'событие' : 'действие'}</h1>
<div className="flex flex-col items-center">
<Select
className="mb-6 h-[34px] w-[200px] max-w-[200px] py-1"
options={options}
onChange={onSelect(setComponents)}
value={components}
isSearchable={false}
/>
<Select
className="mb-6 h-[34px] w-[200px] max-w-[200px] py-1"
options={optionsMethods}
onChange={onSelect(setMethods)}
value={methods}
isSearchable={false}
/>
{parameters?.length > 0 ? <div className="mb-6">{parameters}</div> : ''}
</div>
<form onSubmit={handleSubmit}>
<div className="flex flex-col items-center">
<Select
className="mb-6 h-[34px] w-[200px] max-w-[200px] py-1"
options={options}
onChange={onSelect(setComponents)}
value={components}
isSearchable={false}
/>
<Select
className="mb-6 h-[34px] w-[200px] max-w-[200px] py-1"
options={optionsMethods}
onChange={onSelect(setMethods)}
value={methods}
isSearchable={false}
/>
{parameters?.length > 0 ? <div className="mb-6">{parameters}</div> : ''}
</div>
<div className="flex items-center justify-end gap-2">
<button type="button" className="btn-secondary" onClick={onClose}>
{cancelLabel ?? 'Закрыть'}
</button>
<button type="submit" className="btn-primary" hidden={!onSubmit} disabled={!methods}>
{submitLabel ?? 'Сохранить'}
</button>
</div>
</form>
</ReactModal>
</Modal>
);
};
17 changes: 14 additions & 3 deletions src/renderer/src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import ReactModal, { Props } from 'react-modal';
import { ReactComponent as Close } from '@renderer/assets/icons/close.svg';

import './style.css';
import { twMerge } from 'tailwind-merge';

ReactModal.setAppElement('#root');

interface ModalProps extends Props {
interface ModalProps extends Omit<Props, 'className' | 'overlayClassName'> {
title: string;
cancelLabel?: string;
submitLabel?: string;
Expand All @@ -19,6 +20,8 @@ interface ModalProps extends Props {
onSide?: React.FormEventHandler;
onSubmit?: React.FormEventHandler;
submitDisabled?: boolean;
className?: string;
overlayClassName?: string;
}

export const Modal: React.FC<ModalProps> = ({
Expand All @@ -32,13 +35,21 @@ export const Modal: React.FC<ModalProps> = ({
onExtra,
onSide,
submitDisabled,
className,
overlayClassName,
...props
}) => {
return (
<ReactModal
{...props}
className="absolute left-1/2 top-12 max-h-[90vh] w-full max-w-3xl -translate-x-1/2 rounded-lg bg-bg-primary p-6 outline-none"
overlayClassName="bg-[rgba(0,0,0,0.6)] fixed inset-0 backdrop-blur z-50"
className={twMerge(
'absolute left-1/2 top-12 max-h-[90vh] w-full max-w-3xl -translate-x-1/2 rounded-lg bg-bg-primary p-6 outline-none',
className
)}
overlayClassName={twMerge(
'bg-[rgba(0,0,0,0.6)] fixed inset-0 backdrop-blur z-50',
overlayClassName
)}
closeTimeoutMS={100}
>
<div className="relative mb-3 flex items-center justify-between border-b border-border-primary pb-1">
Expand Down

0 comments on commit e07f19e

Please sign in to comment.