@moontra/moonui 6.7.0 → 6.8.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.map +1 -1
- package/dist/index.d.mts +24 -24
- package/dist/index.d.ts +24 -24
- package/dist/index.global.js +365 -52
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +145 -111
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +143 -112
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/ui/__tests__/a11y-group-c.test.tsx +266 -0
- package/src/components/ui/__tests__/breadcrumb.test.tsx +24 -9
- package/src/components/ui/breadcrumb.tsx +85 -27
- package/src/components/ui/pagination.tsx +64 -44
- package/src/components/ui/tabs.tsx +66 -16
|
@@ -5,13 +5,16 @@ import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
|
|
|
5
5
|
import { cn } from "../../lib/utils"
|
|
6
6
|
import { ButtonProps, buttonVariants } from "./button"
|
|
7
7
|
|
|
8
|
-
const Pagination =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
const Pagination = React.forwardRef<HTMLElement, React.ComponentProps<"nav">>(
|
|
9
|
+
({ className, ...props }, ref) => (
|
|
10
|
+
<nav
|
|
11
|
+
ref={ref}
|
|
12
|
+
role="navigation"
|
|
13
|
+
aria-label="pagination"
|
|
14
|
+
className={cn("moonui-theme", "mx-auto flex w-full justify-center", className)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
)
|
|
15
18
|
)
|
|
16
19
|
Pagination.displayName = "Pagination"
|
|
17
20
|
|
|
@@ -40,71 +43,85 @@ type PaginationLinkProps = {
|
|
|
40
43
|
} & Partial<Pick<ButtonProps, "size">> &
|
|
41
44
|
React.ComponentProps<"a">
|
|
42
45
|
|
|
43
|
-
const PaginationLink = (
|
|
44
|
-
className,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
{...props}
|
|
59
|
-
/>
|
|
46
|
+
const PaginationLink = React.forwardRef<HTMLAnchorElement, PaginationLinkProps>(
|
|
47
|
+
({ className, isActive, size = "icon", ...props }, ref) => (
|
|
48
|
+
<a
|
|
49
|
+
ref={ref}
|
|
50
|
+
aria-current={isActive ? "page" : undefined}
|
|
51
|
+
className={cn(
|
|
52
|
+
buttonVariants({
|
|
53
|
+
variant: isActive ? "outline" : "ghost",
|
|
54
|
+
size,
|
|
55
|
+
}),
|
|
56
|
+
className
|
|
57
|
+
)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
60
61
|
)
|
|
61
62
|
PaginationLink.displayName = "PaginationLink"
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
/**
|
|
65
|
+
* #315: "Previous"/"Next" etiketleri KOŞULSUZ render ediliyordu ve component'te hiçbir
|
|
66
|
+
* responsive affordance yoktu. 375px'te ölçüm: nav clientWidth=229 / scrollWidth=317
|
|
67
|
+
* (88px iç taşma) → ata zincirindeki `overflow-hidden` etiketi kırpıyor, kullanıcı
|
|
68
|
+
* "Previous" yerine "vious" görüyordu. Etiket artık `sm` altında gizleniyor; erişilebilir
|
|
69
|
+
* ad `aria-label` ile korunduğu için ekran-okuyucu deneyimi DEĞİŞMİYOR.
|
|
70
|
+
*/
|
|
71
|
+
const paginationLabelClass = "hidden sm:inline"
|
|
72
|
+
|
|
73
|
+
const PaginationPrevious = React.forwardRef<
|
|
74
|
+
HTMLAnchorElement,
|
|
75
|
+
React.ComponentProps<typeof PaginationLink>
|
|
76
|
+
>(({ className, ...props }, ref) => (
|
|
67
77
|
<PaginationLink
|
|
78
|
+
ref={ref}
|
|
68
79
|
aria-label="Go to previous page"
|
|
69
80
|
size="md"
|
|
70
81
|
className={cn("moonui-theme", "gap-1 pl-2.5", className)}
|
|
71
82
|
{...props}
|
|
72
83
|
>
|
|
73
84
|
<ChevronLeft className="h-4 w-4" />
|
|
74
|
-
<span>Previous</span>
|
|
85
|
+
<span className={paginationLabelClass}>Previous</span>
|
|
75
86
|
</PaginationLink>
|
|
76
|
-
)
|
|
87
|
+
))
|
|
77
88
|
PaginationPrevious.displayName = "PaginationPrevious"
|
|
78
89
|
|
|
79
|
-
const PaginationNext =
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
90
|
+
const PaginationNext = React.forwardRef<
|
|
91
|
+
HTMLAnchorElement,
|
|
92
|
+
React.ComponentProps<typeof PaginationLink>
|
|
93
|
+
>(({ className, ...props }, ref) => (
|
|
83
94
|
<PaginationLink
|
|
95
|
+
ref={ref}
|
|
84
96
|
aria-label="Go to next page"
|
|
85
97
|
size="md"
|
|
86
98
|
className={cn("moonui-theme", "gap-1 pr-2.5", className)}
|
|
87
99
|
{...props}
|
|
88
100
|
>
|
|
89
|
-
<span>Next</span>
|
|
101
|
+
<span className={paginationLabelClass}>Next</span>
|
|
90
102
|
<ChevronRight className="h-4 w-4" />
|
|
91
103
|
</PaginationLink>
|
|
92
|
-
)
|
|
104
|
+
))
|
|
93
105
|
PaginationNext.displayName = "PaginationNext"
|
|
94
106
|
|
|
95
|
-
const PaginationEllipsis =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
107
|
+
const PaginationEllipsis = React.forwardRef<
|
|
108
|
+
HTMLSpanElement,
|
|
109
|
+
React.ComponentProps<"span">
|
|
110
|
+
>(({ className, ...props }, ref) => (
|
|
111
|
+
// #315: `aria-hidden` ESKİDEN BU ELEMANDAYDI → içindeki `sr-only` "More pages" metni
|
|
112
|
+
// erişilebilirlik ağacından düşüyor, hiç duyurulmuyordu. Gizleme artık yalnız dekoratif
|
|
113
|
+
// ikonda. (breadcrumb.tsx'te birebir aynı çakışma vardı — aynı PR'da düzeltildi.)
|
|
99
114
|
<span
|
|
100
|
-
|
|
115
|
+
ref={ref}
|
|
101
116
|
className={cn("moonui-theme", "flex h-9 w-9 items-center justify-center", className)}
|
|
102
117
|
{...props}
|
|
103
118
|
>
|
|
104
|
-
<
|
|
119
|
+
<span aria-hidden="true" className="flex items-center">
|
|
120
|
+
<MoreHorizontal className="h-4 w-4" />
|
|
121
|
+
</span>
|
|
105
122
|
<span className="sr-only">More pages</span>
|
|
106
123
|
</span>
|
|
107
|
-
)
|
|
124
|
+
))
|
|
108
125
|
PaginationEllipsis.displayName = "PaginationEllipsis"
|
|
109
126
|
|
|
110
127
|
export {
|
|
@@ -115,4 +132,7 @@ export {
|
|
|
115
132
|
PaginationLink,
|
|
116
133
|
PaginationNext,
|
|
117
134
|
PaginationPrevious,
|
|
118
|
-
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// #315: Props tiplerinin hiçbiri export edilmiyordu.
|
|
138
|
+
export type { PaginationLinkProps }
|
|
@@ -9,22 +9,52 @@ import { cn } from "../../lib/utils";
|
|
|
9
9
|
/* -------------------------------------------------------------------------------------------------
|
|
10
10
|
* Tabs Root
|
|
11
11
|
* -----------------------------------------------------------------------------------------------*/
|
|
12
|
+
type TabsOrientation = "horizontal" | "vertical";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* #322: Yönelim için TEK KAYNAK.
|
|
16
|
+
*
|
|
17
|
+
* Eskiden üç ayrı yol vardı ve birbirini eziyordu:
|
|
18
|
+
* 1. Root `vertical` prop'undan `orientation` hesaplıyor, ARDINDAN `{...props}` yayıyordu
|
|
19
|
+
* → tüketicinin (ya da Radix'in kalıtsal) `orientation` prop'u `vertical`'ı SESSİZCE
|
|
20
|
+
* eziyordu.
|
|
21
|
+
* 2. `TabsList`/`TabsTrigger` kendi `orientation` prop'unu yalnız CVA sınıfına veriyor,
|
|
22
|
+
* Root'tan hiç beslenmiyordu → klavye yönü dikey, görünüm yatay kalabiliyordu.
|
|
23
|
+
*
|
|
24
|
+
* Artık Root çözülmüş yönelimi context ile dağıtıyor; alt component'ler kendi prop'unu
|
|
25
|
+
* verirse o kazanır (yerel ezme kasıtlı olarak korundu).
|
|
26
|
+
*/
|
|
27
|
+
const TabsOrientationContext = React.createContext<TabsOrientation>("horizontal");
|
|
28
|
+
|
|
12
29
|
interface TabsProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root> {
|
|
13
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated `orientation="vertical"` kullanın — pro `MoonUITabsPro` ile aynı ad ve
|
|
32
|
+
* tip. `vertical` yalnız `orientation` verilmediğinde dikkate alınır.
|
|
33
|
+
*/
|
|
14
34
|
vertical?: boolean;
|
|
15
35
|
}
|
|
16
36
|
|
|
17
37
|
const Tabs = React.forwardRef<
|
|
18
38
|
React.ElementRef<typeof TabsPrimitive.Root>,
|
|
19
39
|
TabsProps
|
|
20
|
-
>(({ vertical = false, ...props }, ref) =>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
{
|
|
26
|
-
|
|
27
|
-
|
|
40
|
+
>(({ vertical = false, orientation, className, ...props }, ref) => {
|
|
41
|
+
const resolvedOrientation: TabsOrientation =
|
|
42
|
+
orientation ?? (vertical ? "vertical" : "horizontal");
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<TabsOrientationContext.Provider value={resolvedOrientation}>
|
|
46
|
+
<TabsPrimitive.Root
|
|
47
|
+
ref={ref}
|
|
48
|
+
// #322: `className` eskiden destructure EDİLMİYORDU; `cn("moonui-theme", …)`
|
|
49
|
+
// hesaplanıp ardından `{...props}` yayıldığı için tüketici `className` verdiğinde
|
|
50
|
+
// hesaplanan değer tümüyle eziliyor ve `moonui-theme` tema kapsamı düşüyordu.
|
|
51
|
+
className={cn("moonui-theme", className)}
|
|
52
|
+
orientation={resolvedOrientation}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
</TabsOrientationContext.Provider>
|
|
56
|
+
);
|
|
57
|
+
});
|
|
28
58
|
|
|
29
59
|
Tabs.displayName = TabsPrimitive.Root.displayName;
|
|
30
60
|
|
|
@@ -77,10 +107,14 @@ const TabsList = React.forwardRef<
|
|
|
77
107
|
TabsListProps
|
|
78
108
|
>(({ className, variant, orientation, fullWidth, scrollable, ...props }, ref) => {
|
|
79
109
|
// scrollable prop'unu DOM'a geçirmemek için destructure ediyoruz
|
|
110
|
+
// #322: yönelim Root'tan context ile geliyor; yerel prop verilirse o kazanır.
|
|
111
|
+
const contextOrientation = React.useContext(TabsOrientationContext);
|
|
112
|
+
const resolvedOrientation = orientation ?? contextOrientation;
|
|
113
|
+
|
|
80
114
|
return (
|
|
81
115
|
<TabsPrimitive.List
|
|
82
116
|
ref={ref}
|
|
83
|
-
className={cn("moonui-theme", tabsListVariants({ variant, orientation, fullWidth, scrollable, className }))}
|
|
117
|
+
className={cn("moonui-theme", tabsListVariants({ variant, orientation: resolvedOrientation, fullWidth, scrollable, className }))}
|
|
84
118
|
{...props}
|
|
85
119
|
/>
|
|
86
120
|
);
|
|
@@ -152,14 +186,19 @@ const TabsTrigger = React.forwardRef<
|
|
|
152
186
|
fadeTabs = false,
|
|
153
187
|
orientation,
|
|
154
188
|
fullWidth,
|
|
155
|
-
children,
|
|
156
|
-
...props
|
|
157
|
-
}, ref) =>
|
|
189
|
+
children,
|
|
190
|
+
...props
|
|
191
|
+
}, ref) => {
|
|
192
|
+
// #322: yönelim Root'tan context ile geliyor; yerel prop verilirse o kazanır.
|
|
193
|
+
const contextOrientation = React.useContext(TabsOrientationContext);
|
|
194
|
+
const resolvedOrientation = orientation ?? contextOrientation;
|
|
195
|
+
|
|
196
|
+
return (
|
|
158
197
|
<TabsPrimitive.Trigger
|
|
159
198
|
ref={ref}
|
|
160
199
|
className={cn(
|
|
161
200
|
"moonui-theme",
|
|
162
|
-
tabsTriggerVariants({ variant, size, orientation, fullWidth }),
|
|
201
|
+
tabsTriggerVariants({ variant, size, orientation: resolvedOrientation, fullWidth }),
|
|
163
202
|
fadeTabs && "data-[state=inactive]:opacity-60",
|
|
164
203
|
className
|
|
165
204
|
)}
|
|
@@ -176,7 +215,8 @@ const TabsTrigger = React.forwardRef<
|
|
|
176
215
|
<span className="ml-2">{badge}</span>
|
|
177
216
|
)}
|
|
178
217
|
</TabsPrimitive.Trigger>
|
|
179
|
-
)
|
|
218
|
+
);
|
|
219
|
+
});
|
|
180
220
|
|
|
181
221
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
182
222
|
|
|
@@ -207,4 +247,14 @@ const TabsContent = React.forwardRef<
|
|
|
207
247
|
|
|
208
248
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
209
249
|
|
|
210
|
-
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
|
250
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants, tabsTriggerVariants };
|
|
251
|
+
|
|
252
|
+
// #322: Props interface'lerinin hiçbiri export edilmiyordu (pro tarafı `MoonUITabsProProps`
|
|
253
|
+
// ve `TabItem`'ı export ediyor — asimetriydi).
|
|
254
|
+
export type {
|
|
255
|
+
TabsProps,
|
|
256
|
+
TabsListProps,
|
|
257
|
+
TabsTriggerProps,
|
|
258
|
+
TabsContentProps,
|
|
259
|
+
TabsOrientation,
|
|
260
|
+
};
|