@zmzai/theme 0.2.0 → 0.2.2
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.
- package/package.json +1 -1
- package/src/components/badge/Badge.tsx +1 -1
- package/src/components/button/button.styles.ts +2 -2
- package/src/components/card/card.styles.ts +1 -1
- package/src/components/icon-button/IconButton.tsx +46 -0
- package/src/components/icon-button/index.ts +2 -0
- package/src/components/index.ts +2 -0
- package/src/components/input/input.styles.ts +2 -2
- package/src/components/select/Select.tsx +2 -2
- package/src/components/tabs/Tabs.tsx +46 -0
- package/src/components/tabs/index.ts +2 -0
- package/src/components/textarea/Textarea.tsx +2 -2
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ import { cva } from "class-variance-authority";
|
|
|
5
5
|
import { cn } from "../../utils/cn";
|
|
6
6
|
|
|
7
7
|
export const badgeVariants = cva(
|
|
8
|
-
"inline-flex items-center gap-1.5 rounded-
|
|
8
|
+
"inline-flex items-center gap-1.5 rounded-sm font-medium text-xs whitespace-nowrap",
|
|
9
9
|
{
|
|
10
10
|
variants: {
|
|
11
11
|
variant: {
|
|
@@ -4,13 +4,13 @@ import { cva } from "class-variance-authority";
|
|
|
4
4
|
* Button variant styles.
|
|
5
5
|
*
|
|
6
6
|
* Design:
|
|
7
|
-
* -
|
|
7
|
+
* - 锐角 2px(v0.2 暖纸风),hover 轻微缩放
|
|
8
8
|
* - primary: black fill, white text, hover scale + shadow
|
|
9
9
|
* - secondary: transparent, border, hover fill
|
|
10
10
|
* - ghost: no border, subtle hover bg
|
|
11
11
|
*/
|
|
12
12
|
export const buttonVariants = cva(
|
|
13
|
-
"inline-flex cursor-pointer items-center justify-center gap-2 rounded-
|
|
13
|
+
"inline-flex cursor-pointer items-center justify-center gap-2 rounded-sm font-semibold transition-colors transition-transform disabled:pointer-events-none disabled:opacity-40 select-none",
|
|
14
14
|
{
|
|
15
15
|
variants: {
|
|
16
16
|
variant: {
|
|
@@ -8,7 +8,7 @@ import { cva } from "class-variance-authority";
|
|
|
8
8
|
* - interactive: hover lifts up + shadow + border darkens
|
|
9
9
|
*/
|
|
10
10
|
export const cardVariants = cva(
|
|
11
|
-
"bg-bg border rounded-
|
|
11
|
+
"bg-bg border rounded-sm transition-colors transition-transform duration-200",
|
|
12
12
|
{
|
|
13
13
|
variants: {
|
|
14
14
|
variant: {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { forwardRef, type ButtonHTMLAttributes } from "react";
|
|
4
|
+
import { cn } from "../../utils/cn";
|
|
5
|
+
|
|
6
|
+
export interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "ref"> {
|
|
7
|
+
/** 尺寸:sm=h-6 md=h-7 lg=h-8(密集工具条场景,不做 hover 缩放) */
|
|
8
|
+
size?: "sm" | "md" | "lg";
|
|
9
|
+
/** 视觉:ghost=透明 hover 背景;quiet=无 hover 背景只有颜色变化 */
|
|
10
|
+
tone?: "ghost" | "quiet";
|
|
11
|
+
label?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* IconButton — 密集场景的纯图标按钮。
|
|
16
|
+
*
|
|
17
|
+
* 与 Button 的区别:不做 framer-motion hover 缩放(工具条里会跳),
|
|
18
|
+
* 尺寸更小(6/7/8),tone=quiet 时连背景都没有(纯颜色 hover)。
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* <IconButton label="重命名"><Icon name="edit" size={12} /></IconButton>
|
|
22
|
+
*/
|
|
23
|
+
export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
|
|
24
|
+
({ className, size = "md", tone = "ghost", label, type = "button", ...props }, ref) => {
|
|
25
|
+
return (
|
|
26
|
+
<button
|
|
27
|
+
ref={ref}
|
|
28
|
+
type={type}
|
|
29
|
+
aria-label={label}
|
|
30
|
+
title={label}
|
|
31
|
+
className={cn(
|
|
32
|
+
"inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm text-ink-3 transition-colors disabled:pointer-events-none disabled:opacity-40",
|
|
33
|
+
size === "sm" && "h-6 w-6",
|
|
34
|
+
size === "md" && "h-7 w-7",
|
|
35
|
+
size === "lg" && "h-8 w-8",
|
|
36
|
+
tone === "ghost" && "hover:bg-surface-2 hover:text-ink",
|
|
37
|
+
tone === "quiet" && "hover:text-ink",
|
|
38
|
+
className,
|
|
39
|
+
)}
|
|
40
|
+
{...props}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
IconButton.displayName = "IconButton";
|
package/src/components/index.ts
CHANGED
|
@@ -13,6 +13,8 @@ export * from "./tooltip";
|
|
|
13
13
|
export * from "./dialog";
|
|
14
14
|
export * from "./dropdown-menu";
|
|
15
15
|
export * from "./select";
|
|
16
|
+
export * from "./icon-button";
|
|
17
|
+
export * from "./tabs";
|
|
16
18
|
|
|
17
19
|
// === Interactive Enhancement ===
|
|
18
20
|
export * from "./magnetic-button";
|
|
@@ -13,9 +13,9 @@ export const inputVariants = cva(
|
|
|
13
13
|
variants: {
|
|
14
14
|
variant: {
|
|
15
15
|
default:
|
|
16
|
-
"border border-line rounded-
|
|
16
|
+
"border border-line rounded-sm px-4 py-2.5 text-sm focus:border-ink",
|
|
17
17
|
brutal:
|
|
18
|
-
"border-2 border-ink rounded-
|
|
18
|
+
"border-2 border-ink rounded-sm px-4 py-3 text-sm",
|
|
19
19
|
},
|
|
20
20
|
size: {
|
|
21
21
|
sm: "text-xs py-2 px-3",
|
|
@@ -18,7 +18,7 @@ export function SelectTrigger({
|
|
|
18
18
|
return (
|
|
19
19
|
<SelectPrimitive.Trigger
|
|
20
20
|
className={cn(
|
|
21
|
-
"inline-flex h-9 items-center justify-between gap-2 rounded-
|
|
21
|
+
"inline-flex h-9 items-center justify-between gap-2 rounded-sm border border-line bg-bg px-3 py-2 text-sm font-medium text-ink outline-none transition-colors",
|
|
22
22
|
"hover:border-ink/40 focus:border-ink data-[placeholder]:text-ink-3",
|
|
23
23
|
className
|
|
24
24
|
)}
|
|
@@ -48,7 +48,7 @@ export function SelectContent({
|
|
|
48
48
|
position={position}
|
|
49
49
|
sideOffset={4}
|
|
50
50
|
className={cn(
|
|
51
|
-
"z-50 min-w-[8rem] overflow-hidden rounded-
|
|
51
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-sm border border-line bg-bg p-1 shadow-lg",
|
|
52
52
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
53
53
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
54
54
|
className
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../utils/cn";
|
|
4
|
+
|
|
5
|
+
export type TabItem = { value: string; label: React.ReactNode; count?: number };
|
|
6
|
+
|
|
7
|
+
export interface TabsProps {
|
|
8
|
+
items: TabItem[];
|
|
9
|
+
value: string;
|
|
10
|
+
onValueChange: (value: string) => void;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Tabs — 下划线激活态的水平标签栏(锐角风)。
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* <Tabs items={[{value:"a",label:"产物",count:2},{value:"b",label:"改动"}]} value={tab} onValueChange={setTab} />
|
|
19
|
+
*/
|
|
20
|
+
export function Tabs({ items, value, onValueChange, className }: TabsProps) {
|
|
21
|
+
return (
|
|
22
|
+
<div className={cn("flex gap-0 border-b border-line", className)} role="tablist">
|
|
23
|
+
{items.map((item) => {
|
|
24
|
+
const active = item.value === value;
|
|
25
|
+
return (
|
|
26
|
+
<button
|
|
27
|
+
key={item.value}
|
|
28
|
+
type="button"
|
|
29
|
+
role="tab"
|
|
30
|
+
aria-selected={active}
|
|
31
|
+
className={cn(
|
|
32
|
+
"cursor-pointer border-b-2 px-3 py-2.5 text-xs font-medium transition-colors",
|
|
33
|
+
active ? "border-ink text-ink" : "border-transparent text-ink-3 hover:text-ink-2",
|
|
34
|
+
)}
|
|
35
|
+
onClick={() => onValueChange(item.value)}
|
|
36
|
+
>
|
|
37
|
+
{item.label}
|
|
38
|
+
{typeof item.count === "number" && (
|
|
39
|
+
<span className="ml-1 rounded-full bg-surface-2 px-1.5 text-[10px]">{item.count}</span>
|
|
40
|
+
)}
|
|
41
|
+
</button>
|
|
42
|
+
);
|
|
43
|
+
})}
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -25,9 +25,9 @@ export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
|
25
25
|
className={cn(
|
|
26
26
|
"w-full resize-none bg-bg font-sans text-ink placeholder:text-ink-3 outline-none transition-all",
|
|
27
27
|
variant === "default" &&
|
|
28
|
-
"border border-line rounded-
|
|
28
|
+
"border border-line rounded-sm px-4 py-2.5 text-sm focus:border-ink",
|
|
29
29
|
variant === "brutal" &&
|
|
30
|
-
"border-2 border-ink rounded-
|
|
30
|
+
"border-2 border-ink rounded-sm px-4 py-3 text-sm",
|
|
31
31
|
className
|
|
32
32
|
)}
|
|
33
33
|
{...props}
|