@brandrail/kit
v0.3.2
Published
UI kit by Thiago Baptistella: React components and custom elements (any framework) that follow your Brandrail Brand Kit.
Readme
@brandrail/kit
The Brandrail UI kit: React components, and the same components as custom elements for any framework. They follow your Brand Kit through CSS variables.
Install
npm i @brandrail/kitReact apps also need react and react-dom 19. Angular, Vue and plain HTML apps use the custom elements (below) and need nothing else. Use is covered by LICENSE.md: free with a Brandrail account.
Use
import "@brandrail/kit/styles.css";
import "./brandrail.tokens.css"; // written by `npx brandrail init`: maps your Brand Kit onto the kit
import { Button, ColorMode } from "@brandrail/kit";
export default function App() {
return (
<div className="brandrail light">
<Button theme="brandrail" colorMode={ColorMode.LIGHT} label="Save" />
</div>
);
}brandrail init writes brandrail.tokens.css with your published Brand Kit: colours, spacing, radius, type and font. The kit picks them up automatically, whatever order the stylesheets load in.
Use in any framework (custom elements)
Every component is also a custom element: Button is <br-button>, DatePicker is <br-date-picker>, and so on (br- + the name in kebab-case). One import registers them all; it carries its own small React-compatible runtime (Preact), so the page needs no React. About 59 KB gzipped for all 28.
import "@brandrail/kit/elements"; // once, at the app entry
import "./brandrail.tokens.css"; // from `npx brandrail init`: your Brand Kit- Attributes are the React props in kebab-case:
<br-button label="Save" type="cta" size="small">. Lists and objects take JSON (items='[{"label":"Home"}]') or a property (el.items = [...]). - Events are the callback props as DOM events with the value in
event.detail:onChange→br-change,onClick→br-click. Inputs, checkboxes, toggles, dropdowns and date pickers keep their own value, and expose it as a property (el.value,el.checked,el.selected,el.selectedDate). - Children: containers take kit elements:
<br-button-group><br-button label="Day"></br-button-group>,<br-dropdown><br-list-item label="Brake" value="brake"></br-dropdown>,<br-radio-group>with<br-radio>,<br-checkbox-group>with<br-checkbox>.<br-tooltip content="…">wraps any content. - Theme:
theme="brandrail"is the default; dark mode withcolor-mode="dark"or adarkclass on any ancestor. - Styles are added to the page once by the import. With a strict Content Security Policy (no inline styles), link
dist/styles.cssyourself with adata-brandrail-kitattribute and nothing is injected.
Angular (any version with Ivy, including 14):
@NgModule({ /* … */ schemas: [CUSTOM_ELEMENTS_SCHEMA] }) // or in a standalone component's `schemas`<br-input-text label="Truck ID" [value]="id" (br-change)="id = $any($event).detail"></br-input-text>
<br-breadcrumb [items]="crumbs"></br-breadcrumb>
<!-- Angular types $event on unknown elements as Event: read the value with $any($event).detail. -->Vue 3: tell the compiler the tags are custom elements, then bind as usual:
// vite.config.js
vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith("br-") } } })<br-toggle label="Alerts" :checked="on" @br-change="on = $event.detail" />Plain HTML, PHP, Twig, Mustache: copy dist/elements.js into your assets and load it once with <script type="module" src="/assets/elements.js"></script>.
Editors: custom-elements.json (in the package) gives VS Code and JetBrains attribute completion; dist/elements-tags.d.ts types document.querySelector("br-button").
Publishing (maintainers)
Published to the public npm registry as @brandrail/kit (built files only: minified, no source maps, no TypeScript source; the script refuses to publish if any slip in). Needs an npm account in the brandrail npm organisation (npm login first).
cd packages/kit
pnpm run publish:npm -- --dry-run # lists exactly what would be published
pnpm run publish:npmBump version in package.json before each release. Inside the monorepo the web app uses the TypeScript source directly. (publish:github still publishes the old private GitHub Packages copy.)
