feat(react-dock): convert to TypeScript (#607)

* feature(react-dock): convert to TypeScript

* And that

* Fun

* pretty

* More fun

* Try that
This commit is contained in:
Nathan Bierema 2020-08-24 00:37:43 -04:00 committed by GitHub
parent 97adc01b78
commit 78ded9e0ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 251 additions and 118 deletions

View File

@ -27,7 +27,8 @@
"ts-node": "^9.0.0", "ts-node": "^9.0.0",
"typescript": "^3.9.7", "typescript": "^3.9.7",
"webpack": "^4.44.1", "webpack": "^4.44.1",
"webpack-cli": "^3.3.12" "webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}, },
"scripts": { "scripts": {
"lerna": "lerna", "lerna": "lerna",

View File

@ -1,8 +1,11 @@
{ {
"presets": ["@babel/preset-env", "@babel/preset-react"], "presets": [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [ "plugins": [
"@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-export-default-from",
"react-hot-loader/babel" "react-hot-loader/babel"
] ]
} }

View File

@ -0,0 +1,37 @@
module.exports = {
extends: '../../.eslintrc',
overrides: [
{
files: ['*.ts', '*.tsx'],
extends: '../../eslintrc.ts.react.base.json',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
},
{
files: ['test/*.ts', 'test/*.tsx'],
extends: '../../eslintrc.ts.react.jest.base.json',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./test/tsconfig.json'],
},
},
{
files: ['demo/**/*.ts', 'demo/**/*.tsx'],
extends: '../../eslintrc.ts.react.base.json',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./demo/tsconfig.json'],
},
},
{
files: ['webpack.config.ts'],
extends: '../../eslintrc.ts.base.json',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.webpack.json'],
},
},
],
};

View File

@ -39,24 +39,29 @@ const Remove = styled(BsX)`
cursor: pointer; cursor: pointer;
`; `;
const positions = ['left', 'top', 'right', 'bottom']; const positions = ['left', 'top', 'right', 'bottom'] as const;
const dimModes = ['transparent', 'none', 'opaque']; const dimModes = ['transparent', 'none', 'opaque'] as const;
class App extends Component { interface State {
constructor(props) { positionIdx: number;
super(props); dimModeIdx: number;
this.state = { isVisible: boolean;
positionIdx: 0, fluid: boolean;
dimModeIdx: 0, customAnimation: boolean;
isVisible: true, slow: boolean;
fluid: true, size: number;
customAnimation: false, }
slow: false,
size: 0.25,
};
}
componentDidMount() {} class App extends Component<never, State> {
state: State = {
positionIdx: 0,
dimModeIdx: 0,
isVisible: true,
fluid: true,
customAnimation: false,
slow: false,
size: 0.25,
};
render() { render() {
const duration = this.state.slow ? 2000 : 200; const duration = this.state.slow ? 2000 : 200;
@ -166,11 +171,11 @@ class App extends Component {
); );
} }
handleVisibleChange = (isVisible) => { handleVisibleChange = (isVisible: boolean) => {
this.setState({ isVisible }); this.setState({ isVisible });
}; };
handleSizeChange = (size) => { handleSizeChange = (size: number) => {
this.setState({ size }); this.setState({ size });
}; };

View File

@ -0,0 +1,4 @@
{
"extends": "../../../tsconfig.react.base.json",
"include": ["../src", "src"]
}

View File

@ -0,0 +1,3 @@
module.exports = {
preset: 'ts-jest',
};

View File

@ -2,63 +2,65 @@
"name": "react-dock", "name": "react-dock",
"version": "0.2.4", "version": "0.2.4",
"description": "Resizable dockable react component", "description": "Resizable dockable react component",
"scripts": {
"build-lib": "babel src --out-dir lib",
"build-demo": "NODE_ENV=production webpack -p",
"stats": "webpack --profile --json > stats.json",
"start": "webpack-dev-server",
"preversion": "npm run lint && npm run test",
"version": "npm run build-demo && git add -A .",
"postversion": "git push",
"prepublish": "npm run build-lib",
"test": "jest"
},
"main": "lib/index.js",
"files": [
"lib",
"src"
],
"repository": {
"type": "git",
"url": "https://github.com/reduxjs/redux-devtools.git"
},
"keywords": [ "keywords": [
"react", "react",
"reactjs", "reactjs",
"dock", "dock",
"sidebar" "sidebar"
], ],
"author": "Alexander <alexkuz@gmail.com> (http://kuzya.org/)", "homepage": "https://github.com/reduxjs/redux-devtools",
"license": "MIT",
"bugs": { "bugs": {
"url": "https://github.com/reduxjs/redux-devtools/issues" "url": "https://github.com/reduxjs/redux-devtools/issues"
}, },
"homepage": "https://github.com/reduxjs/redux-devtools", "license": "MIT",
"author": "Alexander <alexkuz@gmail.com> (http://kuzya.org/)",
"files": [
"lib",
"src"
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/reduxjs/redux-devtools.git"
},
"scripts": {
"start": "webpack-dev-server",
"stats": "webpack --profile --json > stats.json",
"build:demo": "NODE_ENV=production webpack -p",
"build": "npm run build:types && npm run build:js",
"build:types": "tsc --emitDeclarationOnly",
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
"clean": "rimraf lib umd",
"test": "jest",
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch",
"preversion": "npm run type-check && npm run lint && npm run test",
"prepublishOnly": "npm run clean && npm run build"
},
"dependencies": {
"@types/prop-types": "^15.7.3",
"lodash.debounce": "^4.0.8",
"prop-types": "^15.7.2"
},
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.10.5", "@types/lodash.debounce": "^4.0.6",
"@babel/core": "^7.11.1", "@types/react": "^16.9.46",
"@babel/plugin-proposal-class-properties": "^7.10.4", "@types/react-dom": "^16.9.8",
"@babel/plugin-proposal-export-default-from": "^7.10.4", "@types/react-test-renderer": "^16.9.3",
"@babel/preset-env": "^7.11.0", "@types/styled-components": "^5.1.2",
"@babel/preset-react": "^7.10.4",
"babel-loader": "^8.1.0",
"react": "^16.13.1", "react": "^16.13.1",
"react-bootstrap": "^1.3.0", "react-bootstrap": "^1.3.0",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-hot-loader": "^4.12.21", "react-hot-loader": "^4.12.21",
"react-icons": "^3.10.0", "react-icons": "^3.10.0",
"react-pure-render": "^1.0.2",
"react-test-renderer": "^16.13.1", "react-test-renderer": "^16.13.1",
"styled-components": "^5.1.1", "styled-components": "^5.1.1"
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": "^16.3.18",
"react": "^16.3.0" "react": "^16.3.0"
},
"dependencies": {
"lodash.debounce": "^4.0.8",
"prop-types": "^15.7.2"
} }
} }

View File

@ -3,8 +3,12 @@ import PropTypes from 'prop-types';
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce';
import autoprefix from './autoprefix'; import autoprefix from './autoprefix';
function autoprefixes(styles) { interface Styles {
return Object.keys(styles).reduce( [key: string]: React.CSSProperties;
}
function autoprefixes(styles: Styles) {
return Object.keys(styles).reduce<Styles>(
(obj, key) => ((obj[key] = autoprefix(styles[key])), obj), (obj, key) => ((obj[key] = autoprefix(styles[key])), obj),
{} {}
); );
@ -74,21 +78,21 @@ const styles = autoprefixes({
}, },
}); });
function getTransitions(duration) { function getTransitions(duration: number) {
return ['left', 'top', 'width', 'height'].map( return ['left', 'top', 'width', 'height'].map(
(p) => `${p} ${duration / 1000}s ease-out` (p) => `${p} ${duration / 1000}s ease-out`
); );
} }
function getDockStyles( function getDockStyles(
{ fluid, dockStyle, dockHiddenStyle, duration, position, isVisible }, { fluid, dockStyle, dockHiddenStyle, duration, position, isVisible }: Props,
{ size, isResizing, fullWidth, fullHeight } { size, isResizing, fullWidth, fullHeight }: State
) { ) {
let posStyle; let posStyle;
const absSize = fluid ? size * 100 + '%' : size + 'px'; const absSize = fluid ? `${size * 100}%` : `${size}px`;
function getRestSize(fullSize) { function getRestSize(fullSize: number) {
return fluid ? 100 - size * 100 + '%' : fullSize - size + 'px'; return fluid ? `${100 - size * 100}%` : `${fullSize - size}px`;
} }
switch (position) { switch (position) {
@ -139,8 +143,8 @@ function getDockStyles(
} }
function getDimStyles( function getDimStyles(
{ dimMode, dimStyle, duration, isVisible }, { dimMode, dimStyle, duration, isVisible }: Props,
{ isTransitionStarted } { isTransitionStarted }: State
) { ) {
return [ return [
styles.dim, styles.dim,
@ -155,7 +159,7 @@ function getDimStyles(
]; ];
} }
function getResizerStyles(position) { function getResizerStyles(position: 'left' | 'right' | 'top' | 'bottom') {
let resizerStyle; let resizerStyle;
const size = 10; const size = 10;
@ -201,23 +205,57 @@ function getResizerStyles(position) {
return [styles.resizer, autoprefix(resizerStyle)]; return [styles.resizer, autoprefix(resizerStyle)];
} }
function getFullSize(position, fullWidth, fullHeight) { function getFullSize(
position: 'left' | 'right' | 'top' | 'bottom',
fullWidth: number,
fullHeight: number
) {
return position === 'left' || position === 'right' ? fullWidth : fullHeight; return position === 'left' || position === 'right' ? fullWidth : fullHeight;
} }
export default class Dock extends Component { interface Props {
constructor(props) { position: 'left' | 'right' | 'top' | 'bottom';
super(props); zIndex: number;
this.state = { fluid: boolean;
isControlled: typeof props.size !== 'undefined', size?: number;
size: props.size || props.defaultSize, defaultSize: number;
isDimHidden: !props.isVisible, dimMode: 'none' | 'transparent' | 'opaque';
fullWidth: typeof window !== 'undefined' && window.innerWidth, isVisible?: boolean;
fullHeight: typeof window !== 'undefined' && window.innerHeight, onVisibleChange?: (isVisible: boolean) => void;
isTransitionStarted: false, onSizeChange?: (size: number) => void;
isWindowResizing: false, dimStyle?: React.CSSProperties | null;
}; dockStyle?: React.CSSProperties | null;
} dockHiddenStyle?: React.CSSProperties | null;
duration: number;
children?: React.FunctionComponent<{
position: 'left' | 'right' | 'top' | 'bottom';
isResizing: boolean | undefined;
size: number;
isVisible: boolean | undefined;
}>;
}
interface State {
isControlled: boolean;
size: number;
isDimHidden: boolean;
fullWidth: number;
fullHeight: number;
isTransitionStarted: boolean;
isWindowResizing: unknown;
isResizing?: boolean;
}
export default class Dock extends Component<Props, State> {
state: State = {
isControlled: typeof this.props.size !== 'undefined',
size: this.props.size || this.props.defaultSize,
isDimHidden: !this.props.isVisible,
fullWidth: window.innerWidth,
fullHeight: window.innerHeight,
isTransitionStarted: false,
isWindowResizing: false,
};
static propTypes = { static propTypes = {
position: PropTypes.oneOf(['left', 'right', 'top', 'bottom']), position: PropTypes.oneOf(['left', 'right', 'top', 'bottom']),
@ -250,9 +288,7 @@ export default class Dock extends Component {
window.addEventListener('mousemove', this.handleMouseMove); window.addEventListener('mousemove', this.handleMouseMove);
window.addEventListener('resize', this.handleResize); window.addEventListener('resize', this.handleResize);
if (!window.fullWidth) { this.updateWindowSize();
this.updateWindowSize();
}
} }
componentWillUnmount() { componentWillUnmount() {
@ -263,12 +299,12 @@ export default class Dock extends Component {
window.removeEventListener('resize', this.handleResize); window.removeEventListener('resize', this.handleResize);
} }
UNSAFE_componentWillReceiveProps(nextProps) { UNSAFE_componentWillReceiveProps(nextProps: Props) {
const isControlled = typeof nextProps.size !== 'undefined'; const isControlled = typeof nextProps.size !== 'undefined';
this.setState({ isControlled }); this.setState({ isControlled });
if (isControlled && this.props.size !== nextProps.size) { if (isControlled && nextProps.size && this.props.size !== nextProps.size) {
this.setState({ size: nextProps.size }); this.setState({ size: nextProps.size });
} else if (this.props.fluid !== nextProps.fluid) { } else if (this.props.fluid !== nextProps.fluid) {
this.updateSize(nextProps); this.updateSize(nextProps);
@ -281,7 +317,7 @@ export default class Dock extends Component {
} }
} }
updateSize(props) { updateSize(props: Props) {
const { fullWidth, fullHeight } = this.state; const { fullWidth, fullHeight } = this.state;
this.setState({ this.setState({
@ -291,7 +327,7 @@ export default class Dock extends Component {
}); });
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps: Props) {
if (this.props.isVisible !== prevProps.isVisible) { if (this.props.isVisible !== prevProps.isVisible) {
if (!this.props.isVisible) { if (!this.props.isVisible) {
window.setTimeout(() => this.hideDim(), this.props.duration); window.setTimeout(() => this.hideDim(), this.props.duration);
@ -367,7 +403,7 @@ export default class Dock extends Component {
} }
}; };
updateWindowSize = (windowResize) => { updateWindowSize = (windowResize?: true) => {
const sizeState = { const sizeState = {
fullWidth: window.innerWidth, fullWidth: window.innerWidth,
fullHeight: window.innerHeight, fullHeight: window.innerHeight,
@ -407,18 +443,18 @@ export default class Dock extends Component {
this.setState({ isResizing: false }); this.setState({ isResizing: false });
}; };
handleMouseMove = (e) => { handleMouseMove = (e: MouseEvent | TouchEvent) => {
if (!this.state.isResizing || this.state.isWindowResizing) return; if (!this.state.isResizing || this.state.isWindowResizing) return;
if (!e.touches) e.preventDefault(); if (!(e as TouchEvent).touches) e.preventDefault();
const { position, fluid } = this.props; const { position, fluid } = this.props;
const { fullWidth, fullHeight, isControlled } = this.state; const { fullWidth, fullHeight, isControlled } = this.state;
let { clientX: x, clientY: y } = e; let { clientX: x, clientY: y } = e as MouseEvent;
if (e.touches) { if ((e as TouchEvent).touches) {
x = e.touches[0].clientX; x = (e as TouchEvent).touches[0].clientX;
y = e.touches[0].clientY; y = (e as TouchEvent).touches[0].clientY;
} }
let size; let size;

View File

@ -1,6 +1,8 @@
// Same as https://github.com/SimenB/react-vendor-prefixes/blob/master/src/index.js, // Same as https://github.com/SimenB/react-vendor-prefixes/blob/master/src/index.js,
// but dumber // but dumber
import { CSSProperties } from 'react';
const vendorSpecificProperties = [ const vendorSpecificProperties = [
'animation', 'animation',
'animationDelay', 'animationDelay',
@ -34,8 +36,8 @@ const vendorSpecificProperties = [
const prefixes = ['Moz', 'Webkit', 'ms', 'O']; const prefixes = ['Moz', 'Webkit', 'ms', 'O'];
function prefixProp(key, value) { function prefixProp<Value>(key: string, value: Value) {
return prefixes.reduce( return prefixes.reduce<{ [key: string]: Value }>(
(obj, pre) => ( (obj, pre) => (
(obj[pre + key[0].toUpperCase() + key.substr(1)] = value), obj (obj[pre + key[0].toUpperCase() + key.substr(1)] = value), obj
), ),
@ -43,13 +45,13 @@ function prefixProp(key, value) {
); );
} }
export default function autoprefix(style) { export default function autoprefix(style: CSSProperties) {
return Object.keys(style).reduce( return Object.keys(style).reduce(
(obj, key) => (obj, key) =>
vendorSpecificProperties.indexOf(key) !== -1 vendorSpecificProperties.indexOf(key) !== -1
? { ? {
...obj, ...obj,
...prefixProp(key, style[key]), ...prefixProp(key, style[key as keyof CSSProperties]),
} }
: obj, : obj,
style style

View File

@ -1 +0,0 @@
export default from './Dock';

View File

@ -0,0 +1,2 @@
import Dock from './Dock';
export default Dock;

View File

@ -1,14 +1,14 @@
import React from 'react'; import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow'; import { createRenderer } from 'react-test-renderer/shallow';
import Dock from '../src/Dock'; import Dock from '../src/Dock';
describe('Dock component', function () { describe('Dock component', function () {
it('should have shallow rendering', function () { it('should have shallow rendering', function () {
const shallowRenderer = new ShallowRenderer(); const renderer = createRenderer();
const DockEl = <Dock />; const DockEl = <Dock />;
shallowRenderer.render(DockEl); renderer.render(DockEl);
const result = shallowRenderer.getRenderOutput(); const result = renderer.getRenderOutput();
expect(DockEl.props).toEqual({ expect(DockEl.props).toEqual({
position: 'left', position: 'left',

View File

@ -0,0 +1,4 @@
{
"extends": "../../../tsconfig.react.base.json",
"include": ["../src", "."]
}

View File

@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.react.base.json",
"compilerOptions": {
"outDir": "lib"
},
"include": ["src"]
}

View File

@ -0,0 +1,4 @@
{
"extends": "../../tsconfig.base.json",
"include": ["webpack.config.ts"]
}

View File

@ -1,7 +1,7 @@
var path = require('path'); import * as path from 'path';
var webpack = require('webpack'); import * as webpack from 'webpack';
var isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
module.exports = { module.exports = {
mode: isProduction ? 'production' : 'development', mode: isProduction ? 'production' : 'development',
@ -20,12 +20,12 @@ module.exports = {
}, },
plugins: isProduction ? [] : [new webpack.HotModuleReplacementPlugin()], plugins: isProduction ? [] : [new webpack.HotModuleReplacementPlugin()],
resolve: { resolve: {
extensions: ['.js', '.jsx'], extensions: ['.js', '.jsx', '.ts', '.tsx'],
}, },
module: { module: {
rules: [ rules: [
{ {
test: /\.jsx?$/, test: /\.(js|ts)x?$/,
loader: 'babel-loader', loader: 'babel-loader',
include: [ include: [
path.join(__dirname, 'src'), path.join(__dirname, 'src'),
@ -37,7 +37,6 @@ module.exports = {
devServer: isProduction devServer: isProduction
? null ? null
: { : {
quiet: true,
publicPath: '/static/', publicPath: '/static/',
port: 3000, port: 3000,
contentBase: './demo/', contentBase: './demo/',

View File

@ -51,7 +51,7 @@
"react-base16-styling": "^0.7.0" "react-base16-styling": "^0.7.0"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^16.3.18", "@types/react": "^16.9.46",
"@types/react-test-renderer": "^16.9.3", "@types/react-test-renderer": "^16.9.3",
"react": "^16.13.1", "react": "^16.13.1",
"react-test-renderer": "^16.13.1" "react-test-renderer": "^16.13.1"

View File

@ -6,6 +6,8 @@
"strict": true, "strict": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"esModuleInterop": true, "esModuleInterop": true,
"forceConsistentCasingInFileNames": true "forceConsistentCasingInFileNames": true,
// See https://github.com/DefinitelyTyped/DefinitelyTyped/issues/33311
"types": ["node", "jest"]
} }
} }

View File

@ -3136,7 +3136,7 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/hoist-non-react-statics@^3.3.0": "@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.0":
version "3.3.1" version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
@ -3217,6 +3217,13 @@
dependencies: dependencies:
"@types/lodash" "*" "@types/lodash" "*"
"@types/lodash.debounce@^4.0.6":
version "4.0.6"
resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.6.tgz#c5a2326cd3efc46566c47e4c0aa248dc0ee57d60"
integrity sha512-4WTmnnhCfDvvuLMaF3KV4Qfki93KebocUF45msxhYyjMttZDQYzHkO639ohhk8+oco2cluAFL3t5+Jn4mleylQ==
dependencies:
"@types/lodash" "*"
"@types/lodash@*", "@types/lodash@^4.14.159": "@types/lodash@*", "@types/lodash@^4.14.159":
version "4.14.159" version "4.14.159"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.159.tgz#61089719dc6fdd9c5cb46efc827f2571d1517065" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.159.tgz#61089719dc6fdd9c5cb46efc827f2571d1517065"
@ -3294,6 +3301,13 @@
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-native@*":
version "0.63.8"
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.8.tgz#73ec087122c64c309eeaf150b565b8d755f0fb1f"
integrity sha512-QRwGFRTyGafRVTUS+0GYyJrlpmS3boyBaFI0ULSc+mh/lQNxrzbdQvoL2k5X7+t9hxyqA4dTQAlP6l0ir/fNJQ==
dependencies:
"@types/react" "*"
"@types/react-redux@^7.1.9": "@types/react-redux@^7.1.9":
version "7.1.9" version "7.1.9"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.9.tgz#280c13565c9f13ceb727ec21e767abe0e9b4aec3" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.9.tgz#280c13565c9f13ceb727ec21e767abe0e9b4aec3"
@ -3344,6 +3358,16 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
"@types/styled-components@^5.1.2":
version "5.1.2"
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.2.tgz#652af475b4af917b355ea1c3068acae63d46455f"
integrity sha512-HNocYLfrsnNNm8NTS/W53OERSjRA8dx5Bn6wBd2rXXwt4Z3s+oqvY6/PbVt3e6sgtzI63GX//WiWiRhWur08qQ==
dependencies:
"@types/hoist-non-react-statics" "*"
"@types/react" "*"
"@types/react-native" "*"
csstype "^3.0.2"
"@types/tapable@*", "@types/tapable@^1.0.5": "@types/tapable@*", "@types/tapable@^1.0.5":
version "1.0.6" version "1.0.6"
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74"