Contribution & Open Source
How to contribute a component to Babelize Elements — from opening an issue to shipping a pull request.
Contributing
Babelize Elements is an open-source, community-driven library. The components you see here were built by contributors — and the next one could be yours.
How it works
- Pick an issue — browse the GitHub issues for a component request marked
good first issueorhelp wanted. - Build the component — implement it in
src/registry/components/following the component template below. - Open a pull request — our maintainers review it, request changes if needed, and merge it.
- It ships — merged components are documented on this site and available to every Babelize Elements user.
No component exists yet? Open an issue proposing one. Great candidates: language switchers, locale pickers, translation widgets, RTL utilities, pluralization helpers, and locale-aware formatters.
Component template
"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
import { useControllableState } from "@/lib/use-controllable-state";
import type { Locale } from "./types";
export interface LanguageSelectProps extends Omit<
React.ComponentPropsWithoutRef<"select">,
"value" | "defaultValue" | "onChange"
> {
/** Available locales — only `code` is required */
locales: Locale[];
/** Selected locale code. Provide this to control the component. */
value?: string;
/** Initial locale code when uncontrolled */
defaultValue?: string;
/** Fired once per selection */
onValueChange?: (code: string) => void;
}
export const LanguageSelect = React.forwardRef<HTMLSelectElement, LanguageSelectProps>(
function LanguageSelect(
{ locales, value, defaultValue, onValueChange, className, ...rest },
ref,
) {
const [locale, setLocale] = useControllableState(
value,
defaultValue ?? locales[0]?.code ?? "",
onValueChange,
);
return (
<select
ref={ref}
value={locale}
onChange={(e) => setLocale(e.target.value)}
className={cn(
"h-10 rounded-md border border-zinc-200 bg-white px-3 text-sm outline-none transition-colors focus:border-emerald-500 dark:border-zinc-800 dark:bg-zinc-900",
className,
)}
{...rest}
>
{locales.map((l) => (
<option key={l.code} value={l.code}>
{l.label ?? l.code}
</option>
))}
</select>
);
},
);Note the four conventions every component follows: a value / defaultValue /
onValueChange trio via useControllableState, a forwarded ref, ...rest spread
onto the root element, and the shared Locale type from ./types rather than a
local copy.
Contribution checklist
- TypeScript-first with exported interfaces for all props
- Localization-aware: handles locale codes, pluralization, or RTL as applicable
- Accessible: keyboard support, ARIA labels, focus states
- Styled with Tailwind CSS
- A short demo or usage example for the docs
Need help?
Open a discussion on GitHub or join the Babelize community. We're friendly.