diff --git a/apps/v4/components/component-preview-tabs.tsx b/apps/v4/components/component-preview-tabs.tsx index d93eeb5b8..d5d1d55db 100644 --- a/apps/v4/components/component-preview-tabs.tsx +++ b/apps/v4/components/component-preview-tabs.tsx @@ -34,8 +34,6 @@ export function ComponentPreviewTabs({ styleName?: string }) { const [isMobileCodeVisible, setIsMobileCodeVisible] = React.useState(false) - - // Determine the base from styleName (e.g., "base-nova" -> "base", "radix-nova" -> "radix"). const base = styleName?.split("-")[0] return ( diff --git a/apps/v4/components/component-preview.tsx b/apps/v4/components/component-preview.tsx index 40fdec8cc..0f443de1e 100644 --- a/apps/v4/components/component-preview.tsx +++ b/apps/v4/components/component-preview.tsx @@ -15,6 +15,7 @@ export function ComponentPreview({ chromeLessOnMobile = false, styleName = "new-york-v4", direction = "ltr", + caption, ...props }: React.ComponentProps<"div"> & { name: string @@ -26,9 +27,13 @@ export function ComponentPreview({ chromeLessOnMobile?: boolean previewClassName?: string direction?: "ltr" | "rtl" + caption?: string }) { + const translationDisclaimer = direction === "rtl" ? "Automatic translation may contain errors." : undefined + const finalCaption = [caption, translationDisclaimer].filter(Boolean).join(" ") || undefined + if (type === "block") { - return ( + const content = (
) + + if (finalCaption) { + return ( +
+ {content} +
+ {finalCaption} +
+
+ ) + } + + return content } const Component = getRegistryComponent(name, styleName) @@ -65,7 +83,7 @@ export function ComponentPreview({ ) } - return ( + const content = ( ) + + if (finalCaption) { + return ( +
+ {content} +
+ {finalCaption} +
+
+ ) + } + + return content } function DynamicComponent({ diff --git a/apps/v4/content/docs/components/base/alert-dialog.mdx b/apps/v4/content/docs/components/base/alert-dialog.mdx index 98f759d18..a8fa565e3 100644 --- a/apps/v4/content/docs/components/base/alert-dialog.mdx +++ b/apps/v4/content/docs/components/base/alert-dialog.mdx @@ -146,6 +146,17 @@ Use the `AlertDialogAction` component to add a destructive action button to the previewClassName="h-56" /> +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### size diff --git a/apps/v4/content/docs/components/base/alert.mdx b/apps/v4/content/docs/components/base/alert.mdx index 4ceac8a1f..924e6a6cc 100644 --- a/apps/v4/content/docs/components/base/alert.mdx +++ b/apps/v4/content/docs/components/base/alert.mdx @@ -109,6 +109,17 @@ You can customize the alert colors by adding custom classes such as `bg-amber-50 previewClassName="h-auto sm:h-72 p-6" /> +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### Alert diff --git a/apps/v4/content/docs/components/base/aspect-ratio.mdx b/apps/v4/content/docs/components/base/aspect-ratio.mdx index 10ad08bf7..e9ba8cb2b 100644 --- a/apps/v4/content/docs/components/base/aspect-ratio.mdx +++ b/apps/v4/content/docs/components/base/aspect-ratio.mdx @@ -79,6 +79,17 @@ A portrait aspect ratio component using the `ratio={9 / 16}` prop. This is usefu previewClassName="h-96" /> +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### AspectRatio diff --git a/apps/v4/content/docs/components/base/avatar.mdx b/apps/v4/content/docs/components/base/avatar.mdx index e778664fb..7005036e9 100644 --- a/apps/v4/content/docs/components/base/avatar.mdx +++ b/apps/v4/content/docs/components/base/avatar.mdx @@ -129,6 +129,17 @@ You can use the `Avatar` component as a trigger for a dropdown menu. +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### Avatar diff --git a/apps/v4/content/docs/components/base/badge.mdx b/apps/v4/content/docs/components/base/badge.mdx index 97807baa4..6b36e0878 100644 --- a/apps/v4/content/docs/components/base/badge.mdx +++ b/apps/v4/content/docs/components/base/badge.mdx @@ -85,6 +85,16 @@ You can customize the colors of a badge by adding custom classes such as `bg-gre +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### Badge diff --git a/apps/v4/content/docs/components/base/breadcrumb.mdx b/apps/v4/content/docs/components/base/breadcrumb.mdx index 001bfb39f..2de58ab85 100644 --- a/apps/v4/content/docs/components/base/breadcrumb.mdx +++ b/apps/v4/content/docs/components/base/breadcrumb.mdx @@ -116,6 +116,17 @@ To use a custom link component from your routing library, you can use the `rende +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### Breadcrumb diff --git a/apps/v4/content/docs/components/base/dropdown-menu.mdx b/apps/v4/content/docs/components/base/dropdown-menu.mdx index 030fa338b..5ba5e840b 100644 --- a/apps/v4/content/docs/components/base/dropdown-menu.mdx +++ b/apps/v4/content/docs/components/base/dropdown-menu.mdx @@ -170,8 +170,6 @@ To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl) direction="rtl" /> - - ## API Reference See the [Base UI documentation](https://base-ui.com/react/components/dropdown-menu) for the full API reference. diff --git a/apps/v4/content/docs/components/base/sidebar.mdx b/apps/v4/content/docs/components/base/sidebar.mdx index ebf0768f5..f952671d8 100644 --- a/apps/v4/content/docs/components/base/sidebar.mdx +++ b/apps/v4/content/docs/components/base/sidebar.mdx @@ -5,12 +5,7 @@ base: base component: true --- -
- -
- A sidebar that collapses to icons. -
-
+ Sidebars are one of the most complex components to build. They are central to any application and often contain a lot of moving parts. diff --git a/apps/v4/content/docs/components/radix/alert-dialog.mdx b/apps/v4/content/docs/components/radix/alert-dialog.mdx index e69f4e836..b36577099 100644 --- a/apps/v4/content/docs/components/radix/alert-dialog.mdx +++ b/apps/v4/content/docs/components/radix/alert-dialog.mdx @@ -146,6 +146,17 @@ Use the `AlertDialogAction` component to add a destructive action button to the previewClassName="h-56" /> +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### size diff --git a/apps/v4/content/docs/components/radix/alert.mdx b/apps/v4/content/docs/components/radix/alert.mdx index 709ab5e45..3c65fdbd9 100644 --- a/apps/v4/content/docs/components/radix/alert.mdx +++ b/apps/v4/content/docs/components/radix/alert.mdx @@ -113,6 +113,17 @@ You can customize the alert colors by adding custom classes such as `bg-amber-50 previewClassName="h-auto sm:h-72 p-6" /> +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### Alert diff --git a/apps/v4/content/docs/components/radix/aspect-ratio.mdx b/apps/v4/content/docs/components/radix/aspect-ratio.mdx index fb426193b..f08ad1ed8 100644 --- a/apps/v4/content/docs/components/radix/aspect-ratio.mdx +++ b/apps/v4/content/docs/components/radix/aspect-ratio.mdx @@ -82,6 +82,17 @@ A portrait aspect ratio component using the `ratio={9 / 16}` prop. This is usefu previewClassName="h-96" /> +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### AspectRatio diff --git a/apps/v4/content/docs/components/radix/avatar.mdx b/apps/v4/content/docs/components/radix/avatar.mdx index c8e96f84c..ef8652b19 100644 --- a/apps/v4/content/docs/components/radix/avatar.mdx +++ b/apps/v4/content/docs/components/radix/avatar.mdx @@ -145,6 +145,17 @@ You can use the `Avatar` component as a trigger for a dropdown menu. +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### Avatar diff --git a/apps/v4/content/docs/components/radix/badge.mdx b/apps/v4/content/docs/components/radix/badge.mdx index a6cd129ba..52c645def 100644 --- a/apps/v4/content/docs/components/radix/badge.mdx +++ b/apps/v4/content/docs/components/radix/badge.mdx @@ -81,6 +81,16 @@ You can customize the colors of a badge by adding custom classes such as `bg-gre +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### Badge diff --git a/apps/v4/content/docs/components/radix/breadcrumb.mdx b/apps/v4/content/docs/components/radix/breadcrumb.mdx index 9215d6627..114c2aaf4 100644 --- a/apps/v4/content/docs/components/radix/breadcrumb.mdx +++ b/apps/v4/content/docs/components/radix/breadcrumb.mdx @@ -110,6 +110,17 @@ To use a custom link component from your routing library, you can use the `asChi +## RTL + +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). + + + ## API Reference ### Breadcrumb diff --git a/apps/v4/content/docs/components/radix/dropdown-menu.mdx b/apps/v4/content/docs/components/radix/dropdown-menu.mdx index a22c6d2d5..18212665f 100644 --- a/apps/v4/content/docs/components/radix/dropdown-menu.mdx +++ b/apps/v4/content/docs/components/radix/dropdown-menu.mdx @@ -163,9 +163,9 @@ A richer example combining groups, icons, and submenus. -### RTL +## RTL -Wrap your menu in `DirectionProvider` for right-to-left support. +To enable RTL support in shadcn/ui, see the [RTL configuration guide](/docs/rtl). > = { return { default: mod.default || mod[exportName] } }), }, + "alert-dialog-rtl": { + name: "alert-dialog-rtl", + filePath: "examples/radix/alert-dialog-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./radix/alert-dialog-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "alert-dialog-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "alert-dialog-small-media": { name: "alert-dialog-small-media", filePath: "examples/radix/alert-dialog-small-media.tsx", @@ -239,6 +252,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "alert-rtl": { + name: "alert-rtl", + filePath: "examples/radix/alert-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./radix/alert-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "alert-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "aspect-ratio-demo": { name: "aspect-ratio-demo", filePath: "examples/radix/aspect-ratio-demo.tsx", @@ -278,6 +304,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "aspect-ratio-rtl": { + name: "aspect-ratio-rtl", + filePath: "examples/radix/aspect-ratio-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./radix/aspect-ratio-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "aspect-ratio-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "avatar-badge-icon": { name: "avatar-badge-icon", filePath: "examples/radix/avatar-badge-icon.tsx", @@ -382,6 +421,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "avatar-rtl": { + name: "avatar-rtl", + filePath: "examples/radix/avatar-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./radix/avatar-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "avatar-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "avatar-size": { name: "avatar-size", filePath: "examples/radix/avatar-size.tsx", @@ -421,6 +473,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "badge-rtl": { + name: "badge-rtl", + filePath: "examples/radix/badge-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./radix/badge-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "badge-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "badge-icon": { name: "badge-icon", filePath: "examples/radix/badge-icon.tsx", @@ -538,6 +603,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "breadcrumb-rtl": { + name: "breadcrumb-rtl", + filePath: "examples/radix/breadcrumb-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./radix/breadcrumb-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "breadcrumb-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "breadcrumb-separator": { name: "breadcrumb-separator", filePath: "examples/radix/breadcrumb-separator.tsx", @@ -5142,6 +5220,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "alert-dialog-rtl": { + name: "alert-dialog-rtl", + filePath: "examples/base/alert-dialog-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./base/alert-dialog-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "alert-dialog-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "alert-dialog-small-media": { name: "alert-dialog-small-media", filePath: "examples/base/alert-dialog-small-media.tsx", @@ -5168,6 +5259,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "alert-rtl": { + name: "alert-rtl", + filePath: "examples/base/alert-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./base/alert-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "alert-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "aspect-ratio-demo": { name: "aspect-ratio-demo", filePath: "examples/base/aspect-ratio-demo.tsx", @@ -5207,6 +5311,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "aspect-ratio-rtl": { + name: "aspect-ratio-rtl", + filePath: "examples/base/aspect-ratio-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./base/aspect-ratio-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "aspect-ratio-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "avatar-badge-icon": { name: "avatar-badge-icon", filePath: "examples/base/avatar-badge-icon.tsx", @@ -5311,6 +5428,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "avatar-rtl": { + name: "avatar-rtl", + filePath: "examples/base/avatar-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./base/avatar-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "avatar-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "avatar-size": { name: "avatar-size", filePath: "examples/base/avatar-size.tsx", @@ -5350,6 +5480,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "badge-rtl": { + name: "badge-rtl", + filePath: "examples/base/badge-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./base/badge-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "badge-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "badge-icon": { name: "badge-icon", filePath: "examples/base/badge-icon.tsx", @@ -5467,6 +5610,19 @@ export const ExamplesIndex: Record> = { return { default: mod.default || mod[exportName] } }), }, + "breadcrumb-rtl": { + name: "breadcrumb-rtl", + filePath: "examples/base/breadcrumb-rtl.tsx", + component: React.lazy(async () => { + const mod = await import("./base/breadcrumb-rtl") + const exportName = + Object.keys(mod).find( + (key) => + typeof mod[key] === "function" || typeof mod[key] === "object" + ) || "breadcrumb-rtl" + return { default: mod.default || mod[exportName] } + }), + }, "breadcrumb-separator": { name: "breadcrumb-separator", filePath: "examples/base/breadcrumb-separator.tsx", diff --git a/apps/v4/examples/base/alert-dialog-rtl.tsx b/apps/v4/examples/base/alert-dialog-rtl.tsx new file mode 100644 index 000000000..e2ed4824d --- /dev/null +++ b/apps/v4/examples/base/alert-dialog-rtl.tsx @@ -0,0 +1,77 @@ +"use client" + +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@/examples/base/ui-rtl/alert-dialog" +import { Button } from "@/examples/base/ui-rtl/button" + +import { + useTranslation, + type Translations, +} from "@/components/language-selector" + +const translations: Translations = { + en: { + dir: "ltr", + values: { + showDialog: "Show Dialog", + title: "Are you absolutely sure?", + description: + "This action cannot be undone. This will permanently delete your account from our servers.", + cancel: "Cancel", + continue: "Continue", + }, + }, + ar: { + dir: "rtl", + values: { + showDialog: "إظهار الحوار", + title: "هل أنت متأكد تمامًا؟", + description: + "لا يمكن التراجع عن هذا الإجراء. سيؤدي هذا إلى حذف حسابك نهائيًا من خوادمنا.", + cancel: "إلغاء", + continue: "متابعة", + }, + }, + he: { + dir: "rtl", + values: { + showDialog: "הצג דיאלוג", + title: "האם אתה בטוח לחלוטין?", + description: + "פעולה זו לא ניתנת לביטול. זה ימחק לצמיתות את החשבון שלך מהשרתים שלנו.", + cancel: "ביטול", + continue: "המשך", + }, + }, +} + +export function AlertDialogRtl() { + const { dir, t } = useTranslation(translations, "ar") + + return ( + + }> + {t.showDialog} + + + + {t.title} + {t.description} + + + {t.cancel} + {t.continue} + + + + ) +} diff --git a/apps/v4/examples/base/alert-rtl.tsx b/apps/v4/examples/base/alert-rtl.tsx index 16e182dfb..ef6b5c7bc 100644 --- a/apps/v4/examples/base/alert-rtl.tsx +++ b/apps/v4/examples/base/alert-rtl.tsx @@ -1,7 +1,11 @@ "use client" import * as React from "react" -import { Alert, AlertDescription, AlertTitle } from "@/examples/base/ui-rtl/alert" +import { + Alert, + AlertDescription, + AlertTitle, +} from "@/examples/base/ui-rtl/alert" import { CheckCircle2Icon, InfoIcon } from "lucide-react" import { diff --git a/apps/v4/examples/base/aspect-ratio-rtl.tsx b/apps/v4/examples/base/aspect-ratio-rtl.tsx new file mode 100644 index 000000000..3f6e05d80 --- /dev/null +++ b/apps/v4/examples/base/aspect-ratio-rtl.tsx @@ -0,0 +1,51 @@ +"use client" + +import * as React from "react" +import Image from "next/image" +import { AspectRatio } from "@/examples/base/ui-rtl/aspect-ratio" + +import { + useTranslation, + type Translations, +} from "@/components/language-selector" + +const translations: Translations = { + en: { + dir: "ltr", + values: { + caption: "Beautiful landscape", + }, + }, + ar: { + dir: "rtl", + values: { + caption: "منظر طبيعي جميل", + }, + }, + he: { + dir: "rtl", + values: { + caption: "נוף יפה", + }, + }, +} + +export function AspectRatioRtl() { + const { dir, t } = useTranslation(translations, "ar") + + return ( +
+ + Photo + +
+ {t.caption} +
+
+ ) +} diff --git a/apps/v4/examples/base/avatar-dropdown.tsx b/apps/v4/examples/base/avatar-dropdown.tsx index f36fc648f..df2160e02 100644 --- a/apps/v4/examples/base/avatar-dropdown.tsx +++ b/apps/v4/examples/base/avatar-dropdown.tsx @@ -1,3 +1,5 @@ +"use client" + import { Avatar, AvatarFallback, AvatarImage } from "@/examples/base/ui/avatar" import { Button } from "@/examples/base/ui/button" import { diff --git a/apps/v4/examples/base/avatar-rtl.tsx b/apps/v4/examples/base/avatar-rtl.tsx new file mode 100644 index 000000000..0c0a3b677 --- /dev/null +++ b/apps/v4/examples/base/avatar-rtl.tsx @@ -0,0 +1,83 @@ +"use client" + +import * as React from "react" +import { + Avatar, + AvatarBadge, + AvatarFallback, + AvatarGroup, + AvatarGroupCount, + AvatarImage, +} from "@/examples/base/ui-rtl/avatar" + +import { + useTranslation, + type Translations, +} from "@/components/language-selector" + +const translations: Translations = { + en: { + dir: "ltr", + values: { + moreUsers: "+3", + }, + }, + ar: { + dir: "rtl", + values: { + moreUsers: "+٣", + }, + }, + he: { + dir: "rtl", + values: { + moreUsers: "+3", + }, + }, +} + +export function AvatarRtl() { + const { dir, t } = useTranslation(translations, "ar") + + return ( +
+ + + CN + + + + ER + + + + + + CN + + + + LR + + + + ER + + {t.moreUsers} + +
+ ) +} diff --git a/apps/v4/examples/base/badge-rtl.tsx b/apps/v4/examples/base/badge-rtl.tsx new file mode 100644 index 000000000..0b87263e6 --- /dev/null +++ b/apps/v4/examples/base/badge-rtl.tsx @@ -0,0 +1,67 @@ +"use client" + +import * as React from "react" +import { Badge } from "@/examples/base/ui-rtl/badge" +import { BadgeCheck, BookmarkIcon } from "lucide-react" + +import { + useTranslation, + type Translations, +} from "@/components/language-selector" + +const translations: Translations = { + en: { + dir: "ltr", + values: { + badge: "Badge", + secondary: "Secondary", + destructive: "Destructive", + outline: "Outline", + verified: "Verified", + bookmark: "Bookmark", + }, + }, + ar: { + dir: "rtl", + values: { + badge: "شارة", + secondary: "ثانوي", + destructive: "مدمر", + outline: "مخطط", + verified: "متحقق", + bookmark: "إشارة مرجعية", + }, + }, + he: { + dir: "rtl", + values: { + badge: "תג", + secondary: "משני", + destructive: "הרסני", + outline: "קווי מתאר", + verified: "מאומת", + bookmark: "סימנייה", + }, + }, +} + +export function BadgeRtl() { + const { dir, t } = useTranslation(translations, "ar") + + return ( +
+ {t.badge} + {t.secondary} + {t.destructive} + {t.outline} + + + {t.verified} + + + {t.bookmark} + + +
+ ) +} diff --git a/apps/v4/examples/base/breadcrumb-rtl.tsx b/apps/v4/examples/base/breadcrumb-rtl.tsx new file mode 100644 index 000000000..e0c097024 --- /dev/null +++ b/apps/v4/examples/base/breadcrumb-rtl.tsx @@ -0,0 +1,101 @@ +"use client" + +import * as React from "react" +import Link from "next/link" +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "@/examples/base/ui-rtl/breadcrumb" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/examples/base/ui-rtl/dropdown-menu" +import { ChevronDownIcon, DotIcon } from "lucide-react" + +import { + useTranslation, + type Translations, +} from "@/components/language-selector" + +const translations: Translations = { + en: { + dir: "ltr", + values: { + home: "Home", + components: "Components", + documentation: "Documentation", + themes: "Themes", + github: "GitHub", + breadcrumb: "Breadcrumb", + }, + }, + ar: { + dir: "rtl", + values: { + home: "الرئيسية", + components: "المكونات", + documentation: "التوثيق", + themes: "السمات", + github: "جيت هاب", + breadcrumb: "مسار التنقل", + }, + }, + he: { + dir: "rtl", + values: { + home: "בית", + components: "רכיבים", + documentation: "תיעוד", + themes: "ערכות נושא", + github: "גיטהאב", + breadcrumb: "פירורי לחם", + }, + }, +} + +export function BreadcrumbRtl() { + const { dir, t } = useTranslation(translations, "ar") + + return ( + + + + }>{t.home} + + + + + + + } + > + {t.components} + + + + + {t.documentation} + {t.themes} + {t.github} + + + + + + + + + {t.breadcrumb} + + + + ) +} diff --git a/apps/v4/examples/base/dropdown-menu-rtl.tsx b/apps/v4/examples/base/dropdown-menu-rtl.tsx index 8dfcdee17..be044d3df 100644 --- a/apps/v4/examples/base/dropdown-menu-rtl.tsx +++ b/apps/v4/examples/base/dropdown-menu-rtl.tsx @@ -112,92 +112,87 @@ export function DropdownMenuRtl() { return ( - }> - {t.open} - - - - {t.team} - {t.team} - - {t.inviteUsers} - - - {t.email} - {t.message} - - {t.more} - - - {t.calendar} - {t.chat} - - {t.webhook} - - - - - {t.advanced} - - - - - {t.newTeam} - ⌘+T - - - - - {t.view} - - {t.statusBar} - - - {t.activityBar} - - - {t.panel} - - - - - {t.position} - - {t.top} - - {t.bottom} - - - {t.right} - - - {t.left} - - - - - + }> + {t.open} + + + + {t.team} + {t.team} + + {t.inviteUsers} + + + {t.email} + {t.message} + + {t.more} + + + {t.calendar} + {t.chat} + + {t.webhook} + + + + + {t.advanced} + + + + + {t.newTeam} + ⌘+T + + + + + {t.view} + + {t.statusBar} + + + {t.activityBar} + + + {t.panel} + + + + + {t.position} + + {t.top} + + {t.bottom} + + + {t.right} + + {t.left} + + + + ) } diff --git a/apps/v4/examples/base/ui-rtl/accordion.tsx b/apps/v4/examples/base/ui-rtl/accordion.tsx index 663fd2622..e701c65ce 100644 --- a/apps/v4/examples/base/ui-rtl/accordion.tsx +++ b/apps/v4/examples/base/ui-rtl/accordion.tsx @@ -1,8 +1,8 @@ "use client" -import { cn } from "@/examples/base/lib/utils" import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion" +import { cn } from "@/examples/base/lib/utils" import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder" function Accordion({ className, ...props }: AccordionPrimitive.Root.Props) { @@ -35,7 +35,7 @@ function AccordionTrigger({
diff --git a/apps/v4/examples/base/ui-rtl/alert-dialog.tsx b/apps/v4/examples/base/ui-rtl/alert-dialog.tsx index 2d6472cbc..3e1d0b1f2 100644 --- a/apps/v4/examples/base/ui-rtl/alert-dialog.tsx +++ b/apps/v4/examples/base/ui-rtl/alert-dialog.tsx @@ -1,9 +1,10 @@ "use client" import * as React from "react" +import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog" + import { cn } from "@/examples/base/lib/utils" import { Button } from "@/examples/base/ui-rtl/button" -import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog" function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) { return @@ -29,7 +30,7 @@ function AlertDialogOverlay({ ) @@ -84,7 +82,7 @@ function AlertDialogFooter({
) @@ -115,10 +110,7 @@ function AlertDialogTitle({ return ( ) @@ -131,10 +123,7 @@ function AlertDialogDescription({ return ( ) diff --git a/apps/v4/examples/base/ui-rtl/alert.tsx b/apps/v4/examples/base/ui-rtl/alert.tsx index 0e7651a7f..efe52e70b 100644 --- a/apps/v4/examples/base/ui-rtl/alert.tsx +++ b/apps/v4/examples/base/ui-rtl/alert.tsx @@ -1,22 +1,19 @@ import * as React from "react" -import { cn } from "@/examples/base/lib/utils" import { cva, type VariantProps } from "class-variance-authority" -const alertVariants = cva( - "grid gap-0.5 rounded-lg border px-2.5 py-2 text-start text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pe-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 w-full relative group/alert", - { - variants: { - variant: { - default: "bg-card text-card-foreground", - destructive: - "text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current", - }, +import { cn } from "@/examples/base/lib/utils" + +const alertVariants = cva("grid gap-0.5 rounded-lg border px-2.5 py-2 text-start text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pe-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 w-full relative group/alert", { + variants: { + variant: { + default: "bg-card text-card-foreground", + destructive: "text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current", }, - defaultVariants: { - variant: "default", - }, - } -) + }, + defaultVariants: { + variant: "default", + }, +}) function Alert({ className, @@ -38,7 +35,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3", + "font-medium group-has-[>svg]/alert:col-start-2 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3", className )} {...props} @@ -54,7 +51,7 @@ function AlertDescription({
) { return (
) diff --git a/apps/v4/examples/base/ui-rtl/avatar.tsx b/apps/v4/examples/base/ui-rtl/avatar.tsx index 12b152b19..125457459 100644 --- a/apps/v4/examples/base/ui-rtl/avatar.tsx +++ b/apps/v4/examples/base/ui-rtl/avatar.tsx @@ -1,9 +1,10 @@ "use client" import * as React from "react" -import { cn } from "@/examples/base/lib/utils" import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar" +import { cn } from "@/examples/base/lib/utils" + function Avatar({ className, size = "default", @@ -16,7 +17,7 @@ function Avatar({ data-slot="avatar" data-size={size} className={cn( - "after:border-border group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten", + "size-8 rounded-full after:rounded-full data-[size=lg]:size-10 data-[size=sm]:size-6 after:border-border group/avatar relative flex shrink-0 select-none after:absolute after:inset-0 after:border after:mix-blend-darken dark:after:mix-blend-lighten", className )} {...props} @@ -29,7 +30,7 @@ function AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) { svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3", - className - )} + className={cn("bg-muted text-muted-foreground size-8 rounded-full text-sm group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3 ring-background relative flex shrink-0 items-center justify-center ring-2", className)} {...props} /> ) diff --git a/apps/v4/examples/base/ui-rtl/badge.tsx b/apps/v4/examples/base/ui-rtl/badge.tsx index 808568273..d5cc19d2e 100644 --- a/apps/v4/examples/base/ui-rtl/badge.tsx +++ b/apps/v4/examples/base/ui-rtl/badge.tsx @@ -1,22 +1,19 @@ -import { cn } from "@/examples/base/lib/utils" import { mergeProps } from "@base-ui/react/merge-props" import { useRender } from "@base-ui/react/use-render" import { cva, type VariantProps } from "class-variance-authority" +import { cn } from "@/examples/base/lib/utils" + const badgeVariants = cva( "h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&>svg]:size-3! inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&>svg]:pointer-events-none focus-visible:border-eing focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive overflow-hidden group/badge", { variants: { variant: { default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80", - secondary: - "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80", - destructive: - "bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20", - outline: - "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground", - ghost: - "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50", + secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80", + destructive: "bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20", + outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground", + ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50", link: "text-primary underline-offset-4 hover:underline", }, }, diff --git a/apps/v4/examples/base/ui-rtl/breadcrumb.tsx b/apps/v4/examples/base/ui-rtl/breadcrumb.tsx index f40d805c6..cf2500c41 100644 --- a/apps/v4/examples/base/ui-rtl/breadcrumb.tsx +++ b/apps/v4/examples/base/ui-rtl/breadcrumb.tsx @@ -1,8 +1,8 @@ import * as React from "react" -import { cn } from "@/examples/base/lib/utils" import { mergeProps } from "@base-ui/react/merge-props" import { useRender } from "@base-ui/react/use-render" +import { cn } from "@/examples/base/lib/utils" import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder" function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) { @@ -21,7 +21,7 @@ function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
    ) { return (
  1. ) @@ -92,6 +92,7 @@ function BreadcrumbSeparator({ hugeicons="ArrowRight01Icon" phosphor="CaretRightIcon" remixicon="RiArrowRightSLine" + className="rtl:rotate-180" /> )}
  2. @@ -108,7 +109,7 @@ function BreadcrumbEllipsis({ role="presentation" aria-hidden="true" className={cn( - "flex size-5 items-center justify-center [&>svg]:size-4", + "size-5 [&>svg]:size-4 flex items-center justify-center", className )} {...props} diff --git a/apps/v4/examples/base/ui-rtl/button-group.tsx b/apps/v4/examples/base/ui-rtl/button-group.tsx index b91d02b71..791fb950c 100644 --- a/apps/v4/examples/base/ui-rtl/button-group.tsx +++ b/apps/v4/examples/base/ui-rtl/button-group.tsx @@ -1,9 +1,10 @@ -import { cn } from "@/examples/base/lib/utils" -import { Separator } from "@/examples/base/ui-rtl/separator" import { mergeProps } from "@base-ui/react/merge-props" import { useRender } from "@base-ui/react/use-render" import { cva, type VariantProps } from "class-variance-authority" +import { cn } from "@/examples/base/lib/utils" +import { Separator } from "@/examples/base/ui-rtl/separator" + const buttonGroupVariants = cva( "has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-e-lg flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1", { diff --git a/apps/v4/examples/base/ui-rtl/button.tsx b/apps/v4/examples/base/ui-rtl/button.tsx index a6ecfd876..4b74a9471 100644 --- a/apps/v4/examples/base/ui-rtl/button.tsx +++ b/apps/v4/examples/base/ui-rtl/button.tsx @@ -1,36 +1,30 @@ "use client" -import { cn } from "@/examples/base/lib/utils" import { Button as ButtonPrimitive } from "@base-ui/react/button" import { cva, type VariantProps } from "class-variance-authority" +import { cn } from "@/examples/base/lib/utils" + const buttonVariants = cva( "focus-visible:border-eing focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", { variants: { variant: { default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80", - outline: - "border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground", - ghost: - "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground", - destructive: - "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30", + outline: "border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground", + ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground", + destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30", link: "text-primary underline-offset-4 hover:underline", }, size: { - default: - "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2", + default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2", xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3", sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&_svg:not([class*='size-'])]:size-3.5", lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pe-3 has-data-[icon=inline-start]:ps-3", icon: "size-8", - "icon-xs": - "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3", - "icon-sm": - "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg", + "icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3", + "icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg", "icon-lg": "size-9", }, }, diff --git a/apps/v4/examples/base/ui-rtl/calendar.tsx b/apps/v4/examples/base/ui-rtl/calendar.tsx index 471f4e9ea..2ecf2f2ae 100644 --- a/apps/v4/examples/base/ui-rtl/calendar.tsx +++ b/apps/v4/examples/base/ui-rtl/calendar.tsx @@ -1,14 +1,14 @@ "use client" import * as React from "react" -import { cn } from "@/examples/base/lib/utils" -import { Button, buttonVariants } from "@/examples/base/ui-rtl/button" import { DayPicker, getDefaultClassNames, type DayButton, } from "react-day-picker" +import { cn } from "@/examples/base/lib/utils" +import { Button, buttonVariants } from "@/examples/base/ui-rtl/button" import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder" function Calendar({ @@ -29,7 +29,7 @@ function Calendar({ svg]:rotate-180`, String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`, className @@ -227,7 +227,7 @@ function CalendarDayButton({ data-range-end={modifiers.range_end} data-range-middle={modifiers.range_middle} className={cn( - "data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring dark:hover:text-foreground relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-e-(--cell-radius) data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-s-(--cell-radius) [&>span]:text-xs [&>span]:opacity-70", + "data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-eing group-data-[focused=true]/day:ring-ring/50 dark:hover:text-foreground relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-e-(--cell-radius) data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-s-(--cell-radius) [&>span]:text-xs [&>span]:opacity-70", defaultClassNames.day, className )} diff --git a/apps/v4/examples/base/ui-rtl/card.tsx b/apps/v4/examples/base/ui-rtl/card.tsx index 9cd6893d6..1da0623b2 100644 --- a/apps/v4/examples/base/ui-rtl/card.tsx +++ b/apps/v4/examples/base/ui-rtl/card.tsx @@ -1,4 +1,5 @@ import * as React from "react" + import { cn } from "@/examples/base/lib/utils" function Card({ @@ -10,10 +11,7 @@ function Card({
    img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl", - className - )} + className={cn("ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col", className)} {...props} /> ) @@ -24,7 +22,7 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
    ) { return (
    ) @@ -82,10 +77,7 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) { return (
    ) diff --git a/apps/v4/examples/base/ui-rtl/carousel.tsx b/apps/v4/examples/base/ui-rtl/carousel.tsx index 9763dfabe..c2bb04a0d 100644 --- a/apps/v4/examples/base/ui-rtl/carousel.tsx +++ b/apps/v4/examples/base/ui-rtl/carousel.tsx @@ -1,12 +1,12 @@ "use client" import * as React from "react" -import { cn } from "@/examples/base/lib/utils" -import { Button } from "@/examples/base/ui-rtl/button" import useEmblaCarousel, { type UseEmblaCarouselType, } from "embla-carousel-react" +import { cn } from "@/examples/base/lib/utils" +import { Button } from "@/examples/base/ui-rtl/button" import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder" type CarouselApi = UseEmblaCarouselType[1] @@ -185,10 +185,10 @@ function CarouselPrevious({ variant={variant} size={size} className={cn( - "absolute touch-manipulation rounded-full", + "rounded-full absolute touch-manipulation", orientation === "horizontal" - ? "-start-12 top-1/2 -translate-y-1/2" - : "start-1/2 -top-12 -translate-x-1/2 rotate-90", + ? "top-1/2 -start-12 -translate-y-1/2" + : "-top-12 start-1/2 -translate-x-1/2 rotate-90", className )} disabled={!canScrollPrev} @@ -221,10 +221,10 @@ function CarouselNext({ variant={variant} size={size} className={cn( - "absolute touch-manipulation rounded-full", + "rounded-full absolute touch-manipulation", orientation === "horizontal" - ? "-end-12 top-1/2 -translate-y-1/2" - : "start-1/2 -bottom-12 -translate-x-1/2 rotate-90", + ? "top-1/2 -end-12 -translate-y-1/2" + : "-bottom-12 start-1/2 -translate-x-1/2 rotate-90", className )} disabled={!canScrollNext} diff --git a/apps/v4/examples/base/ui-rtl/chart.tsx b/apps/v4/examples/base/ui-rtl/chart.tsx index 35feff3fa..ad5161b1c 100644 --- a/apps/v4/examples/base/ui-rtl/chart.tsx +++ b/apps/v4/examples/base/ui-rtl/chart.tsx @@ -1,9 +1,10 @@ "use client" import * as React from "react" -import { cn } from "@/examples/base/lib/utils" import * as RechartsPrimitive from "recharts" +import { cn } from "@/examples/base/lib/utils" + // Format: { THEME_NAME: CSS_SELECTOR } const THEMES = { light: "", dark: ".dark" } as const @@ -172,7 +173,7 @@ function ChartTooltipContent({ return (
    diff --git a/apps/v4/examples/base/ui-rtl/checkbox.tsx b/apps/v4/examples/base/ui-rtl/checkbox.tsx index 4a639cc60..1438c506b 100644 --- a/apps/v4/examples/base/ui-rtl/checkbox.tsx +++ b/apps/v4/examples/base/ui-rtl/checkbox.tsx @@ -1,8 +1,8 @@ "use client" -import { cn } from "@/examples/base/lib/utils" import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox" +import { cn } from "@/examples/base/lib/utils" import { IconPlaceholder } from "@/app/(create)/components/icon-placeholder" function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) { @@ -10,14 +10,14 @@ function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) { ) @@ -125,7 +125,7 @@ function ComboboxContent({ data-slot="combobox-content" data-chips={!!anchor} className={cn( - "bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 rtl:data-[side=left]:slide-in-from-left-2 data-[side=right]:slide-in-from-left-2 rtl:data-[side=right]:slide-in-from-right-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:border-input/30 cn-menu-target group/combobox-content relative max-h-(--available-height) max-h-72 w-(--anchor-width) max-w-(--available-width) min-w-36 min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-lg shadow-md ring-1 duration-100 data-[chips=true]:min-w-(--anchor-width) *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:shadow-none", + "bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:border-input/30 max-h-72 min-w-36 overflow-hidden rounded-lg shadow-md ring-1 duration-100 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:shadow-none cn-menu-target group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) data-[chips=true]:min-w-(--anchor-width)", className )} {...props} @@ -140,7 +140,7 @@ function ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) { {children} - } + render={} >