skin-material
A Material Design skin for Fluixi UI — activate with data-ui="material".
Restyles the components to a Material 3 flavour: pill buttons with per-variant
elevation and a click-origin ripple, M3 switch geometry, filled text fields, M3
surface radii, emphasized motion, and self-hosted Roboto. It composes with the
data-theme and data-accent axes.
Installation
pnpm add @fluixi-ui/skin-material
Usage
Import the stylesheet after the tokens + preset, then set data-ui="material":
import '@fluixi-ui/tokens/preset.css';
import '@fluixi-ui/skin-material/styles.css';
document.documentElement.dataset.ui = 'material';
Or drive it reactively — lazy-loading the CSS only when the skin is active:
import { createTheme } from '@fluixi/core';
const skin = createTheme({
attribute: 'data-ui',
themes: ['fluixi', 'material'],
default: 'fluixi',
load: (s) => s === 'material' && import('@fluixi-ui/skin-material/styles.css'),
});
skin.init();
The ripple
The CSS state layer covers hover / focus / press, but a true click-origin ripple
needs the pointer position — so it's a tiny JS primitive. Call installRipple
once; it delegates a single pointerdown listener that spawns the ripple inside
any Material control:
import { installRipple } from '@fluixi-ui/skin-material/ripple';
installRipple(); // returns a disposer
What it restyles
- Buttons — pill shape;
solidrests on elevation and lifts on hover (contained), whileoutline/ghost/softstay flat (per-variant, as Material assigns it); currentColor state layer + ripple. - Selection controls — M3 switch (52×32, growing thumb), rounded checkbox, filled slider thumb.
- Fields — filled text field / combobox (bottom border thickens to primary on focus).
- Menus & lists — full-bleed rows with roomier padding.
- Surfaces — M3 corner radii (dialog 28px, hover-card 12px, tooltip 4px); elevation from the shadow tokens.
- Tabs — 3px rounded primary indicator.
How it works
All rules live in the flx.skin cascade layer, which sits above
flx.components (the default look), so they win wherever they match — while your
CSS stays unlayered and wins over both. Everything is scoped to
[data-ui="material"], so the skin only applies where you opt in.
Part of the Fluixi UI component library. Made with ☕ by the Fluixi team.