@neuctra/ui 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,117 +1,25 @@
1
- import React, { useMemo } from "react";
2
- /** 🎨 Utility: generate lighter/darker shades */
3
- function adjustColor(color, amount) {
4
- return ("#" +
5
- color
6
- .replace(/^#/, "")
7
- .replace(/../g, (hex) => ("0" +
8
- Math.min(255, Math.max(0, parseInt(hex, 16) + amount)).toString(16)).slice(-2)));
9
- }
10
- /** 🌈 Default color palettes */
11
- const defaultColors = {
12
- light: {
13
- default: "#111",
14
- primary: "#2563eb",
15
- secondary: "#64748b",
16
- success: "#16a34a",
17
- danger: "#dc2626",
18
- white: "#ffffff",
19
- muted: "#6b7280",
20
- },
21
- dark: {
22
- default: "#f8fafc",
23
- primary: "#60a5fa",
24
- secondary: "#94a3b8",
25
- success: "#22c55e",
26
- danger: "#f87171",
27
- white: "#ffffff",
28
- muted: "#9ca3af",
29
- },
1
+ "use client";
2
+ import React from "react";
3
+ import clsx from "clsx";
4
+ const sizeClasses = {
5
+ xs: "text-xs",
6
+ sm: "text-sm",
7
+ md: "text-base",
8
+ lg: "text-lg",
9
+ xl: "text-xl",
10
+ "2xl": "text-2xl",
30
11
  };
31
- /** 💬 Main Component (HTML-only tags) */
32
- export function Text({ as, children, color = "default", size = "md", weight = "normal", align = "left", transform = "none", italic = false, underline = false, strikethrough = false, truncate = false, selectable = true, hoverable = false, onClick, darkMode = false, baseColor, className = "", style = {}, ...rest }) {
33
- // element type as provided (constrained to HTML tags)
12
+ export function Text({ as, children, size = "md", weight = 400, align = "left", truncate = false, className, style, ...rest }) {
34
13
  const Element = (as || "p");
35
- /** 🎨 Dynamic color palette generation */
36
- const theme = useMemo(() => {
37
- if (!baseColor)
38
- return defaultColors[darkMode ? "dark" : "light"];
39
- const lightMode = {
40
- default: "#111",
41
- primary: baseColor,
42
- secondary: adjustColor(baseColor, -50),
43
- success: adjustColor(baseColor, -30),
44
- danger: "#dc2626",
45
- white: "#ffffff",
46
- muted: "#6b7280",
47
- };
48
- const darkModeTheme = {
49
- default: "#f8fafc",
50
- primary: adjustColor(baseColor, 80),
51
- secondary: adjustColor(baseColor, 120),
52
- success: adjustColor(baseColor, 100),
53
- danger: "#f87171",
54
- white: "#ffffff",
55
- muted: "#9ca3af",
56
- };
57
- return darkMode ? darkModeTheme : lightMode;
58
- }, [baseColor, darkMode]);
59
- /** 📏 Font sizes */
60
- const sizes = {
61
- xs: "0.75rem",
62
- sm: "0.875rem",
63
- md: "1rem",
64
- lg: "1.25rem",
65
- xl: "1.5rem",
66
- "2xl": "2rem",
67
- };
68
- /** 💅 Computed styles */
69
- const computedStyle = {
70
- color: theme[color] || color,
71
- fontSize: sizes[size] || size,
72
- fontWeight: weight,
73
- textAlign: align,
74
- textTransform: transform,
75
- fontStyle: italic ? "italic" : "normal",
76
- textDecoration: underline ? "underline" : strikethrough ? "line-through" : "none",
77
- userSelect: selectable ? "text" : "none",
78
- overflow: truncate ? "hidden" : undefined,
79
- whiteSpace: truncate ? "nowrap" : undefined,
80
- textOverflow: truncate ? "ellipsis" : undefined,
81
- cursor: onClick ? "pointer" : "default",
82
- transition: "all 0.25s ease-in-out",
83
- ...style,
84
- };
85
- /** 🧠 Hover events (narrow to HTMLElement at runtime) */
86
- const handleMouseEnter = (e) => {
87
- if (!hoverable)
88
- return;
89
- const target = e.currentTarget;
90
- if (target instanceof HTMLElement) {
91
- target.style.opacity = "0.8";
92
- }
93
- };
94
- const handleMouseLeave = (e) => {
95
- if (!hoverable)
96
- return;
97
- const target = e.currentTarget;
98
- if (target instanceof HTMLElement) {
99
- target.style.opacity = "1";
100
- }
101
- };
102
- /**
103
- * Build props object. We cast only once to the correct intrinsic props type.
104
- * This prevents TypeScript from having to compute giant unions for event types.
105
- */
106
- const props = {
107
- className,
108
- style: computedStyle,
109
- onClick,
110
- onMouseEnter: handleMouseEnter,
111
- onMouseLeave: handleMouseLeave,
14
+ return React.createElement(Element, {
15
+ className: clsx("text-inherit", // inherits parent color
16
+ sizeClasses[size] || "", truncate && "truncate", className),
17
+ style: {
18
+ fontWeight: weight,
19
+ textAlign: align,
20
+ ...style,
21
+ },
112
22
  ...rest,
113
- };
114
- // Use React.createElement to avoid JSX generic complexity
115
- return React.createElement(Element, props, children);
23
+ }, children);
116
24
  }
117
25
  export default Text;