Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@uppy/react: add useUppyState #4711

Merged
merged 18 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions e2e/clients/react/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,37 @@
import Uppy from '@uppy/core'
/* eslint-disable-next-line no-unused-vars */
import React, { useState } from 'react'
import { Dashboard, DashboardModal, DragDrop } from '@uppy/react'
import { Dashboard, DashboardModal, DragDrop, useUppyState } from '@uppy/react'
import ThumbnailGenerator from '@uppy/thumbnail-generator'

import '@uppy/core/dist/style.css'
import '@uppy/dashboard/dist/style.css'
import '@uppy/drag-drop/dist/style.css'

const uppyDashboard = new Uppy({ id: 'dashboard' })
const uppyModal = new Uppy({ id: 'modal' })
const uppyDragDrop = new Uppy({ id: 'drag-drop' }).use(ThumbnailGenerator)

export default function App () {
const uppyDashboard = new Uppy({ id: 'dashboard' })
const uppyModal = new Uppy({ id: 'modal' })
const uppyDragDrop = new Uppy({ id: 'drag-drop' }).use(ThumbnailGenerator)
const [open, setOpen] = useState(false)
const files = useUppyState(uppyDashboard, (state) => state.files)

// drag-drop has no visual output so we test it via the uppy instance
window.uppy = uppyDragDrop

return (
<div style={{ maxWidth: '30em', margin: '5em 0', display: 'grid', gridGap: '2em' }}>
<div
style={{
maxWidth: '30em',
margin: '5em 0',
display: 'grid',
gridGap: '2em',
}}
>
<button type="button" id="open" onClick={() => setOpen(!open)}>
Open Modal
</button>
<p>Dashboard file count: {Object.keys(files).length}</p>

<Dashboard id="dashboard" uppy={uppyDashboard} />
<DashboardModal id="modal" open={open} uppy={uppyModal} />
Expand Down
2 changes: 2 additions & 0 deletions e2e/clients/react/index.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* eslint-disable react/react-in-jsx-scope */
// eslint-disable-next-line no-unused-vars
import React from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'

Expand Down
1 change: 1 addition & 0 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@uppy/zoom": "workspace:^"
},
"devDependencies": {
"@types/react": "^18.2.23",
"cypress": "^12.9.0",
"cypress-terminal-report": "^4.1.2",
"deep-freeze": "^0.0.1",
Expand Down
4 changes: 2 additions & 2 deletions examples/react-native-expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"expo-file-system": "~13.0.3",
"expo-status-bar": "~1.1.0",
"preact-render-to-string": "^5.1.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react": "^18.1.0",
"react-dom": "^18.1.0",
Murderlon marked this conversation as resolved.
Show resolved Hide resolved
"react-native": "0.64.3",
"react-native-web": "0.17.1"
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"postcss-logical": "^5.0.0",
"pre-commit": "^1.2.2",
"prettier": "^3.0.3",
"process": "^0.11.10",
Murderlon marked this conversation as resolved.
Show resolved Hide resolved
"remark-cli": "^11.0.0",
"resolve": "^1.17.0",
"sass": "^1.29.0",
Expand Down Expand Up @@ -166,7 +167,6 @@
},
"resolutions": {
"@types/eslint@^7.2.13": "^8.2.0",
"@types/react": "^17",
"@types/webpack-dev-server": "^4",
"pre-commit": "patch:pre-commit@npm:1.2.2#.yarn/patches/pre-commit-npm-1.2.2-f30af83877.patch",
"preact": "patch:preact@npm:10.10.0#.yarn/patches/preact-npm-10.10.0-dd04de05e8.patch",
Expand Down
1 change: 1 addition & 0 deletions packages/@uppy/react/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export { default as ProgressBar } from './ProgressBar.js'
export { default as StatusBar } from './StatusBar.js'
export { default as FileInput } from './FileInput.js'
export { default as useUppy } from './useUppy.js'
export { default as useUppyState } from './useUppyState.js'
2 changes: 2 additions & 0 deletions packages/@uppy/react/src/useUppy.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useEffect, useRef } from 'react'
import { Uppy as UppyCore } from '@uppy/core'

// TODO: remove in the next major

/**
* @deprecated Initialize Uppy outside of the component.
*/
Expand Down
13 changes: 13 additions & 0 deletions packages/@uppy/react/src/useUppyState.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Uppy, State } from '@uppy/core'

type ValueOf<T> = T[keyof T];

/**
* Subscribe to a part of Uppy's state and only re-render when that part changes.
*/
declare function useUppyState(
uppy: Uppy,
selector: (state: State) => ValueOf<State>
): ValueOf<State>;

export default useUppyState
20 changes: 20 additions & 0 deletions packages/@uppy/react/src/useUppyState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useSyncExternalStore, useCallback } from 'react'

