mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-22 22:19:48 +03:00
stash
This commit is contained in:
parent
807b594d0b
commit
48dac45b5d
|
@ -50,6 +50,10 @@
|
|||
"devDependencies": {
|
||||
"@storybook/addon-essentials": "^6.0.21",
|
||||
"@storybook/react": "^6.0.21",
|
||||
"@types/codemirror": "^0.0.97",
|
||||
"@types/react-jsonschema-form": "^1.7.4",
|
||||
"@types/react-select": "^3.0.19",
|
||||
"csstype": "^3.0.2",
|
||||
"enzyme": "^3.11.0",
|
||||
"enzyme-adapter-react-16": "^1.15.3",
|
||||
"enzyme-to-json": "^3.5.0",
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { MdFiberManualRecord } from 'react-icons/md';
|
||||
import { Story } from '@storybook/react';
|
||||
import Button from './';
|
||||
import { ButtonProps } from './Button';
|
||||
|
||||
export default {
|
||||
title: 'Button',
|
||||
|
@ -16,7 +18,7 @@ const Container = styled.div`
|
|||
align-items: center;
|
||||
`;
|
||||
|
||||
const Template = (args) => (
|
||||
const Template: Story<ButtonProps> = (args) => (
|
||||
<Container>
|
||||
<Button {...args} />
|
||||
</Container>
|
||||
|
|
|
@ -1,15 +1,51 @@
|
|||
import React, { Component } from 'react';
|
||||
import React, { Component, ReactNode } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import createStyledComponent from '../utils/createStyledComponent';
|
||||
import * as styles from './styles';
|
||||
import { commonStyle, tooltipStyle } from './styles/common';
|
||||
import { Theme } from '../themes/default';
|
||||
|
||||
const ButtonWrapper = createStyledComponent(styles, 'button');
|
||||
const TooltipWrapper = createStyledComponent(tooltipStyle);
|
||||
const CommonWrapper = createStyledComponent(commonStyle);
|
||||
|
||||
export default class Button extends Component {
|
||||
shouldComponentUpdate(nextProps) {
|
||||
export type TooltipPosition =
|
||||
| 'top'
|
||||
| 'bottom'
|
||||
| 'left'
|
||||
| 'right'
|
||||
| 'bottom-left'
|
||||
| 'bottom-right'
|
||||
| 'top-left'
|
||||
| 'top-right';
|
||||
|
||||
export type Size = 'big' | 'normal' | 'small';
|
||||
|
||||
export type Mark =
|
||||
| 'base08'
|
||||
| 'base09'
|
||||
| 'base0A'
|
||||
| 'base0B'
|
||||
| 'base0C'
|
||||
| 'base0D'
|
||||
| 'base0E'
|
||||
| 'base0F';
|
||||
|
||||
export interface ButtonProps {
|
||||
children: ReactNode;
|
||||
title?: string;
|
||||
tooltipPosition: TooltipPosition;
|
||||
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
||||
type?: 'button' | 'reset' | 'submit';
|
||||
disabled?: boolean;
|
||||
primary?: boolean;
|
||||
size?: Size;
|
||||
mark?: Mark | false;
|
||||
theme?: Theme;
|
||||
}
|
||||
|
||||
export default class Button extends Component<ButtonProps> {
|
||||
shouldComponentUpdate(nextProps: ButtonProps) {
|
||||
return (
|
||||
nextProps.children !== this.props.children ||
|
||||
nextProps.disabled !== this.props.disabled ||
|
||||
|
@ -21,8 +57,8 @@ export default class Button extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
onMouseUp = (e) => {
|
||||
e.target.blur();
|
||||
onMouseUp: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
||||
e.currentTarget.blur();
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -53,40 +89,40 @@ export default class Button extends Component {
|
|||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
children: PropTypes.any.isRequired,
|
||||
title: PropTypes.string,
|
||||
tooltipPosition: PropTypes.oneOf([
|
||||
'top',
|
||||
'bottom',
|
||||
'left',
|
||||
'right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
'top-left',
|
||||
'top-right',
|
||||
]),
|
||||
onClick: PropTypes.func,
|
||||
type: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
primary: PropTypes.bool,
|
||||
size: PropTypes.oneOf(['big', 'normal', 'small']),
|
||||
mark: PropTypes.oneOf([
|
||||
false,
|
||||
'base08',
|
||||
'base09',
|
||||
'base0A',
|
||||
'base0B',
|
||||
'base0C',
|
||||
'base0D',
|
||||
'base0E',
|
||||
'base0F',
|
||||
]),
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
tooltipPosition: 'top',
|
||||
};
|
||||
}
|
||||
|
||||
Button.propTypes = {
|
||||
children: PropTypes.any.isRequired,
|
||||
title: PropTypes.string,
|
||||
tooltipPosition: PropTypes.oneOf([
|
||||
'top',
|
||||
'bottom',
|
||||
'left',
|
||||
'right',
|
||||
'bottom-left',
|
||||
'bottom-right',
|
||||
'top-left',
|
||||
'top-right',
|
||||
]),
|
||||
onClick: PropTypes.func,
|
||||
type: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
primary: PropTypes.bool,
|
||||
size: PropTypes.oneOf(['big', 'normal', 'small']),
|
||||
mark: PropTypes.oneOf([
|
||||
false,
|
||||
'base08',
|
||||
'base09',
|
||||
'base0A',
|
||||
'base0B',
|
||||
'base0C',
|
||||
'base0D',
|
||||
'base0E',
|
||||
'base0F',
|
||||
]),
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
|
||||
Button.defaultProps = {
|
||||
tooltipPosition: 'top',
|
||||
};
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { fadeIn } from '../../utils/animations';
|
||||
import colorEffect from '../../utils/color';
|
||||
import { Mark, Size, TooltipPosition } from '../Button';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
const both = (tooltipPosition) => {
|
||||
const both = (tooltipPosition: TooltipPosition) => {
|
||||
switch (tooltipPosition) {
|
||||
case 'bottom':
|
||||
return `
|
||||
|
@ -46,7 +48,7 @@ const both = (tooltipPosition) => {
|
|||
}
|
||||
};
|
||||
|
||||
const before = (tooltipPosition) => {
|
||||
const before = (tooltipPosition: TooltipPosition) => {
|
||||
switch (tooltipPosition) {
|
||||
case 'bottom-left':
|
||||
return `
|
||||
|
@ -69,7 +71,7 @@ const before = (tooltipPosition) => {
|
|||
}
|
||||
};
|
||||
|
||||
const after = (tooltipPosition, color) => {
|
||||
const after = (tooltipPosition: TooltipPosition, color: string) => {
|
||||
switch (tooltipPosition) {
|
||||
case 'bottom':
|
||||
return `
|
||||
|
@ -110,13 +112,13 @@ const after = (tooltipPosition, color) => {
|
|||
}
|
||||
};
|
||||
|
||||
const getDirection = (tooltipPosition) => {
|
||||
const getDirection = (tooltipPosition: TooltipPosition) => {
|
||||
return tooltipPosition.indexOf('-') > 0
|
||||
? tooltipPosition.substring(0, tooltipPosition.indexOf('-'))
|
||||
: tooltipPosition;
|
||||
};
|
||||
|
||||
const getSize = (size) => {
|
||||
const getSize = (size: Size | undefined) => {
|
||||
switch (size) {
|
||||
case 'big':
|
||||
return 'min-height: 34px; padding: 2px 12px;';
|
||||
|
@ -127,7 +129,16 @@ const getSize = (size) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const commonStyle = ({ theme, mark, size }) => css`
|
||||
interface CommonStyleProps {
|
||||
size: Size | undefined;
|
||||
mark: Mark | false | undefined;
|
||||
}
|
||||
|
||||
export const commonStyle = ({
|
||||
theme,
|
||||
mark,
|
||||
size,
|
||||
}: ThemedStyledProps<CommonStyleProps, Theme>) => css`
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
|
@ -164,13 +175,20 @@ export const commonStyle = ({ theme, mark, size }) => css`
|
|||
}
|
||||
`;
|
||||
|
||||
interface TooltipStyleProps {
|
||||
tooltipTitle: string | undefined;
|
||||
tooltipPosition: TooltipPosition;
|
||||
size: Size | undefined;
|
||||
mark: Mark | false | undefined;
|
||||
}
|
||||
|
||||
export const tooltipStyle = ({
|
||||
theme,
|
||||
tooltipTitle,
|
||||
tooltipPosition,
|
||||
mark,
|
||||
size,
|
||||
}) => css`
|
||||
}: ThemedStyledProps<TooltipStyleProps, Theme>) => css`
|
||||
${commonStyle({ theme, mark, size })}
|
||||
|
||||
&:before {
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export const style = ({ theme, primary, disabled }) => css`
|
||||
export interface StyleProps {
|
||||
primary: boolean | undefined;
|
||||
disabled: boolean | undefined;
|
||||
}
|
||||
|
||||
export const style = ({
|
||||
theme,
|
||||
primary,
|
||||
disabled,
|
||||
}: ThemedStyledProps<StyleProps, Theme>) => css`
|
||||
box-sizing: border-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
outline: none;
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { ripple } from '../../utils/animations';
|
||||
import { StyleProps } from './default';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export const style = ({ theme, primary, disabled }) => css`
|
||||
export const style = ({
|
||||
theme,
|
||||
primary,
|
||||
disabled,
|
||||
}: ThemedStyledProps<StyleProps, Theme>) => css`
|
||||
box-sizing: border-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
outline: none;
|
||||
|
|
|
@ -1,10 +1,23 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ThemeProvider } from 'styled-components';
|
||||
import { getTheme } from '../utils/theme';
|
||||
import { getTheme, ThemeData } from '../utils/theme';
|
||||
import { MainContainerWrapper, ContainerWrapper } from './styles';
|
||||
import { Theme } from '../themes/default';
|
||||
|
||||
const Container = ({ themeData, className, theme, children }) => {
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
themeData?: ThemeData;
|
||||
theme?: Theme;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const Container: React.FunctionComponent<Props> = ({
|
||||
themeData,
|
||||
className,
|
||||
theme,
|
||||
children,
|
||||
}) => {
|
||||
if (!themeData) {
|
||||
return (
|
||||
<ContainerWrapper className={className} theme={theme}>
|
||||
|
@ -24,8 +37,8 @@ const Container = ({ themeData, className, theme, children }) => {
|
|||
|
||||
Container.propTypes = {
|
||||
children: PropTypes.node,
|
||||
themeData: PropTypes.object,
|
||||
theme: PropTypes.object,
|
||||
themeData: PropTypes.any,
|
||||
theme: PropTypes.any,
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Story } from '@storybook/react';
|
||||
import ContextMenu from './';
|
||||
import { items } from './data';
|
||||
import { ContextMenuProps } from './ContextMenu';
|
||||
|
||||
export default {
|
||||
title: 'ContextMenu',
|
||||
|
@ -16,7 +18,7 @@ const Container = styled.div`
|
|||
align-items: center;
|
||||
`;
|
||||
|
||||
const Template = (args) => (
|
||||
const Template: Story<ContextMenuProps> = (args) => (
|
||||
<Container>
|
||||
<ContextMenu {...args} />
|
||||
</Container>
|
||||
|
|
|
@ -5,13 +5,34 @@ import styles from './styles/index';
|
|||
|
||||
const ContextMenuWrapper = createStyledComponent(styles);
|
||||
|
||||
export default class ContextMenu extends Component {
|
||||
constructor(props) {
|
||||
type ReactButtonElement = React.ReactElement<
|
||||
JSX.IntrinsicElements['button'],
|
||||
'button'
|
||||
>;
|
||||
type Item = { name: string; value?: string } | ReactButtonElement;
|
||||
|
||||
function isReactButtonElement(item: Item): item is ReactButtonElement {
|
||||
return (item as ReactButtonElement).type === 'button';
|
||||
}
|
||||
|
||||
export interface ContextMenuProps {
|
||||
items: Item[];
|
||||
onClick: (value: string) => void;
|
||||
x: number;
|
||||
y: number;
|
||||
visible?: boolean;
|
||||
}
|
||||
|
||||
export default class ContextMenu extends Component<ContextMenuProps> {
|
||||
constructor(props: ContextMenuProps) {
|
||||
super(props);
|
||||
this.updateItems(props.items);
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
menu?: HTMLDivElement | null;
|
||||
items?: React.ReactNode[];
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps: ContextMenuProps) {
|
||||
if (
|
||||
nextProps.items !== this.props.items ||
|
||||
nextProps.visible !== this.props.visible
|
||||
|
@ -24,25 +45,25 @@ export default class ContextMenu extends Component {
|
|||
this.amendPosition();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
componentDidUpdate(prevProps: ContextMenuProps) {
|
||||
if (prevProps.x !== this.props.x || prevProps.y !== this.props.y) {
|
||||
this.amendPosition();
|
||||
}
|
||||
}
|
||||
|
||||
onMouseUp = (e) => {
|
||||
e.target.blur();
|
||||
onMouseUp: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
||||
e.currentTarget.blur();
|
||||
};
|
||||
|
||||
onClick = (e) => {
|
||||
this.props.onClick(e.target.value);
|
||||
onClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
||||
this.props.onClick(e.currentTarget.value);
|
||||
};
|
||||
|
||||
amendPosition() {
|
||||
const { x, y } = this.props;
|
||||
const { scrollTop, scrollLeft } = document.documentElement;
|
||||
const { innerWidth, innerHeight } = window;
|
||||
const rect = this.menu.getBoundingClientRect();
|
||||
const rect = this.menu!.getBoundingClientRect();
|
||||
let left = x + scrollLeft;
|
||||
let top = y + scrollTop;
|
||||
|
||||
|
@ -59,14 +80,14 @@ export default class ContextMenu extends Component {
|
|||
left = rect.width < innerWidth ? (innerWidth - rect.width) / 2 : 0;
|
||||
}
|
||||
|
||||
this.menu.style.top = `${top}px`;
|
||||
this.menu.style.left = `${left}px`;
|
||||
this.menu!.style.top = `${top}px`;
|
||||
this.menu!.style.left = `${left}px`;
|
||||
}
|
||||
|
||||
updateItems(items) {
|
||||
updateItems(items: Item[]) {
|
||||
this.items = items.map((item) => {
|
||||
if (isReactButtonElement(item)) return item;
|
||||
const value = item.value || item.name;
|
||||
if (item.type === 'button') return item;
|
||||
return (
|
||||
<button
|
||||
key={value}
|
||||
|
@ -80,7 +101,7 @@ export default class ContextMenu extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
menuRef = (c) => {
|
||||
menuRef: React.RefCallback<HTMLDivElement> = (c) => {
|
||||
this.menu = c;
|
||||
};
|
||||
|
||||
|
@ -96,12 +117,12 @@ export default class ContextMenu extends Component {
|
|||
</ContextMenuWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ContextMenu.propTypes = {
|
||||
items: PropTypes.array.isRequired,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
x: PropTypes.number.isRequired,
|
||||
y: PropTypes.number.isRequired,
|
||||
visible: PropTypes.bool,
|
||||
};
|
||||
static propTypes = {
|
||||
items: PropTypes.array.isRequired,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
x: PropTypes.number.isRequired,
|
||||
y: PropTypes.number.isRequired,
|
||||
visible: PropTypes.bool,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export default ({ theme, left, top, visible }) => css`
|
||||
interface StyleProps {
|
||||
left: number;
|
||||
top: number;
|
||||
visible: boolean | undefined;
|
||||
}
|
||||
|
||||
export default ({
|
||||
theme,
|
||||
left,
|
||||
top,
|
||||
visible,
|
||||
}: ThemedStyledProps<StyleProps, Theme>) => css`
|
||||
${visible
|
||||
? `
|
||||
visibility: visible;
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
import React from 'react';
|
||||
import { Story } from '@storybook/react';
|
||||
import Dialog from './';
|
||||
import { schema, uiSchema, formData } from '../Form/schema';
|
||||
import { DialogProps } from './Dialog';
|
||||
import { Props as FormProps } from '../Form/Form';
|
||||
|
||||
export default {
|
||||
title: 'Dialog',
|
||||
component: Dialog,
|
||||
};
|
||||
|
||||
const Template = (args) => <Dialog {...args} />;
|
||||
const Template: Story<DialogProps | (DialogProps & FormProps<unknown>)> = (
|
||||
args
|
||||
) => <Dialog {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
|
|
|
@ -4,20 +4,60 @@ import createStyledComponent from '../utils/createStyledComponent';
|
|||
import * as styles from './styles';
|
||||
import Button from '../Button';
|
||||
import Form from '../Form';
|
||||
import { Theme } from '../themes/default';
|
||||
import { Props as FormProps } from '../Form/Form';
|
||||
|
||||
const DialogWrapper = createStyledComponent(styles);
|
||||
|
||||
export default class Dialog extends (PureComponent || Component) {
|
||||
export interface DialogProps {
|
||||
open?: boolean;
|
||||
title?: string;
|
||||
children?: React.ReactNode;
|
||||
actions?: React.ReactNode[];
|
||||
submitText?: string;
|
||||
fullWidth?: boolean;
|
||||
noHeader?: boolean;
|
||||
noFooter?: boolean;
|
||||
modal?: boolean;
|
||||
onDismiss: (
|
||||
e: React.MouseEvent<HTMLButtonElement | HTMLDivElement> | false
|
||||
) => void;
|
||||
onSubmit: () => void;
|
||||
theme?: Theme;
|
||||
}
|
||||
|
||||
type Rest<P> = Omit<
|
||||
DialogProps & FormProps<P>,
|
||||
| 'modal'
|
||||
| 'open'
|
||||
| 'fullWidth'
|
||||
| 'title'
|
||||
| 'children'
|
||||
| 'actions'
|
||||
| 'noHeader'
|
||||
| 'noFooter'
|
||||
| 'submitText'
|
||||
| 'onDismiss'
|
||||
>;
|
||||
function isForm<P>(rest?: FormProps<P>): rest is FormProps<P> {
|
||||
return (rest as FormProps<P>).schema !== undefined;
|
||||
}
|
||||
|
||||
export default class Dialog<P> extends (PureComponent || Component)<
|
||||
DialogProps | (DialogProps & FormProps<P>)
|
||||
> {
|
||||
submitButton?: HTMLInputElement | null;
|
||||
|
||||
onSubmit = () => {
|
||||
if (this.submitButton) this.submitButton.click();
|
||||
else this.props.onSubmit();
|
||||
};
|
||||
|
||||
getFormButtonRef = (node) => {
|
||||
getFormButtonRef: React.RefCallback<HTMLInputElement> = (node) => {
|
||||
this.submitButton = node;
|
||||
};
|
||||
|
||||
onKeyDown = (e) => {
|
||||
onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (e) => {
|
||||
if (e.keyCode === 27 /* esc */) {
|
||||
e.preventDefault();
|
||||
this.props.onDismiss(false);
|
||||
|
@ -38,7 +78,7 @@ export default class Dialog extends (PureComponent || Component) {
|
|||
onDismiss,
|
||||
...rest
|
||||
} = this.props;
|
||||
const schema = rest.schema;
|
||||
const schema = (rest as Rest<P>).schema;
|
||||
|
||||
return (
|
||||
<DialogWrapper
|
||||
|
@ -47,7 +87,7 @@ export default class Dialog extends (PureComponent || Component) {
|
|||
onKeyDown={this.onKeyDown}
|
||||
theme={rest.theme}
|
||||
>
|
||||
<div onClick={!modal && onDismiss} />
|
||||
<div onClick={!modal ? onDismiss : undefined} />
|
||||
<div>
|
||||
{!noHeader && (
|
||||
<div className="mc-dialog--header">
|
||||
|
@ -57,8 +97,8 @@ export default class Dialog extends (PureComponent || Component) {
|
|||
)}
|
||||
<div className="mc-dialog--body">
|
||||
{children}
|
||||
{schema && (
|
||||
<Form {...rest}>
|
||||
{isForm(rest as FormProps<P>) && (
|
||||
<Form {...(rest as FormProps<P>)}>
|
||||
{!noFooter && (
|
||||
<input
|
||||
type="submit"
|
||||
|
@ -97,19 +137,19 @@ export default class Dialog extends (PureComponent || Component) {
|
|||
</DialogWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Dialog.propTypes = {
|
||||
open: PropTypes.bool,
|
||||
title: PropTypes.string,
|
||||
children: PropTypes.any,
|
||||
actions: PropTypes.node,
|
||||
submitText: PropTypes.string,
|
||||
fullWidth: PropTypes.bool,
|
||||
noHeader: PropTypes.bool,
|
||||
noFooter: PropTypes.bool,
|
||||
modal: PropTypes.bool,
|
||||
onDismiss: PropTypes.func,
|
||||
onSubmit: PropTypes.func,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
static propTypes = {
|
||||
open: PropTypes.bool,
|
||||
title: PropTypes.string,
|
||||
children: PropTypes.any,
|
||||
actions: PropTypes.node,
|
||||
submitText: PropTypes.string,
|
||||
fullWidth: PropTypes.bool,
|
||||
noHeader: PropTypes.bool,
|
||||
noFooter: PropTypes.bool,
|
||||
modal: PropTypes.bool,
|
||||
onDismiss: PropTypes.func,
|
||||
onSubmit: PropTypes.func,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export const style = ({ theme, open, fullWidth }) => css`
|
||||
export interface StyleProps {
|
||||
open: boolean | undefined;
|
||||
fullWidth: boolean | undefined;
|
||||
}
|
||||
|
||||
export const style = ({
|
||||
theme,
|
||||
open,
|
||||
fullWidth,
|
||||
}: ThemedStyledProps<StyleProps, Theme>) => css`
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { StyleProps } from './default';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export const style = ({ theme, open, fullWidth }) => css`
|
||||
export const style = ({
|
||||
theme,
|
||||
open,
|
||||
fullWidth,
|
||||
}: ThemedStyledProps<StyleProps, Theme>) => css`
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import React from 'react';
|
||||
import { Story } from '@storybook/react';
|
||||
import Editor from './';
|
||||
import { default as WithTabsComponent } from './WithTabs';
|
||||
import { default as WithTabsComponent, WithTabsProps } from './WithTabs';
|
||||
import { EditorProps } from './Editor';
|
||||
|
||||
const value = `
|
||||
var themes = [];
|
||||
|
@ -15,7 +17,7 @@ export default {
|
|||
component: Editor,
|
||||
};
|
||||
|
||||
const Template = (args) => <Editor {...args} />;
|
||||
const Template: Story<EditorProps> = (args) => <Editor {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
|
@ -33,7 +35,9 @@ Default.argTypes = {
|
|||
onChange: { control: { disable: true } },
|
||||
};
|
||||
|
||||
const WithTabsTemplate = (args) => <WithTabsComponent {...args} />;
|
||||
const WithTabsTemplate: Story<WithTabsProps> = (args) => (
|
||||
<WithTabsComponent {...args} />
|
||||
);
|
||||
|
||||
export const WithTabs = WithTabsTemplate.bind({});
|
||||
WithTabs.args = {
|
||||
|
|
|
@ -3,17 +3,37 @@ import PropTypes from 'prop-types';
|
|||
import styled from 'styled-components';
|
||||
import CodeMirror from 'codemirror';
|
||||
import { defaultStyle, themedStyle } from './styles';
|
||||
import { Theme } from '../themes/default';
|
||||
|
||||
const EditorContainer = styled.div('', ({ theme }) =>
|
||||
theme.scheme === 'default' && theme.light ? defaultStyle : themedStyle(theme)
|
||||
const EditorContainer = styled.div(
|
||||
('' as unknown) as TemplateStringsArray,
|
||||
({ theme }: { theme: Theme }) =>
|
||||
theme.scheme === 'default' && theme.light
|
||||
? defaultStyle
|
||||
: themedStyle(theme)
|
||||
);
|
||||
|
||||
export interface EditorProps {
|
||||
value: string;
|
||||
mode: string;
|
||||
lineNumbers: boolean;
|
||||
lineWrapping: boolean;
|
||||
readOnly: boolean;
|
||||
theme?: Theme;
|
||||
foldGutter: boolean;
|
||||
autofocus: boolean;
|
||||
onChange: (value: string, change: CodeMirror.EditorChangeLinkedList) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on [CodeMirror](http://codemirror.net/).
|
||||
*/
|
||||
export default class Editor extends Component {
|
||||
export default class Editor extends Component<EditorProps> {
|
||||
cm?: CodeMirror.Editor | null;
|
||||
node?: HTMLDivElement | null;
|
||||
|
||||
componentDidMount() {
|
||||
this.cm = CodeMirror(this.node, {
|
||||
this.cm = CodeMirror(this.node!, {
|
||||
value: this.props.value,
|
||||
mode: this.props.mode,
|
||||
lineNumbers: this.props.lineNumbers,
|
||||
|
@ -31,21 +51,21 @@ export default class Editor extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.value !== this.cm.getValue()) {
|
||||
this.cm.setValue(nextProps.value);
|
||||
UNSAFE_componentWillReceiveProps(nextProps: EditorProps) {
|
||||
if (nextProps.value !== this.cm!.getValue()) {
|
||||
this.cm!.setValue(nextProps.value);
|
||||
}
|
||||
if (nextProps.readOnly !== this.props.readOnly) {
|
||||
this.cm.setOption('readOnly', nextProps.readOnly);
|
||||
this.cm!.setOption('readOnly', nextProps.readOnly);
|
||||
}
|
||||
if (nextProps.lineNumbers !== this.props.lineNumbers) {
|
||||
this.cm.setOption('lineNumbers', nextProps.lineNumbers);
|
||||
this.cm!.setOption('lineNumbers', nextProps.lineNumbers);
|
||||
}
|
||||
if (nextProps.lineWrapping !== this.props.lineWrapping) {
|
||||
this.cm.setOption('lineWrapping', nextProps.lineWrapping);
|
||||
this.cm!.setOption('lineWrapping', nextProps.lineWrapping);
|
||||
}
|
||||
if (nextProps.foldGutter !== this.props.foldGutter) {
|
||||
this.cm.setOption('foldGutter', nextProps.foldGutter);
|
||||
this.cm!.setOption('foldGutter', nextProps.foldGutter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,38 +74,38 @@ export default class Editor extends Component {
|
|||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const node = this.node;
|
||||
const node = this.node!;
|
||||
node.removeChild(node.children[0]);
|
||||
this.cm = null;
|
||||
}
|
||||
|
||||
getRef = (node) => {
|
||||
getRef: React.RefCallback<HTMLDivElement> = (node) => {
|
||||
this.node = node;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <EditorContainer ref={this.getRef} theme={this.props.theme} />;
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
value: PropTypes.string,
|
||||
mode: PropTypes.string,
|
||||
lineNumbers: PropTypes.bool,
|
||||
lineWrapping: PropTypes.bool,
|
||||
readOnly: PropTypes.bool,
|
||||
theme: PropTypes.object,
|
||||
foldGutter: PropTypes.bool,
|
||||
autofocus: PropTypes.bool,
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
value: '',
|
||||
mode: 'javascript',
|
||||
lineNumbers: true,
|
||||
lineWrapping: false,
|
||||
readOnly: false,
|
||||
foldGutter: true,
|
||||
autofocus: false,
|
||||
};
|
||||
}
|
||||
|
||||
Editor.propTypes = {
|
||||
value: PropTypes.string,
|
||||
mode: PropTypes.string,
|
||||
lineNumbers: PropTypes.bool,
|
||||
lineWrapping: PropTypes.bool,
|
||||
readOnly: PropTypes.bool,
|
||||
theme: PropTypes.object,
|
||||
foldGutter: PropTypes.bool,
|
||||
autofocus: PropTypes.bool,
|
||||
onChange: PropTypes.func,
|
||||
};
|
||||
|
||||
Editor.defaultProps = {
|
||||
value: '',
|
||||
mode: 'javascript',
|
||||
lineNumbers: true,
|
||||
lineWrapping: false,
|
||||
readOnly: false,
|
||||
foldGutter: true,
|
||||
autofocus: false,
|
||||
};
|
||||
|
|
|
@ -10,8 +10,18 @@ const value2 = `
|
|||
const func2 = () => {}
|
||||
`;
|
||||
|
||||
export interface WithTabsProps {
|
||||
align: 'left' | 'right' | 'center';
|
||||
lineNumbers: boolean;
|
||||
}
|
||||
|
||||
interface TabProps {
|
||||
value: string;
|
||||
lineNumbers: boolean;
|
||||
}
|
||||
|
||||
/* eslint-disable react/prop-types */
|
||||
export default class WithTabs extends Component {
|
||||
export default class WithTabs extends Component<WithTabsProps> {
|
||||
state = {
|
||||
selected: 'Function 1',
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { css } from 'styled-components';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export const defaultStyle = `
|
||||
height: 100%;
|
||||
|
@ -10,7 +11,7 @@ export const defaultStyle = `
|
|||
}
|
||||
`;
|
||||
|
||||
export const themedStyle = (theme) => css`
|
||||
export const themedStyle = (theme: Theme) => css`
|
||||
height: 100%;
|
||||
|
||||
> div {
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import React from 'react';
|
||||
import { Story } from '@storybook/react';
|
||||
import Form from './';
|
||||
import { schema, uiSchema, formData } from './schema';
|
||||
import { Props as FormProps } from './Form';
|
||||
|
||||
export default {
|
||||
title: 'Form',
|
||||
component: Form,
|
||||
};
|
||||
|
||||
const Template = (args) => <Form {...args} />;
|
||||
const Template: Story<FormProps<unknown>> = (args) => <Form {...args} />;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
import React, { PureComponent, Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import JSONSchemaForm from 'react-jsonschema-form';
|
||||
import JSONSchemaForm, { FormProps } from 'react-jsonschema-form';
|
||||
import createStyledComponent from '../utils/createStyledComponent';
|
||||
import styles from './styles';
|
||||
import Button from '../Button';
|
||||
import customWidgets from './widgets';
|
||||
import { Theme } from '../themes/default';
|
||||
|
||||
const FormContainer = createStyledComponent(styles, JSONSchemaForm);
|
||||
|
||||
export interface Props<T> extends FormProps<T> {
|
||||
children?: React.ReactNode;
|
||||
submitText?: string;
|
||||
primaryButton?: boolean;
|
||||
noSubmit?: boolean;
|
||||
theme?: Theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around [`react-jsonschema-form`](https://github.com/mozilla-services/react-jsonschema-form) with custom widgets.
|
||||
*/
|
||||
export default class Form extends (PureComponent || Component) {
|
||||
export default class Form<T> extends (PureComponent || Component)<Props<T>> {
|
||||
render() {
|
||||
const {
|
||||
widgets,
|
||||
|
@ -22,7 +31,10 @@ export default class Form extends (PureComponent || Component) {
|
|||
...rest
|
||||
} = this.props;
|
||||
return (
|
||||
<FormContainer {...rest} widgets={{ ...customWidgets, ...widgets }}>
|
||||
<FormContainer
|
||||
{...(rest as Props<unknown>)}
|
||||
widgets={{ ...customWidgets, ...widgets }}
|
||||
>
|
||||
{noSubmit ? (
|
||||
<noscript />
|
||||
) : (
|
||||
|
@ -40,17 +52,17 @@ export default class Form extends (PureComponent || Component) {
|
|||
</FormContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Form.propTypes = {
|
||||
children: PropTypes.any,
|
||||
submitText: PropTypes.string,
|
||||
primaryButton: PropTypes.bool,
|
||||
noSubmit: PropTypes.bool,
|
||||
schema: PropTypes.object.isRequired,
|
||||
uiSchema: PropTypes.object,
|
||||
formData: PropTypes.any,
|
||||
widgets: PropTypes.objectOf(
|
||||
PropTypes.oneOfType([PropTypes.func, PropTypes.object])
|
||||
),
|
||||
};
|
||||
static propTypes = {
|
||||
children: PropTypes.any,
|
||||
submitText: PropTypes.string,
|
||||
primaryButton: PropTypes.bool,
|
||||
noSubmit: PropTypes.bool,
|
||||
schema: PropTypes.object.isRequired,
|
||||
uiSchema: PropTypes.object,
|
||||
formData: PropTypes.any,
|
||||
widgets: PropTypes.objectOf(
|
||||
PropTypes.oneOfType([PropTypes.func, PropTypes.object])
|
||||
),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,89 +1,91 @@
|
|||
module.exports = {
|
||||
schema: {
|
||||
title: 'Example form',
|
||||
description: 'A simple form example.',
|
||||
type: 'object',
|
||||
required: ['name'],
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
title: 'Full name',
|
||||
},
|
||||
age: {
|
||||
type: 'integer',
|
||||
title: 'Age',
|
||||
},
|
||||
bio: {
|
||||
type: 'string',
|
||||
title: 'Bio',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
title: 'Password',
|
||||
minLength: 3,
|
||||
},
|
||||
multipleChoicesList: {
|
||||
type: 'array',
|
||||
title: 'A multiple choices list',
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: ['foo', 'bar', 'fuzz'],
|
||||
},
|
||||
uniqueItems: true,
|
||||
},
|
||||
numberEnum: {
|
||||
type: 'number',
|
||||
title: 'Number enum',
|
||||
enum: [1, 2, 3],
|
||||
},
|
||||
numberEnumRadio: {
|
||||
type: 'number',
|
||||
title: 'Number enum',
|
||||
enum: [1, 2, 3],
|
||||
},
|
||||
integerRange: {
|
||||
title: 'Integer range',
|
||||
type: 'integer',
|
||||
minimum: 42,
|
||||
maximum: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
uiSchema: {
|
||||
import { JSONSchema6 } from 'json-schema';
|
||||
|
||||
export const schema: JSONSchema6 = {
|
||||
title: 'Example form',
|
||||
description: 'A simple form example.',
|
||||
type: 'object',
|
||||
required: ['name'],
|
||||
properties: {
|
||||
name: {
|
||||
'ui:autofocus': true,
|
||||
type: 'string',
|
||||
title: 'Full name',
|
||||
},
|
||||
age: {
|
||||
'ui:widget': 'updown',
|
||||
type: 'integer',
|
||||
title: 'Age',
|
||||
},
|
||||
bio: {
|
||||
'ui:widget': 'textarea',
|
||||
type: 'string',
|
||||
title: 'Bio',
|
||||
},
|
||||
password: {
|
||||
'ui:widget': 'password',
|
||||
'ui:help': 'Hint: Make it strong!',
|
||||
},
|
||||
date: {
|
||||
'ui:widget': 'alt-datetime',
|
||||
type: 'string',
|
||||
title: 'Password',
|
||||
minLength: 3,
|
||||
},
|
||||
multipleChoicesList: {
|
||||
'ui:widget': 'checkboxes',
|
||||
type: 'array',
|
||||
title: 'A multiple choices list',
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: ['foo', 'bar', 'fuzz'],
|
||||
},
|
||||
uniqueItems: true,
|
||||
},
|
||||
numberEnum: {
|
||||
type: 'number',
|
||||
title: 'Number enum',
|
||||
enum: [1, 2, 3],
|
||||
},
|
||||
numberEnumRadio: {
|
||||
'ui:widget': 'radio',
|
||||
'ui:options': {
|
||||
inline: true,
|
||||
},
|
||||
type: 'number',
|
||||
title: 'Number enum',
|
||||
enum: [1, 2, 3],
|
||||
},
|
||||
integerRange: {
|
||||
'ui:widget': 'range',
|
||||
title: 'Integer range',
|
||||
type: 'integer',
|
||||
minimum: 42,
|
||||
maximum: 100,
|
||||
},
|
||||
},
|
||||
formData: {
|
||||
name: 'Chuck Norris',
|
||||
age: 75,
|
||||
bio: 'Roundhouse kicking asses since 1940',
|
||||
password: 'noneed',
|
||||
integerRange: 52,
|
||||
};
|
||||
|
||||
export const uiSchema = {
|
||||
name: {
|
||||
'ui:autofocus': true,
|
||||
},
|
||||
age: {
|
||||
'ui:widget': 'updown',
|
||||
},
|
||||
bio: {
|
||||
'ui:widget': 'textarea',
|
||||
},
|
||||
password: {
|
||||
'ui:widget': 'password',
|
||||
'ui:help': 'Hint: Make it strong!',
|
||||
},
|
||||
date: {
|
||||
'ui:widget': 'alt-datetime',
|
||||
},
|
||||
multipleChoicesList: {
|
||||
'ui:widget': 'checkboxes',
|
||||
},
|
||||
numberEnumRadio: {
|
||||
'ui:widget': 'radio',
|
||||
'ui:options': {
|
||||
inline: true,
|
||||
},
|
||||
},
|
||||
integerRange: {
|
||||
'ui:widget': 'range',
|
||||
},
|
||||
};
|
||||
|
||||
export const formData = {
|
||||
name: 'Chuck Norris',
|
||||
age: 75,
|
||||
bio: 'Roundhouse kicking asses since 1940',
|
||||
password: 'noneed',
|
||||
integerRange: 52,
|
||||
};
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export default ({ theme }) => css`
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export default ({ theme }: ThemedStyledProps<{}, Theme>) => css`
|
||||
padding: 10px;
|
||||
line-height: 1.846;
|
||||
font-size: 14px;
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import React from 'react';
|
||||
import { Widget } from 'react-jsonschema-form';
|
||||
import Select from '../Select';
|
||||
import Slider from '../Slider';
|
||||
|
||||
/* eslint-disable react/prop-types */
|
||||
const SelectWidget = ({ options, multi, ...rest }) => (
|
||||
const SelectWidget: Widget = ({ options, multi, ...rest }) => (
|
||||
<Select options={options.enumOptions} multiple={multi} {...rest} />
|
||||
);
|
||||
|
||||
const RangeWidget = ({
|
||||
const RangeWidget: Widget = ({
|
||||
schema,
|
||||
readonly,
|
||||
autofocus,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Story } from '@storybook/react';
|
||||
import Notification from './';
|
||||
import { NotificationProps } from './Notification';
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
|
@ -15,7 +17,7 @@ export default {
|
|||
component: Notification,
|
||||
};
|
||||
|
||||
const Template = (args) => (
|
||||
const Template: Story<NotificationProps> = (args) => (
|
||||
<Container>
|
||||
<Notification {...args} />
|
||||
</Container>
|
||||
|
|
|
@ -6,11 +6,21 @@ import { MdError } from 'react-icons/md';
|
|||
import { MdCheckCircle } from 'react-icons/md';
|
||||
import createStyledComponent from '../utils/createStyledComponent';
|
||||
import styles from './styles';
|
||||
import { Theme } from '../themes/default';
|
||||
|
||||
const NotificationWrapper = createStyledComponent(styles);
|
||||
|
||||
export default class Notification extends Component {
|
||||
shouldComponentUpdate(nextProps) {
|
||||
export type Type = 'info' | 'success' | 'warning' | 'error';
|
||||
|
||||
export interface NotificationProps {
|
||||
children?: React.ReactNode;
|
||||
type: Type;
|
||||
onClose?: React.MouseEventHandler<HTMLButtonElement>;
|
||||
theme?: Theme;
|
||||
}
|
||||
|
||||
export default class Notification extends Component<NotificationProps> {
|
||||
shouldComponentUpdate(nextProps: NotificationProps) {
|
||||
return (
|
||||
nextProps.children !== this.props.children ||
|
||||
nextProps.type !== this.props.type
|
||||
|
@ -43,15 +53,15 @@ export default class Notification extends Component {
|
|||
</NotificationWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
children: PropTypes.any.isRequired,
|
||||
type: PropTypes.oneOf(['info', 'success', 'warning', 'error']),
|
||||
onClose: PropTypes.func,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
type: 'info',
|
||||
};
|
||||
}
|
||||
|
||||
Notification.propTypes = {
|
||||
children: PropTypes.any.isRequired,
|
||||
type: PropTypes.oneOf(['info', 'success', 'warning', 'error']),
|
||||
onClose: PropTypes.func,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
|
||||
Notification.defaultProps = {
|
||||
type: 'info',
|
||||
};
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { Theme } from '../../themes/default';
|
||||
import { Type } from '../Notification';
|
||||
|
||||
const getBackground = (theme, type) => {
|
||||
const getBackground = (theme: Theme, type: Type) => {
|
||||
switch (type) {
|
||||
case 'success':
|
||||
return `background-color: ${theme.base0B};`;
|
||||
|
@ -13,7 +15,11 @@ const getBackground = (theme, type) => {
|
|||
}
|
||||
};
|
||||
|
||||
export default ({ theme, type }) => css`
|
||||
interface StyleProps {
|
||||
type: Type;
|
||||
}
|
||||
|
||||
export default ({ theme, type }: ThemedStyledProps<StyleProps, Theme>) => css`
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-shrink: 0;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Story } from '@storybook/react';
|
||||
import SegmentedControl from './';
|
||||
import { SegmentedControlProps } from './SegmentedControl';
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
|
@ -15,7 +17,7 @@ export default {
|
|||
component: SegmentedControl,
|
||||
};
|
||||
|
||||
const Template = (args) => (
|
||||
const Template: Story<Omit<SegmentedControlProps, 'values'>> = (args) => (
|
||||
<Container>
|
||||
<SegmentedControl values={['Button1', 'Button2', 'Button3']} {...args} />
|
||||
</Container>
|
||||
|
|
|
@ -2,23 +2,32 @@ import React, { Component } from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import createStyledComponent from '../utils/createStyledComponent';
|
||||
import styles from './styles';
|
||||
import { Theme } from '../themes/default';
|
||||
|
||||
const SegmentedWrapper = createStyledComponent(styles);
|
||||
|
||||
export default class SegmentedControl extends Component {
|
||||
shouldComponentUpdate(nextProps) {
|
||||
export interface SegmentedControlProps {
|
||||
values: string[];
|
||||
selected?: string;
|
||||
onClick: (value: string) => void;
|
||||
disabled?: boolean;
|
||||
theme?: Theme;
|
||||
}
|
||||
|
||||
export default class SegmentedControl extends Component<SegmentedControlProps> {
|
||||
shouldComponentUpdate(nextProps: SegmentedControlProps) {
|
||||
return (
|
||||
nextProps.disabled !== this.props.disabled ||
|
||||
nextProps.selected !== this.props.selected
|
||||
);
|
||||
}
|
||||
|
||||
onClick = (e) => {
|
||||
this.props.onClick(e.target.value);
|
||||
onClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
||||
this.props.onClick(e.currentTarget.value);
|
||||
};
|
||||
|
||||
onMouseUp = (e) => {
|
||||
e.target.blur();
|
||||
onMouseUp: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
||||
e.currentTarget.blur();
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -39,12 +48,12 @@ export default class SegmentedControl extends Component {
|
|||
</SegmentedWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SegmentedControl.propTypes = {
|
||||
values: PropTypes.array.isRequired,
|
||||
selected: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
disabled: PropTypes.bool,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
static propTypes = {
|
||||
values: PropTypes.array.isRequired,
|
||||
selected: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
disabled: PropTypes.bool,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import color from '../../utils/color';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export default ({ theme, disabled }) => css`
|
||||
interface StyleProps {
|
||||
disabled: boolean | undefined;
|
||||
}
|
||||
|
||||
export default ({
|
||||
theme,
|
||||
disabled,
|
||||
}: ThemedStyledProps<StyleProps, Theme>) => css`
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ import React from 'react';
|
|||
import styled from 'styled-components';
|
||||
import Select from './';
|
||||
import { options } from './options';
|
||||
import { Story } from '@storybook/react';
|
||||
import { SelectProps } from './Select';
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
|
@ -20,7 +22,10 @@ export default {
|
|||
component: Select,
|
||||
};
|
||||
|
||||
const Template = ({ value, ...args }) => (
|
||||
type TemplateArgs = Omit<SelectProps, 'value'> & { value: string };
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const Template: Story<TemplateArgs> = ({ value, ...args }) => (
|
||||
<Container>
|
||||
<Select
|
||||
options={options}
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
import React, { PureComponent, Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReactSelect from 'react-select';
|
||||
import ReactSelect, { Props as ReactSelectProps } from 'react-select';
|
||||
import createThemedComponent from '../utils/createThemedComponent';
|
||||
import { Theme } from '../themes/default';
|
||||
|
||||
export interface SelectProps extends Omit<ReactSelectProps, 'theme'> {
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around [React Select](https://github.com/JedWatson/react-select).
|
||||
*/
|
||||
class Select extends (PureComponent || Component) {
|
||||
class Select extends (PureComponent || Component)<SelectProps> {
|
||||
render() {
|
||||
return (
|
||||
<ReactSelect
|
||||
|
@ -37,17 +42,17 @@ class Select extends (PureComponent || Component) {
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
isClearable: PropTypes.bool, // should it be possible to reset value
|
||||
isDisabled: PropTypes.bool, // whether the Select is disabled or not
|
||||
isLoading: PropTypes.bool, // whether the Select is loading externally or not
|
||||
maxMenuHeight: PropTypes.number, // maximum css height for the opened menu of options
|
||||
isMulti: PropTypes.bool, // multi-value input
|
||||
isSearchable: PropTypes.bool, // whether to enable searching feature or not
|
||||
value: PropTypes.any, // initial field value
|
||||
menuPlacement: PropTypes.oneOf(['auto', 'bottom', 'top']), // value to control the opening direction
|
||||
};
|
||||
}
|
||||
|
||||
Select.propTypes = {
|
||||
isClearable: PropTypes.bool, // should it be possible to reset value
|
||||
isDisabled: PropTypes.bool, // whether the Select is disabled or not
|
||||
isLoading: PropTypes.bool, // whether the Select is loading externally or not
|
||||
maxMenuHeight: PropTypes.number, // maximum css height for the opened menu of options
|
||||
isMulti: PropTypes.bool, // multi-value input
|
||||
isSearchable: PropTypes.bool, // whether to enable searching feature or not
|
||||
value: PropTypes.any, // initial field value
|
||||
menuPlacement: PropTypes.oneOf(['auto', 'bottom', 'top']), // value to control the opening direction
|
||||
};
|
||||
|
||||
export default createThemedComponent(Select);
|
||||
|
|
|
@ -1 +1 @@
|
|||
export default from './Select';
|
||||
export { default } from './Select';
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Story } from '@storybook/react';
|
||||
import Slider from './';
|
||||
import { SliderProps } from './Slider';
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
|
@ -15,7 +17,7 @@ export default {
|
|||
component: Slider,
|
||||
};
|
||||
|
||||
const Template = (args) => (
|
||||
const Template: Story<SliderProps> = (args) => (
|
||||
<Container>
|
||||
<Slider {...args} />
|
||||
</Container>
|
||||
|
|
|
@ -3,12 +3,25 @@ import PropTypes from 'prop-types';
|
|||
import createStyledComponent from '../utils/createStyledComponent';
|
||||
import * as styles from './styles';
|
||||
import { containerStyle } from './styles/common';
|
||||
import { Theme } from '../themes/default';
|
||||
|
||||
const SliderWrapper = createStyledComponent(styles);
|
||||
const ContainerWithValue = createStyledComponent(containerStyle);
|
||||
|
||||
export default class Slider extends Component {
|
||||
shouldComponentUpdate(nextProps) {
|
||||
export interface SliderProps {
|
||||
value: number;
|
||||
min: number;
|
||||
max: number;
|
||||
label?: string;
|
||||
sublabel?: string;
|
||||
withValue?: boolean;
|
||||
disabled?: boolean;
|
||||
onChange: (value: number) => void;
|
||||
theme?: Theme;
|
||||
}
|
||||
|
||||
export default class Slider extends Component<SliderProps> {
|
||||
shouldComponentUpdate(nextProps: SliderProps) {
|
||||
return (
|
||||
nextProps.label !== this.props.label ||
|
||||
nextProps.value !== this.props.value ||
|
||||
|
@ -19,7 +32,7 @@ export default class Slider extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
onChange = (e) => {
|
||||
onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
||||
this.props.onChange(parseFloat(e.target.value));
|
||||
};
|
||||
|
||||
|
@ -53,18 +66,18 @@ export default class Slider extends Component {
|
|||
</SliderWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
value: PropTypes.number,
|
||||
min: PropTypes.number,
|
||||
max: PropTypes.number,
|
||||
label: PropTypes.string,
|
||||
sublabel: PropTypes.string,
|
||||
withValue: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
onChange: PropTypes.func,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
|
||||
static defaultProps = { value: 0, min: 0, max: 100 };
|
||||
}
|
||||
|
||||
Slider.propTypes = {
|
||||
value: PropTypes.number,
|
||||
min: PropTypes.number,
|
||||
max: PropTypes.number,
|
||||
label: PropTypes.string,
|
||||
sublabel: PropTypes.string,
|
||||
withValue: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
onChange: PropTypes.func,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
|
||||
Slider.defaultProps = { value: 0, min: 0, max: 100 };
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export const containerStyle = ({ theme }) => css`
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export const containerStyle = ({ theme }: ThemedStyledProps<{}, Theme>) => css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
|
|
@ -6,10 +6,22 @@ Based on:
|
|||
http://codepen.io/thebabydino/pen/YPOPxr
|
||||
*/
|
||||
|
||||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { prefixSelectors } from '../../utils/autoPrefix';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export const style = ({ theme, percent, disabled, withLabel }) => css`
|
||||
export interface StyleProps {
|
||||
percent: number;
|
||||
disabled: boolean;
|
||||
withLabel: boolean;
|
||||
}
|
||||
|
||||
export const style = ({
|
||||
theme,
|
||||
percent,
|
||||
disabled,
|
||||
withLabel,
|
||||
}: ThemedStyledProps<StyleProps, Theme>) => css`
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
import { css } from 'styled-components';
|
||||
import { css, ThemedStyledProps } from 'styled-components';
|
||||
import { prefixSelectors } from '../../utils/autoPrefix';
|
||||
import color from '../../utils/color';
|
||||
import { animationCurve } from '../../utils/animations';
|
||||
import { StyleProps } from './default';
|
||||
import { Theme } from '../../themes/default';
|
||||
|
||||
export const style = ({ theme, percent, disabled, withLabel }) => css`
|
||||
export const style = ({
|
||||
theme,
|
||||
percent,
|
||||
disabled,
|
||||
withLabel,
|
||||
}: ThemedStyledProps<StyleProps, Theme>) => css`
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
|
|
@ -3,27 +3,42 @@ import PropTypes from 'prop-types';
|
|||
import TabsHeader from './TabsHeader';
|
||||
import { TabsContainer } from './styles/common';
|
||||
|
||||
export default class Tabs extends Component {
|
||||
constructor(props) {
|
||||
export type Position = 'left' | 'right' | 'center';
|
||||
|
||||
export interface TabsProps<P> {
|
||||
tabs: Tab<P>[];
|
||||
selected?: string;
|
||||
main?: boolean;
|
||||
onClick: (value: string) => void;
|
||||
collapsible?: boolean;
|
||||
position: Position;
|
||||
}
|
||||
|
||||
export default class Tabs<P> extends Component<TabsProps<P>> {
|
||||
constructor(props: TabsProps<P>) {
|
||||
super(props);
|
||||
this.updateTabs(props);
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
tabsHeader?: ReactButtonElement[];
|
||||
SelectedComponent?: React.ComponentType<P>;
|
||||
selector?: () => P;
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps: TabsProps<P>) {
|
||||
if (nextProps.selected !== this.props.selected) {
|
||||
this.updateTabs(nextProps);
|
||||
}
|
||||
}
|
||||
|
||||
onMouseUp = (e) => {
|
||||
e.target.blur();
|
||||
onMouseUp: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
||||
e.currentTarget.blur();
|
||||
};
|
||||
|
||||
onClick = (e) => {
|
||||
this.props.onClick(e.target.value);
|
||||
onClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
||||
this.props.onClick(e.currentTarget.value);
|
||||
};
|
||||
|
||||
updateTabs(props) {
|
||||
updateTabs(props: TabsProps<P>) {
|
||||
const tabs = props.tabs;
|
||||
const selected = props.selected;
|
||||
|
||||
|
@ -34,7 +49,7 @@ export default class Tabs extends Component {
|
|||
isSelected = true;
|
||||
if (tab.component) {
|
||||
this.SelectedComponent = tab.component;
|
||||
if (tab.selector) this.selector = () => tab.selector(tab);
|
||||
if (tab.selector) this.selector = () => tab.selector!(tab);
|
||||
}
|
||||
}
|
||||
return (
|
||||
|
@ -54,7 +69,7 @@ export default class Tabs extends Component {
|
|||
render() {
|
||||
const tabsHeader = (
|
||||
<TabsHeader
|
||||
tabs={this.tabsHeader}
|
||||
tabs={this.tabsHeader!}
|
||||
items={this.props.tabs}
|
||||
main={this.props.main}
|
||||
collapsible={this.props.collapsible}
|
||||
|
@ -76,7 +91,7 @@ export default class Tabs extends Component {
|
|||
<TabsContainer position={this.props.position}>
|
||||
{tabsHeader}
|
||||
<div>
|
||||
<this.SelectedComponent {...(this.selector && this.selector())} />
|
||||
<this.SelectedComponent {...(this.selector! && this.selector!())} />
|
||||
</div>
|
||||
</TabsContainer>
|
||||
);
|
||||
|
|
|
@ -8,8 +8,37 @@ import * as styles from './styles';
|
|||
|
||||
const TabsWrapper = createStyledComponent(styles);
|
||||
|
||||
export default class TabsHeader extends Component {
|
||||
constructor(props) {
|
||||
export type ReactButtonElement = React.ReactElement<
|
||||
JSX.IntrinsicElements['button'],
|
||||
'button'
|
||||
>;
|
||||
|
||||
export interface Tab<P> {
|
||||
name: string;
|
||||
value?: string;
|
||||
component?: React.ComponentType<P>;
|
||||
selector?: (tab: this) => P;
|
||||
}
|
||||
|
||||
interface Props<P> {
|
||||
tabs: ReactButtonElement[];
|
||||
items: Tab<P>;
|
||||
main: boolean | undefined;
|
||||
onClick: (value: string) => void;
|
||||
position: 'left' | 'right' | 'center';
|
||||
collapsible: boolean | undefined;
|
||||
selected: string | undefined;
|
||||
}
|
||||
|
||||
interface State {
|
||||
visibleTabs: ReactButtonElement[];
|
||||
hiddenTabs: ReactButtonElement[];
|
||||
subMenuOpened: boolean;
|
||||
contextMenu: { top: number; left: number } | undefined;
|
||||
}
|
||||
|
||||
export default class TabsHeader<P> extends Component<Props<P>, State> {
|
||||
constructor(props: Props<P>) {
|
||||
super(props);
|
||||
this.state = {
|
||||
visibleTabs: props.tabs.slice(),
|
||||
|
@ -21,7 +50,7 @@ export default class TabsHeader extends Component {
|
|||
this.hiddenTabsWidth = [];
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
UNSAFE_componentWillReceiveProps(nextProps: Props<P>) {
|
||||
if (
|
||||
nextProps.tabs !== this.props.tabs ||
|
||||
nextProps.selected !== this.props.selected ||
|
||||
|
@ -38,7 +67,7 @@ export default class TabsHeader extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
componentDidUpdate(prevProps: Props<P>) {
|
||||
const { collapsible } = this.props;
|
||||
if (!collapsible) {
|
||||
if (prevProps.collapsible !== collapsible) this.disableResizeEvents();
|
||||
|
|
|
@ -1,4 +1,24 @@
|
|||
export default (colors) => ({
|
||||
import { Base16Theme } from 'base16';
|
||||
import * as CSS from 'csstype';
|
||||
import * as themes from './index';
|
||||
|
||||
export interface Theme extends Base16Theme {
|
||||
fontFamily: CSS.Property.FontFamily;
|
||||
codeFontFamily: CSS.Property.FontFamily;
|
||||
inputHeight: number;
|
||||
inputBorderWidth: number;
|
||||
inputBorderRadius: number;
|
||||
spinnerSize: number;
|
||||
inputPadding: number;
|
||||
selectArrowWidth: number;
|
||||
inputInternalHeight: number;
|
||||
inputBorderColor: string;
|
||||
inputFocusedStyle: string;
|
||||
type?: keyof typeof themes;
|
||||
light?: boolean;
|
||||
}
|
||||
|
||||
export default (colors: Base16Theme) => ({
|
||||
...colors,
|
||||
fontFamily: "'Source Sans Pro', sans-serif",
|
||||
codeFontFamily: "'Source Code Pro', monospace",
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export default (colors) => ({
|
||||
import { Base16Theme } from 'base16';
|
||||
|
||||
export default (colors: Base16Theme) => ({
|
||||
fontFamily: "'Roboto', sans-serif",
|
||||
codeFontFamily: "'Roboto Mono', monospace",
|
||||
inputPadding: 5,
|
||||
|
|
|
@ -7,7 +7,10 @@ import Color from 'color';
|
|||
effect('#000000', 'alpha', 0.5);
|
||||
*/
|
||||
|
||||
export default (color, effect, val) =>
|
||||
new Color(color)[effect](val).hsl().string();
|
||||
export default (
|
||||
color: string,
|
||||
effect: 'fade' | 'lighten' | 'alpha',
|
||||
val: number
|
||||
) => (new Color(color)[effect](val) as Color).hsl().string();
|
||||
|
||||
// TODO: memoize it
|
||||
|
|
|
@ -1,13 +1,68 @@
|
|||
import styled from 'styled-components';
|
||||
import getDefaultTheme from '../themes/default';
|
||||
import React from 'react';
|
||||
import styled, {
|
||||
InterpolationFunction,
|
||||
StyledComponent,
|
||||
StyledComponentPropsWithRef,
|
||||
ThemedStyledInterface,
|
||||
ThemedStyledProps,
|
||||
} from 'styled-components';
|
||||
import getDefaultTheme, { Theme } from '../themes/default';
|
||||
import { Base16Theme } from 'base16';
|
||||
import { ThemeFromProvider } from './theme';
|
||||
|
||||
const getStyle = (styles, type) =>
|
||||
typeof styles === 'object' ? styles[type] || styles.default : styles;
|
||||
type StyleFunction<
|
||||
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
O extends object = {}
|
||||
> = InterpolationFunction<
|
||||
ThemedStyledProps<StyledComponentPropsWithRef<C> & O, Theme>
|
||||
>;
|
||||
|
||||
export default (styles, component) =>
|
||||
styled(component || 'div')`
|
||||
${(props) =>
|
||||
props.theme.type
|
||||
interface StylesObject<
|
||||
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
O extends object = {}
|
||||
> {
|
||||
[type: string]: StyleFunction<C, O>;
|
||||
}
|
||||
|
||||
type Styles<
|
||||
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
O extends object = {}
|
||||
> = StylesObject<C, O> | StyleFunction<C, O>;
|
||||
|
||||
function isStylesObject<
|
||||
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
O extends object = {}
|
||||
>(styles: Styles<C>): styles is StylesObject<C, O> {
|
||||
return typeof styles === 'object';
|
||||
}
|
||||
|
||||
const getStyle = <
|
||||
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
O extends object = {}
|
||||
>(
|
||||
styles: Styles<C, O>,
|
||||
type: string
|
||||
) => (isStylesObject(styles) ? styles[type] || styles.default : styles);
|
||||
|
||||
function isThemeFromProvider(
|
||||
theme: Theme | Base16Theme
|
||||
): theme is ThemeFromProvider {
|
||||
return (theme as ThemeFromProvider).type !== undefined;
|
||||
}
|
||||
|
||||
export default function createStyledComponent<
|
||||
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
O extends object = {}
|
||||
>(styles: Styles<C, O>, component?: C): StyledComponent<C, Theme, O> {
|
||||
return (styled as ThemedStyledInterface<Theme>)((component || 'div') as C)`
|
||||
${(props: ThemedStyledProps<StyledComponentPropsWithRef<C> & O, Theme>) =>
|
||||
isThemeFromProvider(props.theme)
|
||||
? getStyle(styles, props.theme.type)
|
||||
: // used outside of container (theme provider)
|
||||
getStyle(
|
||||
|
@ -18,5 +73,6 @@ export default (styles, component) =>
|
|||
theme: getDefaultTheme(props.theme),
|
||||
})}
|
||||
`;
|
||||
}
|
||||
|
||||
// TODO: memoize it?
|
||||
|
|
|
@ -1,14 +1,30 @@
|
|||
import * as themes from '../themes';
|
||||
import defaultDarkScheme from 'redux-devtools-themes/lib/nicinabox';
|
||||
import { nicinabox as defaultDarkScheme } from 'redux-devtools-themes';
|
||||
import * as baseSchemes from 'base16';
|
||||
import * as additionalSchemes from '../colorSchemes';
|
||||
import invertColors from '../utils/invertColors';
|
||||
import { Theme } from '../themes/default';
|
||||
|
||||
export const schemes = { ...baseSchemes, ...additionalSchemes };
|
||||
export const listSchemes = () => Object.keys(schemes).slice(1).sort(); // remove `__esModule`
|
||||
export const listThemes = () => Object.keys(themes);
|
||||
|
||||
export const getTheme = ({ theme: type, scheme, light }) => {
|
||||
export interface ThemeData {
|
||||
theme: keyof typeof themes;
|
||||
scheme: keyof typeof schemes;
|
||||
light: boolean;
|
||||
}
|
||||
|
||||
export interface ThemeFromProvider extends Theme {
|
||||
type: keyof typeof themes;
|
||||
light: boolean;
|
||||
}
|
||||
|
||||
export const getTheme = ({
|
||||
theme: type,
|
||||
scheme,
|
||||
light,
|
||||
}: ThemeData): ThemeFromProvider => {
|
||||
let colors;
|
||||
if (scheme === 'default') {
|
||||
colors = light ? schemes.default : defaultDarkScheme;
|
||||
|
|
45
yarn.lock
45
yarn.lock
|
@ -3330,6 +3330,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999"
|
||||
integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ==
|
||||
|
||||
"@types/codemirror@^0.0.97":
|
||||
version "0.0.97"
|
||||
resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-0.0.97.tgz#6f2d8266b7f1b34aacfe8c77221fafe324c3d081"
|
||||
integrity sha512-n5d7o9nWhC49DjfhsxANP7naWSeTzrjXASkUDQh7626sM4zK9XP2EVcHp1IcCf/IPV6c7ORzDUDF3Bkt231VKg==
|
||||
dependencies:
|
||||
"@types/tern" "*"
|
||||
|
||||
"@types/color-convert@*":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-1.9.0.tgz#bfa8203e41e7c65471e9841d7e306a7cd8b5172d"
|
||||
|
@ -3379,6 +3386,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
||||
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
|
||||
|
||||
"@types/estree@*":
|
||||
version "0.0.45"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884"
|
||||
integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==
|
||||
|
||||
"@types/express-serve-static-core@*":
|
||||
version "4.17.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.9.tgz#2d7b34dcfd25ec663c25c85d76608f8b249667f1"
|
||||
|
@ -3514,6 +3526,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/jsan/-/jsan-3.1.0.tgz#128fdb14a102134ede764b11682e795d1b380c43"
|
||||
integrity sha512-V5wfm0++TqM92D0ZkAhl9MDQHPTi88fXhMNVin5LV/Y3RnuU/FUv6wML4Vt/amZmPN9WaFTmDhKW+h58kAFmIg==
|
||||
|
||||
"@types/json-schema@*":
|
||||
version "7.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
|
||||
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
|
||||
|
||||
"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5":
|
||||
version "7.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
|
||||
|
@ -3675,7 +3692,7 @@
|
|||
"@types/react" "*"
|
||||
"@types/reactcss" "*"
|
||||
|
||||
"@types/react-dom@^16.9.8":
|
||||
"@types/react-dom@*", "@types/react-dom@^16.9.8":
|
||||
version "16.9.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.8.tgz#fe4c1e11dfc67155733dfa6aa65108b4971cb423"
|
||||
integrity sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==
|
||||
|
@ -3689,6 +3706,14 @@
|
|||
dependencies:
|
||||
"@types/dragula" "*"
|
||||
|
||||
"@types/react-jsonschema-form@^1.7.4":
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-jsonschema-form/-/react-jsonschema-form-1.7.4.tgz#b9dded80f830bce11a623107633b13964a143cca"
|
||||
integrity sha512-TSsntIuB8bfheC/ZpjUmgB6+m5cLR4Gbh8rnqpSYB6T4e2TwzNICuKC5AykZI0XTxqLJmShyVsJxuo4aih64Gw==
|
||||
dependencies:
|
||||
"@types/json-schema" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-native@*":
|
||||
version "0.63.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.8.tgz#73ec087122c64c309eeaf150b565b8d755f0fb1f"
|
||||
|
@ -3714,6 +3739,15 @@
|
|||
"@types/history" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-select@^3.0.19":
|
||||
version "3.0.19"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-3.0.19.tgz#f73b04b8113451b0597df8a8315f9bf8ce03eb44"
|
||||
integrity sha512-d+6qtfFXZeIOAABlVL1e50RZn8ctOABE4tFDxM6KW4lKuXgTTgLVrSik5AX9XjBjV7N80FtS6GTN/WeoXL9Jww==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
"@types/react-dom" "*"
|
||||
"@types/react-transition-group" "*"
|
||||
|
||||
"@types/react-syntax-highlighter@11.0.4":
|
||||
version "11.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz#d86d17697db62f98046874f62fdb3e53a0bbc4cd"
|
||||
|
@ -3728,7 +3762,7 @@
|
|||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-transition-group@^4.4.0":
|
||||
"@types/react-transition-group@*", "@types/react-transition-group@^4.4.0":
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d"
|
||||
integrity sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==
|
||||
|
@ -3797,6 +3831,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74"
|
||||
integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==
|
||||
|
||||
"@types/tern@*":
|
||||
version "0.23.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/tern/-/tern-0.23.3.tgz#4b54538f04a88c9ff79de1f6f94f575a7f339460"
|
||||
integrity sha512-imDtS4TAoTcXk0g7u4kkWqedB3E4qpjXzCpD2LU5M5NAXHzCDsypyvXSaG7mM8DKYkCRa7tFp4tS/lp/Wo7Q3w==
|
||||
dependencies:
|
||||
"@types/estree" "*"
|
||||
|
||||
"@types/uglify-js@*":
|
||||
version "3.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.9.3.tgz#d94ed608e295bc5424c9600e6b8565407b6b4b6b"
|
||||
|
|
Loading…
Reference in New Issue
Block a user