forked from
slices.network/slices
Highly ambitious ATProtocol AppView service and sdks
1import type { JSX, ComponentChildren } from "preact";
2import { cn } from "../../utils/cn.ts";
3
4type TextVariant =
5 | "primary" // Main body text: text-zinc-900 dark:text-white
6 | "secondary" // Medium text: text-zinc-600 dark:text-zinc-400
7 | "muted" // Muted text: text-zinc-500 dark:text-zinc-400
8 | "label" // Form labels: text-zinc-700 dark:text-zinc-300
9 | "subtle" // Subtle text: text-zinc-400 dark:text-zinc-500
10 | "error" // Error text: text-red-600 dark:text-red-400
11 | "warning" // Warning text: text-yellow-600 dark:text-yellow-400
12 | "success"; // Success text: text-green-600 dark:text-green-400
13
14type TextSize = "xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "3xl";
15
16type TextWeight = "normal" | "medium" | "semibold" | "bold";
17
18type TextElement =
19 | "p"
20 | "span"
21 | "div"
22 | "time"
23 | "label"
24 | "h1"
25 | "h2"
26 | "h3"
27 | "h4"
28 | "h5"
29 | "h6"
30 | "dt"
31 | "dd"
32 | "strong";
33
34interface TextProps {
35 variant?: TextVariant;
36 size?: TextSize;
37 weight?: TextWeight;
38 as?: TextElement;
39 className?: string;
40 children: ComponentChildren;
41}
42
43const textColors = {
44 primary: "text-zinc-900 dark:text-white",
45 secondary: "text-zinc-600 dark:text-zinc-400",
46 muted: "text-zinc-500 dark:text-zinc-400",
47 label: "text-zinc-700 dark:text-zinc-300",
48 subtle: "text-zinc-400 dark:text-zinc-500",
49 error: "text-red-600 dark:text-red-400",
50 warning: "text-yellow-600 dark:text-yellow-400",
51 success: "text-green-600 dark:text-green-400",
52};
53
54const textSizes = {
55 xs: "text-xs",
56 sm: "text-sm",
57 base: "text-base",
58 lg: "text-lg",
59 xl: "text-xl",
60 "2xl": "text-2xl",
61 "3xl": "text-3xl",
62};
63
64const textWeights = {
65 normal: "font-normal",
66 medium: "font-medium",
67 semibold: "font-semibold",
68 bold: "font-bold",
69};
70
71export function Text({
72 variant = "primary",
73 size = "base",
74 weight,
75 as = "span",
76 className,
77 children,
78}: TextProps): JSX.Element {
79 const Component = as;
80
81 const classes = cn(
82 textColors[variant],
83 textSizes[size],
84 weight && textWeights[weight],
85 className
86 );
87
88 return <Component className={classes}>{children}</Component>;
89}