Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/components/ClearButton/ClearButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import { resultExceptions } from '../Tree/types';
import { text } from '../../helpers';
import { render } from '../../utils/test-util';
import { useResultContext } from '../../contexts/ResultContext';
import { useTextareaContext } from '../../contexts/TextareaContext';
import { useTextareaRefContext } from '../../contexts/TextareaRefContext';

jest.mock('../../contexts/ResultContext');
jest.mock('../../contexts/TextareaContext');
jest.mock('../../contexts/TextareaRefContext');

const mockSetResult = jest.fn();
const mockSetTextareaValue = jest.fn();

(useResultContext as jest.Mock).mockReturnValue({ setResult: mockSetResult });
(useTextareaContext as jest.Mock).mockReturnValue({
(useTextareaRefContext as jest.Mock).mockReturnValue({
setTextareaValue: mockSetTextareaValue,
});

Expand Down
6 changes: 3 additions & 3 deletions src/components/ClearButton/ClearButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import React from 'react';
import Button from '../common/Button';
import { text } from '../../helpers/index';
import { useResultContext } from '../../contexts/ResultContext';
import { useTextareaContext } from '../../contexts/TextareaContext';
import { useTextareaRefContext } from '../../contexts/TextareaRefContext';
import { resultExceptions } from '../Tree/types';

const ClearButton: React.FC = () => {
const { setResult } = useResultContext();
const { setTextareaValue } = useTextareaContext();
const { setTextareaValue } = useTextareaRefContext();

const handleClear = () => {
setTextareaValue('');
Expand All @@ -17,4 +17,4 @@ const ClearButton: React.FC = () => {
return <Button onClick={handleClear}>{text.clearBtn}</Button>;
};

export default React.memo(ClearButton);
export default ClearButton;
38 changes: 22 additions & 16 deletions src/components/CreateButton/CreateButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ import { text } from '../../helpers';
import { render } from '../../utils/test-util';
import { buildTree } from '../../utils/buildTree';
import { useResultContext } from '../../contexts/ResultContext';
import { useTextareaContext } from '../../contexts/TextareaContext';

import { useTextareaRefContext } from '../../contexts/TextareaRefContext';
jest.mock('../../contexts/ResultContext');
jest.mock('../../contexts/TextareaContext');
jest.mock('../../contexts/TextareaRefContext');
jest.mock('../../utils/buildTree');

const mockSetResult = jest.fn();
const mockTextareaValue = '';
const mockTextareaRef = { current: { value: '' } };
const mockSetTextareaValue = jest.fn();

(useResultContext as jest.Mock).mockReturnValue({ setResult: mockSetResult });
(useTextareaContext as jest.Mock).mockReturnValue({
textareaValue: mockTextareaValue,
(useTextareaRefContext as jest.Mock).mockReturnValue({
textareaRef: mockTextareaRef,
setTextareaValue: mockSetTextareaValue,
});

describe('CreateButton Component', () => {
Expand All @@ -32,8 +33,9 @@ describe('CreateButton Component', () => {
});

it('handles create with empty textarea and example paths', () => {
(useTextareaContext as jest.Mock).mockReturnValueOnce({
textareaValue: '',
(useTextareaRefContext as jest.Mock).mockReturnValueOnce({
textareaRef: { current: { value: '' } },
setTextareaValue: mockSetTextareaValue,
});
(buildTree as jest.Mock).mockReturnValueOnce({});

Expand All @@ -47,8 +49,9 @@ describe('CreateButton Component', () => {

it('handles create with empty textarea and non-empty tree', () => {
const mockTree = { root: {} };
(useTextareaContext as jest.Mock).mockReturnValueOnce({
textareaValue: '',
(useTextareaRefContext as jest.Mock).mockReturnValueOnce({
textareaRef: { current: { value: '' } },
setTextareaValue: mockSetTextareaValue,
});
(buildTree as jest.Mock).mockReturnValueOnce(mockTree);

Expand All @@ -59,8 +62,9 @@ describe('CreateButton Component', () => {
});

it('handles create with invalid JSON in textarea', () => {
(useTextareaContext as jest.Mock).mockReturnValueOnce({
textareaValue: 'invalid JSON',
(useTextareaRefContext as jest.Mock).mockReturnValueOnce({
textareaRef: { current: { value: 'invalid JSON' } },
setTextareaValue: mockSetTextareaValue,
});

const { getByText } = render(<CreateButton />);
Expand All @@ -70,8 +74,9 @@ describe('CreateButton Component', () => {
});

it('handles create with valid JSON in textarea resulting in empty tree', () => {
(useTextareaContext as jest.Mock).mockReturnValueOnce({
textareaValue: '[]',
(useTextareaRefContext as jest.Mock).mockReturnValueOnce({
textareaRef: { current: { value: '[]' } },
setTextareaValue: mockSetTextareaValue,
});
(buildTree as jest.Mock).mockReturnValueOnce({});

Expand All @@ -83,8 +88,9 @@ describe('CreateButton Component', () => {

it('handles create with valid JSON in textarea resulting in non-empty tree', () => {
const mockTree = { root: {} };
(useTextareaContext as jest.Mock).mockReturnValueOnce({
textareaValue: '["path"]',
(useTextareaRefContext as jest.Mock).mockReturnValueOnce({
textareaRef: { current: { value: '["path"]' } },
setTextareaValue: mockSetTextareaValue,
});
(buildTree as jest.Mock).mockReturnValueOnce(mockTree);

Expand Down
7 changes: 5 additions & 2 deletions src/components/CreateButton/CreateButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import { text } from '../../helpers/index';
import { pathsExample } from '../../helpers/index';
import { buildTree } from '../../utils/buildTree';
import { useResultContext } from '../../contexts/ResultContext';
import { useTextareaContext } from '../../contexts/TextareaContext';
import { useTextareaRefContext } from '../../contexts/TextareaRefContext';

const CreateButton: React.FC = () => {
const { setResult } = useResultContext();
const { textareaValue } = useTextareaContext();
const { textareaRef, setTextareaValue } = useTextareaRefContext();

const handleCreate = () => {
const textareaValue = textareaRef.current?.value;

try {
let paths;

if (textareaValue) {
setTextareaValue(textareaValue);
paths = JSON.parse(textareaValue);
} else {
paths = pathsExample;
Expand Down
6 changes: 3 additions & 3 deletions src/components/Providers/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { ReactNode } from 'react';
import { ThemeProvider } from 'styled-components';
import theme from '../../styles/styles-theme';
import { ResultProvider } from '../../contexts/ResultContext';
import { TextareaProvider } from '../../contexts/TextareaContext';
import { TextareaRefProvider } from '../../contexts/TextareaRefContext';

interface ProvidersProps {
children: ReactNode;
Expand All @@ -11,9 +11,9 @@ interface ProvidersProps {
const Providers: React.FC<ProvidersProps> = ({ children }) => {
return (
<ThemeProvider theme={theme}>
<TextareaProvider>
<TextareaRefProvider>
<ResultProvider>{children}</ResultProvider>
</TextareaProvider>
</TextareaRefProvider>
</ThemeProvider>
);
};
Expand Down
17 changes: 12 additions & 5 deletions src/components/Textarea/Textarea.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import React, { useState } from 'react';
import { useTextareaRefContext } from '../../contexts/TextareaRefContext';
import styled from 'styled-components';
import { useTextareaContext } from '../../contexts/TextareaContext';

const StyledTextarea = styled.textarea`
width: 100%;
Expand All @@ -24,14 +24,21 @@ interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}

const Textarea: React.FC<TextareaProps> = (props) => {
const { textareaValue, setTextareaValue } = useTextareaContext();
const [state, setState] = useState('');
const { textareaRef } = useTextareaRefContext();

const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setTextareaValue(e.target.value);
setState(e.target.value);
};

return (
<StyledTextarea value={textareaValue} onChange={handleChange} {...props} />
<StyledTextarea
ref={textareaRef}
id="textarea"
value={state}
onChange={handleChange}
{...props}
/>
);
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/Tree/Tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ const Tree: React.FC = () => {
return null;
};

export default React.memo(Tree);
export default Tree;
2 changes: 1 addition & 1 deletion src/components/common/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ const Button: React.FC<ButtonProps> = ({ children, ...props }) => {
return <StyledButton {...props}>{children}</StyledButton>;
};

export default React.memo(Button);
export default Button;
43 changes: 0 additions & 43 deletions src/contexts/TextareaContext.tsx

This file was deleted.

46 changes: 46 additions & 0 deletions src/contexts/TextareaRefContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, {
createContext,
useContext,
useRef,
ReactNode,
RefObject,
} from 'react';

interface TextareaRefContextType {
textareaRef: RefObject<HTMLTextAreaElement>;
setTextareaValue: (value: string) => void;
}

const TextareaRefContext = createContext<TextareaRefContextType | undefined>(
undefined
);

export const TextareaRefProvider: React.FC<{ children: ReactNode }> = ({
children,
}) => {
const textareaRef = useRef<HTMLTextAreaElement>(null);

const setTextareaValue = (value: string) => {
if (textareaRef.current) {
textareaRef.current.value = value;
}
};

const contextValue = { textareaRef, setTextareaValue };

return (
<TextareaRefContext.Provider value={contextValue}>
{children}
</TextareaRefContext.Provider>
);
};

export const useTextareaRefContext = () => {
const context = useContext(TextareaRefContext);
if (context === undefined) {
throw new Error(
'useTextareaRefContext must be used within a TextareaRefProvider'
);
}
return context;
};
7 changes: 4 additions & 3 deletions src/utils/buildTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,14 @@ const cleanTree = (node: TreeNodeType): void => {
delete child.__isFile;
}

const isFileHasChild = child.__isFile && Object.keys(child).length > 1;
const childArray = Object.keys(child).length > 1;

const isFileHasChild = child.__isFile && childArray;
if (isFileHasChild) {
delete child.__isFile;
}

const isEmptyHasChild =
child.__isEmptyFolder && Object.keys(child).length > 1;
const isEmptyHasChild = child.__isEmptyFolder && childArray;
if (isEmptyHasChild) {
delete child.__isEmptyFolder;
}
Expand Down