Skip to content

Repository files navigation

foldstylex

shadcn-inspired styling for Foldkit, powered by StyleX.

foldstylex is a small monorepo that turns StyleX design tokens and component styles into named composition primitives so Foldkit apps can build intent-shaped UI instead of anonymous layout soup.

// Prefer named primitives…
Card.section({
  title: 'Overview',
  children: [
    Stack.view({
      gap: 'md',
      children: [
        Row.view({
          align: 'between',
          children: [
            Text.view({ variant: 'sectionTitle', children: 'Pending' }),
            Badge.view({ label: '3' }),
          ],
        }),
        Stat.card({
          label: 'Open items',
          state: new Ready({ value: '12' }),
        }),
      ],
    }),
  ],
})

// …not StyleX key salads on every div
// h.div(elAttrs(sxAttrs(h, cardStyles.root, layoutStyles.panelPad)), [ … ])

Not a domain UI kit. No product vocabulary (accounting, imports, CPA, …) lives here—only reusable layout, form, data-display, and chrome primitives.

How the layers fit

Layer Responsibility
@foldstylex/tokens Theme vars (colors, layout metrics)
@foldstylex/styles StyleX rules for components + layout (public escape hatch)
@foldstylex/foldkit Named Html helpers: Button, Card, Stack, Input, Stat, …
Foldkit / @foldkit/ui MVU runtime, headless behavior, a11y
Product apps Domain models, formatting, workflows

Inspiration, not ports:

  • shadcn — slot-style chrome (Card.header / Card.title) and control variants
  • daisyUI — short names for common patterns (stat, stack-like layout)
  • Tailwind — parametric layout options (gap, align) instead of dozens of one-off APIs
  • StyleX — typed, composable styles as data

Philosophy (short)

  1. Anti–div soup — when a layout pattern is common, give it a name (Stack, Row, Text, Stat). Residual raw h.div is fine for true one-offs.
  2. Role-based APIs — not every export is view(config). Layout, controls, form fields, chrome slots, Foldkit stateful widgets, and async display each have a deliberate shape. See AGENTS.md.
  3. Styles stay public — primitives map to StyleX; apps may still compose layoutStyles when needed. Public StyleX keys are also zero-domain.
  4. Effect-first variants — closed unions and async UI state use Schema tagged types and Match (e.g. Stat Loading | Failed | Ready).
  5. 3+ uses — promote a pattern when it repeats; do not invent speculative mega-APIs.
  6. Zero domain + generic axes — public APIs expose visual axes (density, width, align, row presentation, cell tone). Apps map domain meaning at the boundary. No product vocabulary in the library or in public style keys.
  7. Consumer exports only — package surface is a consumer contract. Tests must not force private mapping helpers into exports. Prefer clean cutover (no shims/aliases) for unpublished internal/demo APIs.
// Library axes — not domain roles
Input.control({ density: 'compact', width: 'sm', align: 'end',})
Table.tr({ presentation: 'summary', children: [
  Table.td({ align: 'right', tone: 'success', children: total }),
]})

Full agent rules (TDD, naming, testing bar): AGENTS.md.
System completeness tracking: issue #1.

Packages

Package Role
@foldstylex/tokens StyleX theme variables
@foldstylex/styles Component + layout StyleX modules, document reset
@foldstylex/foldkit Named primitives + StyleX attribute glue
examples/sidebar-demo Kitchen sink catalog + sidebar demo

Develop

Requires Node >=20.19 or >=22.12, pnpm, and mise (optional but used for task runners).

pnpm install

mise run dev         # kitchen sink + sidebar demo (Vite)
mise run typecheck   # tsc across packages
mise run test        # vitest
mise run check       # full typecheck + tests (always; independent of dirty files)
mise run pre-commit  # hk changed-file hooks

mise run check is the authoritative full verifier after implementation work.

Open the demo and use the components / kitchen sink views as the living catalog for how primitives compose.

Interactive/MVU changes need Foldkit Story or Scene tests that exercise the real transition. Pure factory tests assert observable structure/a11y/style behavior.

Effect

This repo targets Effect v4 (effect@4.0.0-beta.x, same lineage as effect-smol). Local clone at ../effect-smol is useful for API exploration. Project guides:

mise exec -- effect-solutions list

License

Private / unpublished monorepo unless noted otherwise in package manifests.

About

shadcn-inspired styling for Foldkit, powered by StyleX

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages