v0.3.0 — the primitives layer
0.2.0 shipped 14 structural components — card, modal, navbar, table — and nothing underneath them. This release adds the layer an app actually uses hundreds of times.
Primitives
Seven components, across all five themes, in both template sets:
button · badge · heading · label · icon · box · prose
<!-- django-cotton -->
<c-cf.button variant="primary" size="large" type="submit">Save</c-cf.button>
<!-- JinjaX -->
<Cf:Button variant="primary" size="large" type="submit">Save</Cf:Button>They share one closed vocabulary rather than each inventing its own — variant, size, state, emphasis, level, type. A value outside a set raises PrimitiveConfigError naming the values that would have worked, instead of falling through to an unstyled element.
Every axis declares what its value becomes — a class, a tag, or an attribute — and that one fact decides whether an empty value is benign. An absent variant yields an unstyled element, which is correct. An absent level has no <h?> to render, so it raises: without that check you get <h class="title">, which is not an element, is absent from the document outline, and is unreachable by screen-reader heading navigation while still looking like a heading.
primitives.py is the vocabulary and the per-theme class map, exported as cf_ui_primitives.json. The classes are also spelled out longhand in the templates, on purpose — daisyUI compiles through Tailwind, whose scanner reads source text, so a class assembled at render time is tree-shaken away with no error. A bidirectional parity test fails the build the moment the module and the templates disagree, in either direction.
Upgrading from 0.2.0
On the daisy theme only, cf_ui_head now emits Tailwind's Play CDN script alongside the daisyUI stylesheet. daisyUI is a Tailwind plugin — its CDN stylesheet is the component layer and never the utility layer the shipped templates rely on for layout, so the previous single tag produced buttons and cards that looked right sitting in a layout that did not work.
If you already have a real Tailwind build supplying both layers:
CF_UI_DAISY_CDN = "off"Every other theme is unchanged, and there are no API breaks.
Also in this release
- Layout is out of scope, and now says so. cf-ui ships no grid. Fomantic's grid is 16 columns where the others are 12, and Bulma's
mobiletier is a max-width cap where every other ladder is min-width — so a shared span vocabulary has no single concept underneath it.docs/primitives.mdcarries the full reasoning and what to use instead. - djLint runs over both template trees, wired into
just check. - The release wheel guard is derived rather than counted. It asserted
>= 14templates per set — 0.1.0 figures — so a regression dropping all seven primitives from all five themes would have passed. It now checks the wheel against the source tree and cannot go stale.
Full detail in CHANGELOG.md · docs at fsecada01.github.io/component-framework-ui