General
Standards
The naming, props, styling and testing rules every component in this registry follows.
The rules every component in this registry follows. Keep this page short enough that people read it — and edit it: it is yours.
Naming
- Package folders and files are kebab-case (
date-picker); the component itself is PascalCase (DatePicker); its props interface isDatePickerProps. - One exported component per package. Helpers stay un-exported or live in
index.ts.
Props
- Every public prop has a one-line JSDoc comment — it becomes the props table on the site.
- Prefer a small set of semantic props (
variant,size,disabled) over booleans for every visual tweak. - Accept
classNameand spread the rest onto the root element, so a consumer can always reach the DOM attributes.
Styling
-
Every component names its classes through
getClassNamefrom@bht-component-registry/class-names, BEM-style: the root element carries the block class, every inner element a__childclass, and variants are--modifierclasses on the root only. The generator writes this for you:1const [rootClass, getChildClass] = getClassName({2 rootClass: "ACME__DatePicker",3 styles,4 className,5 modifiers: { open },6});7<div className={rootClass}>8 <span className={getChildClass("label")} />9</div>;and the stylesheet mirrors it:
.ACME__DatePicker { &__label {} &--open {} }. No barestyles.fooand no hand-written class strings. -
A stylesheet styles its own component only. To change how a child component looks inside yours, pass it a
className(or give it a prop) — never target its classes from your file. -
State is never styled from an attribute selector (
[aria-invalid],[aria-current],[disabled]): it comes in as a prop and is styled through a modifier (active→&--active); the prop also sets the matching attribute. Pseudo-classes (:disabled,:hover) are fine, as is Radix runtime state with no prop (the open/closeddata-stateRadix sets for presence animations, including tooltip'sdelayed-open,data-highlighted,data-swipe). A child that needs a modifier becomes its own child component. -
Colour, spacing and type come from the design tokens (
--md-sys-*), never from literal values, so a theme change reaches every component.
Examples
Every visual state has a named export in *.example.tsx. A fenced jsx live block in any docs page renders live with the whole registry in scope, so a standard can show itself:
Testing
- A spec per component covers what it renders and how it behaves on interaction — not how it looks.
- Tests use roles and labels (
getByRole,getByLabelText), not class names.