@mesgflow/ui-kit
v0.11.1
Published
Independent Angular component kit (button, select, dialog, table, sidebar, and more) built on a Tailwind v4 design token system. See README.md for setup and prerequisites.
Maintainers
Readme
@mesgflow/ui-kit
An independent Angular component kit — button, select, dialog, table,
sidebar, tabs, date-picker, and more — distributed as a real npm package in
the PrimeNG/ng-zorro-antd mold: it does not bundle Angular/CDK
(peerDependencies), and it does not hardcode app-specific things like
language (injected, see Internationalization
below). Angular 22+, standalone + zoneless, built on signals and a
Tailwind v4 design token system.
- Docs & live examples: https://hurdenizyener.github.io/mesgflow-ui-kit/
- Changelog:
CHANGELOG.md - Contributing:
CONTRIBUTING.md
Install
The quickest way is the schematic — it installs the peer dependencies,
sets up Tailwind v4 + the kit preset in your global stylesheet, adds
provideMesgflowUi() to app.config.ts and the flash-free dark mode
script to index.html (every step is idempotent):
ng add @mesgflow/ui-kitOr install manually and follow the sections below:
npm install @mesgflow/ui-kitLater upgrades run the kit's migrations automatically:
ng update @mesgflow/ui-kit.
Every primitive also has its own secondary entry point (same pattern as
@angular/cdk), so either of these works:
import { Button } from '@mesgflow/ui-kit'; // primary barrel
import { Button } from '@mesgflow/ui-kit/button'; // standalonePeer dependencies
@angular/core, @angular/common, @angular/forms, @angular/cdk, @angular/aria ^22.1.0
class-variance-authority ^0.7.1
clsx ^2.1.1
date-fns ^4.4.0
tailwind-merge ^3.6.0
@material-symbols/font-400 ^0.47.1Optional peers (only needed if you use the kit's own font stack rather than your own):
@fontsource-variable/inter
@fontsource-variable/space-grotesk
@fontsource-variable/jetbrains-monoThe project must be standalone + zoneless (it isn't tested with NgModules or zone.js).
Styles
In your Tailwind v4 entry stylesheet, after the @import "tailwindcss/theme.css" layer(theme);
lines:
@import '@mesgflow/ui-kit/preset.css';That one line bundles everything: this kit's design tokens, the official
@angular/cdk/overlay stylesheet (required for Select/Tooltip/DatePicker/
Sidebar/Table menus to position correctly), Material Symbols (for the
Icon primitive's ligatures), and a @source directive so Tailwind's
scanner picks up this package's own class names from
node_modules/@mesgflow/ui-kit/fesm2022/*.mjs — Tailwind v4's automatic source
scanning skips node_modules by default, so without this the kit renders
"half-styled" (no hover/disabled/focus states, no width on layout
primitives) with no build error. If @source ever fails to resolve in your
setup, add it explicitly as a fallback:
@source '../node_modules/@mesgflow/ui-kit/fesm2022/*.mjs';If you're using the kit's own font stack, import it too (optional — with no
font imports the design still works, it just falls back to the browser's
system-ui/monospace fonts):
@import '@fontsource-variable/inter';
@import '@fontsource-variable/space-grotesk';
@import '@fontsource-variable/jetbrains-mono';Dark mode
Every token reacts to a .dark class on the root element. The kit ships
the state for it in @mesgflow/ui-kit/theming: MfColorModeService
(light / dark / system, persisted in localStorage, follows the OS
preference live, switches with a View Transition) and colorModeInitScript()
— inline its output in index.html's <head> so dark mode is applied
before Angular boots (no white flash; ng add does this for you).
provideMfColorMode({ storageKey, defaultMode }) changes the defaults, and
<mf-theme-switcher> is a ready-made toggle.
Internationalization
Every component's text defaults to English. To provide your own strings
(and/or a date-fns locale for DatePicker/Calendar), add
provideMesgflowUi() to your providers:
import { provideMesgflowUi } from '@mesgflow/ui-kit';
import { mfLabelsTr } from '@mesgflow/ui-kit/i18n/tr';
import { tr } from 'date-fns/locale';
providers: [provideMesgflowUi({ labels: mfLabelsTr, dateLocale: tr })];labels is a deep-partial override — you only need to supply the fields
you want to change, everything else falls back to the English default. It
also accepts a reactive Signal<DeepPartial<MfLabels>> if your app's
language can change at runtime. @mesgflow/ui-kit/i18n/tr ships a complete
Turkish translation as a ready-made example (mfLabelsTr); it is not
re-exported from the primary barrel, so it's fully opt-in.
Dialog/ConfirmDialog/DialogService previously had their own standalone
MF_DIALOG_LABELS injection token — that still works as an escape hatch if
you only need to override dialog text, but provideMesgflowUi() is the
recommended entry point for everything now.
Design tokens
All color/elevation/radius/typography/motion tokens live in
@mesgflow/ui-kit/tokens.css (bundled into preset.css, so you don't need to
import it separately unless you want tokens without the rest of the
preset). Role tokens (bg-surface, text-fg, text-fg-muted,
shadow-control, border-hairline, bg-glass, bg-accent-fill, etc.)
automatically swap value between light and dark — templates never need a
dark: twin when using them. Every semantic tone (success/warning/
danger/info/help, plus primary) exposes the same five-token set:
bg-X-fill/hover:bg-X-fill-hover/text-X-fill-fg for solid blocks, and
bg-X-tint/text-X-tint-fg (a color-mix()-based soft badge/alert
background) for tonal marks. The kit is border-first: containers
(card/table/toolbar/popover/menu) use border-hairline (a ~16% opaque,
brand-tinted 1px line) instead of a shadow; shadow-1 is reserved for
small contact shadows (segmented pill, slider thumb), and shadow-glow
(primary filled button only) adds a soft emerald glow in dark mode.
Dialog/Sheet/Drawer panels, Toast items, and the docs site's sticky header
use a micro glassmorphism surface (bg-glass + backdrop-blur, falling
back to a solid surface when backdrop-filter isn't supported or the
visitor prefers reduced transparency). See the docs site's Foundations
pages (Colors/Typography/Radius/Elevation/Motion) for a live, inspectable
reference.
Design tokens as JSON (DTCG)
@mesgflow/ui-kit/tokens.json exports the same tokens in the W3C Design
Tokens format — a primitives set (ramps, radius, control heights, fonts,
type scale, durations/easings) plus light and dark role sets that alias
the primitives. It is Tokens Studio compatible (multi-set + $themes) and
works as a Style Dictionary source. It is generated from the CSS, so the CSS
stays the single source of truth.
Icons
<span mfIcon>search</span> uses the Material Symbols font by default. For
crisp stroke icons with no font download, add the optional Lucide set — it
maps the Material names the kit uses (and ~170 common ones) to Lucide SVGs;
unmapped names fall back to the font:
import { provideMfLucideIcons } from '@mesgflow/ui-kit/icons-lucide';
providers: [provideMfLucideIcons({ strokeWidth: 1.75 })];Blocks
@mesgflow/ui-kit/blocks contains ready-made compositions built from the
primitives, with all texts in MfLabels:
<mf-auth-card>— sign-in card with validation, social provider slot ([mfAuthProviders]), remember me and error state; emitssignIn.<mf-invite-members [roles]>— multi-email tag input + role select; emitsinvitewith only valid addresses.<mf-settings-section heading>— the two-column settings layout with an[mfSettingsActions]footer strip.
Theming
@mesgflow/ui-kit/theming (opt-in, not re-exported from the primary barrel —
same pattern as @mesgflow/ui-kit/i18n/tr) lets you swap the accent color,
radius scale, and neutral tint at runtime, with no rebuild:
import { applyMfTheme } from '@mesgflow/ui-kit/theming';
applyMfTheme({ accent: '#4f46e5', radiusScale: 'soft', neutralTint: 'cool' });This works because every Tailwind utility the kit generates
(bg-accent-fill, rounded-md, …) compiles to a var(--color-accent-fill) /
var(--radius-md) reference rather than a baked-in value — applyMfTheme()
overwrites those CSS custom properties on document.documentElement (or a
target element you pass), and the whole kit repaints instantly. Passing
accent regenerates all 11 ramp steps (--color-primary-50..950) from the
given #rgb/#rrggbb hex via OKLCH (hue/chroma preserved, a fixed
lightness curve per step) and writes three role lines explicitly as
light-dark(…): a WCAG-safe --mf-fg-on-accent, --mf-accent-fill, and
--mf-accent-fill-hover — light half from the ramp's own 600/700, dark half
from 400/500 (the same split the kit's own default ramp uses). fg-on-accent
is computed separately for each half, since a 600-step and a 400-step color
are usually very different in brightness and may need different text
colors. The other light/dark role tokens (--mf-accent, --mf-focus-ring,
--mf-primary-tint(-fg), --mf-shadow-glow, …) already reference the raw
ramp via var(), so they update automatically. Passing accent: null
clears every inline override those calls left behind, reverting to the
kit's default "Deep Emerald" ramp.
exportMfThemeCss(config) returns the same result as a static :root { … }
block you can paste into your own stylesheet at build time instead of
calling applyMfTheme() at runtime.
createAccentRamp(hex) is also exported directly if you only need the 11
hex values (e.g. to render a preview swatch) without touching the DOM.
The five semantic ramps (--color-success/warning/danger/info/help-50..950)
are hand-tuned to the default "Deep Emerald" accent and are not
regenerated by applyMfTheme(). They're plain :root/.dark custom
properties like any other token, so if you pick an accent that collides
with one of them (e.g. an amber accent next to warning), override the
relevant custom properties yourself after calling applyMfTheme().
License
MIT — see LICENSE.
Internal architecture notes for contributors (directive-vs-component
rules, the cva/token conventions, @angular/aria composition patterns,
the i18n system's internals, etc.) live in
docs/tr/mimari.md
(Turkish) — that content is for people working on this repo, not for
consumers of the published package.
