feat(#1251): Add file selector to demo application (#1859)

* feat(#1251): Add file selector to demo application

This PR should fix the request to add a file selector to the demo application see issue #1251 .

* refactor(): Remove function, use it implicit

* refactor(): Add interface props

* refactor(): Update method usage

use regular func as a Component declaration and the arrow func as a handler inside the component.
This commit is contained in:
Depickere Sven 2022-01-24 18:58:46 +01:00 committed by GitHub
parent 18f943d2b5
commit b74dcde42b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 2 deletions

View File

@ -0,0 +1,52 @@
import * as yaml from 'js-yaml';
import * as React from 'react';
import { ChangeEvent, RefObject, useRef } from 'react';
import styled from '../../src/styled-components';
const Button = styled.button`
background-color: #fff;
color: #333;
padding: 2px 10px;
touch-action: manipulation;
cursor: pointer;
user-select: none;
border: 1px solid #ccc;
font-size: 16px;
height: 28px;
box-sizing: border-box;
vertical-align: middle;
line-height: 1;
outline: none;
white-space: nowrap;
@media (max-width: 699px) {
display: none;
}
`;
function FileInput(props: { onUpload }) {
const hiddenFileInput: RefObject<HTMLInputElement> = useRef<HTMLInputElement>(null);
const handleClick = () => {
if (hiddenFileInput && hiddenFileInput.current) {
hiddenFileInput.current.click();
}
};
const uploadFile = (event: ChangeEvent<HTMLInputElement>) => {
const file = (event.target as HTMLInputElement).files![0];
const reader = new FileReader();
reader.onload = () => {
props.onUpload(yaml.load(reader.result));
};
reader.readAsText(file);
};
return (
<span>
<Button onClick={handleClick}>Upload a file</Button>
<input type="file" style={{ display: 'none' }} onChange={uploadFile} ref={hiddenFileInput} />
</span>
);
}
export default FileInput;

View File

@ -4,6 +4,7 @@ import styled from 'styled-components';
import { resolve as urlResolve } from 'url'; import { resolve as urlResolve } from 'url';
import { RedocStandalone } from '../src'; import { RedocStandalone } from '../src';
import ComboBox from './ComboBox'; import ComboBox from './ComboBox';
import FileInput from './components/FileInput';
const DEFAULT_SPEC = 'openapi.yaml'; const DEFAULT_SPEC = 'openapi.yaml';
const NEW_VERSION_SPEC = 'openapi-3-1.yaml'; const NEW_VERSION_SPEC = 'openapi-3-1.yaml';
@ -22,7 +23,7 @@ const demos = [
class DemoApp extends React.Component< class DemoApp extends React.Component<
{}, {},
{ specUrl: string; dropdownOpen: boolean; cors: boolean } { spec: object | undefined; specUrl: string; dropdownOpen: boolean; cors: boolean }
> { > {
constructor(props) { constructor(props) {
super(props); super(props);
@ -40,15 +41,24 @@ class DemoApp extends React.Component<
} }
this.state = { this.state = {
spec: undefined,
specUrl: url, specUrl: url,
dropdownOpen: false, dropdownOpen: false,
cors, cors,
}; };
} }
handleUploadFile = (spec: object) => {
this.setState({
spec,
specUrl: '',
});
};
handleChange = (url: string) => { handleChange = (url: string) => {
if (url === NEW_VERSION_SPEC) { if (url === NEW_VERSION_SPEC) {
this.setState({ cors: false }) this.setState({ cors: false });
0;
} }
this.setState({ this.setState({
specUrl: url, specUrl: url,
@ -90,6 +100,7 @@ class DemoApp extends React.Component<
/> />
</a> </a>
<ControlsContainer> <ControlsContainer>
<FileInput onUpload={this.handleUploadFile} />
<ComboBox <ComboBox
placeholder={'URL to a spec to try'} placeholder={'URL to a spec to try'}
options={demos} options={demos}
@ -110,6 +121,7 @@ class DemoApp extends React.Component<
/> />
</Heading> </Heading>
<RedocStandalone <RedocStandalone
spec={this.state.spec}
specUrl={proxiedUrl} specUrl={proxiedUrl}
options={{ scrollYOffset: 'nav', untrustedSpec: true }} options={{ scrollYOffset: 'nav', untrustedSpec: true }}
/> />