diff --git a/.prettierrc b/.prettierrc index 2795c672a..dc5c1e3c8 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,7 +3,7 @@ "printWidth": 80, "tabWidth": 2, "useTabs": false, - "semi": false, + "semi": true, "singleQuote": true, "trailingComma": "all", "bracketSpacing": true, diff --git a/core/editors/.babelrc b/core/editors/.babelrc new file mode 100644 index 000000000..ca7af650c --- /dev/null +++ b/core/editors/.babelrc @@ -0,0 +1,14 @@ +{ + "plugins": ["lodash"], + "presets": [ + "@babel/preset-typescript", + [ + "@babel/preset-env", + { + "targets": { + "node": "current" + } + } + ] + ] +} \ No newline at end of file diff --git a/core/editors/.eslintignore b/core/editors/.eslintignore new file mode 100644 index 000000000..53c37a166 --- /dev/null +++ b/core/editors/.eslintignore @@ -0,0 +1 @@ +dist \ No newline at end of file diff --git a/core/editors/.eslintrc.js b/core/editors/.eslintrc.js new file mode 100644 index 000000000..0e39085f9 --- /dev/null +++ b/core/editors/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: 'docz-ts', +} \ No newline at end of file diff --git a/core/editors/LICENSE.md b/core/editors/LICENSE.md new file mode 100644 index 000000000..a64cf9401 --- /dev/null +++ b/core/editors/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Atanas Stoyanov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/core/editors/README.md b/core/editors/README.md new file mode 100644 index 000000000..85dddb820 --- /dev/null +++ b/core/editors/README.md @@ -0,0 +1 @@ +# Componnet Control Editors diff --git a/core/editors/package.json b/core/editors/package.json new file mode 100644 index 000000000..91ff4e37c --- /dev/null +++ b/core/editors/package.json @@ -0,0 +1,68 @@ +{ + "name": "@component-controls/editors", + "version": "0.1.2", + "description": "Component controls specification and utility routines", + "main": "dist/index.js", + "module": "dist/index.esm.js", + "typings": "dist/index.d.ts", + "files": [ + "dist/", + "package.json", + "README.md" + ], + "scripts": { + "build": "yarn cross-env NODE_ENV=production rollup -c", + "dev": "yarn cross-env NODE_ENV=development yarn build -w", + "fix": "yarn lint --fix", + "lint": "yarn eslint . --ext mdx,ts,tsx", + "precommit": "lint-staged", + "prepare": "yarn build", + "test": "yarn jest" + }, + "homepage": "https://github.com/atanasster/component-controls", + "bugs": { + "url": "https://github.com/atanasster/component-controls/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/atanasster/component-controls.git", + "directory": "core/specification" + }, + "license": "MIT", + "dependencies": { + "@component-controls/specification": "0.1.2", + "@storybook/components": "6.0.0-alpha.6", + "@storybook/theming": "6.0.0-alpha.6", + "copy-to-clipboard": "^3.2.1", + "global": "^4.3.2", + "polished": "^3.4.4", + "qs": "^6.9.1", + "react": "^16.8.3", + "react-color": "^2.17.0", + "react-dom": "^16.8.3", + "react-select": "^3.0.8", + "react-textarea-autosize": "^7.1.0" + }, + "devDependencies": { + "@types/qs": "^6.9.1", + "@types/react-color": "^3.0.1", + "@types/react-select": "^3.0.10", + "@types/react-textarea-autosize": "^4.3.3", + "@types/jest": "^25.1.2", + "cross-env": "^5.2.1", + "docz-rollup": "^2.1.0", + "eslint": "^6.5.1", + "eslint-config-docz-ts": "^2.1.0", + "jest": "^24.9.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + }, + "publishConfig": { + "access": "public" + }, + "authors": [ + "Atanas Stoyanov" + ] +} diff --git a/core/editors/rollup.config.js b/core/editors/rollup.config.js new file mode 100644 index 000000000..381f83b7f --- /dev/null +++ b/core/editors/rollup.config.js @@ -0,0 +1,5 @@ +import { config } from 'docz-rollup' + +export default config({ + input: './src/index.ts', +}) \ No newline at end of file diff --git a/core/editors/src/ArrayEditor/ArrayEditor.stories.tsx b/core/editors/src/ArrayEditor/ArrayEditor.stories.tsx new file mode 100644 index 000000000..3dd57d3ca --- /dev/null +++ b/core/editors/src/ArrayEditor/ArrayEditor.stories.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { ControlTypes } from '@component-controls/specification'; +import { ArrayEditor } from './ArrayEditor'; + +export default { + title: 'Basics/PropEditors/ArrayEditor', + component: ArrayEditor, +}; + +export const sample = () => { + const [state, setState] = React.useState(['Laptop', 'Book', 'Whiskey']); + return ( + <> + setState(newVal)} + prop={{ type: ControlTypes.ARRAY, value: state }} + /> + + + ); +}; diff --git a/core/editors/src/ArrayEditor/ArrayEditor.tsx b/core/editors/src/ArrayEditor/ArrayEditor.tsx new file mode 100644 index 000000000..e851028a7 --- /dev/null +++ b/core/editors/src/ArrayEditor/ArrayEditor.tsx @@ -0,0 +1,46 @@ +import React, { ChangeEvent } from 'react'; +import { ComponentControlArray } from '@component-controls/specification'; +import { Form } from '@storybook/components'; +import { PropertyControlProps, PropertyEditor } from '../types'; + +interface ArrayEditorProps extends PropertyControlProps { + prop: ComponentControlArray; +} + +const formatArray = (value: string, separator: string) => { + if (value === '') { + return []; + } + return value.split(separator); +}; + +const deserialize = (value: string[]) => { + if (Array.isArray(value)) return value; + return Object.keys(value) + .sort() + .reduce((array, key) => [...array, value[key]], []); +}; + +export const ArrayEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => { + const handleChange = (e: ChangeEvent): void => { + const { value } = e.target as HTMLTextAreaElement; + const newVal = formatArray(value, prop.separator || ','); + onChange(name, newVal); + }; + + const value = prop.value && deserialize(prop.value).join(prop.separator); + + return ( + + ); +}; diff --git a/core/editors/src/ArrayEditor/index.ts b/core/editors/src/ArrayEditor/index.ts new file mode 100644 index 000000000..59b802d97 --- /dev/null +++ b/core/editors/src/ArrayEditor/index.ts @@ -0,0 +1 @@ +export { ArrayEditor } from './ArrayEditor'; diff --git a/core/editors/src/BooleanEditor/BooleanEditor.stories.tsx b/core/editors/src/BooleanEditor/BooleanEditor.stories.tsx new file mode 100644 index 000000000..efef9abdd --- /dev/null +++ b/core/editors/src/BooleanEditor/BooleanEditor.stories.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { ControlTypes } from '@component-controls/specification'; +import { BooleanEditor } from './BooleanEditor'; + +export default { + title: 'Basics/PropEditors/BooleanEditor', + component: BooleanEditor, +}; + +export const sample = () => { + const [state, setState] = React.useState(false); + return ( + setState(newVal)} + prop={{ type: ControlTypes.BOOLEAN, value: state }} + /> + ); +}; diff --git a/core/editors/src/BooleanEditor/BooleanEditor.tsx b/core/editors/src/BooleanEditor/BooleanEditor.tsx new file mode 100644 index 000000000..488766b0a --- /dev/null +++ b/core/editors/src/BooleanEditor/BooleanEditor.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { ComponentControlBoolean } from '@component-controls/specification'; +import { Toggle } from './Toggle'; +import { FlexContainer } from '../FlexContainer'; +import { PropertyControlProps, PropertyEditor } from '../types'; + +interface BooleanEditorProps extends PropertyControlProps { + prop: ComponentControlBoolean; +} + +export const BooleanEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => ( + + onChange(name, checked)} + checked={prop.value} + /> + +); diff --git a/core/editors/src/BooleanEditor/Toggle.stories.tsx b/core/editors/src/BooleanEditor/Toggle.stories.tsx new file mode 100644 index 000000000..5bfc938b6 --- /dev/null +++ b/core/editors/src/BooleanEditor/Toggle.stories.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Icons } from '@storybook/components'; +import { Toggle } from './Toggle'; + +export default { + title: 'Basics/Toggle', +}; + +export const allToggles = () => { + const [checked, setChecked] = React.useState(false); + return ( +
+

Default toggle

+ setChecked(check)} /> +
+

Toggle on a Form

+
+

Custom labels

+ setChecked(check)} + /> +
+

Custom icon labels

