@raster-app/react 0.1.0-canary-fd0f8dd → 0.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -64
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -1,28 +1,26 @@
|
|
|
1
1
|
# @raster-app/react
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[raster.app/docs](https://raster.app/docs)
|
|
8
|
-
|
|
9
|
-
## Requirements
|
|
10
|
-
|
|
11
|
-
- React 18 or 19
|
|
12
|
-
- Node.js 24 or later
|
|
13
|
-
|
|
14
|
-
## Installation
|
|
3
|
+
React bindings for [`@raster-app/sdk`](https://www.npmjs.com/package/@raster-app/sdk): a drop-in
|
|
4
|
+
Raster asset picker, and the provider and hooks it is built on (session, organizations,
|
|
5
|
+
libraries, assets, search, uploads and the navigation model every Raster plugin shares). They
|
|
6
|
+
cache in TanStack Query.
|
|
15
7
|
|
|
16
8
|
```sh
|
|
17
9
|
npm install @raster-app/react
|
|
18
10
|
```
|
|
19
11
|
|
|
20
|
-
It
|
|
21
|
-
|
|
12
|
+
It takes the host's React, 18 or 19, as a peer dependency. It re-exports all of
|
|
13
|
+
`@raster-app/sdk`, so the client, `toUserMessage` and types such as `Asset` and `Library` come
|
|
14
|
+
from `@raster-app/react` too.
|
|
22
15
|
|
|
23
|
-
##
|
|
16
|
+
## The picker
|
|
24
17
|
|
|
25
|
-
|
|
18
|
+
`RasterPicker` is Raster's asset picker, drawn in Raster's own design: sign-in with the device
|
|
19
|
+
grant or an API key, Raster's organization switcher, the organization's libraries, search, and
|
|
20
|
+
infinite scroll. A tile opens its asset large, with Pick asset and Open in Raster, which goes
|
|
21
|
+
through the host's `openExternal`, over the asset's versions, where a variant is uploaded or set as
|
|
22
|
+
the default. It uploads into a library from its menu or a drop. An organization or a library is
|
|
23
|
+
read as the pointer reaches it, so it opens at once. It fills its container.
|
|
26
24
|
|
|
27
25
|
```tsx
|
|
28
26
|
import {
|
|
@@ -33,11 +31,11 @@ import {
|
|
|
33
31
|
} from '@raster-app/react'
|
|
34
32
|
import '@raster-app/react/styles.css'
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
function Picker({ onImage }: { onImage: (url: string) => void }) {
|
|
37
35
|
return (
|
|
38
36
|
<RasterProvider
|
|
39
37
|
config={{
|
|
40
|
-
host: { name: '
|
|
38
|
+
host: { name: 'Sanity', openExternal: (url) => window.open(url, '_blank') },
|
|
41
39
|
credentials: localStorageCredentialStore(),
|
|
42
40
|
}}
|
|
43
41
|
>
|
|
@@ -47,23 +45,19 @@ export function Picker({ onImage }: { onImage: (url: string) => void }) {
|
|
|
47
45
|
}
|
|
48
46
|
```
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
| Prop | What it does |
|
|
49
|
+
| ---------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
50
|
+
| `onPick` | Called with the picked `Asset`, from any view, and its organization's id. `getFullSizeUrl(asset)` is the image. |
|
|
51
|
+
| `organizationId` | Binds the device sign-in to one organization: any other grant fails with `ORGANIZATION_MISMATCH`. |
|
|
52
|
+
| `scope` | The consent the device sign-in asks for: `'org'` when `organizationId` is set, `'user'` otherwise. |
|
|
53
|
+
| `onError` | Called once with each `RasterApiError` the picker shows, for the host to log. |
|
|
54
|
+
| `theme` | `'light'` or `'dark'`. The system's color scheme when unset. |
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
58
|
-
| `onPick(asset, organizationId)` | Called with the picked asset. `getFullSizeUrl(asset)` is its image. |
|
|
59
|
-
| `organizationId` | Limits sign-in to this organization. |
|
|
60
|
-
| `scope` | `'org'` to ask for one organization, `'user'` for the whole account. Defaults to `'org'` with an `organizationId`. |
|
|
61
|
-
| `onError(error)` | Called with each error the picker shows, for logging. |
|
|
62
|
-
| `theme` | `'light'` or `'dark'`. Follows the system when unset. |
|
|
56
|
+
The styles are scoped under `.rs`, so they leave the host's own untouched.
|
|
63
57
|
|
|
64
|
-
|
|
58
|
+
## Your own UI
|
|
65
59
|
|
|
66
|
-
|
|
60
|
+
A host that draws its own UI uses the hooks under the same provider.
|
|
67
61
|
|
|
68
62
|
```tsx
|
|
69
63
|
import {
|
|
@@ -71,53 +65,73 @@ import {
|
|
|
71
65
|
createRasterClient,
|
|
72
66
|
localStorageCredentialStore,
|
|
73
67
|
useAssets,
|
|
68
|
+
useLibraries,
|
|
74
69
|
useSession,
|
|
75
70
|
} from '@raster-app/react'
|
|
76
71
|
|
|
77
|
-
//
|
|
72
|
+
// Build the client once, outside render — a second one means a second session store.
|
|
78
73
|
const client = createRasterClient({
|
|
79
|
-
host: { name: '
|
|
74
|
+
host: { name: 'Sanity', openExternal: (url) => window.open(url, '_blank') },
|
|
80
75
|
credentials: localStorageCredentialStore(),
|
|
81
76
|
})
|
|
82
77
|
|
|
83
|
-
|
|
78
|
+
function App() {
|
|
84
79
|
return (
|
|
85
80
|
<RasterProvider client={client}>
|
|
86
|
-
<
|
|
81
|
+
<Browser />
|
|
87
82
|
</RasterProvider>
|
|
88
83
|
)
|
|
89
84
|
}
|
|
90
85
|
|
|
91
|
-
function
|
|
92
|
-
const {
|
|
93
|
-
const
|
|
86
|
+
function Browser() {
|
|
87
|
+
const { isConfigured } = useSession()
|
|
88
|
+
const libraries = useLibraries({ organizationId: 'acme' })
|
|
89
|
+
const assets = useAssets({ organizationId: 'acme', libraryId: 'lib-1' })
|
|
94
90
|
|
|
95
|
-
if (credentials === undefined) return null // still loading
|
|
96
91
|
if (!isConfigured) return <SignIn />
|
|
97
|
-
return <Grid assets={assets ?? []}
|
|
92
|
+
return <Grid assets={assets.assets ?? []} onLoadMore={assets.loadMore} />
|
|
98
93
|
}
|
|
99
94
|
```
|
|
100
95
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
|
112
|
-
|
|
113
|
-
`
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
`
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
96
|
+
## Provider
|
|
97
|
+
|
|
98
|
+
| Prop | What it does |
|
|
99
|
+
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
100
|
+
| `client` or `config` | An existing `RasterClient`, or the config for one the provider creates. |
|
|
101
|
+
| `queryClient` | The host's own TanStack `QueryClient`, from the same TanStack Query major as this package. Without one the provider creates its own, which shadows the host's for everything below. |
|
|
102
|
+
| `state` | The `StateStore` where `useRasterNavigation` remembers the last organization and library: `memoryStateStore()` (the default), `localStorageStateStore()`, or the host's own. |
|
|
103
|
+
|
|
104
|
+
## Hooks
|
|
105
|
+
|
|
106
|
+
| Hook | What it gives you |
|
|
107
|
+
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
|
|
108
|
+
| `useSession()` | The credential, `isConfigured` / `isSignedIn`, `userName`, `signOut`. |
|
|
109
|
+
| `useSignIn()` | Device grant or API key. One state machine for both. Takes `scope` and `organizationId` for the device grant. |
|
|
110
|
+
| `useOrganizations()` | Everything the credential reaches, from `/me`, as a TanStack query result. |
|
|
111
|
+
| `useLibraries({ organizationId })` | The libraries in one organization, as a query result. Each carries `access`: `'write'`, `'read'` or `null` for none. |
|
|
112
|
+
| `useAssets({ organizationId, libraryId })` | A library's assets, paged. |
|
|
113
|
+
| `useAssetSearch(scope, query)` | Debounced, paged search that keeps the last results up while the next query runs. |
|
|
114
|
+
| `useAssetUpload()` | Upload, then poll until Raster has finished processing. |
|
|
115
|
+
| `usePromoteVariant()` | Promote a variant to its asset's default, then poll until Raster has swapped the files. Takes an optimistic update. |
|
|
116
|
+
| `useRasterNavigation({ organizations })` | `organization → library → asset`, persisted; `refresh()` refetches every Raster query. |
|
|
117
|
+
|
|
118
|
+
## Things worth knowing
|
|
119
|
+
|
|
120
|
+
- **The provider fixes its client on mount.** An inline `config` builds one client for the
|
|
121
|
+
provider's life, and a later `client` prop is ignored: remount with a new `key` to switch.
|
|
122
|
+
Two clients for one credential would each refresh it, spending each other's refresh token.
|
|
123
|
+
- **`credentials` is `undefined` while the store is read.** Gate the sign-in screen on
|
|
124
|
+
`isConfigured` once it has settled, or it flashes on every launch.
|
|
125
|
+
- **Every fetch aborts when superseded**, which frees its connection for the requests that
|
|
126
|
+
follow.
|
|
127
|
+
- **The cache belongs to a sign-in.** Query keys carry the session's `credentialIdentity()`,
|
|
128
|
+
and a sign-out or a different account drops the previous one's queries. For an API key that
|
|
129
|
+
identity is a digest of the key, so the key itself stays out of the cache.
|
|
130
|
+
- **Errors are `RasterApiError`s.** Branch on `code`, and show `toUserMessage(error)`.
|
|
131
|
+
- **Raster finishes uploads and promotes after answering.** Both hooks poll until the work
|
|
132
|
+
lands, and settle as `timed-out` when it outlasts the wait: the work is still running, and a
|
|
133
|
+
later refetch shows it.
|
|
134
|
+
|
|
135
|
+
## Preact
|
|
136
|
+
|
|
137
|
+
To use the hooks with Preact, alias `react` and `react-dom` to `preact/compat` in the bundler.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raster-app/react",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-rc.1",
|
|
4
4
|
"description": "React provider and hooks for the Raster SDK: session, organizations, libraries, assets, search and uploads.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://raster.app/docs",
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
"assets",
|
|
11
11
|
"react",
|
|
12
12
|
"hooks",
|
|
13
|
+
"figma",
|
|
14
|
+
"sanity",
|
|
13
15
|
"plugin"
|
|
14
16
|
],
|
|
15
17
|
"type": "module",
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
"test": "bun test"
|
|
41
43
|
},
|
|
42
44
|
"dependencies": {
|
|
43
|
-
"@raster-app/sdk": "0.1.0-
|
|
45
|
+
"@raster-app/sdk": "^0.1.0-rc.1",
|
|
44
46
|
"@tanstack/react-query": "^5.103.1"
|
|
45
47
|
},
|
|
46
48
|
"peerDependencies": {
|
|
@@ -53,4 +55,4 @@
|
|
|
53
55
|
"publishConfig": {
|
|
54
56
|
"access": "public"
|
|
55
57
|
}
|
|
56
|
-
}
|
|
58
|
+
}
|