@moontra/moonui 6.11.0 → 6.12.0
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/dist/hooks/index.global.js +0 -29
- package/dist/hooks/index.global.js.map +1 -1
- package/dist/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.global.js +16 -16
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +55 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +55 -30
- package/dist/index.mjs.map +1 -1
- package/dist/lib/theme.global.js +14 -1
- package/dist/lib/theme.global.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ui/__tests__/card-size-aschild.test.tsx +119 -0
- package/src/components/ui/card.tsx +96 -41
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
5
5
|
import { motion, type HTMLMotionProps } from "framer-motion";
|
|
6
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
6
7
|
import { cn } from "../../lib/utils";
|
|
7
8
|
import { microInteractionVariants, hoverAnimations, tapAnimations } from "@/lib/micro-interactions";
|
|
8
9
|
|
|
@@ -11,16 +12,14 @@ import { microInteractionVariants, hoverAnimations, tapAnimations } from "@/lib/
|
|
|
11
12
|
// hiç uygulanmıyordu; kart kökün `dark:bg-gray-900` değerinde kalıyordu.
|
|
12
13
|
// Semantik `bg-card` token'ına bağlandı.
|
|
13
14
|
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
// Radix `Slot` bağımlılığı + child-tek-eleman sözleşmesi demek.
|
|
23
|
-
// İkisi de #310'da açık kalıyor; bu PR ölü SINIF kısmını kapatıyor.
|
|
15
|
+
// #310 (ikinci tur): `size` ve `asChild` ARTIK GERÇEK.
|
|
16
|
+
// • `size`: CVA'daki dört değer de boş stringdi ve `compoundVariants` yoktu — prop
|
|
17
|
+
// kabul ediliyor, hiçbir görsel fark üretmiyordu. Kökte uygulanacak doğal bir hedefi
|
|
18
|
+
// de yok, çünkü padding `CardHeader/Content/Footer`'ın kendi `p-6`'sında. Bu yüzden
|
|
19
|
+
// kök `size`'ı CONTEXT ile alt bölümlere dağıtıyor (aşağıda).
|
|
20
|
+
// KRİTİK: `md` bugünkü `p-6`'yı KORUR → varsayılan kullanımda görsel değişim YOK.
|
|
21
|
+
// • `asChild`: yalnız tipteydi, gövdede hiç okunmuyordu → `...props` ile native div'e
|
|
22
|
+
// sızıyor (`<div aschild="true">`, React uyarısı). Radix `Slot`a bağlandı.
|
|
24
23
|
|
|
25
24
|
const cardVariants = cva(
|
|
26
25
|
"rounded-lg border bg-card text-card-foreground shadow-sm dark:shadow-gray-900/20 dark:border-gray-800 dark:bg-gray-900 dark:text-gray-100 transition-all duration-200",
|
|
@@ -62,6 +61,29 @@ const cardVariants = cva(
|
|
|
62
61
|
}
|
|
63
62
|
);
|
|
64
63
|
|
|
64
|
+
/**
|
|
65
|
+
* #310: Kart bölümlerinin padding ölçeği. `md` = bugünkü `p-6` — bu, mevcut tüketicide
|
|
66
|
+
* görsel değişim OLMAMASI için zorunlu (varsayılan `size` zaten `md`).
|
|
67
|
+
*/
|
|
68
|
+
type CardSize = "sm" | "md" | "lg" | "xl";
|
|
69
|
+
|
|
70
|
+
const CARD_SECTION_PADDING: Record<CardSize, string> = {
|
|
71
|
+
sm: "p-4",
|
|
72
|
+
md: "p-6",
|
|
73
|
+
lg: "p-8",
|
|
74
|
+
xl: "p-10",
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Kök `Card`ın çözülmüş `size`ını alt bölümlere taşıyan tek kaynak. Alt component'ler
|
|
79
|
+
* `Card` dışında da tek başına kullanılabildiği için context varsayılanı `md`dir.
|
|
80
|
+
*/
|
|
81
|
+
const CardSizeContext = React.createContext<CardSize>("md");
|
|
82
|
+
|
|
83
|
+
/** `default` deprecated alias'tır (#319); kanonik `md`ye eşlenir. */
|
|
84
|
+
const resolveCardSize = (size: CardProps["size"]): CardSize =>
|
|
85
|
+
size && size !== "default" ? size : "md";
|
|
86
|
+
|
|
65
87
|
export interface CardProps
|
|
66
88
|
extends React.HTMLAttributes<HTMLDivElement>,
|
|
67
89
|
VariantProps<typeof cardVariants> {
|
|
@@ -70,7 +92,25 @@ export interface CardProps
|
|
|
70
92
|
}
|
|
71
93
|
|
|
72
94
|
const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
|
73
|
-
({ className, variant, size, radius, interactive, microInteraction = "lift", ...props }, ref) => {
|
|
95
|
+
({ className, variant, size, radius, interactive, asChild = false, microInteraction = "lift", ...props }, ref) => {
|
|
96
|
+
const resolvedSize = resolveCardSize(size);
|
|
97
|
+
const rootClassName = cn(
|
|
98
|
+
"moonui-theme",
|
|
99
|
+
cardVariants({ variant, size, radius, interactive, className })
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// #310: `asChild` Radix `Slot`a bağlandı. Slot ile motion sarmalayıcı BİRLİKTE
|
|
103
|
+
// kullanılamaz (Slot tek çocuğa prop birleştirir, motion kendi elemanını ister) —
|
|
104
|
+
// bu yüzden asChild verildiğinde micro-interaction atlanır ve bu davranış
|
|
105
|
+
// belgelenir. Görsel etkileşimi tüketici kendi elemanında kurar.
|
|
106
|
+
if (asChild) {
|
|
107
|
+
return (
|
|
108
|
+
<CardSizeContext.Provider value={resolvedSize}>
|
|
109
|
+
<Slot ref={ref} className={rootClassName} {...props} />
|
|
110
|
+
</CardSizeContext.Provider>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
74
114
|
// Interactive özelliği varsa motion.div, yoksa normal div kullan
|
|
75
115
|
if (interactive && microInteraction !== "none") {
|
|
76
116
|
const interactionProps = {
|
|
@@ -81,22 +121,22 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
|
|
81
121
|
};
|
|
82
122
|
|
|
83
123
|
return (
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
124
|
+
<CardSizeContext.Provider value={resolvedSize}>
|
|
125
|
+
<motion.div
|
|
126
|
+
ref={ref}
|
|
127
|
+
className={rootClassName}
|
|
128
|
+
{...interactionProps}
|
|
129
|
+
{...(props as any)}
|
|
130
|
+
/>
|
|
131
|
+
</CardSizeContext.Provider>
|
|
90
132
|
);
|
|
91
133
|
}
|
|
92
|
-
|
|
134
|
+
|
|
93
135
|
// Non-interactive version
|
|
94
136
|
return (
|
|
95
|
-
<
|
|
96
|
-
ref={ref}
|
|
97
|
-
|
|
98
|
-
{...props}
|
|
99
|
-
/>
|
|
137
|
+
<CardSizeContext.Provider value={resolvedSize}>
|
|
138
|
+
<div ref={ref} className={rootClassName} {...props} />
|
|
139
|
+
</CardSizeContext.Provider>
|
|
100
140
|
);
|
|
101
141
|
}
|
|
102
142
|
);
|
|
@@ -105,13 +145,17 @@ Card.displayName = "Card";
|
|
|
105
145
|
const CardHeader = React.forwardRef<
|
|
106
146
|
HTMLDivElement,
|
|
107
147
|
React.HTMLAttributes<HTMLDivElement>
|
|
108
|
-
>(({ className, ...props }, ref) =>
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
)
|
|
148
|
+
>(({ className, ...props }, ref) => {
|
|
149
|
+
// #310: padding artık kök `Card`ın `size`ından geliyor (eskiden sabit `p-6`).
|
|
150
|
+
const padding = CARD_SECTION_PADDING[React.useContext(CardSizeContext)];
|
|
151
|
+
return (
|
|
152
|
+
<div
|
|
153
|
+
ref={ref}
|
|
154
|
+
className={cn("moonui-theme", "flex flex-col space-y-1.5", padding, className)}
|
|
155
|
+
{...props}
|
|
156
|
+
/>
|
|
157
|
+
);
|
|
158
|
+
});
|
|
115
159
|
CardHeader.displayName = "CardHeader";
|
|
116
160
|
|
|
117
161
|
const CardTitle = React.forwardRef<
|
|
@@ -141,21 +185,32 @@ CardDescription.displayName = "CardDescription";
|
|
|
141
185
|
const CardContent = React.forwardRef<
|
|
142
186
|
HTMLDivElement,
|
|
143
187
|
React.HTMLAttributes<HTMLDivElement>
|
|
144
|
-
>(({ className, ...props }, ref) =>
|
|
145
|
-
|
|
146
|
-
|
|
188
|
+
>(({ className, ...props }, ref) => {
|
|
189
|
+
const padding = CARD_SECTION_PADDING[React.useContext(CardSizeContext)];
|
|
190
|
+
return (
|
|
191
|
+
<div
|
|
192
|
+
ref={ref}
|
|
193
|
+
className={cn("moonui-theme", padding, "pt-0", className)}
|
|
194
|
+
{...props}
|
|
195
|
+
/>
|
|
196
|
+
);
|
|
197
|
+
});
|
|
147
198
|
CardContent.displayName = "CardContent";
|
|
148
199
|
|
|
149
200
|
const CardFooter = React.forwardRef<
|
|
150
201
|
HTMLDivElement,
|
|
151
202
|
React.HTMLAttributes<HTMLDivElement>
|
|
152
|
-
>(({ className, ...props }, ref) =>
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
203
|
+
>(({ className, ...props }, ref) => {
|
|
204
|
+
const padding = CARD_SECTION_PADDING[React.useContext(CardSizeContext)];
|
|
205
|
+
return (
|
|
206
|
+
<div
|
|
207
|
+
ref={ref}
|
|
208
|
+
className={cn("moonui-theme", "flex items-center", padding, "pt-0", className)}
|
|
209
|
+
{...props}
|
|
210
|
+
/>
|
|
211
|
+
);
|
|
212
|
+
});
|
|
159
213
|
CardFooter.displayName = "CardFooter";
|
|
160
214
|
|
|
161
|
-
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
|
|
215
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent, cardVariants };
|
|
216
|
+
export type { CardSize };
|