Restructure into pnpm monorepo with game shell, docs, and SpacetimeDB backend
- Restructure flat static prototype into pnpm workspace monorepo - apps/game: playable shell with R3F 3D scene, HUD, SpacetimeDB connection - apps/docs: design docs and prototypes - apps/site: landing page - packages/ui: shared Button and Panel primitives - services/spacetimedb: backend module (9 tables, 11 reducers) - Archive legacy static files to archive/legacy-static/ - Game loop: connect, undock, target, approach, dock, mine, sell - Add pnpm-workspace.yaml, tsconfig.base.json, spacetime.json
This commit is contained in:
55
packages/ui/src/primitives/Button.tsx
Normal file
55
packages/ui/src/primitives/Button.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import type { ButtonHTMLAttributes, AnchorHTMLAttributes, ReactNode } from "react";
|
||||
|
||||
type ButtonTone = "primary" | "secondary" | "ghost";
|
||||
|
||||
type BaseProps = {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
tone?: ButtonTone;
|
||||
};
|
||||
|
||||
type NativeButtonProps = BaseProps &
|
||||
ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
href?: never;
|
||||
};
|
||||
|
||||
type AnchorButtonProps = BaseProps &
|
||||
AnchorHTMLAttributes<HTMLAnchorElement> & {
|
||||
href: string;
|
||||
};
|
||||
|
||||
export type ButtonProps = NativeButtonProps | AnchorButtonProps;
|
||||
|
||||
const tones: Record<ButtonTone, string> = {
|
||||
primary: "border-accent bg-accent text-bg hover:bg-accent-hover",
|
||||
secondary: "border-border bg-surface-raised text-fg hover:border-border-light hover:bg-surface-hover",
|
||||
ghost: "border-transparent bg-transparent text-cyan hover:border-border-light hover:bg-surface",
|
||||
};
|
||||
|
||||
export function Button({ children, className = "", tone = "secondary", ...props }: ButtonProps) {
|
||||
const classes = [
|
||||
"inline-flex min-h-10 cursor-pointer items-center justify-center gap-2 rounded-md border px-4 py-2 text-sm font-semibold transition-colors duration-150 disabled:cursor-not-allowed disabled:opacity-55",
|
||||
tones[tone],
|
||||
className,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
|
||||
if ("href" in props) {
|
||||
const anchorProps = props as Omit<AnchorButtonProps, keyof BaseProps>;
|
||||
|
||||
return (
|
||||
<a className={classes} {...anchorProps}>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
const buttonProps = props as Omit<NativeButtonProps, keyof BaseProps>;
|
||||
|
||||
return (
|
||||
<button className={classes} {...buttonProps}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user