mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-29 04:53:54 +03:00
fix(*): fix Select types and usages (#724)
* stash * more * stash * Revert port change * Fix test * Fix * Update snapshot
This commit is contained in:
parent
e7477833f0
commit
07e409de6a
|
@ -4,13 +4,22 @@ import Select from '../Select';
|
||||||
import Slider from '../Slider';
|
import Slider from '../Slider';
|
||||||
|
|
||||||
/* eslint-disable react/prop-types */
|
/* eslint-disable react/prop-types */
|
||||||
const SelectWidget: Widget = ({ options, onChange, value, ...rest }) => (
|
const SelectWidget: Widget = ({
|
||||||
<Select
|
options,
|
||||||
options={options.enumOptions}
|
onChange,
|
||||||
onChange={(option: { value: string }) => {
|
value,
|
||||||
onChange(option.value);
|
onBlur,
|
||||||
|
defaultValue,
|
||||||
|
tabIndex,
|
||||||
|
onFocus,
|
||||||
|
...rest
|
||||||
|
}) => (
|
||||||
|
<Select<{ label: string; value: string }>
|
||||||
|
options={options.enumOptions as { label: string; value: string }[]}
|
||||||
|
onChange={(option) => {
|
||||||
|
onChange(option?.value);
|
||||||
}}
|
}}
|
||||||
value={(options.enumOptions as { value: string }[]).find(
|
value={(options.enumOptions as { label: string; value: string }[]).find(
|
||||||
(option) => option.value === value
|
(option) => option.value === value
|
||||||
)}
|
)}
|
||||||
{...rest}
|
{...rest}
|
||||||
|
|
|
@ -22,7 +22,10 @@ export default {
|
||||||
component: Select,
|
component: Select,
|
||||||
};
|
};
|
||||||
|
|
||||||
type TemplateArgs = Omit<SelectProps, 'value'> & { value: string };
|
type TemplateArgs = Omit<
|
||||||
|
SelectProps<{ value: string; label: string }, boolean>,
|
||||||
|
'value'
|
||||||
|
> & { value: string };
|
||||||
|
|
||||||
// eslint-disable-next-line react/prop-types
|
// eslint-disable-next-line react/prop-types
|
||||||
const Template: Story<TemplateArgs> = ({ value, ...args }) => (
|
const Template: Story<TemplateArgs> = ({ value, ...args }) => (
|
||||||
|
|
|
@ -1,17 +1,26 @@
|
||||||
import React, { PureComponent, Component } from 'react';
|
import React, { PureComponent, Component, ReactElement } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ReactSelect, { Props as ReactSelectProps } from 'react-select';
|
import ReactSelect, {
|
||||||
|
NamedProps as ReactSelectProps,
|
||||||
|
OptionTypeBase,
|
||||||
|
} from 'react-select';
|
||||||
import createThemedComponent from '../utils/createThemedComponent';
|
import createThemedComponent from '../utils/createThemedComponent';
|
||||||
import { Theme } from '../themes/default';
|
import { Theme } from '../themes/default';
|
||||||
|
|
||||||
export interface SelectProps extends Omit<ReactSelectProps, 'theme'> {
|
export interface SelectProps<
|
||||||
|
Option extends OptionTypeBase = OptionTypeBase,
|
||||||
|
IsMulti extends boolean = false
|
||||||
|
> extends Omit<ReactSelectProps<Option, IsMulti>, 'theme'> {
|
||||||
theme: Theme;
|
theme: Theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper around [React Select](https://github.com/JedWatson/react-select).
|
* Wrapper around [React Select](https://github.com/JedWatson/react-select).
|
||||||
*/
|
*/
|
||||||
export class Select extends (PureComponent || Component)<SelectProps> {
|
export class Select<
|
||||||
|
Option extends OptionTypeBase = OptionTypeBase,
|
||||||
|
IsMulti extends boolean = false
|
||||||
|
> extends (PureComponent || Component)<SelectProps<Option, IsMulti>> {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<ReactSelect
|
<ReactSelect
|
||||||
|
@ -45,7 +54,7 @@ export class Select extends (PureComponent || Component)<SelectProps> {
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
styles={{
|
styles={{
|
||||||
container: (base, props) => ({
|
container: (base) => ({
|
||||||
...base,
|
...base,
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
}),
|
}),
|
||||||
|
@ -72,4 +81,20 @@ export class Select extends (PureComponent || Component)<SelectProps> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default createThemedComponent(Select);
|
export interface ExternalSelectProps<
|
||||||
|
Option extends OptionTypeBase = OptionTypeBase,
|
||||||
|
IsMulti extends boolean = false
|
||||||
|
> extends Omit<ReactSelectProps<Option, IsMulti>, 'theme'> {
|
||||||
|
theme?: Theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
type SelectComponent = <
|
||||||
|
Option extends OptionTypeBase = OptionTypeBase,
|
||||||
|
IsMulti extends boolean = false
|
||||||
|
>(
|
||||||
|
props: ExternalSelectProps<Option, IsMulti>
|
||||||
|
) => ReactElement;
|
||||||
|
|
||||||
|
export default createThemedComponent(Select) as SelectComponent & {
|
||||||
|
theme?: Theme;
|
||||||
|
};
|
||||||
|
|
|
@ -24,14 +24,14 @@ describe('Select', function () {
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
// noop
|
// noop
|
||||||
}}
|
}}
|
||||||
value="one"
|
value={options.filter((option) => option.value === 'one')}
|
||||||
menuMaxHeight={20}
|
maxMenuHeight={20}
|
||||||
clearable
|
isClearable
|
||||||
disabled
|
isDisabled
|
||||||
isLoading
|
isLoading
|
||||||
multi
|
isMulti
|
||||||
searchable={false}
|
isSearchable={false}
|
||||||
openOuterUp
|
menuPlacement="top"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
expect(renderToJson(wrapper)).toMatchSnapshot();
|
expect(renderToJson(wrapper)).toMatchSnapshot();
|
||||||
|
|
|
@ -70,7 +70,7 @@ exports[`Select renders correctly 1`] = `
|
||||||
|
|
||||||
exports[`Select renders with props 1`] = `
|
exports[`Select renders with props 1`] = `
|
||||||
<div
|
<div
|
||||||
class=" css-butsr4-container"
|
class=" css-ie73ge-container"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class=" css-vmgz7k-control"
|
class=" css-vmgz7k-control"
|
||||||
|
@ -79,34 +79,39 @@ exports[`Select renders with props 1`] = `
|
||||||
class=" css-be27w2-ValueContainer"
|
class=" css-be27w2-ValueContainer"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class=" css-1osw1h9-placeholder"
|
class="css-syqu13-multiValue"
|
||||||
>
|
|
||||||
Select...
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="css-187dxxn-Input"
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class=""
|
class="css-1lxn4sj"
|
||||||
style="display:inline-block"
|
|
||||||
>
|
>
|
||||||
<input
|
One
|
||||||
aria-autocomplete="list"
|
</div>
|
||||||
autocapitalize="none"
|
<div
|
||||||
autocomplete="off"
|
class="css-19nhond"
|
||||||
autocorrect="off"
|
>
|
||||||
id="react-select-3-input"
|
<svg
|
||||||
spellcheck="false"
|
aria-hidden="true"
|
||||||
style="box-sizing:content-box;width:1px;label:input;background:0;border:0;font-size:inherit;opacity:1;outline:0;padding:0;color:inherit"
|
class="css-6q0nyr-Svg"
|
||||||
tabindex="0"
|
focusable="false"
|
||||||
type="text"
|
height="14"
|
||||||
value=""
|
viewBox="0 0 20 20"
|
||||||
/>
|
width="14"
|
||||||
<div
|
>
|
||||||
style="position:absolute;top:0;left:0;visibility:hidden;height:0;overflow:scroll;white-space:pre"
|
<path
|
||||||
/>
|
d="M14.348 14.849c-0.469 0.469-1.229 0.469-1.697 0l-2.651-3.030-2.651 3.029c-0.469 0.469-1.229 0.469-1.697 0-0.469-0.469-0.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-0.469-0.469-0.469-1.228 0-1.697s1.228-0.469 1.697 0l2.652 3.031 2.651-3.031c0.469-0.469 1.228-0.469 1.697 0s0.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c0.469 0.469 0.469 1.229 0 1.698z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<input
|
||||||
|
aria-autocomplete="list"
|
||||||
|
class="css-62g3xt-dummyInput"
|
||||||
|
disabled=""
|
||||||
|
id="react-select-3-input"
|
||||||
|
readonly=""
|
||||||
|
tabindex="0"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class=" css-1hb7zxy-IndicatorsContainer"
|
class=" css-1hb7zxy-IndicatorsContainer"
|
||||||
|
|
|
@ -23,9 +23,10 @@ class InstanceSelector extends Component<Props> {
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
options={this.select}
|
options={this.select}
|
||||||
// TODO Where's the type-checking?
|
onChange={(option) => this.props.onSelect(option!.value)}
|
||||||
onChange={this.props.onSelect}
|
value={this.select.find(
|
||||||
value={this.props.selected || ''}
|
(option) => option.value === this.props.selected
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,9 +182,10 @@ class Dispatcher extends Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let options: { value: string | number; label: string }[] = [
|
let options: {
|
||||||
{ value: 'default', label: 'Custom action' },
|
value: 'default' | 'actions-help' | number;
|
||||||
];
|
label: string;
|
||||||
|
}[] = [{ value: 'default', label: 'Custom action' }];
|
||||||
if (actionCreators && actionCreators.length > 0) {
|
if (actionCreators && actionCreators.length > 0) {
|
||||||
options = options.concat(
|
options = options.concat(
|
||||||
actionCreators.map(({ name, args }, i) => ({
|
actionCreators.map(({ name, args }, i) => ({
|
||||||
|
@ -204,9 +205,12 @@ class Dispatcher extends Component<Props, State> {
|
||||||
{actionElement}
|
{actionElement}
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<Select
|
<Select
|
||||||
openOuterUp
|
menuPlacement="top"
|
||||||
onChange={this.selectActionCreator}
|
onChange={(option) => this.selectActionCreator(option!.value)}
|
||||||
value={this.state.selected || 'default'}
|
value={
|
||||||
|
options.find((option) => option.value === this.state.selected) ||
|
||||||
|
options.find((option) => option.value === 'default')
|
||||||
|
}
|
||||||
options={options}
|
options={options}
|
||||||
/>
|
/>
|
||||||
<Button onClick={this.dispatchAction} primary={this.state.changed}>
|
<Button onClick={this.dispatchAction} primary={this.state.changed}>
|
||||||
|
|
|
@ -52,9 +52,9 @@ export default class TestTab<S, A extends Action<unknown>> extends Component<
|
||||||
(this.props.monitorState as { testGenerator?: TestGeneratorMonitorState })
|
(this.props.monitorState as { testGenerator?: TestGeneratorMonitorState })
|
||||||
.testGenerator || {};
|
.testGenerator || {};
|
||||||
|
|
||||||
handleSelectTemplate = (selectedTemplate: Template) => {
|
handleSelectTemplate = (selectedTemplate: Template | null | undefined) => {
|
||||||
const { templates = getDefaultTemplates() } = this.getPersistedState();
|
const { templates = getDefaultTemplates() } = this.getPersistedState();
|
||||||
this.updateState({ selected: templates.indexOf(selectedTemplate) });
|
this.updateState({ selected: templates.indexOf(selectedTemplate!) });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleCloseTip = () => {
|
handleCloseTip = () => {
|
||||||
|
@ -133,9 +133,9 @@ export default class TestTab<S, A extends Action<unknown>> extends Component<
|
||||||
<div style={{ flexGrow: 1, zIndex: 100 }}>
|
<div style={{ flexGrow: 1, zIndex: 100 }}>
|
||||||
<Select
|
<Select
|
||||||
options={templates}
|
options={templates}
|
||||||
getOptionValue={(template: Template) => template.name}
|
getOptionValue={(template: Template) => template.name!}
|
||||||
getOptionLabel={(template: Template) => template.name}
|
getOptionLabel={(template: Template) => template.name!}
|
||||||
value={templates.filter((template) => template.name === name)}
|
value={templates.find((template) => template.name === name)}
|
||||||
onChange={this.handleSelectTemplate}
|
onChange={this.handleSelectTemplate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user