Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/app/docs/components/label/docs/codeUsage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Import API documentation
import label_api_SourceCode from './component_api/label.tsx';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid importing TSX with explicit extension from JS.

Explicit “.tsx” in JS imports can fail depending on module resolution. Prefer extensionless import.

-import label_api_SourceCode from './component_api/label.tsx';
+import label_api_SourceCode from './component_api/label';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import label_api_SourceCode from './component_api/label.tsx';
import label_api_SourceCode from './component_api/label';
🤖 Prompt for AI Agents
In docs/app/docs/components/label/docs/codeUsage.js around line 2, the import
uses an explicit “.tsx” extension (import label_api_SourceCode from
'./component_api/label.tsx';) which can break in JS module resolution; change it
to an extensionless import (import label_api_SourceCode from
'./component_api/label';) and ensure the build/tsconfig supports resolving
.tsx/.ts via index or appropriate resolver so the same module is found without
the explicit extension.


const code = {
javascript: {
code: `import Label from "@radui/ui/Label"\n\nconst LabelExample = () => (\n <div>\n <Label htmlFor="email">Email</Label>\n <input id="email" type="email" />\n </div>\n)`,
},
Comment on lines +6 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Keep docs import path consistent with package scope.

Ensure the usage snippet’s @radui/ui/Label path matches the actual published entry point (scope and subpath). Update if your repo standard is different.


🏁 Script executed:

#!/bin/bash
# Inspect package.json exports to confirm Label entry
fd package.json | xargs -I{} jq -r '.name, .exports' {} 2>/dev/null | sed -n '1,120p'

Length of output: 24


🏁 Script executed:

#!/bin/bash
# List all package.json files to locate @radui/ui package.json
find . -type f -name package.json

Length of output: 34


🏁 Script executed:

#!/bin/bash
# Show main and exports in root package.json
jq '{main: .main, exports: .exports}' package.json

Length of output: 37


Use package root import for Label

In docs/app/docs/components/label/docs/codeUsage.js (lines 6–7), replace

import Label from "@radui/ui/Label"

with

import Label from "@radui/ui"

to match the package’s published entry point.

🤖 Prompt for AI Agents
In docs/app/docs/components/label/docs/codeUsage.js around lines 6 to 7, the
import uses the internal path "@radui/ui/Label" instead of the package root;
change the import to use the published entry point by replacing the named path
with the package root import "@radui/ui" so the example aligns with the
package's public API.

css: {
code: `.rad-ui-label{\n display: block;\n font-weight: 500;\n margin-bottom: 4px;\n}`
},
};

// API documentation
export const api_documentation = {
label: label_api_SourceCode
};

// Component features
export const features = [
"Pairs text with form controls using htmlFor/id attributes",
"Clicking the label focuses the associated field",
"Improves accessibility and assistive technology support",
"Supports custom root class names",
];

export default code;
45 changes: 45 additions & 0 deletions docs/app/docs/components/label/docs/component_api/label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const data = {
name: "Label",
description: "Associates text with form controls for accessibility.",
columns: [
{ name: "Prop", id: "prop" },
{ name: "Type", id: "type" },
{ name: "Default", id: "default" }
],
data: [
{
prop: {
name: "htmlFor",
info_tooltips: "ID of the form element this label describes",
},
type: "string",
default: "undefined",
},
{
prop: {
name: "children",
info_tooltips: "The label content",
},
type: "ReactNode",
default: "--",
},
{
prop: {
name: "className",
info_tooltips: "Additional CSS class names to apply",
},
type: "string",
default: "''",
},
{
prop: {
name: "customRootClass",
info_tooltips: "Custom root class name to override default styling",
},
type: "string",
default: "''",
}
]
};

export default data;
34 changes: 34 additions & 0 deletions docs/app/docs/components/label/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import PageDetails from '@/components/seo/PageDetails';
import Documentation from "@/components/layout/Documentation/Documentation";
import Label from "@radui/ui/Label";
import codeUsage, { api_documentation, features } from "./docs/codeUsage";
import labelMetadata from "./seo";

export const metadata = labelMetadata;

