mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
chore(ui): migrate more code to typescript
This commit is contained in:
committed by
Łukasz Mierzwa
parent
55170f8812
commit
4d4dd111c1
@@ -1,20 +0,0 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const Tab = ({ title, active, onClick }) => (
|
||||
<span
|
||||
className={`nav-item nav-link cursor-pointer mx-1 px-2 ${
|
||||
active ? "active" : "components-tab-inactive"
|
||||
}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
);
|
||||
Tab.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
active: PropTypes.bool,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export { Tab };
|
||||
18
ui/src/Components/Modal/Tab.tsx
Normal file
18
ui/src/Components/Modal/Tab.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import React, { FC, MouseEvent } from "react";
|
||||
|
||||
const Tab: FC<{
|
||||
title: string;
|
||||
active?: boolean;
|
||||
onClick: (event: MouseEvent<HTMLElement>) => void;
|
||||
}> = ({ title, active, onClick }) => (
|
||||
<span
|
||||
className={`nav-item nav-link cursor-pointer mx-1 px-2 ${
|
||||
active ? "active" : "components-tab-inactive"
|
||||
}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
);
|
||||
|
||||
export { Tab };
|
||||
@@ -3,7 +3,16 @@ import React from "react";
|
||||
import { mount } from "enzyme";
|
||||
|
||||
import { PressKey } from "__mocks__/PressKey";
|
||||
import { Modal } from ".";
|
||||
import { Modal, ModalInner } from ".";
|
||||
|
||||
beforeEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
document.body.className = "";
|
||||
});
|
||||
|
||||
const fakeToggle = jest.fn();
|
||||
|
||||
@@ -15,12 +24,21 @@ const MountedModal = (isOpen, isUpper) => {
|
||||
);
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
document.body.className = "";
|
||||
});
|
||||
describe("<ModalInner />", () => {
|
||||
it("scroll isn't enabled if ref is null", () => {
|
||||
const useRefSpy = jest.spyOn(React, "useRef").mockImplementation(() =>
|
||||
Object.defineProperty({}, "current", {
|
||||
get: () => null,
|
||||
set: () => {},
|
||||
})
|
||||
);
|
||||
const tree = mount(<ModalInner isUpper toggleOpen={fakeToggle} />);
|
||||
tree.setProps({ isUpper: false });
|
||||
tree.setProps({ isUpper: true });
|
||||
tree.setProps({ isUpper: false });
|
||||
expect(useRefSpy).toHaveBeenCalledTimes(4);
|
||||
});
|
||||
|
||||
describe("<Modal />", () => {
|
||||
it("'modal-open' class is appended to MountModal container", () => {
|
||||
const tree = MountedModal(true);
|
||||
expect(tree.find("div").at(0).hasClass("modal-open")).toBe(true);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, { useRef, useEffect } from "react";
|
||||
import React, { FC, useEffect } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { disableBodyScroll, enableBodyScroll } from "body-scroll-lock";
|
||||
|
||||
@@ -11,18 +10,25 @@ import {
|
||||
MountModalBackdrop,
|
||||
} from "Components/Animations/MountModal";
|
||||
|
||||
const ModalInner = ({ size, isUpper, toggleOpen, children }) => {
|
||||
const ref = useRef(null);
|
||||
const ModalInner: FC<{
|
||||
size: "lg" | "xl";
|
||||
isUpper: boolean;
|
||||
toggleOpen: () => void;
|
||||
}> = ({ size, isUpper, toggleOpen, children }) => {
|
||||
// needed for tests to spy on useRef
|
||||
const ref = React.useRef(null as HTMLDivElement | null);
|
||||
|
||||
useEffect(() => {
|
||||
document.body.classList.add("modal-open");
|
||||
disableBodyScroll(ref.current, { reserveScrollBarGap: true });
|
||||
if (ref.current !== null) {
|
||||
document.body.classList.add("modal-open");
|
||||
disableBodyScroll(ref.current, { reserveScrollBarGap: true });
|
||||
|
||||
let modal = ref.current;
|
||||
return () => {
|
||||
if (!isUpper) document.body.classList.remove("modal-open");
|
||||
enableBodyScroll(modal);
|
||||
};
|
||||
let modal = ref.current;
|
||||
return () => {
|
||||
if (!isUpper) document.body.classList.remove("modal-open");
|
||||
enableBodyScroll(modal);
|
||||
};
|
||||
}
|
||||
}, [isUpper]);
|
||||
|
||||
useHotkeys("esc", toggleOpen);
|
||||
@@ -43,7 +49,19 @@ const ModalInner = ({ size, isUpper, toggleOpen, children }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Modal = ({ size, isOpen, isUpper, toggleOpen, children, ...props }) => {
|
||||
const Modal: FC<{
|
||||
size?: "lg" | "xl";
|
||||
isOpen: boolean;
|
||||
isUpper?: boolean;
|
||||
toggleOpen: () => void;
|
||||
}> = ({
|
||||
size = "lg",
|
||||
isOpen,
|
||||
isUpper = false,
|
||||
toggleOpen,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
return ReactDOM.createPortal(
|
||||
<React.Fragment>
|
||||
<MountModal in={isOpen} unmountOnExit {...props}>
|
||||
@@ -58,16 +76,5 @@ const Modal = ({ size, isOpen, isUpper, toggleOpen, children, ...props }) => {
|
||||
document.body
|
||||
);
|
||||
};
|
||||
Modal.propTypes = {
|
||||
size: PropTypes.oneOf(["lg", "xl"]),
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
isUpper: PropTypes.bool,
|
||||
toggleOpen: PropTypes.func.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
Modal.defaultProps = {
|
||||
size: "lg",
|
||||
isUpper: false,
|
||||
};
|
||||
|
||||
export { Modal };
|
||||
export { Modal, ModalInner };
|
||||
Reference in New Issue
Block a user