Krizaka
Toutes les briques

krizaka-ui

Krizaka UI

Jetons, preset Tailwind v4, primitives accessibles, icônes et i18n — web et React Native.

Le problème qu'elle supprime

Trois produits, trois vocabulaires de jetons, 1 153 surcharges light: dans une seule app.

Trois produits, trois vocabulaires de jetons : nous avons mesuré 1 153 surcharges light: dans une seule application, la même carte écrite cinq fois, et pièges à focus, clavier et ARIA réécrits à la main dans chaque kit.

  • Un thème fait de variantes light: et dark: dans chaque composant — un nouveau thème, et il faut tous les toucher.
  • L'accessibilité réécrite par produit, et fausse dans au moins l'un d'eux.
  • Un site de documentation qui décrit les props du trimestre dernier.

Ce qu'elle fait

  • Un vocabulaire sémantique, --kz-*, compilé depuis des design tokens — sombre et clair à égalité.
  • Des primitives accessibles avec parité React Native, un point d'entrée chacune.
  • La documentation de chaque composant générée depuis son code.

Un vocabulaire sémantique (--kz-*) compilé depuis des design tokens, un preset qui en fait des utilitaires Tailwind, et des primitives — bouton, carte, dialogue, champ, onglets, toast, palette de commandes… — avec parité React Native, un point d'entrée chacune. La documentation de chaque composant est générée depuis son code.

Le hibou lit le code, pas un wiki : la page de chaque composant sur krizaka.com/docs/ui est générée depuis son meta.ts et ses exemples nommés, et les tests du registre échouent s'il en manque un.

La règle du hibou

Décisions et compromis

  1. Nous avons choisi

    Un seul vocabulaire de jetons ; le sombre sur :root, le clair sur html.light ; une marque surcharge des valeurs (brands/scoped.css).

    Nous avons refusé

    Des variantes light:/dark: dans les composants, et un jeu de jetons par produit.

    Parce que

    Un thème ou une marque est un jeu de valeurs : l'orange d'Orazaka et le violet d'Orochia utilisent les mêmes composants que ce site.

    Ce que cela vous coûte

    Les composants ne lisent que var(--kz-*) ; les couleurs de palette brutes sont refusées par les règles de lint.

  2. Nous avons choisi

    Radix pour toute interaction non triviale, des variantes tailwind-variants, chaque story auditée par axe en sombre et en clair à chaque pull request.

    Nous avons refusé

    Des pièges à focus et une gestion du clavier écrits à la main.

    Parce que

    L'accessibilité est écrite une fois et testée là où elle est écrite.

    Ce que cela vous coûte

    Radix dans votre bundle ; des budgets size-limit par point d'entrée le tiennent en respect.

  3. Nous avons choisi

    Les mots arrivent en props ; aucune fonction de traduction dans la bibliothèque.

    Nous avons refusé

    Embarquer un moteur de traduction.

    Parce que

    N'importe quelle i18n convient — la nôtre (@krizaka/i18n, catalogues typés et contrôle en CI) ou la vôtre.

    Ce que cela vous coûte

    Vous passez les libellés.

  4. Nous avons choisi

    Un cliquet : par dépôt, des compteurs de classes de palette brutes, de variantes light:, d'utilitaires [var(--…)] et de className en template qui ne peuvent que descendre.

    Nous avons refusé

    Une migration big bang, et une règle de lint activée d'un coup.

    Parce que

    Une application existante l'adopte écran par écran sans laisser la dette repousser.

    Ce que cela vous coûte

    Un lint-ratchet.json à commiter et un contrôle en CI.

En code

tsxapp/globals.css · Save.tsx
/* globals.css — your brand is values, never components */
@import "tailwindcss";
@import "@krizaka/tailwind";        /* tokens + utilities + motion signature */
@import "@krizaka/ui/tailwind.css";
:root      { --kz-accent: hsl(152 62% 40%); }   /* dark is the default */
html.light { --kz-accent: hsl(152 70% 30%); }

// Save.tsx — one entry point per primitive: an app ships only what it imports
import { Button } from "@krizaka/ui/button";

export function Save({ label }: { label: string }) { // words arrive as props: any i18n works
  return <Button variant="primary">{label}</Button>;
}

Ne l'utilisez pas quand

  • Vous n'utilisez pas Tailwind v4 : le preset l'exige (les jetons seuls sont de simples variables CSS).
  • Vous voulez un kit sans style et maîtriser chaque pixel : utilisez Radix directement.
  • Il vous faut des graphiques aujourd'hui : @krizaka/charts est en construction.

Où elle en est

@krizaka/ui, tokens et tailwind 2.2.0 sur npm (latest) — la 2.2.0 a apporté les cinq oiseaux de cette page (@krizaka/ui/mascots) ; icons, i18n, intl et config 0.1.0. Supportées : majeures N et N-1, correctifs six mois après N+1.

Publié

En cours

  • @krizaka/charts — des graphiques qui suivent thème et marque, sur Apache ECharts, chacun avec un tableau de données accessible, puis les effets et les blocs : la feuille de route est un epic ouvert.krizaka-ui#49

L'adopter

bashterminal
npm install @krizaka/ui @krizaka/tailwind @krizaka/tokens tailwindcss
# the debt counters of an existing app (raw palette, light:, [var(--…)], className templates):
npx -p @krizaka/config krizaka-ratchet --json --root .

Dites-nous où ça coince.

Une brique est juste quand elle survit à votre code, pas au nôtre. Posez votre question dans le fil de la brique, proposez un changement comme idée, ou signalez un bug sur son dépôt — chaque décision de cette page reste ouverte à un meilleur argument.

Les autres briques