<Documentation
title="Label"
description="Labels provide accessible names for form fields and ensure proper associations."
>
{/* Component Hero */}
<Documentation.ComponentHero codeUsage={codeUsage}>
<div className='text-gray-1000 p-5 space-y-2'>
<Label htmlFor="email">Email</Label>
<input id="email" type="email" className='border border-gray-400 rounded p-1' />
</div>
</Documentation.ComponentHero>

{/* Component Features */}
<Documentation.ComponentFeatures
features={features}
/>

{/* API Documentation */}
<Documentation.Section title="API Documentation" as="h2" />
<Documentation.Table
title="Label"
description={api_documentation.label.description}
columns={api_documentation.label.columns}
data={api_documentation.label.data}
/>
</Documentation>
8 changes: 8 additions & 0 deletions docs/app/docs/components/label/seo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import generateSeoMetadata from "@/utils/seo/generateSeoMetadata";

const labelMetadata = generateSeoMetadata({
title: "Label - Rad UI",
description: "Accessible label component for pairing text with form inputs and improving usability.",
});

export default labelMetadata;
4 changes: 4 additions & 0 deletions docs/app/docs/docsNavigationSections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ export const docsNavigationSections = [
title:"Kbd",
path:"/docs/components/kbd"
},
{
title:"Label",
path:"/docs/components/label"
},
{
title:"Progress",
path:"/docs/components/progress"
Expand Down
1 change: 1 addition & 0 deletions scripts/RELEASED_COMPONENTS.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const RELEASED_COMPONENTS = [
'Heading',
'Text',
'Kbd',
'Label',
'Progress',
'Separator',
'Strong',
Expand Down
34 changes: 34 additions & 0 deletions src/components/ui/Label/Label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use client';
import React, { ElementRef, ComponentPropsWithoutRef } from 'react';
import { clsx } from 'clsx';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect clsx import will break build.

clsx has a default export; named import { clsx } is undefined in typical setups.

Apply this fix:

-import { clsx } from 'clsx';
+import clsx from 'clsx';
🤖 Prompt for AI Agents
In src/components/ui/Label/Label.tsx around line 3, the import uses a named
import "import { clsx } from 'clsx';" which will be undefined; replace it with
the default import "import clsx from 'clsx';" so the module resolves correctly
and the build won't fail.

import { customClassSwitcher } from '~/core';

const COMPONENT_NAME = 'Label';

export interface LabelProps extends ComponentPropsWithoutRef<'label'> {
/**
* Custom root class to override default styling.
*/
customRootClass?: string;
}

type LabelElement = ElementRef<'label'>;

const Label = React.forwardRef<LabelElement, LabelProps>(
({ className, customRootClass, htmlFor, ...props }, ref) => {
const rootClass = customClassSwitcher(customRootClass, COMPONENT_NAME);
return (
<label
ref={ref}
htmlFor={htmlFor}
className={clsx(rootClass, className)}
{...props}
/>
);
}
);

Label.displayName = COMPONENT_NAME;

export default Label;
export type { LabelElement };
34 changes: 34 additions & 0 deletions src/components/ui/Label/tests/Label.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Label from '../Label';

/**
* Tests for Label component ensuring proper linkage and accessibility.
*/
describe('Label', () => {
test('associates with form field via htmlFor', () => {
render(
<div>
<Label htmlFor="email">Email</Label>
<input id="email" />
</div>
);
const input = screen.getByLabelText('Email');
expect(input).toBeInTheDocument();
});

test('clicking label focuses associated input', async () => {
const user = userEvent.setup();
render(
<div>
<Label htmlFor="name">Name</Label>
<input id="name" />
</div>
);
const label = screen.getByText('Name');
const input = screen.getByLabelText('Name');
await user.click(label);
expect(document.activeElement).toBe(input);
});
});
5 changes: 5 additions & 0 deletions styles/themes/components/label.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.rad-ui-label {
display: block;
font-weight: 500;
margin-bottom: 4px;
}
1 change: 1 addition & 0 deletions styles/themes/default.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
@use "components/heading";
@use "components/hover-card";
@use "components/kbd";
@use "components/label";
@use "components/link";
@use "components/separator";
@use "components/tabs";
Expand Down
Loading