fix: harden kumo base component styling

This commit is contained in:
2026-07-02 10:21:25 -07:00
parent 04f2dfc229
commit c394d85236
9 changed files with 234 additions and 13 deletions

View File

@@ -1,6 +1,8 @@
import * as React from "react";
import { Badge as KumoBadge } from "@cloudflare/kumo/components/badge";
import { cn } from "@/lib/utils";
type KumoBadgeProps = React.ComponentProps<typeof KumoBadge>;
type LegacyBadgeVariant = "default" | "secondary" | "outline" | "success" | "warning" | "danger";
@@ -19,8 +21,8 @@ export type BadgeProps = Omit<KumoBadgeProps, "variant" | "children"> & {
children?: React.ReactNode;
};
export function Badge({ variant = "default", ...props }: BadgeProps): React.ReactElement {
export function Badge({ className, variant = "default", ...props }: BadgeProps): React.ReactElement {
const mappedVariant = variant in variantMap ? variantMap[variant as LegacyBadgeVariant] : (variant as KumoBadgeProps["variant"]);
return <KumoBadge variant={mappedVariant} {...(props as KumoBadgeProps)} />;
return <KumoBadge className={cn("teatea-badge", className)} variant={mappedVariant} {...(props as KumoBadgeProps)} />;
}

View File

@@ -6,6 +6,8 @@ import {
type LinkButtonProps as KumoLinkButtonProps,
} from "@cloudflare/kumo/components/button";
import { cn } from "@/lib/utils";
type ButtonVariant = "default" | "secondary" | "outline" | "ghost" | "destructive";
type ButtonSize = "default" | "sm" | "lg" | "icon";
@@ -35,10 +37,11 @@ export type LinkButtonProps = Omit<KumoLinkButtonProps, "variant" | "size"> & {
};
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(
{ variant = "default", size = "default", ...props },
{ className, variant = "default", size = "default", ...props },
ref,
): React.ReactElement {
const kumoProps = {
className: cn("teatea-button", `teatea-button-${variant}`, className),
ref,
shape: size === "icon" ? "square" : "base",
size: sizeMap[size],
@@ -52,8 +55,16 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function
});
export const LinkButton = React.forwardRef<HTMLAnchorElement, LinkButtonProps>(function LinkButton(
{ variant = "default", size = "default", ...props },
{ className, variant = "default", size = "default", ...props },
ref,
): React.ReactElement {
return <KumoLinkButton ref={ref} size={sizeMap[size]} variant={variantMap[variant]} {...props} />;
return (
<KumoLinkButton
ref={ref}
className={cn("teatea-button", `teatea-button-${variant}`, className)}
size={sizeMap[size]}
variant={variantMap[variant]}
{...props}
/>
);
});

View File

@@ -6,7 +6,7 @@ export function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElemen
return (
<div
className={cn(
"overflow-hidden rounded-lg border border-kumo-line bg-kumo-base text-card-foreground shadow-sm",
"teatea-card overflow-hidden rounded-lg border border-kumo-line bg-kumo-base text-card-foreground shadow-sm",
className,
)}
{...props}
@@ -15,7 +15,7 @@ export function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElemen
}
export function CardHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.ReactElement {
return <div className={cn("flex flex-col gap-1.5 bg-kumo-elevated p-5", className)} {...props} />;
return <div className={cn("teatea-card-header flex flex-col gap-1.5 bg-kumo-elevated p-5", className)} {...props} />;
}
export function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>): React.ReactElement {

View File

@@ -3,6 +3,8 @@
import * as React from "react";
import { Checkbox as KumoCheckbox, type CheckboxProps as KumoCheckboxProps } from "@cloudflare/kumo/components/checkbox";
import { cn } from "@/lib/utils";
type CheckboxProps = Omit<KumoCheckboxProps, "checked" | "onCheckedChange"> & {
checked?: boolean;
defaultChecked?: boolean;
@@ -11,6 +13,7 @@ type CheckboxProps = Omit<KumoCheckboxProps, "checked" | "onCheckedChange"> & {
export function Checkbox({
checked,
className,
defaultChecked = false,
name,
onCheckedChange,
@@ -21,9 +24,10 @@ export function Checkbox({
const currentChecked = isControlled ? checked : uncontrolledChecked;
return (
<>
<span className="teatea-checkbox contents">
<KumoCheckbox
checked={currentChecked}
className={cn("teatea-checkbox-control", className)}
onCheckedChange={(nextChecked) => {
const booleanValue = Boolean(nextChecked);
if (!isControlled) {
@@ -34,6 +38,6 @@ export function Checkbox({
{...props}
/>
{name && currentChecked ? <input name={name} type="hidden" value="on" /> : null}
</>
</span>
);
}

View File

@@ -40,7 +40,7 @@ export function Dialog({
>
<KumoDialog
className={cn(
"dialog-panel-enter fixed left-1/2 top-1/2 z-50 flex max-h-[min(92svh,52rem)] w-[min(calc(100vw-1.5rem),48rem)] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-lg border border-kumo-line bg-kumo-base p-0 shadow-xl outline-none ring-1 ring-kumo-line",
"teatea-dialog dialog-panel-enter fixed left-1/2 top-1/2 z-50 flex max-h-[min(92svh,52rem)] w-[min(calc(100vw-1.5rem),48rem)] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-lg border border-kumo-line bg-kumo-base p-0 shadow-xl outline-none ring-1 ring-kumo-line",
"data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0",
className,
)}

View File

@@ -17,12 +17,12 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(function Inp
{ className, ...props },
ref,
): React.ReactElement {
return <KumoInput ref={ref} className={cn("w-full", className)} {...props} />;
return <KumoInput ref={ref} className={cn("teatea-control w-full", className)} {...props} />;
});
export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(
{ className, ...props },
ref,
): React.ReactElement {
return <KumoTextarea ref={ref} className={cn("min-h-24 w-full", className)} {...props} />;
return <KumoTextarea ref={ref} className={cn("teatea-control min-h-24 w-full", className)} {...props} />;
});

View File

@@ -37,6 +37,7 @@ export function Select({
return (
<KumoSelect<string>
className={cn(
"teatea-select",
"min-h-10 w-full rounded-md border border-input bg-card px-3 py-2 text-left text-sm font-medium text-foreground shadow-sm",
"transition-colors hover:border-primary/45 hover:bg-secondary/35",
"focus-visible:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/25",

View File

@@ -47,7 +47,7 @@ const TableRoot = React.forwardRef<HTMLTableElement, TableProps>(function Table(
return (
<table
ref={ref}
className={cn("border-collapse text-kumo-default", layout === "fixed" && "table-fixed", className)}
className={cn("teatea-table border-collapse text-kumo-default", layout === "fixed" && "table-fixed", className)}
{...props}
/>
);