Fix: harden RTL — tables and tabs were rendering left-to-right

Five-layer defense so that no single library/browser quirk can flip the
layout back to LTR:

1. <body dir="rtl"> in addition to <html dir="rtl"> — some libs read
   document.body.dir, not document.documentElement.dir.
2. Explicit `direction: rtl` on html, body in the @layer base CSS.
3. <DirectionProvider dir="rtl"> from @radix-ui/react-direction wrapping
   the React tree, so every Radix primitive (Tabs, Dialog, Select,
   Popover, Toast) gets RTL context — Radix's useDirection defaults to
   "ltr" without it.
4. shadcn Tabs wrapper now defaults its dir prop to "rtl" — redundant
   with the provider above, but defends against a future provider
   removal silently breaking Tabs.
5. dir="rtl" set explicitly on each <table> element.

Fixes the symptom seen on the live site: deals/appraisals tables had
תאריך (the first <th> in the JSX) rendering on the LEFT instead of the
RIGHT, and Tabs flowed עסקאות→שמאי left-to-right instead of the
expected right-to-left.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-25 13:51:19 +00:00
parent 97bbb852ec
commit 2924f716d4
8 changed files with 22 additions and 7 deletions
+1 -1
View File
@@ -12,7 +12,7 @@
rel="stylesheet"
/>
</head>
<body>
<body dir="rtl">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
+1
View File
@@ -8,6 +8,7 @@
"name": "nadlan-mcp-web",
"version": "0.1.0",
"dependencies": {
"@radix-ui/react-direction": "^1.1.1",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-slot": "^1.1.1",
+1
View File
@@ -11,6 +11,7 @@
"lint": "eslint . --ext ts,tsx --max-warnings=0"
},
"dependencies": {
"@radix-ui/react-direction": "^1.1.1",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-slot": "^1.1.1",
+1 -1
View File
@@ -24,7 +24,7 @@ export function AppraisalsTable({ decisions, totalInDb }: Props) {
נמצאו {decisions.length} מתוך {totalInDb.toLocaleString("he-IL")} החלטות במאגר
</div>
<div className="overflow-x-auto rounded-md border">
<table className="w-full text-sm">
<table dir="rtl" className="w-full text-sm">
<thead className="bg-muted text-muted-foreground">
<tr>
<th className="p-3 text-start font-medium">תאריך הכרעה</th>
+1 -1
View File
@@ -22,7 +22,7 @@ export function DealsTable({ deals }: Props) {
return (
<div className="overflow-x-auto rounded-md border">
<table className="w-full text-sm">
<table dir="rtl" className="w-full text-sm">
<thead className="bg-muted text-muted-foreground">
<tr>
<th className="p-3 text-start font-medium">תאריך</th>
+10 -1
View File
@@ -2,7 +2,16 @@ import * as React from "react";
import * as TabsPrimitive from "@radix-ui/react-tabs";
import { cn } from "../../lib/utils";
const Tabs = TabsPrimitive.Root;
// Default to dir="rtl" so TabsList flexbox flows right-to-left and the
// Roving-focus arrow keys are RTL-correct, even if a future caller
// forgets to pass a dir prop or to wrap the tree in DirectionProvider.
const Tabs = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>
>(({ dir = "rtl", ...props }, ref) => (
<TabsPrimitive.Root ref={ref} dir={dir} {...props} />
));
Tabs.displayName = TabsPrimitive.Root.displayName;
const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
+1
View File
@@ -31,6 +31,7 @@
body {
@apply bg-background text-foreground antialiased;
font-family: "Heebo", system-ui, -apple-system, sans-serif;
direction: rtl;
}
/* Tailwind's default scrollbar gutters cause RTL drift; force stable. */
html {
+6 -3
View File
@@ -1,5 +1,6 @@
import React from "react";
import ReactDOM from "react-dom/client";
import { DirectionProvider } from "@radix-ui/react-direction";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import App from "./App";
import "./index.css";
@@ -16,8 +17,10 @@ const queryClient = new QueryClient({
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
<DirectionProvider dir="rtl">
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</DirectionProvider>
</React.StrictMode>
);