AppLogoPicker
A circular avatar/logo upload — an image ring with a hover overlay and a loading state.
<app-logo-picker name="logo" overlay-label="Update photo" /><app-logo-picker> is the round upload for an identity image — a workspace logo, a company avatar, a profile picture. It shows a circular ring with the current image (or a placeholder) and a hover overlay that invites an update. It's the picker you use in a settings header, not in a form list.
Its look comes entirely from the shared @webority/theme, so the Razor <app-logo-picker> and the React <AppLogoPicker> render identically on every Webority surface. Never hand-roll a raw <input type="file">.
Playground
Every meaningful attribute, live. Each change re-renders the real tag helper on the server, so the markup underneath is the exact call that produced the ring above it.
The upload ring
With no image, the ring shows a placeholder. Hover reveals the update overlay; picking a validated file replaces the image.
Show code
<app-logo-picker name="workspaceLogo" overlay-label="Upload workspace logo" />
AppAvatar.Removing an image
Every freshly-picked image gets a × on the ring to undo it — no attribute needed. For a pre-existing (server) image, add removable so its × shows at load and clears the value.
Show code
<app-logo-picker name="logo" value="/img.png" removable="true" />
Variants
Two placeholder styles for the empty state. initials (default) shows the letters you pass as fallback; avatar shows the standard avatar disc — a person icon when no initials are given. Both upload an image the same way.
Show code
<app-logo-picker variant="initials" fallback="WS" /> <app-logo-picker variant="avatar" fallback="WS" /> <app-logo-picker variant="avatar" /> <!-- no fallback → person icon -->
Sizes
size takes a preset (sm · md · lg) or an exact diameter in pixels. Whatever you pass, the whole control — ring, initials font, overlay and placeholder icon — scales from it.
Show code
<app-logo-picker size="sm" /> <app-logo-picker size="md" /> <app-logo-picker size="lg" />
Show code
<app-logo-picker size="56" /> <app-logo-picker size="96" /> <app-logo-picker size="140" />
Shapes
A logo is not always round. Choose circle (default), rounded or square to match the brand mark.
Show code
<app-logo-picker shape="circle" /> <app-logo-picker shape="rounded" /> <app-logo-picker shape="square" />
Label, hint & error
The ring can be a labelled form field — add a label (with required), hint text, and an inline error, just like the other inputs.
Show code
<app-logo-picker label="Company logo" required="true" hint="PNG or JPG, at least 200×200px." /> <app-logo-picker label="Company logo" required="true" error="Please upload a logo." />
Inline (profile row)
layout="inline" lays the ring on the left with a title/subtitle/hint column beside it — the account-settings avatar row: name, role, and the allowed-files line on one line.
Show code
<app-logo-picker layout="inline" fallback="IJ" title="Ishita Jindal" subtitle="Admin"
hint="Allowed *.jpeg, *.jpg, *.png · Square image, max 5 MB" />
layout="inline" or layout="profile". In the default stacked layout the ring stands alone with the hint below it.Profile (vertical)
layout="profile" is the vertical form of the same identity block — ring on top, with the title/subtitle/hint centred beneath it. An account card or a directory tile.
Show code
<app-logo-picker layout="profile" fallback="IJ" title="Ishita Jindal" subtitle="Admin"
hint="Allowed *.jpeg, *.jpg, *.png · Square image, max 5 MB" />
Overlay label
The hover overlay text is yours to set — “Update photo” by default, but “Change logo” or “Upload avatar” read better in the right context.
Show code
<app-logo-picker name="companyLogo" overlay-label="Change logo" overlay-icon="upload" aria-label="Change company logo" />
Loading & disabled
While a pick is uploading, use loading — the ring shows a spinner and the control is blocked. Use disabled for a read-only picker, which dims the ring and drops the overlay.
loading shows a spinner and blocks interaction; disabled is a static, dimmed, non-interactive ring.Show code
<app-logo-picker loading="true" /> <app-logo-picker disabled="true" />
When to use
Use it when
- An identity image is being set — a workspace logo, a company avatar, a profile picture.
- The upload lives in a header or settings panel, shown as a round ring.
- You want a hover-to-change overlay plus a loading state while the file uploads.
Reach for something else when
- A single, rectangular image where the preview should be large. → AppFilePicker
- A file attached to a record where the name/size matters. → AppFileAttachment
- You only need to display an avatar, not upload one. → AppAvatar
- You hand-roll a raw <input type="file"> with a circular mask. → AppLogoPicker
Best practices
Every option
The whole surface of the component, one cell per value.
variant — with and without fallback
variant="initials" fallback="WS"variant="avatar" fallback="WS"variant="avatar" (no fallback → person icon)size — presets and an exact px
size="sm"size="md"size="lg"size="72" — exact pixel diametershape — every value
shape="circle"shape="rounded"shape="square"state
(default)loading="true"disabled="true"value (removable="false") — no × shownvalue removable="true" — × shownrequired="true" error="…"overlay — icon and label
overlay-icon="image"overlay-icon="camera"overlay-icon="upload"Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| name | string | — | Form field name for the posted file input. |
| value | string | — | Current image URL; when empty the placeholder ring is shown. |
| accept | string | image/png,image/jpeg,image/webp | Accepted MIME types for the file input. |
| overlay-label | string | Update photo | Text shown in the hover overlay; also the button’s accessible name. |
| removable | bool | false | Show the × for a pre-existing value image at load (a just-picked image is always removable). React onRemove. |
| loading | bool | false | Shows a spinner in the ring and blocks interaction while the pick uploads. |
| disabled | bool | false | Static, dimmed, non-interactive ring (read-only). |
| variant | initials | avatar | initials | Placeholder style — initials text, or a standard avatar disc (person icon when no initials). |
| size | sm | md | lg | <px> | md | Ring diameter — a preset or an exact px value (e.g. size="96"); the whole control scales from it. |
| shape | circle | rounded | square | circle | Ring shape for non-round logos. |
| layout | stacked | inline | profile | stacked | stacked = ring with hint below; inline = profile row (ring left, title/subtitle/hint beside); profile = same identity block centred beneath the ring. |
| title | string | — | Bold primary text with the ring — inline/profile layouts only. |
| subtitle | string | — | Muted secondary text with the ring — inline/profile layouts only. |
| label | string | — | Optional field label above the ring. |
| hint | string | — | Helper text — below the ring when stacked, in the side column when inline. |
| error | string | — | Inline error below the ring. |
| required | bool | false | Show a required marker next to the label. |
| aria-label | string | Upload photo | Accessible name for the button (React ariaLabel). |
| fallback | string | — | Initials/text shown when there is no image (React fallback). |
| overlay-icon | string | image | Bootstrap Icons glyph for the hover overlay (React overlayIcon). |
| max-size-mb | int | 5 | Maximum accepted file size in MB (React maxSizeMb). Unset means 5. 0 or less means no size limit. |