From 67bf6e64a01afd399525ea6ae873557782110eda Mon Sep 17 00:00:00 2001 From: Giulio Zausa Date: Sat, 12 Sep 2020 22:29:41 +0200 Subject: [PATCH 1/2] Demo to support alias --- examples/config-overrides.js | 31 ++++++++++++++++++++++--------- examples/package.json | 1 - examples/src/App.js | 2 +- examples/src/components/Text.js | 2 +- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/examples/config-overrides.js b/examples/config-overrides.js index 1de95d5..bf0d6cc 100644 --- a/examples/config-overrides.js +++ b/examples/config-overrides.js @@ -1,13 +1,26 @@ -const { override, addWebpackAlias, addWebpackPlugin } = require('customize-cra') +const { override, addWebpackAlias, addWebpackPlugin, removeModuleScopePlugin, babelInclude } = require('customize-cra') const { addReactRefresh } = require('customize-cra-react-refresh') const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin const path = require('path') -module.exports = override( - addReactRefresh(), - addWebpackAlias({ - three$: path.resolve('./src/utils/three.js'), - '../../../build/three.module.js': path.resolve('./src/utils/three.js'), - }), - //addWebpackPlugin(new BundleAnalyzerPlugin()) -) +module.exports = (config, env) => { + config.resolve.extensions = [...config.resolve.extensions, '.ts', '.tsx'] + return override( + addReactRefresh(), + removeModuleScopePlugin(), + babelInclude([path.resolve('src'), path.resolve('../src')]), + addWebpackAlias({ + 'react-three-flex': path.resolve('../src/index'), + postprocessing: path.resolve('node_modules/postprocessing'), + react: path.resolve('node_modules/react'), + 'react-dom': path.resolve('node_modules/react-dom'), + scheduler: path.resolve('node_modules/scheduler'), + 'react-scheduler': path.resolve('node_modules/react-scheduler'), + 'react-three-fiber': path.resolve('node_modules/react-three-fiber'), + drei: path.resolve('node_modules/drei'), + three$: path.resolve('./src/utils/three.js'), + '../../../build/three.module.js': path.resolve('./src/utils/three.js'), + }), + //addWebpackPlugin(new BundleAnalyzerPlugin()) + )(config, env) +} diff --git a/examples/package.json b/examples/package.json index d5ad511..026f8f7 100644 --- a/examples/package.json +++ b/examples/package.json @@ -12,7 +12,6 @@ "react-postprocessing": "1.2.0", "react-scripts": "3.4.3", "react-three-fiber": "5.0.0-beta.12", - "react-three-flex": "0.5.2", "three": "0.120.1", "troika-three-text": "https://github.com/jmatsushita/troika-three-text", "zustand": "3.1.0" diff --git a/examples/src/App.js b/examples/src/App.js index dfeda31..9dfbd1a 100755 --- a/examples/src/App.js +++ b/examples/src/App.js @@ -1,7 +1,7 @@ import * as THREE from 'three' import React, { Suspense, useEffect, useRef, useState, useCallback, useLayoutEffect } from 'react' import { Canvas, useThree, useFrame, useLoader } from 'react-three-fiber' -import { Flex, Box, useFlexSize } from 'react-three-flex' +import { Flex, Box, useFlexSize } from '../../src/index' import { useAspect } from 'drei/misc/useAspect' import { Line } from 'drei/abstractions/Line' import { Loader } from 'drei/prototyping/Loader' diff --git a/examples/src/components/Text.js b/examples/src/components/Text.js index 373f85c..9daf76f 100755 --- a/examples/src/components/Text.js +++ b/examples/src/components/Text.js @@ -1,5 +1,5 @@ import React from 'react' -import { useReflow } from 'react-three-flex' +import { useReflow } from '../../../src/index' import { Text as TextImpl } from 'drei/abstractions/Text' export default function Text({ bold = false, anchorX = 'left', anchorY = 'top', textAlign = 'left', ...props }) { From 0d9c7d8a76b5d70263af873da8f25c9632dd2f0c Mon Sep 17 00:00:00 2001 From: Giulio Zausa Date: Sat, 12 Sep 2020 22:32:21 +0200 Subject: [PATCH 2/2] Move to yoga-wasm-slim --- .size-snapshot.json | 18 ++-- examples/public/yoga.wasm | Bin 0 -> 54177 bytes examples/yarn.lock | 19 ---- package.json | 3 +- src/Box.tsx | 17 +-- src/Flex.tsx | 51 +++++---- src/context.ts | 8 +- src/props.ts | 18 +--- src/util.ts | 210 +++++++++++++++++++++++--------------- yarn.lock | 17 +-- 10 files changed, 194 insertions(+), 167 deletions(-) create mode 100644 examples/public/yoga.wasm diff --git a/.size-snapshot.json b/.size-snapshot.json index 3c5daaf..121850e 100644 --- a/.size-snapshot.json +++ b/.size-snapshot.json @@ -1,21 +1,21 @@ { "index.js": { - "bundled": 14895, - "minified": 7820, - "gzipped": 2675, + "bundled": 16595, + "minified": 8974, + "gzipped": 2897, "treeshaked": { "rollup": { - "code": 126, - "import_statements": 126 + "code": 151, + "import_statements": 151 }, "webpack": { - "code": 1242 + "code": 1300 } } }, "index.cjs.js": { - "bundled": 21462, - "minified": 10644, - "gzipped": 3409 + "bundled": 24156, + "minified": 12326, + "gzipped": 3877 } } diff --git a/examples/public/yoga.wasm b/examples/public/yoga.wasm new file mode 100644 index 0000000000000000000000000000000000000000..29f7ef27410dd7075665cb1c48dfc1d439f9700f GIT binary patch literal 54177 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

}&lMQ%BYm~>9Ua74K7rP711{6aN%<$5=gwr8 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 uXbb@dt|-`9B=%Gp{() - const node = useMemo(() => Yoga.Node.create(), []) + const node = useMemo(() => yoga._YGNodeNew(), []) const reflow = useReflow() useLayoutEffect(() => { - setYogaProperties(node, flexProps, scaleFactor) + setYogaProperties(yoga, node, flexProps, scaleFactor) }, [flexProps, node, scaleFactor]) // Make child known to the parents yoga instance *before* it calculates layout useLayoutEffect(() => { if (!group.current || !parent) return - parent.insertChild(node, parent.getChildCount()) + yoga._YGNodeInsertChild(parent, node, yoga._YGNodeGetChildCount(parent)) registerBox(node, group.current, flexProps, centerAnchor) // Remove child on unmount return () => { - parent.removeChild(node) + yoga._YGNodeRemoveChild(parent, node) unregisterBox(node) } }, [node, parent, flexProps, centerAnchor, registerBox, unregisterBox]) @@ -215,10 +216,10 @@ export function Box({ const epsilon = 1 / scaleFactor useFrame(() => { const width = - (typeof flexProps.width === 'number' ? flexProps.width : null) || node.getComputedWidth().valueOf() / scaleFactor + (typeof flexProps.width === 'number' ? flexProps.width : null) || yoga._YGNodeLayoutGetWidth(node) / scaleFactor const height = (typeof flexProps.height === 'number' ? flexProps.height : null) || - node.getComputedHeight().valueOf() / scaleFactor + yoga._YGNodeLayoutGetHeight(node) / scaleFactor if (Math.abs(width - size[0]) > epsilon || Math.abs(height - size[1]) > epsilon) { setSize([width, height]) diff --git a/src/Flex.tsx b/src/Flex.tsx index 0f78f8b..2002f2e 100644 --- a/src/Flex.tsx +++ b/src/Flex.tsx @@ -1,9 +1,18 @@ import React, { useLayoutEffect, useMemo, useCallback, PropsWithChildren, useRef } from 'react' -import Yoga, { YogaNode } from 'yoga-layout-prebuilt' +import { YGNodeRef, CONSTANTS } from 'yoga-wasm-slim' import { Vector3, Group, Box3 } from 'three' import { useFrame, useThree, ReactThreeFiber } from 'react-three-fiber' -import { setYogaProperties, rmUndefFromObj, vectorFromObject, Axis, getDepthAxis, getFlex2DSize } from './util' +import { + setYogaProperties, + rmUndefFromObj, + vectorFromObject, + Axis, + getDepthAxis, + getFlex2DSize, + useYogaAsync, + setPropertyString, +} from './util' import { boxContext, flexContext, SharedFlexContext, SharedBoxContext } from './context' import type { R3FlexProps, FlexYogaDirection, FlexPlane } from './props' @@ -196,9 +205,9 @@ export function Flex({ ]) // Keeps track of the yoga nodes of the children and the related wrapper groups - const boxesRef = useRef<{ node: YogaNode; group: Group; flexProps: R3FlexProps; centerAnchor: boolean }[]>([]) + const boxesRef = useRef<{ node: YGNodeRef; group: Group; flexProps: R3FlexProps; centerAnchor: boolean }[]>([]) const registerBox = useCallback( - (node: YogaNode, group: Group, flexProps: R3FlexProps, centerAnchor: boolean = false) => { + (node: YGNodeRef, group: Group, flexProps: R3FlexProps, centerAnchor: boolean = false) => { const i = boxesRef.current.findIndex((b) => b.node === node) if (i !== -1) { boxesRef.current.splice(i, 1) @@ -207,17 +216,19 @@ export function Flex({ }, [] ) - const unregisterBox = useCallback((node: YogaNode) => { + const unregisterBox = useCallback((node: YGNodeRef) => { const i = boxesRef.current.findIndex((b) => b.node === node) if (i !== -1) { boxesRef.current.splice(i, 1) } }, []) + const yoga = useYogaAsync('./') + // Reference to the yoga native node - const node = useMemo(() => Yoga.Node.create(), []) + const node = useMemo(() => yoga._YGNodeNew(), []) useLayoutEffect(() => { - setYogaProperties(node, flexProps, scaleFactor) + setYogaProperties(yoga, node, flexProps, scaleFactor) }, [node, flexProps, scaleFactor]) // Mechanism for invalidating and recalculating layout @@ -241,7 +252,11 @@ export function Flex({ const depthAxis = getDepthAxis(plane) const [flexWidth, flexHeight] = getFlex2DSize(size, plane) const yogaDirection_ = - yogaDirection === 'ltr' ? Yoga.DIRECTION_LTR : yogaDirection === 'rtl' ? Yoga.DIRECTION_RTL : yogaDirection + yogaDirection === 'ltr' + ? CONSTANTS.DIRECTION_LTR + : yogaDirection === 'rtl' + ? CONSTANTS.DIRECTION_RTL + : yogaDirection // Shared context for flex and box const sharedFlexContext = useMemo( @@ -263,23 +278,16 @@ export function Flex({ function reflow() { // Recalc all the sizes boxesRef.current.forEach(({ group, node, flexProps }) => { - const scaledWidth = typeof flexProps.width === 'number' ? flexProps.width * scaleFactor : flexProps.width - const scaledHeight = typeof flexProps.height === 'number' ? flexProps.height * scaleFactor : flexProps.height - - if (scaledWidth !== undefined && scaledHeight !== undefined) { - // Forced size, no need to calculate bounding box - node.setWidth(scaledWidth) - node.setHeight(scaledHeight) - } else { + if (flexProps.width === undefined || flexProps.height === undefined) { // No size specified, calculate bounding box boundingBox.setFromObject(group).getSize(vec) - node.setWidth(scaledWidth || vec[mainAxis] * scaleFactor) - node.setHeight(scaledHeight || vec[crossAxis] * scaleFactor) + setPropertyString(yoga, node, 'Width', flexProps.width || vec[mainAxis], scaleFactor) + setPropertyString(yoga, node, 'Height', flexProps.height || vec[crossAxis], scaleFactor) } }) // Perform yoga layout calculation - node.calculateLayout(flexWidth * scaleFactor, flexHeight * scaleFactor, yogaDirection_) + yoga._YGNodeCalculateLayout(node, flexWidth * scaleFactor, flexHeight * scaleFactor, yogaDirection_) let minX = 0 let maxX = 0 @@ -288,7 +296,10 @@ export function Flex({ // Reposition after recalculation boxesRef.current.forEach(({ group, node, centerAnchor }) => { - const { left, top, width, height } = node.getComputedLayout() + const left = yoga._YGNodeLayoutGetLeft(node) + const top = yoga._YGNodeLayoutGetTop(node) + const width = yoga._YGNodeLayoutGetWidth(node) + const height = yoga._YGNodeLayoutGetHeight(node) const position = vectorFromObject({ [mainAxis]: (left + (centerAnchor ? width / 2 : 0)) / scaleFactor, [crossAxis]: -(top + (centerAnchor ? height / 2 : 0)) / scaleFactor, diff --git a/src/context.ts b/src/context.ts index b016dc2..f04f707 100644 --- a/src/context.ts +++ b/src/context.ts @@ -1,13 +1,13 @@ import { createContext } from 'react' -import { YogaNode } from 'yoga-layout-prebuilt' +import { YGNodeRef } from 'yoga-wasm-slim' import { Group } from 'three' import { R3FlexProps } from './props' export interface SharedFlexContext { scaleFactor: number requestReflow(): void - registerBox(node: YogaNode, group: Group, flexProps: R3FlexProps, centerAnchor?: boolean): void - unregisterBox(node: YogaNode): void + registerBox(node: YGNodeRef, group: Group, flexProps: R3FlexProps, centerAnchor?: boolean): void + unregisterBox(node: YGNodeRef): void } const initialSharedFlexContext: SharedFlexContext = { @@ -26,7 +26,7 @@ const initialSharedFlexContext: SharedFlexContext = { export const flexContext = createContext(initialSharedFlexContext) export interface SharedBoxContext { - node: YogaNode | null + node: YGNodeRef | null size: [number, number] } diff --git a/src/props.ts b/src/props.ts index 551735f..eff66fa 100644 --- a/src/props.ts +++ b/src/props.ts @@ -1,23 +1,13 @@ -import { YogaFlexDirection, YogaAlign, YogaJustifyContent, YogaFlexWrap, YogaDirection } from 'yoga-layout-prebuilt' - -export type FlexYogaDirection = YogaDirection | 'ltr' | 'rtl' +export type FlexYogaDirection = 'ltr' | 'rtl' export type FlexPlane = 'xy' | 'yz' | 'xz' export type Value = string | number -export type FlexDirection = YogaFlexDirection | 'row' | 'column' | 'row-reverse' | 'column-reverse' +export type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse' -export type JustifyContent = - | YogaJustifyContent - | 'center' - | 'flex-end' - | 'flex-start' - | 'space-between' - | 'space-evenly' - | 'space-around' +export type JustifyContent = 'center' | 'flex-end' | 'flex-start' | 'space-between' | 'space-evenly' | 'space-around' export type Align = - | YogaAlign | 'auto' | 'baseline' | 'center' @@ -27,7 +17,7 @@ export type Align = | 'space-between' | 'stretch' -export type FlexWrap = YogaFlexWrap | 'no-wrap' | 'wrap' | 'wrap-reverse' +export type FlexWrap = 'no-wrap' | 'wrap' | 'wrap-reverse' export type R3FlexProps = Partial<{ // Align diff --git a/src/util.ts b/src/util.ts index 69b426a..7cd189c 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,93 +1,143 @@ import { Vector3 } from 'three' -import Yoga, { YogaNode } from 'yoga-layout-prebuilt' +import Yoga, { YogaApi, YGNodeRef, CONSTANTS } from 'yoga-wasm-slim' +import usePromise from 'react-promise-suspense' import { R3FlexProps, FlexPlane } from './props' +let yogaGlobalInstance: YogaApi | null = null +export function useYogaAsync(path: string): YogaApi { + return usePromise( + async (path: string) => { + if (!yogaGlobalInstance) { + const yoga = await Yoga({ locateFile: (file) => path + file }) + yogaGlobalInstance = yoga + } + return yogaGlobalInstance + }, + [path] + ) +} + export const capitalize = (s: string) => s[0].toUpperCase() + s.slice(1) export const jsxPropToYogaProp = (s: string) => s.toUpperCase().replace('-', '_') -export const setYogaProperties = (node: YogaNode, props: R3FlexProps, scaleFactor: number) => { +export function setPropertyString( + yogaInstance: YogaApi, + node: YGNodeRef, + name: string, + value: string | number, + scaleFactor: number, + ...additionalParams: any[] +) { + if (typeof value === 'number') { + ;(yogaInstance as any)[`_YGNodeStyleSet${name}`](node, ...additionalParams, value * scaleFactor) + } else if (value.endsWith('%')) { + ;(yogaInstance as any)[`_YGNodeStyleSet${name}Percent`](node, ...additionalParams, parseFloat(value)) + } else if (value === 'auto') { + ;(yogaInstance as any)[`_YGNodeStyleSet${name}Auto`](node, ...additionalParams) + } else if (value.endsWith('px')) { + ;(yogaInstance as any)[`_YGNodeStyleSet${name}`](node, ...additionalParams, parseFloat(value) * scaleFactor) + } +} + +export const setYogaProperties = (yogaInstance: YogaApi, node: YGNodeRef, props: R3FlexProps, scaleFactor: number) => { return Object.keys(props).forEach((name) => { const value = props[name as keyof R3FlexProps] - if (typeof value === 'string') { - switch (name) { - case 'flexDir': - case 'dir': - case 'flexDirection': - return node.setFlexDirection((Yoga as any)[`FLEX_DIRECTION_${jsxPropToYogaProp(value)}`]) - case 'align': - case 'alignItems': - return node.setAlignItems((Yoga as any)[`ALIGN_${jsxPropToYogaProp(value)}`]) - case 'justify': - case 'justifyContent': - return node.setJustifyContent((Yoga as any)[`JUSTIFY_${jsxPropToYogaProp(value)}`]) - case 'wrap': - case 'flexWrap': - return node.setFlexWrap((Yoga as any)[`WRAP_${jsxPropToYogaProp(value)}`]) - case 'basis': - case 'flexBasis': - return node.setFlexBasis(value) - - default: - return (node[`set${capitalize(name)}` as keyof YogaNode] as any)(value) - } - } else if (typeof value === 'number') { - const scaledValue = value * scaleFactor - switch (name) { - case 'basis': - case 'flexBasis': - return node.setFlexBasis(scaledValue) - case 'grow': - case 'flexGrow': - return node.setFlexGrow(scaledValue) - case 'shrink': - case 'flexShrink': - return node.setFlexShrink(scaledValue) - case 'align': - return node.setAlignItems(value as any) - case 'justify': - return node.setJustifyContent(value as any) - case 'flexDir': - case 'dir': - return node.setFlexDirection(value as any) - case 'wrap': - return node.setFlexWrap(value as any) - case 'padding': - case 'p': - return node.setPadding(Yoga.EDGE_ALL, scaledValue) - case 'paddingLeft': - case 'pl': - return node.setPadding(Yoga.EDGE_LEFT, scaledValue) - case 'paddingRight': - case 'pr': - return node.setPadding(Yoga.EDGE_RIGHT, scaledValue) - case 'paddingTop': - case 'pt': - return node.setPadding(Yoga.EDGE_TOP, scaledValue) - case 'paddingBottom': - case 'pb': - return node.setPadding(Yoga.EDGE_BOTTOM, scaledValue) - - case 'margin': - case 'm': - return node.setMargin(Yoga.EDGE_ALL, scaledValue) - case 'marginLeft': - case 'ml': - return node.setMargin(Yoga.EDGE_LEFT, scaledValue) - case 'marginRight': - case 'mr': - return node.setMargin(Yoga.EDGE_RIGHT, scaledValue) - case 'marginTop': - case 'mt': - return node.setMargin(Yoga.EDGE_TOP, scaledValue) - case 'marginBottom': - case 'mb': - return node.setMargin(Yoga.EDGE_BOTTOM, scaledValue) - - default: - return (node[`set${capitalize(name)}` as keyof YogaNode] as any)(scaledValue) - } + if (!value) return + + switch (name) { + case 'flexDir': + case 'dir': + case 'flexDirection': + return yogaInstance._YGNodeStyleSetFlexDirection( + node, + CONSTANTS[`FLEX_DIRECTION_${jsxPropToYogaProp(value as string)}` as keyof typeof CONSTANTS] + ) + case 'align': + case 'alignItems': + return yogaInstance._YGNodeStyleSetAlignItems( + node, + CONSTANTS[`ALIGN_${jsxPropToYogaProp(value as string)}` as keyof typeof CONSTANTS] + ) + case 'alignContent': + return yogaInstance._YGNodeStyleSetAlignContent( + node, + CONSTANTS[`ALIGN_${jsxPropToYogaProp(value as string)}` as keyof typeof CONSTANTS] + ) + case 'alignSelf': + return yogaInstance._YGNodeStyleSetAlignSelf( + node, + CONSTANTS[`ALIGN_${jsxPropToYogaProp(value as string)}` as keyof typeof CONSTANTS] + ) + case 'justify': + case 'justifyContent': + return yogaInstance._YGNodeStyleSetJustifyContent( + node, + CONSTANTS[`JUSTIFY_${jsxPropToYogaProp(value as string)}` as keyof typeof CONSTANTS] + ) + case 'wrap': + case 'flexWrap': + return yogaInstance._YGNodeStyleSetFlexWrap( + node, + CONSTANTS[`WRAP_${jsxPropToYogaProp(value as string)}` as keyof typeof CONSTANTS] + ) + + case 'basis': + case 'flexBasis': + return setPropertyString(yogaInstance, node, 'FlexBasis', value, scaleFactor) + case 'grow': + case 'flexGrow': + return setPropertyString(yogaInstance, node, 'FlexGrow', value, scaleFactor) + case 'shrink': + case 'flexShrink': + return setPropertyString(yogaInstance, node, 'FlexShrink', value, scaleFactor) + + case 'width': + return setPropertyString(yogaInstance, node, 'Width', value, scaleFactor) + case 'height': + return setPropertyString(yogaInstance, node, 'Height', value, scaleFactor) + + case 'maxHeight': + return setPropertyString(yogaInstance, node, 'MaxWidth', value, scaleFactor) + case 'maxWidth': + return setPropertyString(yogaInstance, node, 'MaxHeight', value, scaleFactor) + case 'minHeight': + return setPropertyString(yogaInstance, node, 'MinWidth', value, scaleFactor) + case 'minWidth': + return setPropertyString(yogaInstance, node, 'MinHeight', value, scaleFactor) + + case 'padding': + case 'p': + return setPropertyString(yogaInstance, node, 'Padding', value, scaleFactor, CONSTANTS.EDGE_ALL) + case 'paddingLeft': + case 'pl': + return setPropertyString(yogaInstance, node, 'Padding', value, scaleFactor, CONSTANTS.EDGE_LEFT) + case 'paddingRight': + case 'pr': + return setPropertyString(yogaInstance, node, 'Padding', value, scaleFactor, CONSTANTS.EDGE_RIGHT) + case 'paddingTop': + case 'pt': + return setPropertyString(yogaInstance, node, 'Padding', value, scaleFactor, CONSTANTS.EDGE_TOP) + case 'paddingBottom': + case 'pb': + return setPropertyString(yogaInstance, node, 'Padding', value, scaleFactor, CONSTANTS.EDGE_BOTTOM) + + case 'margin': + case 'm': + return setPropertyString(yogaInstance, node, 'Margin', value, scaleFactor, CONSTANTS.EDGE_ALL) + case 'marginLeft': + case 'ml': + return setPropertyString(yogaInstance, node, 'Margin', value, scaleFactor, CONSTANTS.EDGE_LEFT) + case 'marginRight': + case 'mr': + return setPropertyString(yogaInstance, node, 'Margin', value, scaleFactor, CONSTANTS.EDGE_RIGHT) + case 'marginTop': + case 'mt': + return setPropertyString(yogaInstance, node, 'Margin', value, scaleFactor, CONSTANTS.EDGE_TOP) + case 'marginBottom': + case 'mb': + return setPropertyString(yogaInstance, node, 'Margin', value, scaleFactor, CONSTANTS.EDGE_BOTTOM) } }) } diff --git a/yarn.lock b/yarn.lock index e528296..cee0b65 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2474,11 +2474,6 @@ dependencies: "@types/yargs-parser" "*" -"@types/yoga-layout@1.9.2": - version "1.9.2" - resolved "https://registry.yarnpkg.com/@types/yoga-layout/-/yoga-layout-1.9.2.tgz#efaf9e991a7390dc081a0b679185979a83a9639a" - integrity sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw== - "@typescript-eslint/eslint-plugin@^3.7.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz#7e061338a1383f59edc204c605899f93dc2e2c8f" @@ -9482,7 +9477,7 @@ react-popper@^1.3.7: typed-styles "^0.0.7" warning "^4.0.2" -react-promise-suspense@^0.3.2: +react-promise-suspense@^0.3.2, react-promise-suspense@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/react-promise-suspense/-/react-promise-suspense-0.3.3.tgz#b085c7e0ac22b85fd3d605b1c4f181cda4310bc9" integrity sha512-OdehKsCEWYoV6pMcwxbvJH99UrbXylmXJ1QpEL9OfHaUBzcAihyfSJV8jFq325M/wW9iKc/BoiLROXxMul+MxA== @@ -11729,9 +11724,7 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yoga-layout-prebuilt@^1.9.6: - version "1.9.6" - resolved "https://registry.yarnpkg.com/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.9.6.tgz#98dde95bbf8e6e12835876e9305f1e995c4bb801" - integrity sha512-Wursw6uqLXLMjBAO4SEShuzj8+EJXhCF71/rJ7YndHTkRAYSU0GY3OghRqfAk9HPUAAFMuqp3U1Wl+01vmGRQQ== - dependencies: - "@types/yoga-layout" "1.9.2" +yoga-wasm-slim@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yoga-wasm-slim/-/yoga-wasm-slim-0.0.6.tgz#0b1604a28f6453260c0b772d45b9d4cf5b11380d" + integrity sha512-H8vUiyp+wbmU4vHl87Jt0vaAZiyItKhheCnE4/Rku2pUQdvWfbrqU+GlB4bTbVIxZu7ZUwcex6Zcg7+KcQerOQ==