Headless / Files & documents
Change your avatar
Pick a photo, crop it in a dialog, and store the result in a bucket. The crop, the transforms, the background fill and the filters are local work from image-crop, a client-only service; storing the result is file-storage's, which is why these parts ship with it. The picture's URL comes back through onChange, so the same parts serve a user's avatar, an organization's logo, or any square image.
32 public parts · 2examples
@slices.sh/file-storage/headless/avatarView as Markdown ↗Your design. Our behavior.
Explore the tree to see what each part controls. Gates reveal the relevant state; roots outline their scope.
Avatar.Root · Scope
Installation
Choose what your component needs. Run these commands in an initialized Next.js app.
Before you start
The steps below run in a Next.js app with shadcn set up (it has a components.json). In an existing Next.js app, such as one from create-next-app, set shadcn up first:
npx shadcn@latest init -t next -b base -p novaOr start fresh: the slices CLI creates the app and sets it up.
npx slices.sh installInstall the service registry
Adds services/index.ts, which import "@/services" loads. A provider setup writes the same file, so skip this if your app has one.
npx add servicesInstall the headless library
npmAdd the React parts to your app, then compose them with your own elements.
npm install @slices.sh/file-storage@^0.2.7Import from @slices.sh/file-storage/headless/avatar.
Install the service
Connect the parts to a provider. Skip this step if this service is already configured in your app.
npx add file-storage.localAdds service configuration and API routes to your app, with the provider dependencies. For a headless composition, add import "@/services" after "use client".
The slices CLI installs the service and provisions its required resources in one command.
Provider setup notes
- Add .data/ to .gitignore: the bytes and the index live there.
- This store lives on one disk. A serverless deployment loses the files between requests, so deploy with @slices.sh/file-storage.s3.
- A screen works in a bucket, a private corner of the config ("files" by default). The config lists the ones its screens work in (`buckets`, which installs grow); list more, or a prefix such as "playground/", in `buckets` in services/file-storage/rules.ts. Any other is not-found.
- Set maxUploadBytes and accept in services/file-storage/default.config.ts: nothing is capped until you do.
Start small
Parts bring the behavior. Use their default elements, or supply your own with render.
"use client"// services/index.ts comes from https://slices.sh/r/services.json (or any provider setup)import "@/services"import { Avatar } from "@slices.sh/file-storage/headless/avatar"export function Example({ onChange }: { onChange: (url: string) => void }) { return ( <Avatar.Root onChange={onChange}> <Avatar.DropZone> <Avatar.Image /> <Avatar.Picker aria-label="Choose a photo" /> </Avatar.DropZone> <Avatar.Content> <Avatar.Crop shape="circle"> <Avatar.CropForm> <Avatar.Viewport> <Avatar.SourceImage /> <Avatar.Selection /> </Avatar.Viewport> <Avatar.Apply>Use photo</Avatar.Apply> </Avatar.CropForm> </Avatar.Crop> </Avatar.Content> </Avatar.Root> )}onChange receives the stored image URL. Save it to your profile in your application handler.
API reference
Every public part used by this experience is listed below. Gates render children without adding an element. Element parts accept native element props and render; function children receive the state declared in their props. Scopes provide context rather than a visual element.
Avatar.Rootscope
Image is <img alt=""> with src locked to the current picture: the stored one, the local one, or the initial URL. Empty renders its children while there is no picture, for a placeholder icon.
Props
6 documented props
| Prop | Type | Default |
|---|---|---|
configThe file-storage config, a slug from the registry. The nearest root's, else | string | — |
enabledLeft out or | Enabled | — |
bucket | string | — |
initialUrl | string | — |
value | string | — |
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/root.tsx
Avatar.Emptygate
Image is <img alt=""> with src locked to the current picture: the stored one, the local one, or the initial URL. Empty renders its children while there is no picture, for a placeholder icon.
Required scope
Avatar.Empty requires Avatar.Root.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/empty.tsx
Avatar.DropZonecontent · <label>
DropZone is a <label> that takes a dropped or pasted image as well as a click. Picker is the file input inside it, accepting JPEG, PNG and WebP, and disabled while an upload runs. Hint's function child gets { limit }, the size the cropper enforces, so the words never drift from it.
Required scope
Avatar.DropZone requires Avatar.Root.
Props
2 documented props · Native <label> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/drop-zone.tsx
Avatar.Pickerinput · <input>
DropZone is a <label> that takes a dropped or pasted image as well as a click. Picker is the file input inside it, accepting JPEG, PNG and WebP, and disabled while an upload runs. Hint's function child gets { limit }, the size the cropper enforces, so the words never drift from it.
Required scope
Avatar.Picker requires Avatar.Root.
Props
2 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/picker.tsx
Avatar.Hintcontent · <span>
The picker's hint. Its function child receives the size limit the cropper enforces, so the words never drift from it.
Props
2 documented props · Native <span> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { limit: string }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/hint.tsx
Avatar.Contentcontent · <div>
Content is the dialog, open while a source is chosen; Title and Description label it. Crop is the crop primitive, with shape ("circle" | "square"), minZoom and maxZoom, and remounts for each new source so nothing leaks from the last photo. CropForm submits on Enter and handles the keyboard: arrows nudge, + and - zoom, R rotates, 0 resets. Viewport takes the photo's own proportions and paints the chosen fill behind it. SourceImage is the photo, Selection the draggable frame, and Grid a guide on one axis, shown only while panning.
Required scope
Avatar.Content requires Avatar.Root.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/content.tsx
Avatar.Titlecontent · <h2>
Content is the dialog, open while a source is chosen; Title and Description label it. Crop is the crop primitive, with shape ("circle" | "square"), minZoom and maxZoom, and remounts for each new source so nothing leaks from the last photo. CropForm submits on Enter and handles the keyboard: arrows nudge, + and - zoom, R rotates, 0 resets. Viewport takes the photo's own proportions and paints the chosen fill behind it. SourceImage is the photo, Selection the draggable frame, and Grid a guide on one axis, shown only while panning.
Props
2 documented props · Native <h2> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/title.tsx
Avatar.Descriptioncontent · <p>
Content is the dialog, open while a source is chosen; Title and Description label it. Crop is the crop primitive, with shape ("circle" | "square"), minZoom and maxZoom, and remounts for each new source so nothing leaks from the last photo. CropForm submits on Enter and handles the keyboard: arrows nudge, + and - zoom, R rotates, 0 resets. Viewport takes the photo's own proportions and paints the chosen fill behind it. SourceImage is the photo, Selection the draggable frame, and Grid a guide on one axis, shown only while panning.
Props
2 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/description.tsx
Avatar.Cropcontent · <div>
A changed source remounts the primitive so crop, zoom, fill, filter and transforms cannot leak to the next photo.
Required scope
Avatar.Crop requires Avatar.Root.
Props
5 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
shape | CropShape | "circle" |
minZoom | number | — |
maxZoom | number | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/crop.tsx
Avatar.CropFormaction · <form>
Content is the dialog, open while a source is chosen; Title and Description label it. Crop is the crop primitive, with shape ("circle" | "square"), minZoom and maxZoom, and remounts for each new source so nothing leaks from the last photo. CropForm submits on Enter and handles the keyboard: arrows nudge, + and - zoom, R rotates, 0 resets. Viewport takes the photo's own proportions and paints the chosen fill behind it. SourceImage is the photo, Selection the draggable frame, and Grid a guide on one axis, shown only while panning.
Required scope
Avatar.CropForm requires Avatar.Crop.
Avatar.CropForm requires Avatar.Root.
Props
2 documented props · Native <form> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/crop-form.tsx
Avatar.Viewportcontent · <div>
The primitive pans and exports as if the photo exactly fills this box, so the box takes the photo's own proportions. In a square box a wide photo showed past the crop but could not be dragged there, and its edges were out of reach at every zoom. Until the photo has a size the box has no height, so the primitive first measures it at its final shape and centres the crop. A chosen background fill is painted here, behind the photo, which is where the export puts it.
Required scope
Avatar.Viewport requires Avatar.Crop.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/viewport.tsx
Avatar.SourceImagecontent · <img>
Content is the dialog, open while a source is chosen; Title and Description label it. Crop is the crop primitive, with shape ("circle" | "square"), minZoom and maxZoom, and remounts for each new source so nothing leaks from the last photo. CropForm submits on Enter and handles the keyboard: arrows nudge, + and - zoom, R rotates, 0 resets. Viewport takes the photo's own proportions and paints the chosen fill behind it. SourceImage is the photo, Selection the draggable frame, and Grid a guide on one axis, shown only while panning.
Required scope
Avatar.SourceImage requires Avatar.Crop.
Avatar.SourceImage requires Avatar.Root.
Props
2 documented props · Native <img> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/source-image.tsx
Avatar.Selectioncontent · <div>
Content is the dialog, open while a source is chosen; Title and Description label it. Crop is the crop primitive, with shape ("circle" | "square"), minZoom and maxZoom, and remounts for each new source so nothing leaks from the last photo. CropForm submits on Enter and handles the keyboard: arrows nudge, + and - zoom, R rotates, 0 resets. Viewport takes the photo's own proportions and paints the chosen fill behind it. SourceImage is the photo, Selection the draggable frame, and Grid a guide on one axis, shown only while panning.
Required scope
Avatar.Selection requires Avatar.Crop.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/selection.tsx
Avatar.Gridcontent · <div>
Content is the dialog, open while a source is chosen; Title and Description label it. Crop is the crop primitive, with shape ("circle" | "square"), minZoom and maxZoom, and remounts for each new source so nothing leaks from the last photo. CropForm submits on Enter and handles the keyboard: arrows nudge, + and - zoom, R rotates, 0 resets. Viewport takes the photo's own proportions and paints the chosen fill behind it. SourceImage is the photo, Selection the draggable frame, and Grid a guide on one axis, shown only while panning.
Required scope
Avatar.Grid requires Avatar.Crop.
Props
3 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
axisRequired | "horizontal" | "vertical" | — |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/grid.tsx
Avatar.Previewcontent · <canvas>
Fill is one background choice with aria-pressed locked; without color it keeps the photo's transparency. Filter is one filter choice (value) and FilterImage shows the photo through it. Preview is a canvas at a given resolution that draws what Apply would store, fill and filter included.
Required scope
Avatar.Preview requires Avatar.Crop.
Avatar.Preview requires Avatar.Root.
Props
3 documented props · Native <canvas> attributes supported
| Prop | Type | Default |
|---|---|---|
resolution | 24 | 40 | 72 | 72 |
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/preview.tsx
Avatar.Zoominput · <input>
Zoom is a range input with min, max, step and value locked to the crop. Rotate turns by 90 degrees, Flip mirrors horizontally, Reset returns to the first framing.
Required scope
Avatar.Zoom requires Avatar.Crop.
Props
2 documented props · Native <input> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/zoom.tsx
Avatar.Rotateaction · <button>
Zoom is a range input with min, max, step and value locked to the crop. Rotate turns by 90 degrees, Flip mirrors horizontally, Reset returns to the first framing.
Required scope
Avatar.Rotate requires Avatar.Crop.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/rotate.tsx
Avatar.Flipaction · <button>
Zoom is a range input with min, max, step and value locked to the crop. Rotate turns by 90 degrees, Flip mirrors horizontally, Reset returns to the first framing.
Required scope
Avatar.Flip requires Avatar.Crop.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/flip.tsx
Avatar.Fillaction · <button>
One background choice. Without a `color` it is the photo's own transparency.
Required scope
Avatar.Fill requires Avatar.Crop.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
color | string | — |
childrenContent rendered inside this part. | ReactNode | ((state: { active: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/fill.tsx
Avatar.Resetaction · <button>
Zoom is a range input with min, max, step and value locked to the crop. Rotate turns by 90 degrees, Flip mirrors horizontally, Reset returns to the first framing.
Required scope
Avatar.Reset requires Avatar.Crop.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/reset.tsx
Avatar.Filteraction · <button>
One filter choice; `Avatar.FilterImage` inside it shows the photo with that filter.
Required scope
Avatar.Filter requires Avatar.Crop.
Props
3 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
valueRequired | AvatarFilter | — |
childrenContent rendered inside this part. | ReactNode | ((state: { active: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/filter-option.tsx
Avatar.FilterImagecontent · <img>
Fill is one background choice with aria-pressed locked; without color it keeps the photo's transparency. Filter is one filter choice (value) and FilterImage shows the photo through it. Preview is a canvas at a given resolution that draws what Apply would store, fill and filter included.
Required scope
Avatar.FilterImage requires Avatar.Root.
Avatar.FilterImage requires Avatar.Filter.
Props
2 documented props · Native <img> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/filter-image.tsx
Avatar.Cancelaction · <button>
Apply is the crop form's submit, with { pending } while the export runs, disabled until the photo has a size. Cancel closes the dialog and drops the source.
Required scope
Avatar.Cancel requires Avatar.Root.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/cancel.tsx
Avatar.Applyaction · <button>
Apply is the crop form's submit, with { pending } while the export runs, disabled until the photo has a size. Cancel closes the dialog and drops the source.
Required scope
Avatar.Apply requires Avatar.Crop.
Avatar.Apply requires Avatar.Root.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { pending: boolean }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/apply.tsx
Avatar.Imagecontent · <img>
Image is <img alt=""> with src locked to the current picture: the stored one, the local one, or the initial URL. Empty renders its children while there is no picture, for a placeholder icon.
Required scope
Avatar.Image requires Avatar.Root.
Props
2 documented props · Native <img> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/image.tsx
Avatar.Savedgate
After Apply. Progress is a progressbar while the upload runs. Saved opens once the picture is stored. Retry sends a failed upload again; Undo restores the picture from before, or discards a local one. Feedback is <p role="alert"> with { message } for a refused file or upload; with crop it reports the crop's own errors instead. Local opens when the picture is kept in the page session because no storage is configured. MissingConfiguration is Configuration.Missing pinned to scope="file-storage", learned when a save meets a server that lacks its configuration.
Required scope
Avatar.Saved requires Avatar.Root.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/saved.tsx
Avatar.Undoaction · <button>
After Apply. Progress is a progressbar while the upload runs. Saved opens once the picture is stored. Retry sends a failed upload again; Undo restores the picture from before, or discards a local one. Feedback is <p role="alert"> with { message } for a refused file or upload; with crop it reports the crop's own errors instead. Local opens when the picture is kept in the page session because no storage is configured. MissingConfiguration is Configuration.Missing pinned to scope="file-storage", learned when a save meets a server that lacks its configuration.
Required scope
Avatar.Undo requires Avatar.Root.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/undo.tsx
Avatar.Localgate
After Apply. Progress is a progressbar while the upload runs. Saved opens once the picture is stored. Retry sends a failed upload again; Undo restores the picture from before, or discards a local one. Feedback is <p role="alert"> with { message } for a refused file or upload; with crop it reports the crop's own errors instead. Local opens when the picture is kept in the page session because no storage is configured. MissingConfiguration is Configuration.Missing pinned to scope="file-storage", learned when a save meets a server that lacks its configuration.
Required scope
Avatar.Local requires Avatar.Root.
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/local.tsx
Avatar.Progresscontent · <div>
After Apply. Progress is a progressbar while the upload runs. Saved opens once the picture is stored. Retry sends a failed upload again; Undo restores the picture from before, or discards a local one. Feedback is <p role="alert"> with { message } for a refused file or upload; with crop it reports the crop's own errors instead. Local opens when the picture is kept in the page session because no storage is configured. MissingConfiguration is Configuration.Missing pinned to scope="file-storage", learned when a save meets a server that lacks its configuration.
Required scope
Avatar.Progress requires Avatar.Root.
Props
2 documented props · Native <div> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/progress.tsx
Avatar.Feedbackcontent · <p>
After Apply. Progress is a progressbar while the upload runs. Saved opens once the picture is stored. Retry sends a failed upload again; Undo restores the picture from before, or discards a local one. Feedback is <p role="alert"> with { message } for a refused file or upload; with crop it reports the crop's own errors instead. Local opens when the picture is kept in the page session because no storage is configured. MissingConfiguration is Configuration.Missing pinned to scope="file-storage", learned when a save meets a server that lacks its configuration.
Required scope
Avatar.Feedback requires Avatar.Root.
Props
3 documented props · Native <p> attributes supported
| Prop | Type | Default |
|---|---|---|
crop | boolean | false |
childrenContent rendered inside this part. | ReactNode | ((state: { message: string }) => ReactNode) | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/feedback.tsx
Avatar.Retryaction · <button>
After Apply. Progress is a progressbar while the upload runs. Saved opens once the picture is stored. Retry sends a failed upload again; Undo restores the picture from before, or discards a local one. Feedback is <p role="alert"> with { message } for a refused file or upload; with crop it reports the crop's own errors instead. Local opens when the picture is kept in the page session because no storage is configured. MissingConfiguration is Configuration.Missing pinned to scope="file-storage", learned when a save meets a server that lacks its configuration.
Required scope
Avatar.Retry requires Avatar.Root.
Props
2 documented props · Native <button> attributes supported
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | — |
renderReplace the default element with your own while retaining the part’s behavior and accessibility. | ReactElement | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/retry.tsx
Avatar.MissingConfigurationgate
The server this avatar is stored on answered that it lacks configuration. Saving is the one request an avatar makes, so this is learned when somebody applies a crop, and not before: nothing is drawn for a deployment that has not said so. → docs/rules/missing-configuration-is-said.md
Props
1 documented props
| Prop | Type | Default |
|---|---|---|
childrenContent rendered inside this part. | ReactNode | ((state: { scopes: readonly string[] }) => ReactNode) | — |
Required props are marked. A dash means no explicit default is declared in this component.
Source: @slices.sh/file-storage/src/headless/avatar/missing-configuration.tsx
When something is missing
- No service configuration
- Install the file-storage setup below and import "@/services". Required service roots report missing setup; gates do not replace that configuration.
- Missing capability or parent scope
- Follow each part’s context requirements and the example composition. Capability-aware controls hide when the provider cannot perform their action.