recipes/icons/page.tsx
One file of recipes/icons, at commit 9a5bb24.
// A page that names icons the three ways there are.
//
// Nothing here draws an icon. The stack ships no drawings (design 144), so every glyph on this
// page comes from the set the recipe installed, and the three ways differ in when the drawing is
// decided: at build time, at import time, or when the page runs.
import { mutable } from '@aweftjs/core';
import { Button, Card, Icon, Icons, Theme, h, light } from '@aweftjs/ui';
import standard from '@aweftjs/icons/lucide/+standard';
Theme.define({
page: {
display: 'flex',
flexDirection: 'column',
gap: '$space5',
padding: '$space6',
fontFamily: '$font',
background: '$background',
color: '$foreground',
},
strip: { display: 'flex', alignItems: 'center', gap: '$space4' },
});
/** The name the run-time lookup asks for. A variable, so the build cannot see it. */
const LATE = 'lucide:anchor';
/** The icon the bundle must not carry, so the check that it does not is checking something. */
export const unnamed = LATE;
export interface PageProps {
/**
* Where the late name is answered from: `fromUrl` over the icon route in a browser, and the
* icons a server already resolved when a page it rendered is being taken over.
*/
readonly icons?: unknown;
}
export const Page = (props: PageProps): unknown => {
const late = mutable<unknown>(LATE);
return (
<main theme="page" id="page">
<h1 theme={['text', '2xl', 'heading']} id="title">Three ways to name an icon</h1>
{/* One: written out, so the build imports that one icon and nothing else. */}
<Card id="named">
<p theme={['text', 'sm', 'muted']}>Named in the source</p>
<div theme="strip">
<Icon name="lucide:check" label="done" id="icon-named" />
<Icon name="lucide:star" size="2rem" label="starred" id="icon-named-big" />
</div>
</Card>
{/* Two: a standard name, answered by whatever pack the page put in front. */}
<Icons value={standard}>
<Card id="standard">
<p theme={['text', 'sm', 'muted']}>A standard name, from the set's standard selection</p>
<div theme="strip">
<Button label="More" icon={<Icon name="chevron-down" />} id="button-standard" />
<Icon name="triangle-alert" label="careful" id="icon-standard" />
</div>
</Card>
</Icons>
{/* Three: a name the page only has when it runs, fetched from the icon route. */}
<Icons value={props.icons}>
<Card id="fetched">
<p theme={['text', 'sm', 'muted']}>Fetched by name when the page runs</p>
<div theme="strip"><Icon name={late} label="anchor" id="icon-fetched" /></div>
</Card>
</Icons>
</main>
);
};
/** The page inside the theme it is drawn in, which is what both the browser and Node mount. */
export const Site = (props: PageProps): unknown => h(Theme, { value: light }, h(Page, { icons: props.icons }));