+ , + false: , + }} + onChange={check => setChecked(check)} + /> +
+
+ ); +}; diff --git a/core/editors/src/BooleanEditor/Toggle.tsx b/core/editors/src/BooleanEditor/Toggle.tsx new file mode 100644 index 000000000..cb7ac6280 --- /dev/null +++ b/core/editors/src/BooleanEditor/Toggle.tsx @@ -0,0 +1,83 @@ +import React, { forwardRef, HTMLProps } from 'react'; +import { styled } from '@storybook/theming'; +import { transparentize, darken } from 'polished'; + +import { Button } from '@storybook/components'; + +interface ToggleButtonProps { + active: boolean; + left: boolean; + onClick: (e: any) => void; +} +const ToggleButton = styled(Button)( + ({ theme, active, left }) => { + const activeColor = darken(0.1, theme.color.light); + return { + '&&': { + borderRadius: left ? '14px 0 0 14px' : '0 14px 14px 0', + margin: 0, + border: 'none', + borderColor: activeColor, + color: active + ? theme.color.defaultText + : transparentize( + theme.base === 'light' ? 0.4 : 0.6, + theme.color.defaultText, + ), + background: active ? activeColor : 'unset', + }, + }; + }, +); + +export interface ToggleOwnProps { + /** whether checked */ + checked?: boolean; + /** onChange event - when one of the toggles in clicked */ + onChange?: (checked: boolean) => void; + + /** custom labels - by defaut 'True' and 'False' */ + labels?: { + true: React.ReactNode; + false: React.ReactNode; + }; +} + +export type ToggleProps = Omit< + HTMLProps, + keyof ToggleOwnProps +> & + ToggleOwnProps; +export const Toggle = forwardRef( + ( + { + checked = false, + onChange, + labels = { + true: 'True', + false: 'False', + }, + ...rest + }: ToggleProps, + ref, + ) => ( +
+ onChange && onChange(true)} + > + {labels.true} + + onChange && onChange(false)} + > + {labels.false} + +
+ ), +); + +Toggle.displayName = 'Toggle'; diff --git a/core/editors/src/BooleanEditor/index.ts b/core/editors/src/BooleanEditor/index.ts new file mode 100644 index 000000000..cce5f1446 --- /dev/null +++ b/core/editors/src/BooleanEditor/index.ts @@ -0,0 +1 @@ +export { BooleanEditor } from './BooleanEditor'; diff --git a/core/editors/src/ButtonEditor/ButtonEditor.stories.tsx b/core/editors/src/ButtonEditor/ButtonEditor.stories.tsx new file mode 100644 index 000000000..bf1eed69a --- /dev/null +++ b/core/editors/src/ButtonEditor/ButtonEditor.stories.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { ControlTypes } from '@component-controls/specification'; +import { ButtonEditor } from './ButtonEditor'; + +export default { + title: 'Basics/PropEditors/ButtonEditor', + component: ButtonEditor, +}; + +export const sample = () => ( + console.log('clicked')} + onChange={() => {}} + prop={{ type: ControlTypes.BUTTON }} + /> +); diff --git a/core/editors/src/ButtonEditor/ButtonEditor.tsx b/core/editors/src/ButtonEditor/ButtonEditor.tsx new file mode 100644 index 000000000..43da4d831 --- /dev/null +++ b/core/editors/src/ButtonEditor/ButtonEditor.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { styled } from '@storybook/theming'; +import { ComponentControlButton } from '@component-controls/specification'; +import { Form } from '@storybook/components'; +import { + PropertyControlProps, + PropertyEditor, + PropertyOnClick, +} from '../types'; + +const FlexButton = styled(Form.Button)({ + flex: '1 1', +}); + +interface ButtonEditorProps extends PropertyControlProps { + prop: ComponentControlButton; + onClick: PropertyOnClick; +} + +export const ButtonEditor: PropertyEditor = ({ + prop, + name, + onClick, +}) => ( + onClick(prop)}> + {name} + +); diff --git a/core/editors/src/ButtonEditor/index.ts b/core/editors/src/ButtonEditor/index.ts new file mode 100644 index 000000000..4937cabad --- /dev/null +++ b/core/editors/src/ButtonEditor/index.ts @@ -0,0 +1 @@ +export { ButtonEditor } from './ButtonEditor'; diff --git a/core/editors/src/ColorEditor/ColorEditor.stories.tsx b/core/editors/src/ColorEditor/ColorEditor.stories.tsx new file mode 100644 index 000000000..2f00b78e3 --- /dev/null +++ b/core/editors/src/ColorEditor/ColorEditor.stories.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { ControlTypes } from '@component-controls/specification'; +import { ColorEditor } from './ColorEditor'; + +export default { + title: 'Basics/PropEditors/ColorEditor', + component: ColorEditor, +}; + +export const sample = () => { + const [state, setState] = React.useState('#dedede'); + return ( + setState(newVal)} + prop={{ type: ControlTypes.COLOR, value: state }} + /> + ); +}; + +export const rgb = () => { + const [state, setState] = React.useState('rgb(192,0,0)'); + return ( + setState(newVal)} + prop={{ type: ControlTypes.COLOR, value: state }} + /> + ); +}; diff --git a/core/editors/src/ColorEditor/ColorEditor.tsx b/core/editors/src/ColorEditor/ColorEditor.tsx new file mode 100644 index 000000000..4cb372f6f --- /dev/null +++ b/core/editors/src/ColorEditor/ColorEditor.tsx @@ -0,0 +1,91 @@ +import React from 'react'; +import { SketchPicker, ColorResult } from 'react-color'; +import { ComponentControlColor } from '@component-controls/specification'; + +import { styled } from '@storybook/theming'; +import { Form } from '@storybook/components'; + +import { PropertyControlProps, PropertyEditor } from '../types'; + +interface ColorButtonProps { + name: string; + type: string; + size: string; + width: string; + onClick: () => any; +} + +const { Button } = Form; + +const Swatch = styled.div<{ color: string | undefined }>( + ({ theme, color }) => ({ + position: 'absolute', + top: '50%', + transform: 'translateY(-50%)', + left: 6, + width: 16, + height: 16, + backgroundColor: color, + boxShadow: `${theme.appBorderColor} 0 0 0 1px inset`, + borderRadius: '1rem', + }), +); + +const ColorButton = styled(Button)(() => ({ + zIndex: 'unset', + paddingLeft: '40px', + minHeight: '36px', + display: 'flex', + flexBasis: '100%', +})); + +const Popover = styled.div({ + position: 'absolute', + zIndex: 3, +}); + +const Cover = styled.div({ + position: 'fixed', + top: '0px', + right: '0px', + bottom: '0px', + left: '0px', +}); + +interface ColorEditorProps extends PropertyControlProps { + prop: ComponentControlColor; +} + +export const ColorEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => { + const [displayColorPicker, setDisplayColorPicker] = React.useState(false); + + const handleChange = (color: ColorResult) => { + onChange( + name, + `rgba(${color.rgb.r},${color.rgb.g},${color.rgb.b},${color.rgb.a})`, + ); + }; + + return ( + setDisplayColorPicker(!displayColorPicker)} + size="flex" + > + {prop.value && prop.value.toUpperCase()} + + {displayColorPicker ? ( + + setDisplayColorPicker(false)} /> + + + ) : null} + + ); +}; diff --git a/core/editors/src/ColorEditor/index.ts b/core/editors/src/ColorEditor/index.ts new file mode 100644 index 000000000..36cdd2ba0 --- /dev/null +++ b/core/editors/src/ColorEditor/index.ts @@ -0,0 +1 @@ +export { ColorEditor } from './ColorEditor'; diff --git a/core/editors/src/ControlEditorsTable.stories.tsx b/core/editors/src/ControlEditorsTable.stories.tsx new file mode 100644 index 000000000..8cd5809cb --- /dev/null +++ b/core/editors/src/ControlEditorsTable.stories.tsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { + ControlTypes, + LoadedComponentControls, +} from '@component-controls/specification'; +import { ControlsEditorsTable } from './ControlEditorsTable'; + +export default { + title: 'Docs/PropEditors/ControlsEditorsTable', + component: ControlsEditorsTable, +}; + +export const pureControlsEditorsTable = () => { + const [controls, setControls] = React.useState({ + name: { + type: ControlTypes.TEXT, + label: 'Name', + value: 'Mark', + defaultValue: 'Mark', + }, + age: { + type: ControlTypes.NUMBER, + label: 'Age', + value: 19, + defaultValue: 19, + }, + clickMe: { + type: ControlTypes.BUTTON, + label: '+1', + onClick: () => {}, + }, + }); + + return ( + <> +

{`Hello, my name is ${controls.name.value}, and I am ${controls.age.value} years old.`}

+ + setControls({ + ...controls, + [name]: { ...controls[name], value }, + }) + } + clickControl={() => + setControls({ + ...controls, + age: { + ...controls.age, + value: parseInt(controls.age.value, 10) + 1, + }, + }) + } + /> + + ); +}; diff --git a/core/editors/src/ControlEditorsTable.tsx b/core/editors/src/ControlEditorsTable.tsx new file mode 100644 index 000000000..2b747f80e --- /dev/null +++ b/core/editors/src/ControlEditorsTable.tsx @@ -0,0 +1,210 @@ +import React, { MouseEvent } from 'react'; +import { window, document } from 'global'; +import { transparentize } from 'polished'; +import { styled, Theme } from '@storybook/theming'; +import qs from 'qs'; +import copy from 'copy-to-clipboard'; + +import { + LoadedComponentControls, + LoadedComponentControl, + getControlValues, +} from '@component-controls/specification'; +import { Table, TabsState, ActionBar } from '@storybook/components'; +import { ControlsEditorsTableProps } from './types'; + +import { PropertyEditorRow } from './PropEditorRow'; + +export const getSectionTitleStyle: (theme: Theme) => object = ( + theme: Theme, +) => ({ + letterSpacing: '0.35em', + textTransform: 'uppercase', + fontWeight: theme.typography.weight.black, + fontSize: theme.typography.size.s1 - 1, + lineHeight: '24px', + color: + theme.base === 'light' + ? transparentize(0.4, theme.color.defaultText) + : transparentize(0.6, theme.color.defaultText), + background: `${theme.background.app} !important`, +}); + +export const getBlockBackgroundStyle: (theme: Theme) => object = ( + theme: Theme, +) => ({ + borderRadius: theme.appBorderRadius, + background: theme.background.content, + boxShadow: + theme.base === 'light' + ? 'rgba(0, 0, 0, 0.10) 0 1px 3px 0' + : 'rgba(0, 0, 0, 0.20) 0 2px 5px 0', + border: `1px solid ${theme.appBorderColor}`, +}); + +const StyleTable = styled(Table)<{}>(() => ({ + '&&': { + margin: 0, + tbody: { + boxShadow: 'none', + }, + 'th:last-of-type, td:last-of-type': { + width: '70%', + }, + }, +})); + +const StyledActionBar = styled(ActionBar)<{}>(() => ({ + zIndex: 0, +})); + +const PropEditorsContainer = styled.div<{}>(({ theme }) => ({ + position: 'relative', + paddingBottom: '25px', + ...getBlockBackgroundStyle(theme), +})); + +const PropEditorsTitle = styled.div<{}>(({ theme }) => ({ + ...getSectionTitleStyle(theme), + padding: '16px', +})); + +const DEFAULT_GROUP_ID = 'Other'; + +export const BlockWrapper: React.FC = ({ children }) => ( + + {' '} + {children} + +); + +const PropGroupTable: React.FC = ({ + controls, + storyId, + setControlValue, + clickControl, +}) => ( + + + {controls && + Object.keys(controls) + .map((key, index) => ({ + name: key, + property: { + ...controls[key], + order: + controls[key].order === undefined ? index : controls[key].order, + }, + })) + .sort((a, b) => { + const aOrder = a.property.order || 0; + const bOrder = b.property.order || 0; + return aOrder - bOrder; + }) + .map(p => ( + + ))} + + +); + +interface GroupedControlsType { + [key: string]: LoadedComponentControls; +} + +export const ControlsEditorsTable: React.FC = props => { + const [copied, setCopied] = React.useState(false); + const { + controls, + title, + storyId, + resetControlValue, + extraActions = [], + } = props; + if (controls && Object.keys(controls).length) { + const onReset = (e: MouseEvent) => { + e.preventDefault(); + if (resetControlValue && storyId) { + resetControlValue(storyId); + } + }; + const onCopy = (e: MouseEvent) => { + e.preventDefault(); + setCopied(true); + const { location } = document; + const query = qs.parse(location.search, { ignoreQueryPrefix: true }); + const values = getControlValues(controls); + Object.keys(values).forEach(key => { + query[`controls-${key}`] = values[key]; + }); + + copy( + `${location.origin + location.pathname}?${qs.stringify(query, { + encode: false, + })}`, + ); + window.setTimeout(() => setCopied(false), 1500); + }; + const groupped: GroupedControlsType = Object.keys(controls) + .filter(k => { + const p: LoadedComponentControl = controls[k]; + return !p.hidden; + }) + .reduce((acc: GroupedControlsType, k: string) => { + const groupId = controls[k].groupId || DEFAULT_GROUP_ID; + return { ...acc, [groupId]: { ...acc[groupId], [k]: controls[k] } }; + }, {}); + return ( + + {title && {title}} + {Object.keys(groupped).length < 2 ? ( + + ) : ( + + {Object.keys(groupped) + .sort() + .map(key => { + const group: LoadedComponentControls = groupped[key]; + const tabId = `prop_editors_div_${props.storyId}_${key}`; + return ( +
+ {({ active }: { active: boolean }) => + active ? ( + + ) : null + } +
+ ); + })} +
+ )} + ({ + title: item.title, + onClick: (e: MouseEvent) => { + e.preventDefault(); + item.onAction(props); + }, + })), + { title: 'Reset', onClick: onReset }, + { title: copied ? 'Copied' : 'Copy', onClick: onCopy }, + ]} + /> +
+ ); + } + return null; +}; diff --git a/core/editors/src/DateEditor/DateEditor.stories.tsx b/core/editors/src/DateEditor/DateEditor.stories.tsx new file mode 100644 index 000000000..ec490ca6e --- /dev/null +++ b/core/editors/src/DateEditor/DateEditor.stories.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { ControlTypes } from '@component-controls/specification'; +import { DateEditor } from './DateEditor'; + +export default { + title: 'Basics/PropEditors/DateEditor', + component: DateEditor, +}; + +export const sample = () => { + const [state, setState] = React.useState(new Date()); + return ( + setState(newVal)} + prop={{ type: ControlTypes.DATE, value: state }} + /> + ); +}; + +export const onlyDatePicker = () => { + const [state, setState] = React.useState(new Date()); + return ( + setState(newVal)} + prop={{ type: ControlTypes.DATE, value: state, timePicker: false }} + /> + ); +}; + +export const onlyTimePicker = () => { + const [state, setState] = React.useState(new Date()); + return ( + setState(newVal)} + prop={{ type: ControlTypes.DATE, value: state, datePicker: false }} + /> + ); +}; diff --git a/core/editors/src/DateEditor/DateEditor.tsx b/core/editors/src/DateEditor/DateEditor.tsx new file mode 100644 index 000000000..0191f0002 --- /dev/null +++ b/core/editors/src/DateEditor/DateEditor.tsx @@ -0,0 +1,127 @@ +import React, { ChangeEvent } from 'react'; +import { styled } from '@storybook/theming'; +import { ComponentControlDate } from '@component-controls/specification'; +import { Form } from '@storybook/components'; +import { PropertyControlProps, PropertyEditor } from '../types'; + +const FlexSpaced = styled.div({ + flex: 1, + display: 'flex', + '&& > *': { + marginLeft: 10, + }, + '&& > *:first-of-type': { + marginLeft: 0, + }, +}); + +const FlexInput = styled(Form.Input)({ flex: 1 }); + +const formatDate = (date: Date | undefined) => { + if (date) { + const year = `000${date.getFullYear()}`.slice(-4); + const month = `0${date.getMonth() + 1}`.slice(-2); + const day = `0${date.getDate()}`.slice(-2); + + return `${year}-${month}-${day}`; + } + return ''; +}; + +const formatTime = (date: Date | undefined) => { + if (date) { + const hours = `0${date.getHours()}`.slice(-2); + const minutes = `0${date.getMinutes()}`.slice(-2); + + return `${hours}:${minutes}`; + } + return ''; +}; + +interface DateEditorProps extends PropertyControlProps { + prop: ComponentControlDate; +} + +export const DateEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => { + const [valid, setValid] = React.useState(true); + const dateInputRef = React.useRef(); + const timeInputRef = React.useRef(); + React.useEffect(() => { + if (valid !== false) { + if (dateInputRef && dateInputRef.current) { + dateInputRef.current.value = formatDate(prop.value); + } + if (timeInputRef && timeInputRef.current) { + timeInputRef.current.value = formatTime(prop.value); + } + } + }, [prop.value]); + + const onDateChange = (e: ChangeEvent) => { + let isValid = false; + const [year, month, day] = e.target.value.split('-'); + if (prop.value) { + const result = new Date(prop.value); + if (result.getTime()) { + result.setFullYear(parseInt(year, 10)); + result.setMonth(parseInt(month, 10) - 1); + result.setDate(parseInt(day, 10)); + if (result.getTime()) { + isValid = true; + onChange(name, result); + } + } + } + if (valid !== isValid) { + setValid(isValid); + } + }; + + const onTimeChange = (e: ChangeEvent) => { + let isValid = false; + const [hours, minutes] = e.target.value.split(':'); + if (prop.value) { + const result = new Date(prop.value); + if (result.getTime()) { + result.setHours(parseInt(hours, 10)); + result.setMinutes(parseInt(minutes, 10)); + if (result.getTime()) { + onChange(name, result); + isValid = true; + } + } + } + if (valid !== isValid) { + setValid(isValid); + } + }; + const { datePicker = true, timePicker = true } = prop; + return name ? ( + + {datePicker && ( + + )} + {timePicker && ( + + )} + {!valid ?
invalid
: null} +
+ ) : null; +}; diff --git a/core/editors/src/DateEditor/index.ts b/core/editors/src/DateEditor/index.ts new file mode 100644 index 000000000..a034e3f30 --- /dev/null +++ b/core/editors/src/DateEditor/index.ts @@ -0,0 +1 @@ +export { DateEditor } from './DateEditor'; diff --git a/core/editors/src/FilesEditor/FilesEditor.stories.tsx b/core/editors/src/FilesEditor/FilesEditor.stories.tsx new file mode 100644 index 000000000..a099c20c3 --- /dev/null +++ b/core/editors/src/FilesEditor/FilesEditor.stories.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { ControlTypes } from '@component-controls/specification'; +import { FilesEditor } from './FilesEditor'; + +export default { + title: 'Basics/PropEditors/FilesEditor', + component: FilesEditor, +}; + +export const sample = () => { + const [state, setState] = React.useState([ + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiARwMCyEWcOFPAAAAP0lEQVQoz8WQMQoAIAwDL/7/z3GwghSp4KDZyiUpBMCYUgd8rehtH16/l3XewgU2KAzapjXBbNFaPS6lDMlKB6OiDv3iAH1OAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTAxLTI4VDEyOjExOjMzLTA3OjAwlAHQBgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wMS0yOFQxMjoxMTozMy0wNzowMOVcaLoAAAAASUVORK5CYII=', + ]); + return ( + <> + setState(newVal)} + prop={{ + type: ControlTypes.FILES, + accept: 'image/*', + value: state, + }} + /> + files editor + + ); +}; diff --git a/core/editors/src/FilesEditor/FilesEditor.tsx b/core/editors/src/FilesEditor/FilesEditor.tsx new file mode 100644 index 000000000..082b14c83 --- /dev/null +++ b/core/editors/src/FilesEditor/FilesEditor.tsx @@ -0,0 +1,44 @@ +import { FileReader } from 'global'; +import React, { ChangeEvent } from 'react'; +import { styled } from '@storybook/theming'; +import { ComponentControlFiles } from '@component-controls/specification'; +import { Form } from '@storybook/components'; +import { PropertyControlProps, PropertyEditor } from '../types'; + +const FileInput = styled(Form.Input)({ + paddingTop: 4, +}); + +function fileReaderPromise(file: File) { + return new Promise(resolve => { + const fileReader = new FileReader(); + fileReader.onload = (e: Event) => + resolve((e.currentTarget as FileReader).result as string); + fileReader.readAsDataURL(file); + }); +} + +interface FilesEditorProps extends PropertyControlProps { + prop: ComponentControlFiles; +} + +export const FilesEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => ( + ) => { + if (e.target.files) { + Promise.all( + Array.from(e.target.files).map(fileReaderPromise), + ).then(files => onChange(name, files)); + } + }} + accept={prop.accept} + size="flex" + /> +); diff --git a/core/editors/src/FilesEditor/index.ts b/core/editors/src/FilesEditor/index.ts new file mode 100644 index 000000000..79a775e2e --- /dev/null +++ b/core/editors/src/FilesEditor/index.ts @@ -0,0 +1 @@ +export { FilesEditor } from './FilesEditor'; diff --git a/core/editors/src/FlexContainer.tsx b/core/editors/src/FlexContainer.tsx new file mode 100644 index 000000000..b650ace3c --- /dev/null +++ b/core/editors/src/FlexContainer.tsx @@ -0,0 +1,14 @@ +import { styled } from '@storybook/theming'; + +export interface FlexContainerProps { + align?: string; +} +export const FlexContainer = styled.div( + ({ align = 'center' }) => ({ + display: 'flex', + alignItems: align, + justifyContent: align, + flexDirection: 'column', + flexBasis: '100%', + }), +); diff --git a/core/editors/src/NumberEditor/NumberEditor.stories.tsx b/core/editors/src/NumberEditor/NumberEditor.stories.tsx new file mode 100644 index 000000000..8fd88c243 --- /dev/null +++ b/core/editors/src/NumberEditor/NumberEditor.stories.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { ControlTypes } from '@component-controls/specification'; +import { NumberEditor } from './NumberEditor'; + +export default { + title: 'Basics/PropEditors/NumberEditor', + component: NumberEditor, +}; + +export const simple = () => { + const [value, setValue] = React.useState(10); + return ( + setValue(newValue)} + prop={{ type: ControlTypes.NUMBER, value, min: 3, max: 22 }} + /> + ); +}; + +export const range = () => { + const [value, setValue] = React.useState(10); + return ( + setValue(newValue)} + prop={{ type: ControlTypes.NUMBER, value, min: 3, max: 22, range: true }} + /> + ); +}; + +export const step = () => { + const [value, setValue] = React.useState(10); + return ( + setValue(newValue)} + prop={{ type: ControlTypes.NUMBER, value, min: 3, max: 22, step: 0.5 }} + /> + ); +}; diff --git a/core/editors/src/NumberEditor/NumberEditor.tsx b/core/editors/src/NumberEditor/NumberEditor.tsx new file mode 100644 index 000000000..bc057bc79 --- /dev/null +++ b/core/editors/src/NumberEditor/NumberEditor.tsx @@ -0,0 +1,84 @@ +import React, { ChangeEvent } from 'react'; +import { styled } from '@storybook/theming'; +import { ComponentControlNumber } from '@component-controls/specification'; +import { Form } from '@storybook/components'; +import { PropertyControlProps, PropertyEditor } from '../types'; + +interface NumberEditorProps extends PropertyControlProps { + prop: ComponentControlNumber; +} + +const RangeInput = styled.input( + { + boxSizing: 'border-box', + height: 25, + outline: 'none', + border: '1px solid #f7f4f4', + borderRadius: 2, + fontSize: 11, + padding: 5, + color: '#444', + }, + { + display: 'table-cell', + flexGrow: 1, + }, +); + +const RangeLabel = styled.span({ + paddingLeft: 5, + paddingRight: 5, + fontSize: 12, + whiteSpace: 'nowrap', +}); + +const RangeWrapper = styled.div({ + display: 'flex', + alignItems: 'center', + width: '100%', +}); + +export const NumberEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => { + const handleChange = (event: ChangeEvent) => { + const { value } = event.target; + + let parsedValue: number | null = Number(value); + + if (Number.isNaN(parsedValue) || value === '') { + parsedValue = null; + } + + onChange(name, parsedValue); + }; + + return prop.range ? ( + + {prop.min} + + {`${prop.value} / ${prop.max}`} + + ) : ( + + ); +}; diff --git a/core/editors/src/NumberEditor/index.ts b/core/editors/src/NumberEditor/index.ts new file mode 100644 index 000000000..7a36f6497 --- /dev/null +++ b/core/editors/src/NumberEditor/index.ts @@ -0,0 +1 @@ +export { NumberEditor } from './NumberEditor'; diff --git a/core/editors/src/ObjectEditor/ObjectEditor.stories.tsx b/core/editors/src/ObjectEditor/ObjectEditor.stories.tsx new file mode 100644 index 000000000..bd598121d --- /dev/null +++ b/core/editors/src/ObjectEditor/ObjectEditor.stories.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { + ControlTypes, + ComponentControls, +} from '@component-controls/specification'; +import { ObjectEditor } from './ObjectEditor'; + +export default { + title: 'Basics/PropEditors/ObjectEditor', + component: ObjectEditor, +}; + +export const sample = () => { + const [state, setState] = React.useState({ + border: { type: ControlTypes.TEXT, value: '2px dashed silver' }, + borderRadius: { type: ControlTypes.NUMBER, value: 10 }, + padding: { type: ControlTypes.NUMBER, value: 10 }, + }); + + return ( + setState(newVal)} + prop={{ type: ControlTypes.OBJECT, value: state }} + /> + ); +}; diff --git a/core/editors/src/ObjectEditor/ObjectEditor.tsx b/core/editors/src/ObjectEditor/ObjectEditor.tsx new file mode 100644 index 000000000..42b1fc5d8 --- /dev/null +++ b/core/editors/src/ObjectEditor/ObjectEditor.tsx @@ -0,0 +1,106 @@ +import React from 'react'; +import { darken } from 'polished'; +import { styled } from '@storybook/theming'; +import { WithTooltipPure, Button, Icons } from '@storybook/components'; +import { + ComponentControl, + ComponentControlObject, + mergeControlValues, + getControlValues, +} from '@component-controls/specification'; +import { PropertyControlProps, PropertyEditor } from '../types'; +import { FlexContainer } from '../FlexContainer'; +import { getPropertyEditor } from '../prop-factory'; + +interface ObjectEditorProps extends PropertyControlProps { + prop: ComponentControlObject; +} + +const StyledButton = styled(Button)(({ theme }) => ({ + color: theme.color.defaultText, + backgroundColor: darken(0.1, theme.color.light), +})); + +const StyledIcon = styled(Icons)(() => ({ + marginLeft: '10px', +})); + +const ChildContainer = styled.div(() => ({ + minWidth: 200, + maxWidth: 800, + padding: 15, + boxSizing: 'content-box', +})); + +export const ObjectEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => { + const [isOpen, setIsOpen] = React.useState(false); + const handleChange = (childName: string, value: any) => { + onChange( + name, + getControlValues(mergeControlValues(prop.value as any, childName, value)), + ); + }; + let children; + if (typeof prop.value === 'object') { + children = Object.keys(prop.value) + .map(key => { + const childProp: ComponentControl = prop.value + ? (prop.value[key] as any) + : null; + if (!childProp) { + return null; + } + return { + name: key, + prop: childProp, + node: getPropertyEditor(childProp.type), + }; + }) + .filter(p => p && p.node); + } + return ( + { + setIsOpen(isVisible); + }} + tooltip={ + + + + {children && + children.map(child => + child ? ( + + + + + ) : null, + )} + +
{child.prop.label || child.name} + +
+
+ } + > + + + Edit object + + + +
+ ); +}; diff --git a/core/editors/src/ObjectEditor/index.ts b/core/editors/src/ObjectEditor/index.ts new file mode 100644 index 000000000..6c7192abd --- /dev/null +++ b/core/editors/src/ObjectEditor/index.ts @@ -0,0 +1 @@ +export { ObjectEditor } from './ObjectEditor'; diff --git a/core/editors/src/OptionsEditor/CheckboxEditor.tsx b/core/editors/src/OptionsEditor/CheckboxEditor.tsx new file mode 100644 index 000000000..bb4c1ff74 --- /dev/null +++ b/core/editors/src/OptionsEditor/CheckboxEditor.tsx @@ -0,0 +1,87 @@ +import React, { ChangeEvent } from 'react'; +import { styled } from '@storybook/theming'; +import { ComponentControlOptions } from '@component-controls/specification'; +import { normalizeOptions, NormalizedOption } from './utils'; +import { PropertyControlProps, PropertyEditor } from '../types'; + +interface CheckboxEditorProps extends PropertyControlProps { + prop: ComponentControlOptions; +} + +const CheckboxesWrapper = styled.div<{ isInline: boolean }>(({ isInline }) => + isInline + ? { + display: 'flex', + flexWrap: 'wrap', + alignItems: 'center', + '> * + *': { + marginLeft: 10, + }, + } + : {}, +); + +const CheckboxFieldset = styled.fieldset({ + border: 0, + padding: 0, + margin: 0, +}); + +const CheckboxLabel = styled.label({ + padding: '3px 0 3px 5px', + lineHeight: '18px', + display: 'inline-block', +}); + +export const CheckboxEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => { + const { options, value } = prop; + const { entries, selected } = normalizeOptions(options, value); + const handleChange = (e: ChangeEvent) => { + const currentValue = (e.target as HTMLInputElement).value; + const values = entries + .filter(entry => { + const entryValue = + typeof entry.value.toString === 'function' + ? entry.value.toString() + : entry.value; + return selected.includes(entry.value) + ? currentValue !== entryValue + : currentValue === entryValue; + }) + .map(entry => entry.value); + onChange(name, values); + }; + + const renderCheckboxList = () => { + return entries.map(entry => renderCheckbox(entry)); + }; + + const renderCheckbox = (entry: NormalizedOption) => { + const id = `${entry.label}-${entry.value}`; + return ( +
+ + {entry.label} +
+ ); + }; + const isInline = prop.display === 'inline-check'; + return ( + + + {renderCheckboxList()} + + + ); +}; diff --git a/core/editors/src/OptionsEditor/OptionsEditor.stories.tsx b/core/editors/src/OptionsEditor/OptionsEditor.stories.tsx new file mode 100644 index 000000000..c5202be1d --- /dev/null +++ b/core/editors/src/OptionsEditor/OptionsEditor.stories.tsx @@ -0,0 +1,317 @@ +import React from 'react'; +import { ControlTypes } from '@component-controls/specification'; +import { OptionsEditor } from './OptionsEditor'; + +export default { + title: 'Basics/PropEditors/OptionsEditor', + component: OptionsEditor, +}; + +export const simple = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: ['one', 'two', 'three'], + }} + /> + ); +}; + +export const objects = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: { One: 'one', Two: 'two', Three: 'three' }, + }} + /> + ); +}; + +export const numeric = () => { + const [state, setState] = React.useState(1); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: [ + { value: 1, label: 'One' }, + { value: 2, label: 'Two' }, + { value: 3, label: 'Three' }, + ], + }} + /> + ); +}; + +export const multiSelectSimple = () => { + const [state, setState] = React.useState(['one']); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: ['one', 'two', 'three'], + display: 'multi-select', + }} + /> + ); +}; + +export const multiSelectObjects = () => { + const [state, setState] = React.useState(['one']); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: { One: 'one', Two: 'two', Three: 'three' }, + display: 'multi-select', + }} + /> + ); +}; + +export const multiSelectNumeric = () => { + const [state, setState] = React.useState([1]); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: [ + { value: 1, label: 'One' }, + { value: 2, label: 'Two' }, + { value: 3, label: 'Three' }, + ], + display: 'multi-select', + }} + /> + ); +}; + +export const simpleRadios = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: ['one', 'two', 'three'], + display: 'radio', + }} + /> + ); +}; + +export const objectsRadios = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: { One: 'one', Two: 'two', Three: 'three' }, + display: 'radio', + }} + /> + ); +}; + +export const numericRadios = () => { + const [state, setState] = React.useState(1); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: [ + { value: 1, label: 'One' }, + { value: 2, label: 'Two' }, + { value: 3, label: 'Three' }, + ], + display: 'radio', + }} + /> + ); +}; + +export const simpleRadiosInline = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: ['one', 'two', 'three'], + display: 'inline-radio', + }} + /> + ); +}; + +export const objectsRadiosInline = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: { One: 'one', Two: 'two', Three: 'three' }, + display: 'inline-radio', + }} + /> + ); +}; + +export const numericRadiosInline = () => { + const [state, setState] = React.useState(1); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: [ + { value: 1, label: 'One' }, + { value: 2, label: 'Two' }, + { value: 3, label: 'Three' }, + ], + display: 'inline-radio', + }} + /> + ); +}; + +export const simpleCheck = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: ['one', 'two', 'three'], + display: 'check', + }} + /> + ); +}; + +export const objectsCheck = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: { One: 'one', Two: 'two', Three: 'three' }, + display: 'check', + }} + /> + ); +}; + +export const numericCheck = () => { + const [state, setState] = React.useState(1); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: [ + { value: 1, label: 'One' }, + { value: 2, label: 'Two' }, + { value: 3, label: 'Three' }, + ], + display: 'check', + }} + /> + ); +}; + +export const simpleCheckInline = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: ['one', 'two', 'three'], + display: 'inline-check', + }} + /> + ); +}; + +export const objectsCheckInline = () => { + const [state, setState] = React.useState('one'); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: { One: 'one', Two: 'two', Three: 'three' }, + display: 'inline-check', + }} + /> + ); +}; + +export const numericCheckInline = () => { + const [state, setState] = React.useState(1); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.OPTIONS, + value: state, + options: [ + { value: 1, label: 'One' }, + { value: 2, label: 'Two' }, + { value: 3, label: 'Three' }, + ], + display: 'inline-check', + }} + /> + ); +}; diff --git a/core/editors/src/OptionsEditor/OptionsEditor.tsx b/core/editors/src/OptionsEditor/OptionsEditor.tsx new file mode 100644 index 000000000..c49a35f8f --- /dev/null +++ b/core/editors/src/OptionsEditor/OptionsEditor.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import ReactSelect from 'react-select'; +import { styled } from '@storybook/theming'; +import { ComponentControlOptions } from '@component-controls/specification'; +import { normalizeOptions } from './utils'; +import { PropertyControlProps, PropertyEditor } from '../types'; + +import { RadiosEditor } from './RadiosEditor'; +import { CheckboxEditor } from './CheckboxEditor'; + +const OptionsSelect = styled(ReactSelect)({ + color: 'black', + flexBasis: '100%', +}); + +type ReactSelectOnChangeFn = + | { (v: OptionsSelectValueItem): void } + | { (v: OptionsSelectValueItem[]): void }; + +interface OptionsSelectValueItem { + value: any; + label: string; +} + +interface OptionsEditorProps extends PropertyControlProps { + prop: ComponentControlOptions; +} + +export const OptionsEditor: PropertyEditor = props => { + const { prop, name, onChange } = props; + const { display, options, value } = prop; + + if (display === 'check' || display === 'inline-check') { + return ; + } + + if (display === 'radio' || display === 'inline-radio') { + return ; + } + + if ( + display === undefined || + display === 'select' || + display === 'multi-select' + ) { + const { entries, selected } = normalizeOptions(options, value); + const isMulti = display === 'multi-select'; + let handleChange: ReactSelectOnChangeFn = (e: OptionsSelectValueItem) => + onChange(name, e.value); + + if (isMulti) { + handleChange = (values: OptionsSelectValueItem[]) => + onChange( + name, + values.map(item => item.value), + ); + } + const selectValue = entries.filter(op => selected.includes(op.value)); + return ( + + ); + } + + return null; +}; diff --git a/core/editors/src/OptionsEditor/RadiosEditor.tsx b/core/editors/src/OptionsEditor/RadiosEditor.tsx new file mode 100644 index 000000000..d53892f1b --- /dev/null +++ b/core/editors/src/OptionsEditor/RadiosEditor.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { styled } from '@storybook/theming'; +import { ComponentControlOptions } from '@component-controls/specification'; +import { normalizeOptions, NormalizedOption } from './utils'; +import { PropertyControlProps, PropertyEditor } from '../types'; + +interface RadiosEditorProps extends PropertyControlProps { + prop: ComponentControlOptions; +} + +const RadiosWrapper = styled.div<{ isInline: boolean }>(({ isInline }) => + isInline + ? { + display: 'flex', + flexWrap: 'wrap', + alignItems: 'center', + '> * + *': { + marginLeft: 10, + }, + } + : {}, +); + +const RadioLabel = styled.label({ + padding: '3px 0 3px 5px', + lineHeight: '18px', + display: 'inline-block', +}); + +export const RadiosEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => { + const renderRadioButton = (entry: NormalizedOption) => { + const id = `${entry.label}-${entry.value}`; + return ( +
+ onChange(name, e.target.value)} + checked={ + entry.value === prop.value || + (typeof entry.value.toString === 'function' && + entry.value.toString() === prop.value) + } + /> + {entry.label} +
+ ); + }; + const renderRadioButtonList = () => { + const { options, value } = prop; + const { entries } = normalizeOptions(options, value); + return entries.map(entry => renderRadioButton(entry)); + }; + const isInline = prop.display === 'inline-radio'; + return ( + {renderRadioButtonList()} + ); +}; diff --git a/core/editors/src/OptionsEditor/index.ts b/core/editors/src/OptionsEditor/index.ts new file mode 100644 index 000000000..3fc160770 --- /dev/null +++ b/core/editors/src/OptionsEditor/index.ts @@ -0,0 +1 @@ +export { OptionsEditor } from './OptionsEditor'; diff --git a/core/editors/src/OptionsEditor/utils.test.ts b/core/editors/src/OptionsEditor/utils.test.ts new file mode 100644 index 000000000..50a1f9ad8 --- /dev/null +++ b/core/editors/src/OptionsEditor/utils.test.ts @@ -0,0 +1,60 @@ +import { OptionsListType } from '@component-controls/specification'; + +import { normalizeOptions, NormalizedOptions } from './utils'; + +describe('Options utility functions', () => { + const objectData: OptionsListType = { Dog: 'dog', Cat: 'cat' }; + const objectEntries: NormalizedOptions = Object.keys(objectData).map(key => ({ + label: key, + value: objectData[key], + })); + const arrayData: OptionsListType = [ + { label: 'Dog', value: 'dog' }, + { label: 'Cat', value: 'cat' }, + ]; + it('Should handle key/value pairs', () => { + expect(normalizeOptions(objectData, 'dog')).toMatchObject({ + entries: objectEntries, + selected: ['dog'], + }); + }); + it('Should handle no selection', () => { + expect(normalizeOptions(objectData, undefined)).toMatchObject({ + entries: objectEntries, + selected: [], + }); + }); + + it('Should handle multi-select object', () => { + expect(normalizeOptions(objectData, ['dog', 'cat'])).toMatchObject({ + entries: objectEntries, + selected: ['dog', 'cat'], + }); + }); + it('Should handle numeric value', () => { + expect(normalizeOptions({ Number: 1 }, 1)).toMatchObject({ + entries: [{ label: 'Number', value: 1 }], + selected: [1], + }); + }); + it('Should handle object value', () => { + expect(normalizeOptions({ Object: objectData }, objectData)).toMatchObject({ + entries: [{ label: 'Object', value: objectData }], + selected: [objectData], + }); + }); + + it('Should handle array input', () => { + expect(normalizeOptions(arrayData, 'dog')).toMatchObject({ + entries: objectEntries, + selected: ['dog'], + }); + }); + + it('Should handle multi-select array input', () => { + expect(normalizeOptions(arrayData, ['dog', 'cat'])).toMatchObject({ + entries: objectEntries, + selected: ['dog', 'cat'], + }); + }); +}); diff --git a/core/editors/src/OptionsEditor/utils.ts b/core/editors/src/OptionsEditor/utils.ts new file mode 100644 index 000000000..1f6a2f2c0 --- /dev/null +++ b/core/editors/src/OptionsEditor/utils.ts @@ -0,0 +1,62 @@ +import { + OptionsListType, + OptionsValueType, +} from '@component-controls/specification'; + +export interface NormalizedOption { + label: string; + value: any; +} +export type NormalizedOptions = NormalizedOption[]; + +export const normalizeOptions = ( + options: OptionsListType, + propValue: OptionsValueType, +): { + entries: NormalizedOptions; + selected: any[]; +} => { + const findLabelOption = ( + label: string | null, + value: any, + ): NormalizedOption => { + if (!value) { + return { + label: label || value, + value, + }; + } + + const val = value.value || value; + if (typeof value !== 'object' || value === null) + return { label: label || val, value: val }; + const vLabel: string = value.label || label || val; + return { + label: vLabel, + value: val, + }; + }; + + let entries: NormalizedOptions; + if (Array.isArray(options)) { + entries = options.reduce((acc: NormalizedOptions, o) => { + return [...acc, findLabelOption(null, o)]; + }, []) as NormalizedOptions; + } else { + entries = Object.keys(options).reduce( + (acc: NormalizedOptions, key: string) => { + return [...acc, findLabelOption(key, options[key])]; + }, + [], + ); + } + const selected = entries + .filter(option => { + if (Array.isArray(propValue)) { + return propValue.findIndex((v: any) => v === option.value) >= 0; + } + return option.value === propValue; + }) + .map(e => e.value); + return { selected, entries }; +}; diff --git a/core/editors/src/PropEditorRow.tsx b/core/editors/src/PropEditorRow.tsx new file mode 100644 index 000000000..73c931243 --- /dev/null +++ b/core/editors/src/PropEditorRow.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { + LoadedComponentControl, + SetControlValueFn, + ResetControlValueFn, + ClickControlFn, +} from '@component-controls/specification'; +import { getPropertyEditor } from './prop-factory'; +import { FlexContainer } from './FlexContainer'; +import { PropertyEditor } from './types'; + +const InvalidType = () => Invalid Type; + +interface PropertyEditorRowProps { + prop: LoadedComponentControl; + name: string; + storyId?: string; + setControlValue?: SetControlValueFn; + resetControlValue?: ResetControlValueFn; + clickControl?: ClickControlFn; +} + +export const PropertyEditorRow: React.FunctionComponent = ({ + prop, + name, + setControlValue, + clickControl, + storyId, +}) => { + const InputType: PropertyEditor = getPropertyEditor(prop.type) || InvalidType; + const onChange = (propName: string, value: any) => { + if (setControlValue && storyId) { + setControlValue(storyId, propName, value); + } + }; + const onClick = () => { + if (clickControl && storyId) { + clickControl(storyId, name); + } + }; + return ( + + {!prop.hideLabel ? prop.label || name : null} + + + + + + + ); +}; diff --git a/core/editors/src/TextEditor/TextEditor.stories.tsx b/core/editors/src/TextEditor/TextEditor.stories.tsx new file mode 100644 index 000000000..dca1b8c2e --- /dev/null +++ b/core/editors/src/TextEditor/TextEditor.stories.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { ControlTypes } from '@component-controls/specification'; +import { TextEditor } from './TextEditor'; + +export default { + title: 'Basics/PropEditors/TextEditor', + component: TextEditor, +}; + +export const simple = () => { + const [state, setState] = React.useState('Hello'); + return ( + setState(newVal)} + prop={{ type: ControlTypes.TEXT, value: state }} + /> + ); +}; + +export const placeholder = () => { + const [state, setState] = React.useState(); + return ( + setState(newVal)} + prop={{ + type: ControlTypes.TEXT, + value: state, + placeholder: 'Enter some text', + }} + /> + ); +}; diff --git a/core/editors/src/TextEditor/TextEditor.tsx b/core/editors/src/TextEditor/TextEditor.tsx new file mode 100644 index 000000000..6ebdeb02d --- /dev/null +++ b/core/editors/src/TextEditor/TextEditor.tsx @@ -0,0 +1,43 @@ +import React, { ChangeEvent } from 'react'; +import { ComponentControlText } from '@component-controls/specification'; +import { Form } from '@storybook/components'; +import { PropertyControlProps, PropertyEditor } from '../types'; + +interface TextEditorProps extends PropertyControlProps { + prop: ComponentControlText; +} + +export const TextEditor: PropertyEditor = ({ + prop, + name, + onChange, +}) => { + const { maxRows = 1, minRows = 1 } = prop; + return minRows > 1 || maxRows > 1 ? ( + ) => { + const { value } = event.target; + onChange(name, value); + }} + size="flex" + /> + ) : ( + ) => { + const { value } = event.target; + onChange(name, value); + }} + size="flex" + /> + ); +}; diff --git a/core/editors/src/TextEditor/index.ts b/core/editors/src/TextEditor/index.ts new file mode 100644 index 000000000..c9ac44376 --- /dev/null +++ b/core/editors/src/TextEditor/index.ts @@ -0,0 +1 @@ +export { TextEditor } from './TextEditor'; diff --git a/core/editors/src/index.ts b/core/editors/src/index.ts new file mode 100644 index 000000000..9ff0dc9f3 --- /dev/null +++ b/core/editors/src/index.ts @@ -0,0 +1,4 @@ +export * from './prop-factory'; +export * from './types'; +export * from './ControlEditorsTable'; +export { FlexContainer } from './FlexContainer'; diff --git a/core/editors/src/prop-factory.ts b/core/editors/src/prop-factory.ts new file mode 100644 index 000000000..98874b2ca --- /dev/null +++ b/core/editors/src/prop-factory.ts @@ -0,0 +1,33 @@ +import { ControlTypes } from '@component-controls/specification'; +import { PropertyEditor } from './types'; +import { TextEditor } from './TextEditor'; +import { NumberEditor } from './NumberEditor'; + +import { BooleanEditor } from './BooleanEditor'; +import { OptionsEditor } from './OptionsEditor'; + +import { DateEditor } from './DateEditor'; +import { ColorEditor } from './ColorEditor'; +import { ButtonEditor } from './ButtonEditor'; + +import { ObjectEditor } from './ObjectEditor'; +import { ArrayEditor } from './ArrayEditor'; +import { FilesEditor } from './FilesEditor'; + +const PropertyEditors: { + [name in ControlTypes]: PropertyEditor; +} = { + [ControlTypes.TEXT]: TextEditor, + [ControlTypes.NUMBER]: NumberEditor, + [ControlTypes.BOOLEAN]: BooleanEditor, + [ControlTypes.OPTIONS]: OptionsEditor, + [ControlTypes.DATE]: DateEditor, + [ControlTypes.COLOR]: ColorEditor, + [ControlTypes.BUTTON]: ButtonEditor, + [ControlTypes.OBJECT]: ObjectEditor, + [ControlTypes.ARRAY]: ArrayEditor, + [ControlTypes.FILES]: FilesEditor, +}; + +export const getPropertyEditor = (type: ControlTypes): PropertyEditor => + PropertyEditors[type]; diff --git a/core/editors/src/types.ts b/core/editors/src/types.ts new file mode 100644 index 000000000..b4e618060 --- /dev/null +++ b/core/editors/src/types.ts @@ -0,0 +1,35 @@ +import React from 'react'; +import { + ComponentControl, + LoadedComponentControls, + SetControlValueFn, + ResetControlValueFn, + ClickControlFn, +} from '@component-controls/specification'; + +export type PropertyOnClick = (prop: ComponentControl) => any; +export interface PropertyControlProps { + prop: ComponentControl; + name: string; + onChange: (name: string, prop: any) => void; + onClick?: PropertyOnClick; +} + +export type PropertyEditor = React.FC; + +export interface ExtraControlAction { + title: string; + onAction: (props: ControlsEditorsTableProps) => void; +} + +export type ExtraControlActions = ExtraControlAction[]; + +export interface ControlsEditorsTableProps { + title?: string; + storyId?: string; + controls?: LoadedComponentControls; + setControlValue?: SetControlValueFn; + resetControlValue?: ResetControlValueFn; + clickControl?: ClickControlFn; + extraActions?: ExtraControlActions; +} diff --git a/core/editors/src/typings.d.ts b/core/editors/src/typings.d.ts new file mode 100644 index 000000000..2f4eb9cf4 --- /dev/null +++ b/core/editors/src/typings.d.ts @@ -0,0 +1 @@ +declare module 'global'; diff --git a/core/editors/tsconfig.json b/core/editors/tsconfig.json new file mode 100644 index 000000000..25ce695d2 --- /dev/null +++ b/core/editors/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "esnext", + "outDir": "dist", + "rootDir": "src", + "declaration": true, + "types": ["node", "jest"], + "typeRoots": ["../../node_modules/@types", "node_modules/@types"] + }, + "include": ["src/**/*", "src/typings.d.ts"], + "exclude": ["node_modules/**"] +} \ No newline at end of file diff --git a/core/specification/package.json b/core/specification/package.json index b64bacc28..e218f4374 100644 --- a/core/specification/package.json +++ b/core/specification/package.json @@ -47,5 +47,5 @@ "authors": [ "Atanas Stoyanov" ], - "gitHead": "18d3441422e05eb4a2db3a89765ac5808a2bed24" + "gitHead": "9bf25e7273da18b16567f776a8286496097ed6f5" } diff --git a/core/specification/src/index.test.ts b/core/specification/src/index.test.ts index c01c809bb..fb8199f3b 100644 --- a/core/specification/src/index.test.ts +++ b/core/specification/src/index.test.ts @@ -1,38 +1,40 @@ -import { ControlTypes } from './types' +import { ControlTypes } from './types'; import { mergeControlValues, resetControlValues, LoadedComponentControls, -} from './index' +} from './index'; describe('Controls utils', () => { const controls: LoadedComponentControls = { name: { type: ControlTypes.TEXT, value: 'hello', defaultValue: 'hello' }, age: { type: ControlTypes.NUMBER, value: 19, defaultValue: 19 }, - } + }; const modifiedControls: LoadedComponentControls = { name: { type: ControlTypes.TEXT, value: 'today', defaultValue: 'hello' }, age: { type: ControlTypes.NUMBER, value: 19, defaultValue: 19 }, - } + }; it('Should merge property value', () => { expect(mergeControlValues(controls, 'name', 'today')).toMatchObject( modifiedControls, - ) - }) + ); + }); it('Should merge property object', () => { expect( mergeControlValues(controls, undefined, { name: modifiedControls.name.value, age: modifiedControls.age.value, }), - ).toMatchObject(modifiedControls) - }) + ).toMatchObject(modifiedControls); + }); it('Should reset property value', () => { - expect(resetControlValues(modifiedControls, 'name')).toMatchObject(controls) - }) + expect(resetControlValues(modifiedControls, 'name')).toMatchObject( + controls, + ); + }); it('Should reset property object', () => { - expect(resetControlValues(modifiedControls)).toMatchObject(controls) - }) -}) + expect(resetControlValues(modifiedControls)).toMatchObject(controls); + }); +}); diff --git a/core/specification/src/index.ts b/core/specification/src/index.ts index 8b1b7886a..a01f5e757 100644 --- a/core/specification/src/index.ts +++ b/core/specification/src/index.ts @@ -1,15 +1,15 @@ -export * from './types' +export * from './types'; -export * from './utils' +export * from './utils'; export type SetControlValueFn = ( storyId: string, propertyName: string | undefined, value: any, -) => void -export type ClickControlFn = (storyId: string, propertyName: string) => void +) => void; +export type ClickControlFn = (storyId: string, propertyName: string) => void; export type ResetControlValueFn = ( storyId: string, propertyName?: string, -) => void +) => void; diff --git a/core/specification/src/types.ts b/core/specification/src/types.ts index cc825deb4..e754fd72e 100644 --- a/core/specification/src/types.ts +++ b/core/specification/src/types.ts @@ -117,7 +117,7 @@ export interface ComponentControlData { * usually comprised of two parts, separated by a dot * example 'internet.avatar' */ - name: string + name: string; /** * options to be passe to the random data generators @@ -125,7 +125,7 @@ export interface ComponentControlData { * min: 10, max: 20 * } */ - options?: { [key: string]: any } + options?: { [key: string]: any }; } /** @@ -134,134 +134,134 @@ export interface ComponentControlData { * */ export interface ComponentControlBase { - type: ControlTypes + type: ControlTypes; /** * label to display next to the field editor * by default uses the property name itself */ - label?: string + label?: string; /** * a default value for the property */ - value?: T + value?: T; /** * hide the label from the property editor */ - hideLabel?: boolean + hideLabel?: boolean; /** * hide the property editor for this property * will only use the value */ - hidden?: boolean + hidden?: boolean; /** * allows grouping of the properties * in a property editor * for example different editor tabs */ - groupId?: string + groupId?: string; /** * allows custom sorting of the properties * if 'order' is not provided, the props * will be sorted by the order/key of the object (unreliable) */ - order?: number + order?: number; /** * helper information to generate random data * can be used in conjunction with faker.js */ - data?: ComponentControlData + data?: ComponentControlData; } export interface ComponentControlText extends ComponentControlBase { - type: ControlTypes.TEXT + type: ControlTypes.TEXT; /** * placeholder for empty properties * either undefined initial value * or user clears the field */ - placeholder?: string + placeholder?: string; /** * minimum number of rows in a TextArea field for longer text * by default, only 1 row = means a Input field */ - minRows?: number + minRows?: number; /** * number of rows in a TextArea field */ - maxRows?: number + maxRows?: number; /** * allows to receive escaped string values * to help prevent XSS attacks * by default - false */ - escapeValue?: boolean + escapeValue?: boolean; } export interface ComponentControlBoolean extends ComponentControlBase { - type: ControlTypes.BOOLEAN + type: ControlTypes.BOOLEAN; } export interface ComponentControlColor extends ComponentControlBase { - type: ControlTypes.COLOR + type: ControlTypes.COLOR; } export interface ComponentControlDate extends ComponentControlBase { - type: ControlTypes.DATE + type: ControlTypes.DATE; /** * whether to display a date picker (calendar). * default: true */ - datePicker?: boolean + datePicker?: boolean; /** * whether to display a time picker (calendar). * default: true */ - timePicker?: boolean + timePicker?: boolean; } export interface ComponentControlFiles extends ComponentControlBase { - type: ControlTypes.FILES + type: ControlTypes.FILES; /** * type of files to accept user to open * ex 'image/*', */ - accept?: string + accept?: string; } export interface ComponentControlArray extends ComponentControlBase { - type: ControlTypes.ARRAY + type: ControlTypes.ARRAY; /** * the array items separator, by default comma */ - separator?: string + separator?: string; } export interface ComponentControlObject extends ComponentControlBase { - type: ControlTypes.OBJECT + type: ControlTypes.OBJECT; } export interface ComponentControlButton void> extends ComponentControlBase { - type: ControlTypes.BUTTON + type: ControlTypes.BUTTON; /** * for button type fields, an onClick handler */ - onClick?: (prop: ComponentControlButton) => void + onClick?: (prop: ComponentControlButton) => void; } export type OptionsValueType = @@ -269,14 +269,14 @@ export type OptionsValueType = | number | string[] | number[] - | { label: string; value: any } + | { label: string; value: any }; /** * value/label pairs or array of OptionsValueType */ export type OptionsListType = | { [key: string]: T } - | OptionsValueType[] + | OptionsValueType[]; /** * list of options can be @@ -287,9 +287,9 @@ export type OptionsListType = export interface ComponentControlOptions extends ComponentControlBase> { - type: ControlTypes.OPTIONS + type: ControlTypes.OPTIONS; - options: OptionsListType + options: OptionsListType; /** * how to render selecting the options: * default is 'select' @@ -301,11 +301,11 @@ export interface ComponentControlOptions | 'radio' | 'inline-radio' | 'check' - | 'inline-check' + | 'inline-check'; } export interface ComponentControlNumber extends ComponentControlBase { - type: ControlTypes.NUMBER + type: ControlTypes.NUMBER; /** * for numeric type fields */ @@ -313,23 +313,23 @@ export interface ComponentControlNumber extends ComponentControlBase { /** * if true, will display a range type slider editor */ - range?: boolean + range?: boolean; /** * minimum allowed value for numeric property */ - min?: number + min?: number; /** * maximum allowed value for numeric property */ - max?: number + max?: number; /** * stepper for numeric editor /i nc/dec value */ - step?: number + step?: number; } /** @@ -350,7 +350,7 @@ export type ComponentControl = | ComponentControlOptions | ComponentControlNumber | ComponentControlArray - | ComponentControlFiles + | ComponentControlFiles; /** * ComponentControls are defined in key value pairs @@ -358,5 +358,5 @@ export type ComponentControl = * and the value is the ComponentControl */ export interface ComponentControls { - [name: string]: ComponentControl + [name: string]: ComponentControl; } diff --git a/core/specification/src/typings.d.ts b/core/specification/src/typings.d.ts index 78bc5bf43..d69a62f56 100644 --- a/core/specification/src/typings.d.ts +++ b/core/specification/src/typings.d.ts @@ -1 +1 @@ -declare module 'escape-html' +declare module 'escape-html'; diff --git a/core/specification/src/utils.ts b/core/specification/src/utils.ts index 5883e7e99..b790131e9 100644 --- a/core/specification/src/utils.ts +++ b/core/specification/src/utils.ts @@ -1,10 +1,10 @@ -import escape from 'escape-html' +import escape from 'escape-html'; -import { ComponentControl, ComponentControls, ControlTypes } from './types' +import { ComponentControl, ComponentControls, ControlTypes } from './types'; -export type LoadedComponentControl = ComponentControl & { defaultValue: any } +export type LoadedComponentControl = ComponentControl & { defaultValue: any }; export interface LoadedComponentControls { - [name: string]: LoadedComponentControl + [name: string]: LoadedComponentControl; } // save default value for 'reset' @@ -12,9 +12,9 @@ export const loadControls = ( controls: ComponentControls, ): LoadedComponentControls => Object.keys(controls).reduce((v, key) => { - const prop = controls[key] - return { ...v, [key]: { ...prop, defaultValue: prop.value } } - }, {}) + const prop = controls[key]; + return { ...v, [key]: { ...prop, defaultValue: prop.value } }; + }, {}); const mergeValue = (control: ComponentControl, value: any): any => { if (control && control.type === ControlTypes.OBJECT) { @@ -25,10 +25,10 @@ const mergeValue = (control: ComponentControl, value: any): any => { undefined, value, ), - } + }; } - return { ...control, value } -} + return { ...control, value }; +}; export const mergeControlValues = ( controls: LoadedComponentControls, @@ -49,8 +49,8 @@ export const mergeControlValues = ( ), }), {}, - ) -} + ); +}; export const resetControlValues = ( controls: LoadedComponentControls, @@ -70,18 +70,18 @@ export const resetControlValues = ( [key]: { ...controls[key], value: controls[key].defaultValue }, }), {}, - ) -} + ); +}; export const getControlValues = ( controls: LoadedComponentControls, ): { [name: string]: any } => Object.keys(controls).reduce((acc, key) => { - const control: ComponentControl = controls[key] - let { value } = control + const control: ComponentControl = controls[key]; + let { value } = control; if (control.type === ControlTypes.TEXT && control.escapeValue) { if (typeof value === 'string') { - value = escape(value) + value = escape(value); } } else if ( control.type === ControlTypes.OBJECT && @@ -90,7 +90,7 @@ export const getControlValues = ( return { ...acc, [key]: getControlValues(value as LoadedComponentControls), - } + }; } - return { ...acc, [key]: value } - }, {}) + return { ...acc, [key]: value }; + }, {}); diff --git a/core/specification/tsconfig copy.json b/core/specification/tsconfig copy.json deleted file mode 100644 index 4894223ce..000000000 --- a/core/specification/tsconfig copy.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "rootDir": "./src" - }, - "include": ["src/**/*"], - "exclude": ["src/**/*.test.ts"] -} diff --git a/core/specification/tsconfig.json b/core/specification/tsconfig.json index 15065563d..25ce695d2 100644 --- a/core/specification/tsconfig.json +++ b/core/specification/tsconfig.json @@ -5,7 +5,7 @@ "outDir": "dist", "rootDir": "src", "declaration": true, - "types": ["node"], + "types": ["node", "jest"], "typeRoots": ["../../node_modules/@types", "node_modules/@types"] }, "include": ["src/**/*", "src/typings.d.ts"], diff --git a/yarn.lock b/yarn.lock index 248184803..4f7b64553 100644 --- a/yarn.lock +++ b/yarn.lock @@ -894,7 +894,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-typescript" "^7.8.3" -"@babel/runtime@7.8.4", "@babel/runtime@^7.2.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6": +"@babel/runtime@7.8.4", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.4.tgz#d79f5a2040f7caa24d53e563aad49cbc05581308" integrity sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ== @@ -1081,7 +1081,7 @@ dependencies: find-up "^4.0.0" -"@emotion/cache@^10.0.27": +"@emotion/cache@^10.0.27", "@emotion/cache@^10.0.9": version "10.0.27" resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.27.tgz#7895db204e2c1a991ae33d51262a3a44f6737303" integrity sha512-Zp8BEpbMunFsTcqAK4D7YTm3MvCp1SekflSLJH8lze2fCcSZ/yMkXHo8kb3t1/1Tdd3hAqf3Fb7z9VZ+FMiC9w== @@ -1091,7 +1091,7 @@ "@emotion/utils" "0.11.3" "@emotion/weak-memoize" "0.2.5" -"@emotion/core@^10.0.0": +"@emotion/core@^10.0.0", "@emotion/core@^10.0.20", "@emotion/core@^10.0.9": version "10.0.27" resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.27.tgz#7c3f78be681ab2273f3bf11ca3e2edc4a9dd1fdc" integrity sha512-XbD5R36pVbohQMnKfajHv43g8EbN4NHdF6Zh9zg/C0nr0jqwOw3gYnC07Xj3yG43OYSRyrGsoQ5qPwc8ycvLZw== @@ -1103,7 +1103,7 @@ "@emotion/sheet" "0.9.4" "@emotion/utils" "0.11.3" -"@emotion/css@^10.0.27": +"@emotion/css@^10.0.27", "@emotion/css@^10.0.9": version "10.0.27" resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c" integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw== @@ -1117,7 +1117,7 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.4.tgz#f14932887422c9056b15a8d222a9074a7dfa2831" integrity sha512-fxfMSBMX3tlIbKUdtGKxqB1fyrH6gVrX39Gsv3y8lRYKUqlgDt3UMqQyGnR1bQMa2B8aGnhLZokZgg8vT0Le+A== -"@emotion/is-prop-valid@0.8.6", "@emotion/is-prop-valid@^0.8.1": +"@emotion/is-prop-valid@0.8.6", "@emotion/is-prop-valid@^0.8.1", "@emotion/is-prop-valid@^0.8.6": version "0.8.6" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.6.tgz#4757646f0a58e9dec614c47c838e7147d88c263c" integrity sha512-mnZMho3Sq8BfzkYYRVc8ilQTnc8U02Ytp6J1AwM6taQStZ3AhsEJBX2LzhA/LJirNCwM2VtHL3VFIZ+sNJUgUQ== @@ -1155,7 +1155,7 @@ "@emotion/serialize" "^0.11.15" "@emotion/utils" "0.11.3" -"@emotion/styled@^10.0.0": +"@emotion/styled@^10.0.0", "@emotion/styled@^10.0.17": version "10.0.27" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf" integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q== @@ -1270,6 +1270,11 @@ unique-filename "^1.1.1" which "^1.3.1" +"@icons/material@^0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" + integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw== + "@jest/console@^24.7.1", "@jest/console@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" @@ -1418,6 +1423,16 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" +"@jest/types@^25.1.0": + version "25.1.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.1.0.tgz#b26831916f0d7c381e11dbb5e103a72aed1b4395" + integrity sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + "@lerna/add@3.15.0": version "3.15.0" resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.15.0.tgz#10be562f43cde59b60f299083d54ac39520ec60a" @@ -2259,6 +2274,58 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@storybook/client-logger@6.0.0-alpha.6": + version "6.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.0.0-alpha.6.tgz#90db9195d1a83cc990f711cc1cc6b7829eab9d67" + integrity sha512-dMU9xZOVb1CHEnyMJVjLkgE7AiXelf4QAfdeGYFL56MYUFa/dwa4LxtmWjoCSkF4wVl4h8S4jtXQ5mzp+uCEdQ== + dependencies: + core-js "^3.0.1" + +"@storybook/components@6.0.0-alpha.6": + version "6.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.0.0-alpha.6.tgz#ed43a97e6d484482e21b985e55e4b4e559fb1f06" + integrity sha512-FHeLceg0Az7uvhz08Cwu2o/Oxn1nLlQFne2+YDELhAApauLUj0X72xyTdv/LuW7DGyFx8iZX/RMsqs0JNzO7Ig== + dependencies: + "@storybook/client-logger" "6.0.0-alpha.6" + "@storybook/theming" "6.0.0-alpha.6" + "@types/react-textarea-autosize" "^4.3.3" + core-js "^3.0.1" + global "^4.3.2" + lodash "^4.17.15" + markdown-to-jsx "^6.9.1" + memoizerific "^1.11.3" + polished "^3.4.4" + popper.js "^1.14.7" + prop-types "^15.7.2" + react "^16.8.3" + react-dom "^16.8.3" + react-focus-lock "^2.1.0" + react-helmet-async "^1.0.2" + react-popper-tooltip "^2.8.3" + react-syntax-highlighter "^11.0.2" + react-textarea-autosize "^7.1.0" + simplebar-react "^1.0.0-alpha.6" + ts-dedent "^1.1.1" + +"@storybook/theming@6.0.0-alpha.6": + version "6.0.0-alpha.6" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.0.0-alpha.6.tgz#f94b205c967097effa164ac9d564c3c72ac65701" + integrity sha512-zhbOGwr2BYtCY4XD3CqNlEUaOs9hmvN4JV1ZKnOW1nDR3skDHTvtpuEeaboS9KOaRVY5JGpR6NKiE6SYB/I8WA== + dependencies: + "@emotion/core" "^10.0.20" + "@emotion/is-prop-valid" "^0.8.6" + "@emotion/styled" "^10.0.17" + "@storybook/client-logger" "6.0.0-alpha.6" + core-js "^3.0.1" + deep-object-diff "^1.1.0" + emotion-theming "^10.0.19" + global "^4.3.2" + memoizerific "^1.11.3" + polished "^3.4.4" + prop-types "^15.7.2" + resolve-from "^5.0.0" + ts-dedent "^1.1.1" + "@stroncium/procfs@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@stroncium/procfs/-/procfs-1.1.1.tgz#6ae4b4938cf3b6c3fb957f3063b2c0a8b26ee599" @@ -2471,6 +2538,14 @@ dependencies: jest-diff "^24.3.0" +"@types/jest@^25.1.2": + version "25.1.2" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.1.2.tgz#1c4c8770c27906c7d8def5d2033df9dbd39f60da" + integrity sha512-EsPIgEsonlXmYV7GzUqcvORsSS9Gqxw/OvkGwHfAdpjduNRxMlhsav0O5Kb0zijc/eXSO/uW6SJt9nwull8AUQ== + dependencies: + jest-diff "^25.1.0" + pretty-format "^25.1.0" + "@types/json-schema@^7.0.3": version "7.0.4" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" @@ -2511,11 +2586,66 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.0.tgz#a2502fb7ce9b6626fdbfc2e2a496f472de1bdd05" integrity sha512-gDE8JJEygpay7IjA/u3JiIURvwZW08f0cZSZLAzFoX/ZmeqvS0Sqv+97aKuHpNsalAMMhwPe+iAS6fQbfmbt7A== +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + "@types/q@^1.5.1": version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== +"@types/qs@^6.9.1": + version "6.9.1" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.1.tgz#937fab3194766256ee09fcd40b781740758617e7" + integrity sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw== + +"@types/react-color@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/react-color/-/react-color-3.0.1.tgz#5433e2f503ea0e0831cbc6fd0c20f8157d93add0" + integrity sha512-J6mYm43Sid9y+OjZ7NDfJ2VVkeeuTPNVImNFITgQNXodHteKfl/t/5pAR5Z9buodZ2tCctsZjgiMlQOpfntakw== + dependencies: + "@types/react" "*" + +"@types/react-dom@*": + version "16.9.5" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.5.tgz#5de610b04a35d07ffd8f44edad93a71032d9aaa7" + integrity sha512-BX6RQ8s9D+2/gDhxrj8OW+YD4R+8hj7FEM/OJHGNR0KipE1h1mSsf39YeyC81qafkq+N3rU3h3RFbLSwE5VqUg== + dependencies: + "@types/react" "*" + +"@types/react-select@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-3.0.10.tgz#c32e0832d368756e6db53ccedf64f767728545d4" + integrity sha512-oUHXqvbkRhC07q5JjeY6hE+NUqgUM6CyaRXEKYPvMCBqUOuLnYltyhiNx6Jpb+iFpYtNHSQtF4dNJfMdMooKoQ== + dependencies: + "@types/react" "*" + "@types/react-dom" "*" + "@types/react-transition-group" "*" + +"@types/react-textarea-autosize@^4.3.3": + version "4.3.5" + resolved "https://registry.yarnpkg.com/@types/react-textarea-autosize/-/react-textarea-autosize-4.3.5.tgz#6c4d2753fa1864c98c0b2b517f67bb1f6e4c46de" + integrity sha512-PiDL83kPMTolyZAWW3lyzO6ktooTb9tFTntVy7CA83/qFLWKLJ5bLeRboy6J6j3b1e8h2Eec6gBTEOOJRjV14A== + dependencies: + "@types/react" "*" + +"@types/react-transition-group@*": + version "4.2.3" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.2.3.tgz#4924133f7268694058e415bf7aea2d4c21131470" + integrity sha512-Hk8jiuT7iLOHrcjKP/ZVSyCNXK73wJAUz60xm0mVhiRujrdiI++j4duLiL282VGxwAgxetHQFfqA29LgEeSkFA== + dependencies: + "@types/react" "*" + +"@types/react@*": + version "16.9.19" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.19.tgz#c842aa83ea490007d29938146ff2e4d9e4360c40" + integrity sha512-LJV97//H+zqKWMms0kvxaKYJDG05U2TtQB3chRLF8MPNs+MQh/H1aGlyDUxjaHvu08EAGerdX2z4LTBc7ns77A== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + "@types/resolve@0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" @@ -2545,6 +2675,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^15.0.0": + version "15.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.3.tgz#41453a0bc7ab393e995d1f5451455638edbd2baf" + integrity sha512-XCMQRK6kfpNBixHLyHUsGmXrpEmFFxzMrcnSXFMziHd8CoNJo8l16FkHyQq4x+xbM7E2XL83/O78OD8u+iZTdQ== + dependencies: + "@types/yargs-parser" "*" + "@typescript-eslint/eslint-plugin@^1.12.0": version "1.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz#22fed9b16ddfeb402fd7bcde56307820f6ebc49f" @@ -3378,6 +3515,11 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +can-use-dom@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/can-use-dom/-/can-use-dom-0.1.0.tgz#22cc4a34a0abc43950f42c6411024a3f6366b45a" + integrity sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo= + caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -3525,6 +3667,15 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= +clipboard@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.4.tgz#836dafd66cf0fea5d71ce5d5b0bf6e958009112d" + integrity sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ== + dependencies: + good-listener "^1.2.2" + select "^1.1.2" + tiny-emitter "^2.0.0" + cliui@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" @@ -3659,6 +3810,11 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +comma-separated-tokens@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" + integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== + commander@^2.20.0, commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -3884,6 +4040,13 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +copy-to-clipboard@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.2.1.tgz#b1a1137100e5665d5a96015cb579e30e90e07c44" + integrity sha512-btru1Q6RD9wbonIvEU5EfnhIRGHLo//BGXQ1hNAD2avIs/nBZlpbOeKtv3mhoUByN4DB9Cb6/vXBymj1S43KmA== + dependencies: + toggle-selection "^1.0.6" + core-js-compat@^3.6.2: version "3.6.4" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.4.tgz#938476569ebb6cda80d339bcf199fae4f16fff17" @@ -3897,6 +4060,11 @@ core-js@^2.4.0, core-js@^2.5.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== +core-js@^3.0.1: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" + integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -3934,6 +4102,14 @@ cp-file@^6.1.0: pify "^4.0.1" safe-buffer "^5.0.1" +create-react-context@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c" + integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw== + dependencies: + gud "^1.0.0" + warning "^4.0.3" + cross-env@^5.2.0, cross-env@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d" @@ -4147,7 +4323,7 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" -csstype@^2.5.7: +csstype@^2.2.0, csstype@^2.5.7: version "2.6.8" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.8.tgz#0fb6fc2417ffd2816a418c9336da74d7f07db431" integrity sha512-msVS9qTuMT5zwAGCVm4mxfrZ18BNc6Csd0oJAtiFMZ1FAx1CCvy2+5MDmYoix63LM/6NDbNtodCiGYGmFgO0dA== @@ -4271,6 +4447,18 @@ dedent@0.7.0, dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= +deep-equal@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -4281,6 +4469,11 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +deep-object-diff@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.0.tgz#d6fabf476c2ed1751fc94d5ca693d2ed8c18bc5a" + integrity sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw== + defaults@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" @@ -4341,6 +4534,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +delegate@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" + integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== + delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" @@ -4366,6 +4564,11 @@ detect-newline@^2.1.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= +detect-node@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" + integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + dezalgo@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" @@ -4384,6 +4587,11 @@ diff-sequences@^24.9.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== +diff-sequences@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.1.0.tgz#fd29a46f1c913fd66c22645dc75bffbe43051f32" + integrity sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw== + dir-glob@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" @@ -4443,6 +4651,13 @@ docz-rollup@^2.1.0: rollup-plugin-progress "^1.1.1" rollup-plugin-typescript2 "^0.22.0" +dom-helpers@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + dom-serializer@0: version "0.2.2" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" @@ -4451,6 +4666,11 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + domelementtype@1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" @@ -4543,6 +4763,15 @@ emojis-list@^2.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= +emotion-theming@^10.0.19: + version "10.0.27" + resolved "https://registry.yarnpkg.com/emotion-theming/-/emotion-theming-10.0.27.tgz#1887baaec15199862c89b1b984b79806f2b9ab10" + integrity sha512-MlF1yu/gYh8u+sLUqA0YuA9JX0P4Hb69WlKc/9OLo+WCXuX6sy/KoIa+qJimgmr2dWqnypYKYPX37esjDBbhdw== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/weak-memoize" "0.2.5" + hoist-non-react-statics "^3.3.0" + encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" @@ -5026,6 +5255,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.0" +fault@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" + integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== + dependencies: + format "^0.2.0" + fb-watchman@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" @@ -5176,6 +5412,11 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +focus-lock@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.6.6.tgz#98119a755a38cfdbeda0280eaa77e307eee850c7" + integrity sha512-Dx69IXGCq1qsUExWuG+5wkiMqVM/zGx/reXSJSLogECwp3x6KeNQZ+NAetgxEFpnC41rD8U3+jRCW68+LNzdtw== + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -5195,6 +5436,11 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +format@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -5507,6 +5753,14 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" +global@^4.3.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -5558,6 +5812,13 @@ globby@^8.0.1: pify "^3.0.0" slash "^1.0.0" +good-listener@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" + integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA= + dependencies: + delegate "^3.1.2" + got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" @@ -5585,6 +5846,11 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= +gud@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" + integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== + gzip-size@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" @@ -5692,11 +5958,38 @@ has@^1.0.0, has@^1.0.3: dependencies: function-bind "^1.1.1" +hast-util-parse-selector@^2.0.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.3.tgz#57edd449103900c7f63fd9e6f694ffd7e4634719" + integrity sha512-nxbeqjQNxsvo/uYYAw9kij6td05YVUlf1qti09rVfbWSLT5H6wo3c+USIwX6nzXWk5kFZzXnEqO82856r0aM2Q== + +hastscript@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.1.tgz#71726ee1e97220575d1f29a8e937387d99d48275" + integrity sha512-xHo1Hkcqd0LlWNuDL3/BxwhgAGp3d7uEvCMgCTrBY+zsOooPPH+8KAvW8PCgl+GB8H3H44nfSaF0A4BQ+4xlYg== + dependencies: + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + hex-color-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== +highlight.js@~9.13.0: + version "9.13.1" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" + integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== + +hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + homedir-polyfill@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" @@ -6086,6 +6379,11 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -6342,7 +6640,7 @@ is-reference@^1.1.2: dependencies: "@types/estree" "0.0.39" -is-regex@^1.0.5: +is-regex@^1.0.4, is-regex@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== @@ -6575,6 +6873,16 @@ jest-diff@^24.3.0, jest-diff@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" +jest-diff@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.1.0.tgz#58b827e63edea1bc80c1de952b80cec9ac50e1ad" + integrity sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw== + dependencies: + chalk "^3.0.0" + diff-sequences "^25.1.0" + jest-get-type "^25.1.0" + pretty-format "^25.1.0" + jest-docblock@^24.3.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" @@ -6621,6 +6929,11 @@ jest-get-type@^24.9.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== +jest-get-type@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.1.0.tgz#1cfe5fc34f148dc3a8a3b7275f6b9ce9e2e8a876" + integrity sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw== + jest-haste-map@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" @@ -7246,6 +7559,11 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -7291,6 +7609,11 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "^3.0.0" +lodash.throttle@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" + integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= + lodash.unescape@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" @@ -7306,7 +7629,7 @@ lodash@4.17.14: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== -lodash@4.17.15, lodash@^4.11.2, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.5, lodash@^4.2.1: +lodash@4.17.15, lodash@^4.0.1, lodash@^4.11.2, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.5, lodash@^4.2.1: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -7353,7 +7676,7 @@ longest@^1.0.1: resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= -loose-envify@^1.0.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7378,6 +7701,14 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lowlight@~1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.11.0.tgz#1304d83005126d4e8b1dc0f07981e9b689ec2efc" + integrity sha512-xrGGN6XLL7MbTMdPD6NfWPwY43SNkjf/d0mecSx/CW36fUZTjRHEq0/Cdug3TWKtRXLWi7iMl1eP0olYxj/a4A== + dependencies: + fault "^1.0.2" + highlight.js "~9.13.0" + lru-cache@^4.0.0, lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -7495,6 +7826,11 @@ map-obj@^2.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= +map-or-similar@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" + integrity sha1-beJlMXSt+12e3DPGnT6Sobdvrwg= + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -7512,6 +7848,19 @@ markdown-table@^1.1.0: resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== +markdown-to-jsx@^6.9.1: + version "6.11.0" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-6.11.0.tgz#a2e3f2bc781c3402d8bb0f8e0a12a186474623b0" + integrity sha512-RH7LCJQ4RFmPqVeZEesKaO1biRzB/k4utoofmTCp3Eiw6D7qfvK8fzZq/2bjEJAtVkfPrM5SMt5APGf2rnaKMg== + dependencies: + prop-types "^15.6.2" + unquote "^1.1.0" + +material-colors@^1.2.1: + version "1.2.6" + resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46" + integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg== + mdast-util-compact@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz#d531bb7667b5123abf20859be086c4d06c894593" @@ -7533,6 +7882,18 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" +memoize-one@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" + integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA== + +memoizerific@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" + integrity sha1-fIekZGREwy11Q4VwkF8tvRsagFo= + dependencies: + map-or-similar "^1.5.0" + memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" @@ -7653,6 +8014,13 @@ mimic-response@^1.0.0, mimic-response@^1.0.1: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + minimatch@^3.0.0, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -8085,6 +8453,11 @@ object-inspect@^1.7.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== +object-is@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" + integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== + object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -8394,7 +8767,7 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-entities@^1.0.2, parse-entities@^1.1.0: +parse-entities@^1.0.2, parse-entities@^1.1.0, parse-entities@^1.1.2: version "1.2.2" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50" integrity sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg== @@ -8629,6 +9002,18 @@ pn@^1.1.0: resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== +polished@^3.4.4: + version "3.4.4" + resolved "https://registry.yarnpkg.com/polished/-/polished-3.4.4.tgz#ac8cd6e704887398f3b802718f9d389b9ea4307b" + integrity sha512-x9PKeExyI9AhWrJP3Q57I1k7GInujjiVBJMPFmycj9hX1yCOo/X9eu9eZwxgOziiXge3WbFQ5XOmkzunOntBSA== + dependencies: + "@babel/runtime" "^7.6.3" + +popper.js@^1.14.4, popper.js@^1.14.7: + version "1.16.1" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" + integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -9019,6 +9404,30 @@ pretty-format@^24.9.0: ansi-styles "^3.2.0" react-is "^16.8.4" +pretty-format@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.1.0.tgz#ed869bdaec1356fc5ae45de045e2c8ec7b07b0c8" + integrity sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ== + dependencies: + "@jest/types" "^25.1.0" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^16.12.0" + +prismjs@^1.8.4: + version "1.19.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.19.0.tgz#713afbd45c3baca4b321569f2df39e17e729d4dc" + integrity sha512-IVFtbW9mCWm9eOIaEkNyo2Vl4NnEifis2GQ7/MLRG5TQe6t+4Sj9J5QWI9i3v+SS43uZBlCAOn+zYTVYQcPXJw== + optionalDependencies: + clipboard "^2.0.0" + +prismjs@~1.17.0: + version "1.17.1" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.17.1.tgz#e669fcbd4cdd873c35102881c33b14d0d68519be" + integrity sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q== + optionalDependencies: + clipboard "^2.0.0" + private@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -9029,6 +9438,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -9067,7 +9481,7 @@ promzard@^0.3.0: dependencies: read "1" -prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -9076,6 +9490,13 @@ prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +property-information@^5.0.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.4.0.tgz#16e08f13f4e5c4a7be2e4ec431c01c4f8dba869a" + integrity sha512-nmMWAm/3vKFGmmOWOcdLjgq/Hlxa+hsuR/px1Lp/UGEyc5A22A6l78Shc2C0E71sPmAqglni+HrS7L7VJ7AUCA== + dependencies: + xtend "^4.0.0" + proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" @@ -9143,6 +9564,11 @@ q@^1.1.2, q@^1.5.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= +qs@^6.9.1: + version "6.9.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9" + integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA== + qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -9163,11 +9589,160 @@ rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-is@^16.8.1, react-is@^16.8.4: +react-clientside-effect@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.2.tgz#6212fb0e07b204e714581dd51992603d1accc837" + integrity sha512-nRmoyxeok5PBO6ytPvSjKp9xwXg9xagoTK1mMjwnQxqM9Hd7MNPl+LS1bOSOe+CV2+4fnEquc7H/S8QD3q697A== + dependencies: + "@babel/runtime" "^7.0.0" + +react-color@^2.17.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.18.0.tgz#34956f0bac394f6c3bc01692fd695644cc775ffd" + integrity sha512-FyVeU1kQiSokWc8NPz22azl1ezLpJdUyTbWL0LPUpcuuYDrZ/Y1veOk9rRK5B3pMlyDGvTk4f4KJhlkIQNRjEA== + dependencies: + "@icons/material" "^0.2.4" + lodash "^4.17.11" + material-colors "^1.2.1" + prop-types "^15.5.10" + reactcss "^1.2.0" + tinycolor2 "^1.4.1" + +react-dom@^16.8.3: + version "16.12.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11" + integrity sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.18.0" + +react-fast-compare@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" + integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== + +react-focus-lock@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.2.1.tgz#1d12887416925dc53481914b7cedd39494a3b24a" + integrity sha512-47g0xYcCTZccdzKRGufepY8oZ3W1Qg+2hn6u9SHZ0zUB6uz/4K4xJe7yYFNZ1qT6m+2JDm82F6QgKeBTbjW4PQ== + dependencies: + "@babel/runtime" "^7.0.0" + focus-lock "^0.6.6" + prop-types "^15.6.2" + react-clientside-effect "^1.2.2" + use-callback-ref "^1.2.1" + use-sidecar "^1.0.1" + +react-helmet-async@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.0.4.tgz#079ef10b7fefcaee6240fefd150711e62463cc97" + integrity sha512-KTGHE9sz8N7+fCkZ2a3vzXH9eIkiTNhL2NhKR7XzzQl3WsGlCHh76arauJUIiGdfhjeMp7DY7PkASAmYFXeJYg== + dependencies: + "@babel/runtime" "^7.3.4" + invariant "^2.2.4" + prop-types "^15.7.2" + react-fast-compare "^2.0.4" + shallowequal "^1.1.0" + +react-input-autosize@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.2.tgz#fcaa7020568ec206bc04be36f4eb68e647c4d8c2" + integrity sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw== + dependencies: + prop-types "^15.5.8" + +react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: version "16.12.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-popper-tooltip@^2.8.3: + version "2.10.1" + resolved "https://registry.yarnpkg.com/react-popper-tooltip/-/react-popper-tooltip-2.10.1.tgz#e10875f31916297c694d64a677d6f8fa0a48b4d1" + integrity sha512-cib8bKiyYcrIlHo9zXx81G0XvARfL8Jt+xum709MFCgQa3HTqTi4au3iJ9tm7vi7WU7ngnqbpWkMinBOtwo+IQ== + dependencies: + "@babel/runtime" "^7.7.4" + react-popper "^1.3.6" + +react-popper@^1.3.6: + version "1.3.7" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.7.tgz#f6a3471362ef1f0d10a4963673789de1baca2324" + integrity sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww== + dependencies: + "@babel/runtime" "^7.1.2" + create-react-context "^0.3.0" + deep-equal "^1.1.1" + popper.js "^1.14.4" + prop-types "^15.6.1" + typed-styles "^0.0.7" + warning "^4.0.2" + +react-select@^3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.0.8.tgz#06ff764e29db843bcec439ef13e196865242e0c1" + integrity sha512-v9LpOhckLlRmXN5A6/mGGEft4FMrfaBFTGAnuPHcUgVId7Je42kTq9y0Z+Ye5z8/j0XDT3zUqza8gaRaI1PZIg== + dependencies: + "@babel/runtime" "^7.4.4" + "@emotion/cache" "^10.0.9" + "@emotion/core" "^10.0.9" + "@emotion/css" "^10.0.9" + memoize-one "^5.0.0" + prop-types "^15.6.0" + react-input-autosize "^2.2.2" + react-transition-group "^2.2.1" + +react-syntax-highlighter@^11.0.2: + version "11.0.2" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz#4e3f376e752b20d2f54e4c55652fd663149e4029" + integrity sha512-kqmpM2OH5OodInbEADKARwccwSQWBfZi0970l5Jhp4h39q9Q65C4frNcnd6uHE5pR00W8pOWj9HDRntj2G4Rww== + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "~9.13.0" + lowlight "~1.11.0" + prismjs "^1.8.4" + refractor "^2.4.1" + +react-textarea-autosize@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.2.tgz#70fdb333ef86bcca72717e25e623e90c336e2cda" + integrity sha512-uH3ORCsCa3C6LHxExExhF4jHoXYCQwE5oECmrRsunlspaDAbS4mGKNlWZqjLfInWtFQcf0o1n1jC/NGXFdUBCg== + dependencies: + "@babel/runtime" "^7.1.2" + prop-types "^15.6.0" + +react-transition-group@^2.2.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + +react@^16.8.3: + version "16.12.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83" + integrity sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + +reactcss@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/reactcss/-/reactcss-1.2.3.tgz#c00013875e557b1cf0dfd9a368a1c3dab3b548dd" + integrity sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A== + dependencies: + lodash "^4.0.1" + read-cmd-shim@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" @@ -9335,6 +9910,15 @@ reflexbox@^4.0.6: "@styled-system/should-forward-prop" "^5.0.0" styled-system "^5.0.0" +refractor@^2.4.1: + version "2.10.1" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.10.1.tgz#166c32f114ed16fd96190ad21d5193d3afc7d34e" + integrity sha512-Xh9o7hQiQlDbxo5/XkOX6H+x/q8rmlmZKr97Ie1Q8ZM32IRRd3B/UxuA/yXDW79DBSXGWxm2yRTbcTVmAciJRw== + dependencies: + hastscript "^5.0.0" + parse-entities "^1.1.2" + prismjs "~1.17.0" + regenerate-unicode-properties@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" @@ -9377,7 +9961,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.3.0: +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== @@ -9598,6 +10182,11 @@ reserved-words@^0.1.2: resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.2.tgz#00a0940f98cd501aeaaac316411d9adc52b31ab1" integrity sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE= +resize-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -9927,6 +10516,19 @@ sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +scheduler@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4" + integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +select@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" + integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" @@ -9979,6 +10581,11 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" +shallowequal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -10042,6 +10649,26 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +simplebar-react@^1.0.0-alpha.6: + version "1.2.3" + resolved "https://registry.yarnpkg.com/simplebar-react/-/simplebar-react-1.2.3.tgz#bd81fa9827628470e9470d06caef6ece15e1c882" + integrity sha512-1EOWJzFC7eqHUp1igD1/tb8GBv5aPQA5ZMvpeDnVkpNJ3jAuvmrL2kir3HuijlxhG7njvw9ssxjjBa89E5DrJg== + dependencies: + prop-types "^15.6.1" + simplebar "^4.2.3" + +simplebar@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/simplebar/-/simplebar-4.2.3.tgz#dac40aced299c17928329eab3d5e6e795fafc10c" + integrity sha512-9no0pK7/1y+8/oTF3sy/+kx0PjQ3uk4cYwld5F1CJGk2gx+prRyUq8GRfvcVLq5niYWSozZdX73a2wIr1o9l/g== + dependencies: + can-use-dom "^0.1.0" + core-js "^3.0.1" + lodash.debounce "^4.0.8" + lodash.memoize "^4.1.2" + lodash.throttle "^4.1.1" + resize-observer-polyfill "^1.5.1" + sisteransi@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.4.tgz#386713f1ef688c7c0304dc4c0632898941cad2e3" @@ -10178,6 +10805,11 @@ sourcemap-codec@^1.4.4: resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== +space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== + spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -10689,6 +11321,16 @@ timsort@^0.3.0: resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= +tiny-emitter@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + +tinycolor2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" + integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -10743,6 +11385,11 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI= + tough-cookie@^2.3.3, tough-cookie@^2.3.4: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -10820,6 +11467,11 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== +ts-dedent@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-1.1.1.tgz#68fad040d7dbd53a90f545b450702340e17d18f3" + integrity sha512-UGTRZu1evMw4uTPyYF66/KFd22XiU+jMaIuHrkIHQ2GivAXVlLV0v/vHrpOuTRf9BmpNHi/SO7Vd0rLu0y57jg== + ts-jest@^24.0.2: version "24.3.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" @@ -10836,7 +11488,7 @@ ts-jest@^24.0.2: semver "^5.5" yargs-parser "10.x" -tslib@1.10.0, tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: +tslib@1.10.0, tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== @@ -10882,6 +11534,11 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typed-styles@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" + integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -11038,7 +11695,7 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== -unquote@~1.1.1: +unquote@^1.1.0, unquote@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= @@ -11088,6 +11745,19 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" +use-callback-ref@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.2.1.tgz#898759ccb9e14be6c7a860abafa3ffbd826c89bb" + integrity sha512-C3nvxh0ZpaOxs9RCnWwAJ+7bJPwQI8LHF71LzbQ3BvzH5XkdtlkMadqElGevg5bYBDFip4sAnD4m06zAKebg1w== + +use-sidecar@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.2.tgz#e72f582a75842f7de4ef8becd6235a4720ad8af6" + integrity sha512-287RZny6m5KNMTb/Kq9gmjafi7lQL0YHO1lYolU6+tY1h9+Z3uCtkJJ3OSOq3INwYf2hBryCcDh4520AhJibMA== + dependencies: + detect-node "^2.0.4" + tslib "^1.9.3" + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -11199,6 +11869,13 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.x" +warning@^4.0.2, warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + wcwidth@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"