From 88a4cbf1a94e5da1da52ce684a37252403d26029 Mon Sep 17 00:00:00 2001 From: Pranay Kothapalli Date: Wed, 10 Sep 2025 23:43:26 +0530 Subject: [PATCH] feat: add Label component with docs and tests --- .../docs/components/label/docs/codeUsage.js | 26 +++++++++++ .../label/docs/component_api/label.tsx | 45 +++++++++++++++++++ docs/app/docs/components/label/page.mdx | 34 ++++++++++++++ docs/app/docs/components/label/seo.ts | 8 ++++ docs/app/docs/docsNavigationSections.tsx | 4 ++ scripts/RELEASED_COMPONENTS.cjs | 1 + src/components/ui/Label/Label.tsx | 34 ++++++++++++++ src/components/ui/Label/tests/Label.test.tsx | 34 ++++++++++++++ styles/themes/components/label.scss | 5 +++ styles/themes/default.scss | 1 + 10 files changed, 192 insertions(+) create mode 100644 docs/app/docs/components/label/docs/codeUsage.js create mode 100644 docs/app/docs/components/label/docs/component_api/label.tsx create mode 100644 docs/app/docs/components/label/page.mdx create mode 100644 docs/app/docs/components/label/seo.ts create mode 100644 src/components/ui/Label/Label.tsx create mode 100644 src/components/ui/Label/tests/Label.test.tsx create mode 100644 styles/themes/components/label.scss diff --git a/docs/app/docs/components/label/docs/codeUsage.js b/docs/app/docs/components/label/docs/codeUsage.js new file mode 100644 index 000000000..e0c6c4e97 --- /dev/null +++ b/docs/app/docs/components/label/docs/codeUsage.js @@ -0,0 +1,26 @@ +// Import API documentation +import label_api_SourceCode from './component_api/label.tsx'; + +const code = { + javascript: { + code: `import Label from "@radui/ui/Label"\n\nconst LabelExample = () => (\n
\n \n \n
\n)`, + }, + 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; diff --git a/docs/app/docs/components/label/docs/component_api/label.tsx b/docs/app/docs/components/label/docs/component_api/label.tsx new file mode 100644 index 000000000..4a1d9e6d5 --- /dev/null +++ b/docs/app/docs/components/label/docs/component_api/label.tsx @@ -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; diff --git a/docs/app/docs/components/label/page.mdx b/docs/app/docs/components/label/page.mdx new file mode 100644 index 000000000..359e28c25 --- /dev/null +++ b/docs/app/docs/components/label/page.mdx @@ -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; + + + {/* Component Hero */} + +
+ + +
+
+ + {/* Component Features */} + + + {/* API Documentation */} + + +
diff --git a/docs/app/docs/components/label/seo.ts b/docs/app/docs/components/label/seo.ts new file mode 100644 index 000000000..0158b9991 --- /dev/null +++ b/docs/app/docs/components/label/seo.ts @@ -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; diff --git a/docs/app/docs/docsNavigationSections.tsx b/docs/app/docs/docsNavigationSections.tsx index d034c5f67..dec949451 100644 --- a/docs/app/docs/docsNavigationSections.tsx +++ b/docs/app/docs/docsNavigationSections.tsx @@ -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" diff --git a/scripts/RELEASED_COMPONENTS.cjs b/scripts/RELEASED_COMPONENTS.cjs index 8fb9e97f0..820dbe5d8 100644 --- a/scripts/RELEASED_COMPONENTS.cjs +++ b/scripts/RELEASED_COMPONENTS.cjs @@ -16,6 +16,7 @@ const RELEASED_COMPONENTS = [ 'Heading', 'Text', 'Kbd', + 'Label', 'Progress', 'Separator', 'Strong', diff --git a/src/components/ui/Label/Label.tsx b/src/components/ui/Label/Label.tsx new file mode 100644 index 000000000..ab3efb81b --- /dev/null +++ b/src/components/ui/Label/Label.tsx @@ -0,0 +1,34 @@ +'use client'; +import React, { ElementRef, ComponentPropsWithoutRef } from 'react'; +import { clsx } from 'clsx'; +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( + ({ className, customRootClass, htmlFor, ...props }, ref) => { + const rootClass = customClassSwitcher(customRootClass, COMPONENT_NAME); + return ( +