Add bunext playground for local component development
Runs at http://localhost:7010 via bun run dev. The playground imports the library from src through a committed symlink and tsconfig path alias, so component edits hot-reload without a build step. It has its own install root and is excluded from the published package.
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
import { useState } from "react";
|
||||
import { ArrowRight, Download, Plus, Sparkles, Trash2 } from "lucide-react";
|
||||
import Button, {
|
||||
TWUIButtonColors,
|
||||
TWUIButtonSizes,
|
||||
TWUIButtonVariants,
|
||||
} from "@moduletrace/twui/layout/Button";
|
||||
import Divider from "@moduletrace/twui/layout/Divider";
|
||||
import H1 from "@moduletrace/twui/layout/H1";
|
||||
import P from "@moduletrace/twui/layout/P";
|
||||
import Row from "@moduletrace/twui/layout/Row";
|
||||
import Span from "@moduletrace/twui/layout/Span";
|
||||
import Stack from "@moduletrace/twui/layout/Stack";
|
||||
import DemoSection from "../(components)/DemoSection";
|
||||
|
||||
export default function ButtonsPage() {
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
function save() {
|
||||
setSaving(true);
|
||||
window.setTimeout(() => setSaving(false), 1500);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack className="w-full gap-10">
|
||||
<Stack className="gap-2">
|
||||
<H1 className="!mb-0">Buttons</H1>
|
||||
<P className="!pt-0 opacity-70">
|
||||
Every color is paired with the three variants. Classes are
|
||||
merged with <code>twMerge</code>, so a consumer{" "}
|
||||
<code>className</code> always wins.
|
||||
</P>
|
||||
</Stack>
|
||||
|
||||
{TWUIButtonVariants.map((variant) => (
|
||||
<DemoSection
|
||||
key={variant}
|
||||
title={`${variant} variant`}
|
||||
description={`variant="${variant}" across TWUIButtonColors.`}
|
||||
>
|
||||
<Row className="gap-3">
|
||||
{TWUIButtonColors.map((color) => (
|
||||
<Button
|
||||
key={color}
|
||||
title={`${color} ${variant} button`}
|
||||
color={color}
|
||||
variant={variant}
|
||||
>
|
||||
{color}
|
||||
</Button>
|
||||
))}
|
||||
</Row>
|
||||
</DemoSection>
|
||||
))}
|
||||
|
||||
<DemoSection
|
||||
title="Sizes"
|
||||
description="smaller, small, normal, large and larger."
|
||||
>
|
||||
<Row className="items-center gap-3">
|
||||
{TWUIButtonSizes.map((size) => (
|
||||
<Button
|
||||
key={size}
|
||||
title={`${size} button`}
|
||||
size={size}
|
||||
>
|
||||
{size}
|
||||
</Button>
|
||||
))}
|
||||
</Row>
|
||||
</DemoSection>
|
||||
|
||||
<DemoSection
|
||||
title="Icons and loading"
|
||||
description="Icons accept a lucide name or a React element. Loading keeps the label in place and swaps in a spinner."
|
||||
>
|
||||
<Row className="gap-3">
|
||||
<Button
|
||||
title="Create button"
|
||||
beforeIcon={<Plus size={16} />}
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
<Button
|
||||
title="Sparkle button"
|
||||
color="secondary"
|
||||
afterIcon={<Sparkles size={16} />}
|
||||
>
|
||||
Enhance
|
||||
</Button>
|
||||
<Button
|
||||
title="Download button"
|
||||
color="success"
|
||||
after_icon_name="Download"
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
<Button
|
||||
title="Delete button"
|
||||
color="error"
|
||||
variant="outlined"
|
||||
beforeIcon={<Trash2 size={16} />}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
<Button
|
||||
title="Saving button"
|
||||
color="primary"
|
||||
loading={saving}
|
||||
onClick={save}
|
||||
>
|
||||
{saving ? "Saving" : "Save changes"}
|
||||
</Button>
|
||||
<Button
|
||||
title="Disabled button"
|
||||
disabled
|
||||
color="gray"
|
||||
variant="outlined"
|
||||
>
|
||||
Disabled
|
||||
</Button>
|
||||
</Row>
|
||||
</DemoSection>
|
||||
|
||||
<DemoSection
|
||||
title="Links and arrows"
|
||||
description="Passing href renders an anchor around the button markup."
|
||||
>
|
||||
<Stack className="gap-3">
|
||||
<Row className="gap-3">
|
||||
<Button
|
||||
title="Open buttons page"
|
||||
href="#"
|
||||
afterIcon={<ArrowRight size={16} />}
|
||||
>
|
||||
Anchor button
|
||||
</Button>
|
||||
<Button
|
||||
title="Download from link"
|
||||
href="#"
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
before_icon_name="Download"
|
||||
>
|
||||
Outlined link
|
||||
</Button>
|
||||
</Row>
|
||||
<Divider />
|
||||
<Row className="gap-2">
|
||||
<Span variant="faded" size="small">
|
||||
Sizes map to the lucide icon scale too:
|
||||
</Span>
|
||||
<Button
|
||||
title="Smaller download"
|
||||
size="smaller"
|
||||
variant="ghost"
|
||||
beforeIcon={<Download size={14} />}
|
||||
>
|
||||
Smaller
|
||||
</Button>
|
||||
<Button
|
||||
title="Larger arrow"
|
||||
size="larger"
|
||||
variant="ghost"
|
||||
afterIcon={<ArrowRight size={20} />}
|
||||
>
|
||||
Larger
|
||||
</Button>
|
||||
</Row>
|
||||
</Stack>
|
||||
</DemoSection>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user