tpmjs/packages/ui/src/Button/Button.ts
Ajax Davis a6753cd8e6 feat: add light/dark theme system and full homepage with comprehensive UI components
Implement theme system:
- Add next-themes for theme management with light mode as default
- Swap CSS variable definitions in globals.css (light in :root, dark in .dark class)
- Create ThemeProvider component wrapping next-themes
- Create ThemeToggle component with sun/moon icons
- Update root layout with ThemeProvider

Build full homepage:
- Add Header component with navigation and theme toggle
- Create hero section with gradient background and search
- Add Featured Tools section with 6 tool cards (icons, badges, usage stats)
- Add Browse by Category section with 12 colored category tiles
- Add Platform Statistics section with 4 metric cards
- Add footer with copyright and links
- Create homePageData.ts with comprehensive mock data

Add Storybook stories:
- Icon.stories.ts (AllIcons, AllSizes, WithColors)
- Badge.stories.ts (Default, AllVariants, AllSizes, WithLongText)
- Input.stories.ts (Default, WithLabel, AllStates, AllSizes, PasswordInput)
- ProgressBar.stories.ts (Default, AllVariants, AllSizes, WithLabel, edge cases)
- CodeBlock.stories.ts (Default, multiple languages, LongCode)
- Tabs.stories.ts (Default, AllSizes, WithCounts, ManyTabs)

Fix production build issues:
- Export IconName type from Icon.ts
- Add sun and moon icons to icons.ts
- Fix Icon prop naming (icon not name)
- Fix Icon size constraints (remove xl, use lg)
- Update ThemeProvider types using ComponentProps
- Add explicit return types where needed
- Remove unused imports
- Replace forEach with for...of in variants system
- Fix template literals in storybook stories

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 01:29:28 +10:00

74 lines
1.6 KiB
TypeScript

import { cn } from "@tpmjs/utils/cn";
import { createElement, forwardRef } from "react";
import type { ButtonProps } from "./types";
import { buttonVariants } from "./variants";
/**
* Button component
*
* A versatile button component with multiple variants, sizes, and states.
* Built with .ts-only React using createElement.
*
* @example
* ```typescript
* import { Button } from '@tpmjs/ui/Button/Button';
* import { createElement } from 'react';
*
* function MyComponent() {
* return createElement(Button, {
* variant: 'outline',
* size: 'lg',
* onClick: () => console.log('clicked'),
* children: 'Click me',
* });
* }
* ```
*/
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
(
{
className,
variant = "default",
size = "md",
loading = false,
disabled = false,
children,
...props
},
ref,
) => {
return createElement(
"button",
{
type: "button",
className: cn(
buttonVariants({
variant,
size,
loading: loading ? "true" : "false",
}),
className,
),
ref,
disabled: disabled || loading,
"aria-disabled": disabled || loading ? "true" : undefined,
"aria-busy": loading ? "true" : undefined,
...props,
},
loading
? createElement(
"span",
{ className: "flex items-center gap-2" },
createElement("span", {
className:
"h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent",
"aria-hidden": "true",
}),
createElement("span", null, children),
)
: children,
);
},
);
Button.displayName = "Button";