export default function useUppyState (uppy, selector) {
// Eslint complains the dependencies are unknown and we should use an inline function
// but we put uppy.store.subscribe in there ourselves.
// eslint-disable-next-line react-hooks/exhaustive-deps
const subscribe = useCallback(uppy.store.subscribe.bind(uppy.store), [
uppy.store.subscribe,
])
const getSnapshot = useCallback(
() => selector(uppy.store.getState()),
// Eslint wants to put `uppy.store` as the dependency
// but that seems unnecessary as we can be more specific.
// eslint-disable-next-line react-hooks/exhaustive-deps
[uppy.store.getState, selector],
)
Murderlon marked this conversation as resolved.
Show resolved Hide resolved

const state = useSyncExternalStore(subscribe, getSnapshot)
return state
}
44 changes: 15 additions & 29 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8673,14 +8673,14 @@ __metadata:
languageName: node
linkType: hard

"@types/react@npm:^17":
version: 17.0.49
resolution: "@types/react@npm:17.0.49"
"@types/react@npm:^18.0.0, @types/react@npm:^18.0.8, @types/react@npm:^18.2.23":
version: 18.2.23
resolution: "@types/react@npm:18.2.23"
dependencies:
"@types/prop-types": "*"
"@types/scheduler": "*"
csstype: ^3.0.2
checksum: e2e8001bb16fdf52dc92dbc2f64c8e49b1c6ab5d5da4725c0f27e3d925939e42b835554fecc306ca6b0951801eb784288b63c924bd703834662bbaccf89cb68a
checksum: efb9d1ed1940c0e7ba08a21ffba5e266d8dbbb8fe618cfb97bc902dfc96385fdd8189e3f7f64b4aa13134f8e61947d60560deb23be151253c3a97b0d070897ca
languageName: node
linkType: hard

Expand Down Expand Up @@ -9076,6 +9076,7 @@ __metadata:
postcss-logical: ^5.0.0
pre-commit: ^1.2.2
prettier: ^3.0.3
process: ^0.11.10
remark-cli: ^11.0.0
resolve: ^1.17.0
sass: ^1.29.0
Expand Down Expand Up @@ -9375,8 +9376,8 @@ __metadata:
expo-file-system: ~13.0.3
expo-status-bar: ~1.1.0
preact-render-to-string: ^5.1.0
react: 17.0.1
react-dom: 17.0.1
react: ^18.1.0
react-dom: ^18.1.0
react-native: 0.64.3
react-native-web: 0.17.1
languageName: unknown
Expand Down Expand Up @@ -14783,6 +14784,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "e2e@workspace:e2e"
dependencies:
"@types/react": ^18.2.23
"@uppy/audio": "workspace:^"
"@uppy/aws-s3": "workspace:^"
"@uppy/aws-s3-multipart": "workspace:^"
Expand Down Expand Up @@ -26370,6 +26372,13 @@ __metadata:
languageName: node
linkType: hard

"process@npm:^0.11.10":
version: 0.11.10
resolution: "process@npm:0.11.10"
checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3
languageName: node
linkType: hard

"prom-client@npm:14.0.1":
version: 14.0.1
resolution: "prom-client@npm:14.0.1"
Expand Down Expand Up @@ -26703,19 +26712,6 @@ __metadata:
languageName: node
linkType: hard

"react-dom@npm:17.0.1":
version: 17.0.1
resolution: "react-dom@npm:17.0.1"
dependencies:
loose-envify: ^1.1.0
object-assign: ^4.1.1
scheduler: ^0.20.1
peerDependencies:
react: 17.0.1
checksum: df2af300dd4f49a5daaccc38f5a307def2a9ae2b7ebffa3dce8fb9986129057696b86a2c94e5ae36133057c69428c500e4ee3bf5884eb44e5632ace8b7ace41f
languageName: node
linkType: hard

"react-dom@npm:^18.0.0, react-dom@npm:^18.1.0":
version: 18.2.0
resolution: "react-dom@npm:18.2.0"
Expand Down Expand Up @@ -26862,16 +26858,6 @@ __metadata:
languageName: node
linkType: hard

"react@npm:17.0.1":
version: 17.0.1
resolution: "react@npm:17.0.1"
dependencies:
loose-envify: ^1.1.0
object-assign: ^4.1.1
checksum: 83b9df9529a2b489f00a4eaa608fc7d55518b258e046c100344ae068713e43ae64e477a140f87e38cfe75489bcfd26d27fce5818f89f4ec41bdbda7ead4bb426
languageName: node
linkType: hard

"react@npm:^18.0.0, react@npm:^18.1.0":
version: 18.2.0
resolution: "react@npm:18.2.0"
Expand Down
Loading