Logo
A brand mark that follows the room it has: the full artwork while the rail is open, the square mark once it collapses. Falls back to the product name, and to its initials when only 52px are left.
src/components/ui/logo.tsxAbout
From the component's own source, where it was written.
A brand mark that answers to how much room it has.
A rail shows a wordmark when it is open and a square mark when it collapses to 52px, and the usual way to get that is two copies of the artwork with opposing visibility classes on them. That works, and it is the thing everyone rewrites per project — including this repo, where the same trick was inlined in the examples' shell and again in the sidebar's own documentation, once with a cropped viewBox to fake the square version.
The switch is CSS by default, keyed off the sidebar's data-state. That is deliberate: reading the sidebar's context would make every project that runs add logo install a sidebar it may not have, and the mark belongs in headers and login screens too. Outside a rail nothing matches the selector, so the full artwork shows and stays shown.
collapsed overrides it. Pass a boolean when something other than a sidebar decides — a header that shrinks on scroll, a canvas that zooms — and only that one mark renders, which is also the way to avoid fetching both files.
The accessible name lives on the container and everything inside it is hidden from assistive technology. Two copies of a logo are one logo, and a reader should not hear the company's name twice for a decision made in CSS.
Install
npx astralyx-ui add logo
Usage
import { Logo } from '@/components/ui/logo'
<Logo
icon="/mark.svg"
full="/logo.svg"
alt="Acme"
fallbackText="Acme"
/>Composer
Change the props and the source below follows.
<Logo
collapsed={false}
icon={<Mark />}
full={<Wordmark />}
alt="Acme"
fallbackText="Acme Corp"
/>Examples
In a rail that collapses
<Logo icon={<Mark />} full={<Wordmark />} alt="Acme" fallbackText="Acme" />No artwork — the name, then its initials
<Logo alt="Acme Corp" fallbackText="Acme Corp" /> <Logo alt="Acme Corp" fallbackText="Acme Corp" collapsed />
A URL that does not resolve falls through to the text
<Logo full="/does-not-exist.svg" alt="Acme" fallbackText="Acme" />
API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
Logo
Extends Omit<ComponentProps<'span'>, 'children'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| icon | LogoSource | — | The square mark, shown once the rail collapses. A URL renders as an image; anything else renders as given. |
| full | LogoSource | — | The full artwork, shown while there is room for it. |
| alt | string | required | The accessible name, set on the container so a reader hears it once whichever rendition is showing. Empty means decorative — use that when the product name is already written beside it. |
| fallbackText | string | '' | Drawn when there is no artwork or an image fails to load. Collapsed it becomes initials, because a name does not fit in 52px. |
| collapsed | boolean | — | Overrides the sidebar. Left off, the switch is CSS keyed to the rail's data-state, so the component needs no context and works outside one. |
Types
| Type | Definition | Description |
|---|---|---|
LogoSource | string | ReactNode | — |
Behaviour
| Topic | Detail | Description |
|---|---|---|
| accessibility | — | Both renditions are in the DOM when the switch is left to CSS, so the name is on the container and the contents are presentational. Two copies of a logo are one logo. |
| both renditions | — | Leaving the switch to CSS puts both images in the document, and a browser fetches both. Pass collapsed when you already have the state — then only one renders. |