diff --git a/docs/react-keyring.md b/docs/react-keyring.md
index 5501f25cc..e9191e3f7 100644
--- a/docs/react-keyring.md
+++ b/docs/react-keyring.md
@@ -32,15 +32,15 @@ Must be used inside of a [`KeyringProvider`](#keyringprovider).
#### `Authenticator.Form`
-A `form` element designed to work with the [`Authenticator`](#authenticator) component. Any passed props will be passed along to the `form` element.
+A `form` element designed to be used inside of an [`Authenticator`](#authenticator) component. Any passed props will be passed along to the `form` element.
#### `Authenticator.Email`
-An email `input` element designed to work with [`Authenticator.Form`](#authenticatorform). Any passed props will be passed along to the `input` component.
+An email `input` element designed to be used inside of an [`Authenticator.Form`](#authenticatorform). Any passed props will be passed along to the `input` component.
#### `Authenticator.CancelButton`
-A `button` element that will cancel space registration, designed to work with [`Authenticator.Form`](#authenticatorform). Any passed props will be passed along to the `button` element.
+A `button` element that will cancel space registration, designed to be used inside of an [`Authenticator.Form`](#authenticatorform). Any passed props will be passed along to the `button` element.
### `KeyringProvider`
diff --git a/docs/react-uploader.md b/docs/react-uploader.md
index bd774f93e..90e093b81 100644
--- a/docs/react-uploader.md
+++ b/docs/react-uploader.md
@@ -28,11 +28,13 @@ Top-level component of the headless Uploader.
Designed to be used with [`Uploader.Form`](#uploaderform) and [`Uploader.Input`](#uploaderinput) to easily create a custom component for uploading files to web3.storage.
+Must be used inside of an [`UploaderProvider`](#uploaderprovider).
+
#### `Uploader.Form`
Form component for the headless Uploader.
-Renders a `form` element designed to work with [`Uploader`](#uploader) that will send files from an [`Uploader.Input`](#uploaderinput) component to the web3.storage service when the form is submitted.
+Renders a `form` element designed to be used inside of an [`Uploader`](#uploader) that will send files from an [`Uploader.Input`](#uploaderinput) component to the web3.storage service when the form is submitted.
Any passed props will be passed along to the `input` element.
@@ -40,7 +42,7 @@ Any passed props will be passed along to the `input` element.
Input component for the headless Uploader.
-Renders a file `input` element designed to work with [`Uploader`](#uploader). When used inside of an [`Uploader.Form`](#uploaderform), files added to the input will be uploaded when the form is submitted.
+Renders a file `input` element designed to be used inside of an [`Uploader`](#uploader). When used inside of an [`Uploader.Form`](#uploaderform), files added to the input will be uploaded when the form is submitted.
### `UploaderProvider`
diff --git a/docs/react-uploads-list.md b/docs/react-uploads-list.md
index c86f2614b..a5bcc1683 100644
--- a/docs/react-uploads-list.md
+++ b/docs/react-uploads-list.md
@@ -28,11 +28,13 @@ Top-level component of the headless UploadsList.
Designed to be used with [`UploadsList.NextButton`](#uploadslistnextbutton), [`UploadsList.ReloadButton`](#uploadslistreloadbutton), etc to easily create a custom component for listing uploads in a web3.storage space.
+Must be used inside of an [`UploadsListProvider`](#uploadslistprovider).
+
#### `UploadsList.NextButton`
Button that loads the next page of results in an UploadsList.
-Renders a `button` element designed to work with [`UploadsList`](#uploadslist). When pressed, will request the next page of uploads from the service.
+Renders a `button` element designed to be used inside of an [`UploadsList`](#uploadslist). When pressed, will request the next page of uploads from the service.
Any passed props will be passed along to the `button` element.
@@ -40,7 +42,7 @@ Any passed props will be passed along to the `button` element.
Button that reloads an UploadsList.
-Renders a `button` element designed to work with [`UploadsList`](#uploadslist). When pressed, will reload list data from the service.
+Renders a `button` element designed to be used inside of an [`UploadsList`](#uploadslist). When pressed, will reload list data from the service.
Any passed props will be passed along to the `button` element.
diff --git a/examples/react/w3console/package.json b/examples/react/w3console/package.json
index 9d62701ab..5d2a9804e 100644
--- a/examples/react/w3console/package.json
+++ b/examples/react/w3console/package.json
@@ -14,11 +14,9 @@
"@heroicons/react": "^2.0.17",
"@ipld/car": "^5.1.0",
"@ipld/dag-ucan": "^3.2.0",
- "@w3ui/keyring-core": "workspace:^",
"@w3ui/react-keyring": "workspace:^",
"@w3ui/react-uploader": "workspace:^",
"@w3ui/react-uploads-list": "workspace:^",
- "@w3ui/uploader-core": "workspace:^",
"blueimp-md5": "^2.19.0",
"preact": "^10.11.3",
"react-router-dom": "^6.9.0"
diff --git a/examples/react/w3console/src/components/Authenticator.tsx b/examples/react/w3console/src/components/Authenticator.tsx
index aca4a7ca6..b1d231646 100644
--- a/examples/react/w3console/src/components/Authenticator.tsx
+++ b/examples/react/w3console/src/components/Authenticator.tsx
@@ -3,6 +3,7 @@ import {
useAuthenticator
} from '@w3ui/react-keyring'
import { serviceName, tosUrl, Logo } from '../brand'
+import Loader from './Loader'
export function AuthenticationForm (): JSX.Element {
const [{ submitted }] = useAuthenticator()
@@ -10,7 +11,7 @@ export function AuthenticationForm (): JSX.Element {
-
+
@@ -43,7 +44,7 @@ export function AuthenticationSubmitted (): JSX.Element {
+ To get started with w3up you'll need to create a space.
+
+
+ Give it a name and hit create!
+
+
+
+
+ );
+}
diff --git a/examples/react/w3console/src/components/SpaceFinder.tsx b/examples/react/w3console/src/components/SpaceFinder.tsx
index ee4c81e51..f7d8b4782 100644
--- a/examples/react/w3console/src/components/SpaceFinder.tsx
+++ b/examples/react/w3console/src/components/SpaceFinder.tsx
@@ -1,4 +1,4 @@
-import type { Space } from '@w3ui/keyring-core'
+import type { Space } from '@w3ui/react-keyring'
import React, { Fragment, useState } from 'react'
import { Combobox, Transition } from '@headlessui/react'
diff --git a/examples/react/w3console/src/components/SpaceRegistrar.tsx b/examples/react/w3console/src/components/SpaceRegistrar.tsx
new file mode 100644
index 000000000..0de68da09
--- /dev/null
+++ b/examples/react/w3console/src/components/SpaceRegistrar.tsx
@@ -0,0 +1,41 @@
+import { useState } from 'react';
+import { useKeyring } from '@w3ui/react-keyring';
+import Loader from './Loader';
+
+export function SpaceRegistrar (): JSX.Element {
+ const [{ account }, { registerSpace }] = useKeyring();
+ const [submitted, setSubmitted] = useState(false);
+ async function onSubmit (e: React.MouseEvent): Promise {
+ e.preventDefault();
+ if (account) {
+ setSubmitted(true);
+ try {
+ await registerSpace(account, { provider: import.meta.env.VITE_W3UP_PROVIDER });
+ } catch (err) {
+ console.log(err);
+ throw new Error('failed to register', { cause: err });
+ } finally {
+ setSubmitted(false);
+ }
+ } else {
+ throw new Error('cannot register space, no account found, have you authorized your email?');
+ }
+ }
+ return (
+
+
+
This space is not yet registered.
+
+ Click the button below to register this space and start uploading.
+
+
+
+ {submitted ? (
+
+ ) : (
+
+ )}
+
+
+ );
+}
diff --git a/examples/react/w3console/src/components/SpaceSection.tsx b/examples/react/w3console/src/components/SpaceSection.tsx
new file mode 100644
index 000000000..5d37d5ecd
--- /dev/null
+++ b/examples/react/w3console/src/components/SpaceSection.tsx
@@ -0,0 +1,79 @@
+import { useEffect } from 'react';
+import { useKeyring } from '@w3ui/react-keyring';
+import { useUploadsList } from '@w3ui/react-uploads-list';
+import { ShareIcon } from '@heroicons/react/20/solid';
+import md5 from 'blueimp-md5';
+import { SpaceShare } from '../share';
+import { Uploader } from './Uploader';
+import { UploadsList } from './UploadsList';
+import { SpaceRegistrar } from './SpaceRegistrar';
+
+interface SpaceSectionProps {
+ viewSpace: (did: string) => void;
+ setShare: (share: boolean) => void;
+ share: boolean;
+}
+export function SpaceSection (props: SpaceSectionProps): JSX.Element {
+ const { viewSpace, share, setShare } = props;
+ const [{ space }] = useKeyring();
+ const [, { reload }] = useUploadsList();
+ // reload the uploads list when the space changes
+ // TODO: this currently does a network request - we'd like to just reset
+ // to the latest state we have and revalidate in the background (SWR)
+ // but it's not clear how all that state should work yet - perhaps
+ // we need some sort of state management primitive in the uploads list?
+ useEffect(() => {
+ void reload();
+ }, [space]);
+ const registered = Boolean(space?.registered());
+ return (
+
Select a space from the dropdown on the left to get started.
+
+ )}
+
+
+ );
+}
diff --git a/examples/react/w3console/src/components/Uploader.tsx b/examples/react/w3console/src/components/Uploader.tsx
index 898fd1659..0ce6fbbc4 100644
--- a/examples/react/w3console/src/components/Uploader.tsx
+++ b/examples/react/w3console/src/components/Uploader.tsx
@@ -1,8 +1,10 @@
-import type { OnUploadComplete } from '@w3ui/react-uploader'
+import type {
+ OnUploadComplete,
+ CARMetadata,
+ CID
+} from '@w3ui/react-uploader'
-import { Link, Version } from 'multiformats'
import { CloudArrowUpIcon } from '@heroicons/react/24/outline'
-import { CARMetadata } from '@w3ui/uploader-core'
import {
Status,
Uploader as UploaderCore,
@@ -38,7 +40,7 @@ export const Errored = ({ error }: { error: any }): JSX.Element => (
interface DoneProps {
file?: File
- dataCID?: Link
+ dataCID?: CID
storedDAGShards?: CARMetadata[]
}
diff --git a/examples/react/w3console/src/components/W3API.tsx b/examples/react/w3console/src/components/W3API.tsx
index ae3ece772..eb302b1b7 100644
--- a/examples/react/w3console/src/components/W3API.tsx
+++ b/examples/react/w3console/src/components/W3API.tsx
@@ -1,5 +1,4 @@
-import React, { useMemo } from 'react'
-import { ServiceConfig } from '@w3ui/uploader-core'
+import { useMemo } from 'react'
import {
useUploader,
UploaderContextValue,
@@ -22,9 +21,6 @@ export interface W3APIContextValue {
uploader: UploaderContextValue
uploadsList: UploadsListContextValue
}
-export interface UploaderProviderProps extends ServiceConfig {
- children?: JSX.Element
-}
export interface W3APIProviderProps {
children: JSX.Element | JSX.Element[]
diff --git a/examples/react/w3console/src/pages/SpaceSelector.tsx b/examples/react/w3console/src/pages/SpaceSelector.tsx
new file mode 100644
index 000000000..b37a301ed
--- /dev/null
+++ b/examples/react/w3console/src/pages/SpaceSelector.tsx
@@ -0,0 +1,19 @@
+import type { Space } from '@w3ui/react-keyring';
+import { SpaceFinder } from '../components/SpaceFinder';
+
+export function SpaceSelector (props: any): JSX.Element {
+ const { selected, setSelected, spaces } = props;
+ return (
+
+
+ Spaces
+
+ {
+ void setSelected(space.did());
+ }} />
+
+ );
+}
diff --git a/examples/react/w3console/src/pages/index.tsx b/examples/react/w3console/src/pages/index.tsx
index 8b9d2d33d..4f70eddb1 100644
--- a/examples/react/w3console/src/pages/index.tsx
+++ b/examples/react/w3console/src/pages/index.tsx
@@ -1,177 +1,13 @@
-import type { ChangeEvent } from 'react'
-import type { Space } from '@w3ui/keyring-core'
-import { useEffect, useState } from 'react'
+import { useState } from 'react'
import { DIDKey } from '@ucanto/interface'
import { useKeyring } from '@w3ui/react-keyring'
-import { useUploadsList } from '@w3ui/react-uploads-list'
-import { ShareIcon } from '@heroicons/react/20/solid'
-import md5 from 'blueimp-md5'
-import { SpaceShare } from '../share'
-import { Uploader } from '../components/Uploader'
-import { UploadsList } from '../components/UploadsList'
-import { SpaceFinder } from '../components/SpaceFinder'
-import { SpaceCreatorForm } from '../components/SpaceCreator'
import { AuthenticationEnsurer } from '../components/Authenticator'
import { DefaultLayout } from '../components/Layout'
-import Loader from '../components/Loader'
-
-function SpaceRegistrar (): JSX.Element {
- const [{ account }, { registerSpace }] = useKeyring()
- const [submitted, setSubmitted] = useState(false)
- async function onSubmit (e: React.MouseEvent): Promise {
- e.preventDefault()
- if (account) {
- setSubmitted(true)
- try {
- await registerSpace(account, { provider: import.meta.env.VITE_W3UP_PROVIDER })
- } catch (err) {
- console.log(err)
- throw new Error('failed to register', { cause: err })
- } finally {
- setSubmitted(false)
- }
- } else {
- throw new Error('cannot register space, no account found, have you authorized your email?')
- }
- }
- return (
-
-
-
This space is not yet registered.
-
- Click the button below to register this space and start uploading.
-
-
-
- {submitted ? (
-
- ) : (
-
- )}
-
-
- )
-}
-
-interface SpaceSectionProps {
- viewSpace: (did: string) => void
- setShare: (share: boolean) => void
- share: boolean
-}
-
-function SpaceSection (props: SpaceSectionProps): JSX.Element {
- const { viewSpace, share, setShare } = props
- const [{ space }] = useKeyring()
- const [, { reload }] = useUploadsList()
- // reload the uploads list when the space changes
- // TODO: this currently does a network request - we'd like to just reset
- // to the latest state we have and revalidate in the background (SWR)
- // but it's not clear how all that state should work yet - perhaps
- // we need some sort of state management primitive in the uploads list?
- useEffect(() => {
- void reload()
- }, [space])
- const registered = Boolean(space?.registered())
- return (
-