batches: SSBC animated library pane collapse (#30069)

This commit is contained in:
Kelli Rockwell 2022-01-24 15:02:54 -08:00 committed by GitHub
parent ceaaed7a16
commit f92fb23568
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 216 additions and 129 deletions

View File

@ -1,7 +1,16 @@
.collapse-container {
.list-container {
margin: 0;
padding: 0;
// Match this to the value in JS
width: 14rem;
}
.collapse-button {
// Match this to the value in JS
width: 1.25rem;
z-index: 1000;
}
.library-item {
list-style: none;
margin: 0;

View File

@ -1,9 +1,9 @@
import ChevronDoubleLeftIcon from 'mdi-react/ChevronDoubleLeftIcon'
import ChevronDoubleRightIcon from 'mdi-react/ChevronDoubleRightIcon'
import React, { useState, useCallback } from 'react'
import { Collapse } from 'reactstrap'
import { animated, useSpring } from 'react-spring'
import { Button } from '@sourcegraph/wildcard'
import { Button, useLocalStorage } from '@sourcegraph/wildcard'
import { Scalars } from '../../../../graphql-operations'
import { insertNameIntoLibraryItem } from '../yaml-util'
@ -27,6 +27,12 @@ const LIBRARY: [LibraryItem, LibraryItem, LibraryItem, LibraryItem] = [
{ name: 'update go imports', code: goImportsSample },
]
const LIBRARY_PANE_DEFAULT_COLLAPSED = 'batch-changes.ssbc-library-pane-default-collapsed'
// Match to `.collapse-button` class width
const BUTTON_WIDTH = '1.25rem'
// Match to `.list-container` class width
const CONTENT_WIDTH = '14rem'
interface LibraryPaneProps {
/**
* The name of the batch change, used for automatically filling in the name for any
@ -37,9 +43,47 @@ interface LibraryPaneProps {
}
export const LibraryPane: React.FunctionComponent<LibraryPaneProps> = ({ name, onReplaceItem }) => {
const [collapsed, setCollapsed] = useState(false)
// Remember the last collapsed state of the pane
const [defaultCollapsed, setDefaultCollapsed] = useLocalStorage(LIBRARY_PANE_DEFAULT_COLLAPSED, false)
const [collapsed, setCollapsed] = useState(defaultCollapsed)
const [selectedItem, setSelectedItem] = useState<LibraryItem>()
const [containerStyle, animateContainer] = useSpring(() => ({
width: collapsed ? BUTTON_WIDTH : CONTENT_WIDTH,
}))
const [headerStyle, animateHeader] = useSpring(() => ({
opacity: collapsed ? 0 : 1,
width: collapsed ? '0rem' : CONTENT_WIDTH,
}))
const [contentStyle, animateContent] = useSpring(() => ({
display: collapsed ? 'none' : 'block',
opacity: collapsed ? 0 : 1,
}))
const toggleCollapse = useCallback(
(collapsed: boolean) => {
setCollapsed(collapsed)
setDefaultCollapsed(collapsed)
animateContainer.start({ width: collapsed ? BUTTON_WIDTH : CONTENT_WIDTH })
animateContent.start({
/* eslint-disable callback-return */
// We need the display: none property change to happen in sequence *after*
// the opacity property change or else the content will disappear
// immediately. This use of the API is following the suggestion from
// https://react-spring.io/hooks/use-spring#this-is-how-you-create-a-script
to: async next => {
await next({ display: 'block', opacity: collapsed ? 0 : 1 })
if (collapsed) {
await next({ display: 'none' })
}
},
/* eslint-enable callback-return */
})
animateHeader.start({ opacity: collapsed ? 0 : 1, width: collapsed ? '0rem' : CONTENT_WIDTH })
},
[animateContainer, animateContent, animateHeader, setDefaultCollapsed]
)
const onConfirm = useCallback(() => {
if (selectedItem) {
const codeWithName = insertNameIntoLibraryItem(selectedItem.code, name)
@ -57,25 +101,28 @@ export const LibraryPane: React.FunctionComponent<LibraryPaneProps> = ({ name, o
onConfirm={onConfirm}
/>
) : null}
<div className="d-flex flex-column">
<div className="d-flex align-items-center justify-space-between flex-0">
<h5 className="flex-grow-1">Library</h5>
<Button
className="flex-0"
onClick={() => setCollapsed(!collapsed)}
aria-label={collapsed ? 'Expand' : 'Collapse'}
>
{collapsed ? (
<ChevronDoubleRightIcon className="icon-inline mr-1" />
) : (
<ChevronDoubleLeftIcon className="icon-inline mr-1" />
)}
</Button>
<animated.div style={containerStyle} className="d-flex flex-column mr-1">
<div className="d-flex align-items-center justify-content-center pb-1">
<animated.h5 className="overflow-hidden" style={headerStyle}>
Library
</animated.h5>
<div className={styles.collapseButton}>
<Button
className="p-0"
onClick={() => toggleCollapse(!collapsed)}
aria-label={collapsed ? 'Expand' : 'Collapse'}
>
{collapsed ? (
<ChevronDoubleRightIcon className="icon-inline" />
) : (
<ChevronDoubleLeftIcon className="icon-inline" />
)}
</Button>
</div>
</div>
{/* TODO: This should slide vertically but not on our version of reactstrap. */}
<Collapse className={styles.collapseContainer} isOpen={!collapsed}>
<ul className="m-0 p-0">
<animated.div style={contentStyle}>
<ul className={styles.listContainer}>
{LIBRARY.map(item => (
<li className={styles.libraryItem} key={item.name}>
<button
@ -88,8 +135,8 @@ export const LibraryPane: React.FunctionComponent<LibraryPaneProps> = ({ name, o
</li>
))}
</ul>
</Collapse>
</div>
</animated.div>
</animated.div>
</>
)
}

View File

@ -1,16 +1,17 @@
export { useDebounce } from './useDebounce'
export { useControlledState } from './useControlledState'
export { useOffsetPagination } from './useOffsetPagination'
export { useSearchParameters } from './useSearchParameters'
export { useAutoFocus } from './useAutoFocus'
export { useControlledState } from './useControlledState'
export { useDebounce } from './useDebounce'
export { useDeepMemo } from './useDeepMemo'
export { useInterval } from './useInterval'
export { useKeyboard } from './useKeyboard'
export { useLocalStorage } from './useLocalStorage'
export { useMatchMedia } from './useMatchMedia'
export { useMeasure } from './useMeasure'
export { useEventObservable, useObservable } from './useObservable'
export { useOffsetPagination } from './useOffsetPagination'
export { useOnClickOutside } from './useOnClickOutside'
export { useSearchParameters } from './useSearchParameters'
export { useTimeoutManager } from './useTimeoutManager'
export { useKeyboard } from './useKeyboard'
export { useDeepMemo } from './useDeepMemo'
export { WildcardThemeContext, useWildcardTheme } from './useWildcardTheme'
// Export type is required to avoid Webpack warnings.
export type { WildcardTheme } from './useWildcardTheme'

View File

@ -0,0 +1,49 @@
import { useLayoutEffect, useMemo, useState } from 'react'
export type Measurements = Pick<DOMRectReadOnly, 'x' | 'y' | 'top' | 'left' | 'right' | 'bottom' | 'height' | 'width'>
const DEFAULTS: Measurements = {
x: 0,
y: 0,
width: 0,
height: 0,
top: 0,
left: 0,
bottom: 0,
right: 0,
}
/**
* Custom hook for observing the size and position of an element using the Resize Observer
* API. Based on https://github.com/streamich/react-use/blob/master/src/useMeasure.ts
*/
export const useMeasure = <E extends Element = Element>(): [
ref: (element: E | null) => void,
measurements: Measurements
] => {
const [element, setElement] = useState<E | null>(null)
const [measurements, setMeasurements] = useState<Measurements>(DEFAULTS)
const observer = useMemo(
() =>
new window.ResizeObserver(entries => {
if (entries[0]) {
// eslint-disable-next-line id-length
const { x, y, width, height, top, left, bottom, right } = entries[0].contentRect
setMeasurements({ x, y, width, height, top, left, bottom, right })
}
}),
[]
)
useLayoutEffect(() => {
if (!element) {
return
}
observer.observe(element)
return () => observer.disconnect()
}, [element, observer])
return [setElement, measurements]
}

View File

@ -292,7 +292,6 @@
"puppeteer": "12.0.1",
"puppeteer-firefox": "^0.5.1",
"react-refresh": "^0.10.0",
"react-spring": "^9.0.0",
"sass": "^1.32.4",
"sass-loader": "^12.1.0",
"shelljs": "^0.8.4",
@ -405,6 +404,7 @@
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scroll-manager": "^1.0.3",
"react-spring": "^9.4.2",
"react-sticky-box": "^0.9.3",
"react-stripe-elements": "^6.1.2",
"react-visibility-sensor": "^5.1.1",

179
yarn.lock
View File

@ -24,11 +24,6 @@
dependencies:
tunnel "0.0.6"
"@alloc/types@^1.2.1":
version "1.3.0"
resolved "https://registry.npmjs.org/@alloc/types/-/types-1.3.0.tgz#904245b8d3260a4b7d8a801c12501968f64fac08"
integrity sha512-mH7LiFiq9g6rX2tvt1LtwsclfG5hnsmtIfkZiauAGrm1AwXhoRS0sF2WrN9JGN7eV5vFXqNaB0eXZ3IvMsVi9g==
"@apidevtools/json-schema-ref-parser@9.0.6":
version "9.0.6"
resolved "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.6.tgz#5d9000a3ac1fd25404da886da6b266adcd99cf1c"
@ -3261,90 +3256,91 @@
prop-types "^15.7.2"
tslib "^2.3.0"
"@react-spring/animated@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@react-spring/animated/-/animated-9.0.0.tgz#5c4704965b959412accf1f565bc25b282d983c35"
integrity sha512-6EF7iNnBJzFozqc9rhdAvqW5WAIcLO3VapGd8OjRqHPL27zHP14n9klfPx2ccSPtVqs5EbttG6a+ntiP6RUTGw==
"@react-spring/animated@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/animated/-/animated-9.4.2.tgz#1dc107233ce4a44b023abac829f3b2ea8327a128"
integrity sha512-Dzum5Ho8e+LIAegAqRyoQFakD2IVH3ZQ2nsFXJorAFq3Xjv6IVPz/+TNxb/wSvnsMludfoF+ZIf319FSFmgD5w==
dependencies:
"@react-spring/shared" "^9.0.0"
"@react-spring/types" "^9.0.0"
react-layout-effect "^1.0.1"
"@react-spring/shared" "~9.4.0"
"@react-spring/types" "~9.4.0"
"@react-spring/core@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@react-spring/core/-/core-9.0.0.tgz#ebc75f55ab958cd89ec6810b351edea954e6d2a4"
integrity sha512-VE193rRuv4BKON+K+UpHhPfs2snt2ySr0bYz35Lm+7Xw9PDoV7VVsoG3p/K/zNKLJWioyUQXKI0UkbUaS3KCfQ==
"@react-spring/core@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/core/-/core-9.4.2.tgz#c20249535b3acaead015d17e1c4ce839ec3d4c9f"
integrity sha512-Ej/ULwdx8rQtMAWEpLgwbKcQEx6vPfjyG3cxLP05zAInpCoWkYpl+sXOp9tn3r99mTNQPTTt7BgQsSnmQA8+rQ==
dependencies:
"@react-spring/animated" "^9.0.0"
"@react-spring/shared" "^9.0.0"
"@react-spring/types" "^9.0.0"
react-layout-effect "^1.0.1"
"@react-spring/animated" "~9.4.0"
"@react-spring/rafz" "~9.4.0"
"@react-spring/shared" "~9.4.0"
"@react-spring/types" "~9.4.0"
"@react-spring/konva@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@react-spring/konva/-/konva-9.0.0.tgz#8eae7215c745ecc9950683bf1826181b265a1f29"
integrity sha512-eTCwVLGecs9D18ak8zj5RE6wOF/ARF1WWac/x989+NChvVGd2DgEEH+TB8kMiU/u7AvE9V2nzJBIW6dfNbdQYw==
"@react-spring/konva@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/konva/-/konva-9.4.2.tgz#aa99947343aa147e5bcfcbad9704d892b8504e0d"
integrity sha512-wzSfyHp+qS0OjnipQ8FFrtMh4yu62dkaWAFa+9ThqbQ5KLbEdCK4ArN4h4GfxPoJZ38NJoEO7zbX+ewtQn8N1g==
dependencies:
"@react-spring/animated" "^9.0.0"
"@react-spring/core" "^9.0.0"
"@react-spring/shared" "^9.0.0"
"@react-spring/types" "^9.0.0"
"@react-spring/animated" "~9.4.0"
"@react-spring/core" "~9.4.0"
"@react-spring/shared" "~9.4.0"
"@react-spring/types" "~9.4.0"
"@react-spring/native@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@react-spring/native/-/native-9.0.0.tgz#f4641fdb6ace86448e0b1f811219d4774f6344fc"
integrity sha512-BvtS/zrHfdWUesrOwfhuzA0RdNwHtEGyACbsF5hvk+hPRJ7DyEI4wPvDMUCgKA1XdU7uHwFC8+F9cdiE27Vfpw==
"@react-spring/native@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/native/-/native-9.4.2.tgz#cb86725f55acc2f71b88af84edffe5b0906488d1"
integrity sha512-QVKpeuPvnYwvW4NvzzJcTgvZseMaogVH2zhAWpT4DkXIOICbaIlz1BsE+C+wrtREIq0LCgUFVbeUwaG89t68UA==
dependencies:
"@react-spring/animated" "^9.0.0"
"@react-spring/core" "^9.0.0"
"@react-spring/shared" "^9.0.0"
"@react-spring/types" "^9.0.0"
"@react-spring/animated" "~9.4.0"
"@react-spring/core" "~9.4.0"
"@react-spring/shared" "~9.4.0"
"@react-spring/types" "~9.4.0"
"@react-spring/shared@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@react-spring/shared/-/shared-9.0.0.tgz#2b11a318c2b38617b98cd3126f13cfff0be5dbe7"
integrity sha512-cbVTcepW5vj5BtGwxm6DU19C1QgK55YiPiEGRQLoQuvyKo/6LUPTWg0DO+Nzti90d52hcyb2WnGA5tE8sQHifw==
dependencies:
"@react-spring/types" "^9.0.0"
fluids "^0.2.2"
rafz "^0.1.13"
"@react-spring/rafz@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.4.2.tgz#40a663d407cd116d436f662c6849f8e5b56234b6"
integrity sha512-rSm+G8E/XEEpnCGtT/xYN6o8VvEXlU8wN/hyKp4Q44XAZzGSMHLIFP7pY94/MmWsxCxjkw1AxUWhiFYxWrnI5Q==
"@react-spring/three@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@react-spring/three/-/three-9.0.0.tgz#6dcbef619699d5bcfa03e91aabf77493841809ec"
integrity sha512-UeaR+i7rSShliF5kcrp/c9E/nLQ1kBPlePVowRBBVHo4vr/6iR9U/WRyK2V+iFLPWctW3PXvolXSzKrucrkDaQ==
"@react-spring/shared@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/shared/-/shared-9.4.2.tgz#45e103eee04f5e857ab2c575c2a84d3a883f0bfa"
integrity sha512-mZtbQLpMm6Vy5+O1MSlY9KuAcMO8rdUQvtdnC7Or7y7xiZlnzj8oAILyO6Y2rD2ZC1PmgVS0gMev/8T+MykW+Q==
dependencies:
"@react-spring/animated" "^9.0.0"
"@react-spring/core" "^9.0.0"
"@react-spring/shared" "^9.0.0"
"@react-spring/types" "^9.0.0"
"@react-spring/rafz" "~9.4.0"
"@react-spring/types" "~9.4.0"
"@react-spring/types@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@react-spring/types/-/types-9.0.0.tgz#3e61e767c718f60cf5a4d7400a2b8e7a67ef3b8c"
integrity sha512-29PVjz3luTk1gMV6ZjVKmyIT45tpTKd7g37hfAzYE8drm7bOC5T/kcLM+gXl2HRYCwrzXKduW7jOwjlpEmma+w==
"@react-spring/three@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/three/-/three-9.4.2.tgz#a39b4f816023ea7792cacf74188f09de8fa13604"
integrity sha512-qAPHOMjQjl9V3Eh4Xbdsdx9mAMe+rtSBfEuZGfoF5l8P8zC42gxggbyM1sKUOip3yyz76YTPiosWkmvgCVxMng==
dependencies:
"@alloc/types" "^1.2.1"
"@react-spring/animated" "~9.4.0"
"@react-spring/core" "~9.4.0"
"@react-spring/shared" "~9.4.0"
"@react-spring/types" "~9.4.0"
"@react-spring/web@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@react-spring/web/-/web-9.0.0.tgz#c7fe40dbad755856fb344dc41e5822c56078b93c"
integrity sha512-A75WR7eYUS1p80KQcmVOakWwXCZ/+bnGd4FhKfAm8E4Kl//ZvPXVMuOuPP8hOsxy5sd7FZkbIULOCsRvXHFRQg==
dependencies:
"@react-spring/animated" "^9.0.0"
"@react-spring/core" "^9.0.0"
"@react-spring/shared" "^9.0.0"
"@react-spring/types" "^9.0.0"
"@react-spring/types@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/types/-/types-9.4.2.tgz#f0518f6d23a0b0f699a71976483323ac84bc4ace"
integrity sha512-GGiIscTM+CEUNV52anj3g5FqAZKL2+eRKtvBOAlC99qGBbvJ3qTLImrUR/I3lXY7PRuLgzI6kh34quA1oUxWYQ==
"@react-spring/zdog@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@react-spring/zdog/-/zdog-9.0.0.tgz#dcf7311de3e3a2066337ddb7c72b6c7d66cba21d"
integrity sha512-DsTUnKIZnpTpsJq6O1aTr0jtjFpXbZimwYRV/Df7wH1QgZgCkFFewjQa45MC/0c7+Mgy1zCEG4BAgUstuYabNA==
"@react-spring/web@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/web/-/web-9.4.2.tgz#ea8bb224c236d10097da463ea9e950f0939b7a5f"
integrity sha512-sWfA9NkVuvVOpjSlMkD2zcF6X3i8NSHTeH/uHCGKsN3mYqgkhvAF+E8GASO/H4KKGNhbRvgCZiwJXOtOGyUg6A==
dependencies:
"@react-spring/animated" "^9.0.0"
"@react-spring/core" "^9.0.0"
"@react-spring/shared" "^9.0.0"
"@react-spring/types" "^9.0.0"
"@react-spring/animated" "~9.4.0"
"@react-spring/core" "~9.4.0"
"@react-spring/shared" "~9.4.0"
"@react-spring/types" "~9.4.0"
"@react-spring/zdog@~9.4.0":
version "9.4.2"
resolved "https://registry.npmjs.org/@react-spring/zdog/-/zdog-9.4.2.tgz#26aacfd14254b9e2260faef866493940f633bc31"
integrity sha512-lQi6Kh5ibEgD8+V3rja5rgMoLsdlgvXsr7cDeBKmBwXx0ne10gR7bSqEeD8wWcAIon/F5qfsR+Ns2B4FpDqYtA==
dependencies:
"@react-spring/animated" "~9.4.0"
"@react-spring/core" "~9.4.0"
"@react-spring/shared" "~9.4.0"
"@react-spring/types" "~9.4.0"
"@samverschueren/stream-to-observable@^0.3.0":
version "0.3.0"
@ -12180,11 +12176,6 @@ fluent-syntax@0.13.0:
resolved "https://registry.npmjs.org/fluent-syntax/-/fluent-syntax-0.13.0.tgz#417144d99cba94ff474c422b3e6623d5a842855a"
integrity sha512-0Bk1AsliuYB550zr4JV9AYhsETsD3ELXUQzdXGJfIc1Ni/ukAfBdQInDhVMYJUaT2QxoamNslwkYF7MlOrPUwg==
fluids@^0.2.2:
version "0.2.8"
resolved "https://registry.npmjs.org/fluids/-/fluids-0.2.8.tgz#96a0afe6f6db23a301e2022b0ec5e967be264ba6"
integrity sha512-60W1IZZaIm7OeNKhlyxNgCqEt0t89ds+RODxiWy6BVgaolK1eXFCamIEmxdAx8o83XtuH1haIl5QkOX2nff9wA==
flush-write-stream@^1.0.2:
version "1.1.1"
resolved "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8"
@ -19387,11 +19378,6 @@ raf@^3.4.0:
dependencies:
performance-now "^2.1.0"
rafz@^0.1.13:
version "0.1.14"
resolved "https://registry.npmjs.org/rafz/-/rafz-0.1.14.tgz#164f01cf7cc6094e08467247ef351ef5c8d278fe"
integrity sha512-YiQkedSt1urYtYbvHhTQR3l67M8SZbUvga5eJFM/v4vx/GmDdtXlE2hjJIyRjhhO/PjcdGC+CXCYOUA4onit8w==
ramda@^0.21.0:
version "0.21.0"
resolved "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35"
@ -19614,11 +19600,6 @@ react-is@^17.0.1, react-is@^17.0.2:
resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-layout-effect@^1.0.1:
version "1.0.5"
resolved "https://registry.npmjs.org/react-layout-effect/-/react-layout-effect-1.0.5.tgz#0dc4e24452aee5de66c93c166f0ec512dfb1be80"
integrity sha512-zdRXHuch+OBHU6bvjTelOGUCM+UDr/iCY+c0wXLEAc+G4/FlcJruD/hUOzlKH5XgO90Y/BUJPNhI/g9kl+VAsA==
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
@ -19771,17 +19752,17 @@ react-smooth@^1.0.5:
raf "^3.4.0"
react-transition-group "^2.5.0"
react-spring@^9.0.0:
version "9.0.0"
resolved "https://registry.npmjs.org/react-spring/-/react-spring-9.0.0.tgz#ff9d3611b8f637f8500d7f1cbd990a5861384d50"
integrity sha512-90s8beqIAKJA3VdmkGBEv8wZNAuhxE7ngKA5TGCd6Ya3wjyoZPzMR76vEYUSGv3Psu6q5R2dYXHh89LdlQTY1A==
react-spring@^9.4.2:
version "9.4.2"
resolved "https://registry.npmjs.org/react-spring/-/react-spring-9.4.2.tgz#71fcbe2d317fae9271058c8b70823af0c3b8ad4d"
integrity sha512-mK9xdq1kAhbe5YpP4EG2IzRa2C1M1UfR/MO1f83PE+IpHwCm1nGQhteF3MGyX6I3wnkoBWTXbY6n4443Dp52Og==
dependencies:
"@react-spring/core" "^9.0.0"
"@react-spring/konva" "^9.0.0"
"@react-spring/native" "^9.0.0"
"@react-spring/three" "^9.0.0"
"@react-spring/web" "^9.0.0"
"@react-spring/zdog" "^9.0.0"
"@react-spring/core" "~9.4.0"
"@react-spring/konva" "~9.4.0"
"@react-spring/native" "~9.4.0"
"@react-spring/three" "~9.4.0"
"@react-spring/web" "~9.4.0"
"@react-spring/zdog" "~9.4.0"
react-sticky-box@^0.9.3:
version "0.9.3"