Mixins / foldkit-mixins
The mental model
There are five ideas to learn:
| Concept | Meaning |
|---|---|
| Slot | A named extension point in a view: root, input, label, trigger, ... |
| Slots | The contract describing which extension points exist and what each permits. |
| Style | Appearance attached to a slot: classes, inline declarations and compiled CSS rules. |
| Behavior | Element-level interaction attached to a slot: attributes and an optional Foldkit Mount. Never application state. |
| SlotView | A pure Foldkit view that renders those slots and resolves attached Style/Behavior. |
Style and Behavior both compile to a Mixin. The resolver combines their contributions and
rejects ambiguous ownership instead of silently choosing a winner.
Slots contract
│
┌───────────┴───────────┐
Style Behavior
appearance interaction
│ │
└───────────┬───────────┘
▼
Mixin
│
▼
resolver
│
▼
ordinary Foldkit attributesWhy not just className and props?
A class name says only "append this string." A slot is a typed public customization point. It can say:
- this point is a text input rather than an arbitrary element;
- it publishes
inputbut notclick; - callers may set
aria-invalidbut may not replace the structuralrole; - this point is internal and cannot be targeted publicly;
- two independent behaviors may not both own the same event.
That matters once a design system, a feature, accessibility logic and product-specific behavior all need to customize the same view without knowing about each other.
Use it when
Use mixins when a view should be restyled or decorated where it is used, not only where it is defined, and you want those customizations checked.
Typical examples are a design system styling a feature component, a tooltip attached by a caller,
analytics on an existing action, ARIA decoration, a focus trap, a ResizeObserver, keyboard
behavior, or a reusable visual recipe.
Not for state. A widget's open/selected/value belongs in a Foldkit Model or Submodel. A
transition is update; a network call is Message → Command; an element-scoped effect is a
Mount. A Behavior that "needs state" is a signal to reach for a Submodel, not to hide an atom
inside the mixin.
Install
pnpm add foldkit-mixinsfoldkit and effect are peer dependencies. foldkit-mixins-surface bridges a Surface
projection, and foldkit-mixins-ui adapts @foldkit/ui components.
The design-system pieces are subpaths, so an application that only attaches classes pays for
none of them: foldkit-mixins/layers, /theme, /layout, /defaults, /prose, /utilities
and /app.