Skip to content

Commit 886d862

Browse files
authored
feat: add support for renderExtraFooter (#55)
* feat: add support for `renderExtraFooter` * test: add tests
1 parent 18a3c85 commit 886d862

File tree

5 files changed

+78
-17
lines changed

5 files changed

+78
-17
lines changed

README.md

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,19 @@ The source code is written in markdown, refer to [example.md](https://raw.github
9494

9595
### `<CodeView>`
9696

97-
| Name | Type | Default value | Description |
98-
| -------------- | --------------------------------- | ----------------------- | ------------------------------------------------------------------------- |
99-
| afterCompile | (code: string) => string | | Executed after compiling the code |
100-
| beforeCompile | (code: string) => string | | Executed before compiling the code |
101-
| children | any | | The code to be rendered is executed. Usually imported via markdown-loader |
102-
| dependencies | object | | Dependent objects required by the executed code |
103-
| editable | boolean | false | Renders a code editor that can modify the source code |
104-
| editor | object | | Editor properties |
105-
| onChange | (code?: string) => void | | Callback triggered after code change |
106-
| renderToolbar | (buttons: ReactNode) => ReactNode | | Customize the rendering toolbar |
107-
| sourceCode | string | | The code to be rendered is executed |
108-
| theme | 'light' , 'dark' | 'light' | Code editor theme, applied to CodeMirror |
109-
| compileOptions | object | defaultTransformOptions | https://github.com/alangpierce/sucrase#transforms |
97+
| Name | Type | Default value | Description |
98+
| ----------------- | --------------------------------- | ----------------------- | ------------------------------------------------------------------------- |
99+
| afterCompile | (code: string) => string | | Executed after compiling the code |
100+
| beforeCompile | (code: string) => string | | Executed before compiling the code |
101+
| children | any | | The code to be rendered is executed. Usually imported via markdown-loader |
102+
| compileOptions | object | defaultTransformOptions | https://github.com/alangpierce/sucrase#transforms |
103+
| dependencies | object | | Dependent objects required by the executed code |
104+
| editable | boolean | false | Renders a code editor that can modify the source code |
105+
| editor | object | | Editor properties |
106+
| onChange | (code?: string) => void | | Callback triggered after code change |
107+
| onCloseEditor | () => void | | Callback triggered when the editor is closed |
108+
| onOpenEditor | () => void | | Callback triggered when the editor is opened |
109+
| renderExtraFooter | () => ReactNode | | Customize the rendering footer |
110+
| renderToolbar | (buttons: ReactNode) => ReactNode | | Customize the rendering toolbar |
111+
| sourceCode | string | | The code to be rendered is executed |
112+
| theme | 'light' , 'dark' | 'light' | Code editor theme, applied to CodeMirror |

__tests__/Renderer-test.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { render } from '@testing-library/react';
2+
import { render, screen, fireEvent } from '@testing-library/react';
33
import Renderer from '../src/Renderer';
44

55
it('refault is rendering', () => {
@@ -12,3 +12,24 @@ it('should render a test div', () => {
1212

1313
expect(container.querySelector('.rcv-render')).toContainHTML('<div>test</div>');
1414
});
15+
16+
it('should render a test div with footer', () => {
17+
render(<Renderer renderExtraFooter={() => <div>footer</div>} />);
18+
19+
expect(screen.getByText('footer')).toBeInTheDocument();
20+
});
21+
22+
it('should call onOpenEditor and onCloseEditor callback', () => {
23+
const onOpenEditor = jest.fn();
24+
const onCloseEditor = jest.fn();
25+
26+
render(<Renderer onOpenEditor={onOpenEditor} onCloseEditor={onCloseEditor} />);
27+
28+
fireEvent.click(screen.getByRole('switch', { name: 'Show the full source' }));
29+
30+
expect(onOpenEditor).toHaveBeenCalled();
31+
32+
fireEvent.click(screen.getByRole('switch', { name: 'Show the full source' }));
33+
34+
expect(onCloseEditor).toHaveBeenCalled();
35+
});

docs/index.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ const App = () => {
2121
afterCompile={(code: string) => {
2222
return code.replace(/import\ [\*\w\,\{\}\ ]+\ from\ ?[\."'@/\w-]+;/gi, '');
2323
}}
24+
onOpenEditor={() => {
25+
console.log('open editor');
26+
}}
27+
onCloseEditor={() => {
28+
console.log('close editor');
29+
}}
30+
renderExtraFooter={() => {
31+
return <div>Footer</div>;
32+
}}
2433
>
2534
{example}
2635
</CodeView>

src/CodeView.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ const CodeView = React.forwardRef((props: CodeViewProps, ref: React.Ref<HTMLDivE
2525
onChange,
2626
beforeCompile,
2727
afterCompile,
28+
onOpenEditor,
29+
onCloseEditor,
30+
renderExtraFooter,
2831
...rest
2932
} = props;
3033

@@ -41,13 +44,16 @@ const CodeView = React.forwardRef((props: CodeViewProps, ref: React.Ref<HTMLDivE
4144
code={fragment.content}
4245
editable={editable}
4346
theme={theme}
47+
editor={editor}
4448
dependencies={dependencies}
4549
transformOptions={transformOptions}
4650
renderToolbar={renderToolbar}
51+
afterCompile={afterCompile}
4752
onChange={onChange}
53+
onOpenEditor={onOpenEditor}
54+
onCloseEditor={onCloseEditor}
4855
beforeCompile={beforeCompile}
49-
afterCompile={afterCompile}
50-
editor={editor}
56+
renderExtraFooter={renderExtraFooter}
5157
/>
5258
);
5359
} else if (fragment.type === 'html') {

src/Renderer.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ export interface RendererProps extends Omit<React.HTMLAttributes<HTMLElement>, '
4949
/** Customize the rendering toolbar */
5050
renderToolbar?: (buttons: React.ReactNode) => React.ReactNode;
5151

52+
/** Customize the rendering footer */
53+
renderExtraFooter?: () => React.ReactNode;
54+
55+
/**
56+
* Callback triggered when the editor is opened
57+
*/
58+
onOpenEditor?: () => void;
59+
/**
60+
* Callback triggered when the editor is closed
61+
*/
62+
onCloseEditor?: () => void;
63+
5264
/** Callback triggered after code change */
5365
onChange?: (code?: string) => void;
5466

@@ -71,6 +83,9 @@ const Renderer = React.forwardRef((props: RendererProps, ref: React.Ref<HTMLDivE
7183
code,
7284
copyCodeButtonAs,
7385
renderToolbar,
86+
renderExtraFooter,
87+
onOpenEditor,
88+
onCloseEditor,
7489
onChange,
7590
beforeCompile,
7691
afterCompile,
@@ -91,7 +106,13 @@ const Renderer = React.forwardRef((props: RendererProps, ref: React.Ref<HTMLDivE
91106

92107
const handleExpandEditor = useCallback(() => {
93108
setEditable(!editable);
94-
}, [editable]);
109+
110+
if (editable) {
111+
onCloseEditor?.();
112+
} else if (!editable) {
113+
onOpenEditor?.();
114+
}
115+
}, [editable, onCloseEditor, onOpenEditor]);
95116

96117
const handleError = useCallback(error => {
97118
setErrorMessage(error.message);
@@ -183,6 +204,7 @@ const Renderer = React.forwardRef((props: RendererProps, ref: React.Ref<HTMLDivE
183204
code={code}
184205
/>
185206
)}
207+
{renderExtraFooter?.()}
186208
</div>
187209
);
188210
});

0 commit comments

Comments
 (0)