Skip to content

Commit

Permalink
refactor: migrate class component to functional (#403)
Browse files Browse the repository at this point in the history
Co-authored-by: Lucas Silveira <[email protected]>
  • Loading branch information
lucaxsilveira and Lucas Silveira authored Oct 13, 2022
1 parent 777316a commit 1caecd3
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 55 deletions.
4 changes: 3 additions & 1 deletion src/components/ActionsProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
* License: MIT
*/

import React from "react";
import React, { useContext } from "react";
import PropTypes from "prop-types";

export const defaultAction = () => {};

export const ActionsContext = React.createContext({ onAction: defaultAction });

export const useActions = () => useContext(ActionsContext);

const ActionsProvider = ({ onAction = defaultAction, children }) => (
<ActionsContext.Provider value={{ onAction }}>
{children}
Expand Down
12 changes: 7 additions & 5 deletions src/components/MediaMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@
import React from "react";
import classNames from "classnames";

export default function MediaMessage(props) {
if (props.text) {
const errorType = props.type ? props.type : "info";
const MediaMessage = ({ text, type }) => {
if (text) {
const errorType = type || "info";
const messageClassName = classNames(
`media__message media__message--${errorType}`
);
return (
<div className={messageClassName}>
<div className="media__message-text">{props.text}</div>
<div className="media__message-text">{text}</div>
</div>
);
}

return null;
}
};

export default MediaMessage;
16 changes: 8 additions & 8 deletions src/components/MediaWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ import React from "react";
*
* https://draftjs.org/docs/advanced-topics-block-components/#recommendations-and-other-notes
*/
export default function MediaWrapper(props) {
const { setReadOnly, setInitialReadOnly, children } = props;

function handleFocus() {
const MediaWrapper = ({ setReadOnly, setInitialReadOnly, children }) => {
const handleFocus = () => {
setReadOnly(true);
}
};

function handleBlur() {
const handleBlur = () => {
setInitialReadOnly();
}
};

return (
<div onBlur={handleBlur} onFocus={handleFocus}>
{children}
</div>
);
}
};

export default MediaWrapper;
82 changes: 41 additions & 41 deletions src/components/PluginsModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,53 @@
* License: MIT
*/

import React, { Component } from "react";
import React, { useCallback } from "react";

import Modal from "backstage-modal";
import ModalPluginList from "./ModalPluginList";

import { ActionsContext } from "./ActionsProvider";
import { PLUGINS_MODAL_CLOSE } from "../constants";

export default class PluginsModal extends Component {
static contextType = ActionsContext;

constructor(props) {
super(props);
this.onCloseRequest = this.onCloseRequest.bind(this);
this.modalOptions = this.props.modalOptions ? this.props.modalOptions : {};
this.modalWidth = this.modalOptions.width || 528;
this.modalHeight = this.modalOptions.height || 394;
}

onCloseRequest() {
if (!this.props.isOpen) {
import { useActions } from "./ActionsProvider";

const PluginsModal = ({
i18n,
isOpen,
toggleModalVisibility,
plugins,
onChange,
editorState,
modalOptions = {}
}) => {
const { onAction } = useActions();
const { width: modalWidth = 528, height: modalHeight = 394 } = modalOptions;

const onCloseRequest = useCallback(() => {
if (!isOpen) {
return;
}
document.body.classList.remove("megadraft-modal--open");
this.context.onAction({ type: PLUGINS_MODAL_CLOSE });
this.props.toggleModalVisibility();
}

render() {
const { i18n } = this.props;

return (
<Modal
className="megadraft-modal"
title={i18n["Block List"]}
isOpen={this.props.isOpen}
onCloseRequest={this.onCloseRequest}
width={this.modalWidth}
height={this.modalHeight}
>
<ModalPluginList
toggleModalVisibility={this.onCloseRequest}
plugins={this.props.plugins}
onChange={this.props.onChange}
editorState={this.props.editorState}
/>
</Modal>
);
}
}
onAction({ type: PLUGINS_MODAL_CLOSE });
toggleModalVisibility();
}, [onAction, toggleModalVisibility, isOpen]);

return (
<Modal
className="megadraft-modal"
title={i18n["Block List"]}
isOpen={isOpen}
onCloseRequest={onCloseRequest}
width={modalWidth}
height={modalHeight}
>
<ModalPluginList
toggleModalVisibility={onCloseRequest}
plugins={plugins}
onChange={onChange}
editorState={editorState}
/>
</Modal>
);
};

export default PluginsModal;
73 changes: 73 additions & 0 deletions tests/components/PluginsModal_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2016, Globo.com (https://github.com/globocom)
*
* License: MIT
*/

import React from "react";
import { mount } from "enzyme";

import image from "../../src/plugins/image/plugin";
import PluginsModal from "../../src/components/PluginsModal";
import { ActionsContext } from "../../src/components/ActionsProvider";

describe("PluginsModal", () => {
beforeEach(() => {
jest.resetAllMocks();
});

const mountComponent = (params = {}, onAction = jest.fn()) => {
const props = {
i18n: {},
isOpen: false,
toggleModalVisibility: jest.fn(),
plugins: [image],
onChange: jest.fn(),
editorState: {},
modalOptions: {},
...params
};

return mount(
<ActionsContext.Provider value={{ onAction }}>
<PluginsModal {...props} />
</ActionsContext.Provider>
);
};

it("should be able to render component", () => {
const component = mountComponent();
expect(component.find("Modal")).toBeTruthy();
});

it("should be able to render modal with different size options", () => {
const component = mountComponent({
modalOptions: {
width: 900,
height: 900
}
});

const { width, height } = component.find("Modal").props();
expect(width).toEqual(900);
expect(height).toEqual(900);
});

it("should be able to execute onCloseRequest function", () => {
const toggleModalVisibility = jest.fn();
const onAction = jest.fn();

const component = mountComponent(
{
isOpen: true,
toggleModalVisibility
},
onAction
);

const { onCloseRequest } = component.find("Modal").props();
onCloseRequest();
expect(toggleModalVisibility).toHaveBeenCalled();
expect(onAction).toHaveBeenCalled();
});
});

0 comments on commit 1caecd3

Please sign in to comment.