Repository: gradio-app/gradio
Pull request: Add `rtl` to `gr.Radio`
## Description

Adds a `rtl` param to gr.Radio. 

Closes: #7539

## 🎯 PRs Should Target Issues

Before your create a PR, please check to see if there is [an existing issue](https://github.com/gradio-app/gradio/issues) for this change. If not, please create an issue before you create this PR, unless the fix is very small. 

Not adhering to this guideline will result in the PR being closed. 

## Testing and Formatting Your Code

1. PRs will only be merged if tests pass on CI. We recommend at least running the backend tests locally, please set up [your Gradio environment locally](https://github.com/gradio-app/gradio/blob/main/CONTRIBUTING.md) and run the backed tests: `bash scripts/run_backend_tests.sh`

2. Please run these bash scripts to automatically format your code: `bash scripts/format_backend.sh`, and (if you made any changes to non-Python files) `bash scripts/format_frontend.sh`
  


Problem statement:
RTL for the radio component
- [x] I have searched to see if a similar issue already exists.


**Is your feature request related to a problem? Please describe.**  
I want to align the label of a radio elemnt rtl.

**Describe the solution you'd like**  
Label of radio componemt aligend rtl for Arabic text. 

**Additional context**  
.

Hints from issue discussion:
Makes sense, we do support rtl for some other components, like `gr.Textbox` and `gr.Markdown`, but not `gr.Radio`. @zaidalyafeai would you like to open a PR for this?

Commit message: add changeset

Patch to review:
diff --git a/.changeset/stale-bottles-tap.md b/.changeset/stale-bottles-tap.md
new file mode 100644
index 0000000000..653ed7eb18
--- /dev/null
+++ b/.changeset/stale-bottles-tap.md
@@ -0,0 +1,7 @@
+---
+"@gradio/atoms": minor
+"@gradio/radio": minor
+"gradio": minor
+---
+
+feat:Add `rtl` to `gr.Radio`
diff --git a/gradio/components/radio.py b/gradio/components/radio.py
index 73bde896e3..7d9ae4bd2b 100644
--- a/gradio/components/radio.py
+++ b/gradio/components/radio.py
@@ -46,6 +46,7 @@ def __init__(
         elem_classes: list[str] | str | None = None,
         render: bool = True,
         key: int | str | None = None,
+        rtl: Literal["ltr", "rtl"] = "ltr",
     ):
         """
         Parameters:
@@ -66,6 +67,7 @@ def __init__(
             elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
             render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
             key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
+            rtl: If "rtl", the radio buttons will be displayed in right-to-left order. Default is "ltr".
         """
         self.choices = (
             # Although we expect choices to be a list of tuples, it can be a list of tuples if the Gradio app
@@ -80,6 +82,7 @@ def __init__(
                 f"Invalid value for parameter `type`: {type}. Please choose from one of: {valid_types}"
             )
         self.type = type
+        self.rtl = rtl
         super().__init__(
             label=label,
             info=info,
diff --git a/js/atoms/src/Block.svelte b/js/atoms/src/Block.svelte
index 1955278375..7f609abd1e 100644
--- a/js/atoms/src/Block.svelte
+++ b/js/atoms/src/Block.svelte
@@ -19,6 +19,8 @@
 	export let min_width = 0;
 	export let flex = false;
 	export let resizable = false;
+	export let rtl = false;
+
 	let element: HTMLElement;
 
 	let tag = type === "fieldset" ? "fieldset" : "div";
@@ -80,6 +82,7 @@
 	style:min-width={`calc(min(${min_width}px, 100%))`}
 	style:border-width="var(--block-border-width)"
 	class:auto-margin={scale === null}
+	dir={rtl ? "rtl" : "ltr"}
 >
 	<slot />
 	{#if resizable}
diff --git a/js/radio/Index.svelte b/js/radio/Index.svelte
index 89e26abb56..9eebfd3042 100644
--- a/js/radio/Index.svelte
+++ b/js/radio/Index.svelte
@@ -5,7 +5,6 @@
 
 <script lang="ts">
 	import type { Gradio, SelectData } from "@gradio/utils";
-	import { afterUpdate } from "svelte";
 	import { Block, BlockTitle } from "@gradio/atoms";
 	import { StatusTracker } from "@gradio/statustracker";
 	import type { LoadingStatus } from "@gradio/statustracker";
@@ -32,6 +31,7 @@
 	export let loading_status: LoadingStatus;
 	export let interactive = true;
 	export let root: string;
+	export let rtl = false;
 
 	function handle_change(): void {
 		gradio.dispatch("change");
@@ -55,6 +55,7 @@
 	{container}
 	{scale}
 	{min_width}
+	{rtl}
 >
 	<StatusTracker
 		autoscroll={gradio.autoscroll}
@@ -72,6 +73,7 @@
 				{internal_value}
 				bind:selected={value}
 				{disabled}
+				{rtl}
 				on:input={() => {
 					gradio.dispatch("select", { value: internal_value, index: i });
 					gradio.dispatch("input");
diff --git a/js/radio/Radio.stories.svelte b/js/radio/Radio.stories.svelte
index 2d1cba0dd8..c794fba182 100644
--- a/js/radio/Radio.stories.svelte
+++ b/js/radio/Radio.stories.svelte
@@ -33,3 +33,18 @@
 		label: "Radio"
 	}}
 />
+
+<Story
+	name="Radio with RTL"
+	args={{
+		value: "option1",
+		choices: [
+			["Option 1", "option1"],
+			["Option 2", "option2"],
+			["Option 3", "option3"],
+			["Option 4", "option4"]
+		],
+		label: "RTL Radio",
+		rtl: true
+	}}
+/>
diff --git a/js/radio/shared/Radio.svelte b/js/radio/shared/Radio.svelte
index 6ed1e91989..83d8fb858a 100644
--- a/js/radio/shared/Radio.svelte
+++ b/js/radio/shared/Radio.svelte
@@ -8,6 +8,7 @@
 	export let internal_value: string | number;
 	export let disabled = false;
 	export let selected: string | null = null;
+	export let rtl = false;
 
 	const dispatch = createEventDispatcher<{ input: string | number }>();
 	let is_selected = false;
@@ -29,6 +30,7 @@
 	class:disabled
 	class:selected={is_selected}
 	data-testid="{display_value}-radio-label"
+	class:rtl
 >
 	<input
 		{disabled}
@@ -38,7 +40,7 @@
 		aria-checked={is_selected}
 		bind:group={selected}
 	/>
-	<span class="ml-2">{display_value}</span>
+	<span>{display_value}</span>
 </label>
 
 <style>
@@ -76,6 +78,11 @@
 		margin-left: var(--size-2);
 	}
 
+	label.rtl > * + * {
+		margin-left: 0;
+		margin-right: var(--size-2);
+	}
+
 	input {
 		--ring-color: transparent;
 		position: relative;


Code review comments:
diff_hunk: @@ -46,6 +46,7 @@ def __init__(
         elem_classes: list[str] | str | None = None,
         render: bool = True,
         key: int | str | None = None,
+        rtl: Literal["ltr", "rtl"] = "ltr",
path: gradio/components/radio.py
text: @user1:
Let's make this a boolean for compatibility with other components, e.g. 

https://github.com/gradio-app/gradio/blob/4d78710bbf266a13568d7920c19a6ef6dd167ecf/gradio/components/chatbot.py#L267

@author:
oh whoops I meant to change that