openpencil/packages/dom-css/AGENTS.md
Danila Poyarkov 4254204685
feat(dom-css): compile component variants into state styles (#965)
* feat(dom-css): compile component variants into state styles

Code export needs a component's variants as one markup tree whose look follows the control's state. stateStyles keeps the rest variant as the base and turns each other variant into only what it changes, under the data-state, data-disabled and interaction conditions Reka and Radix set, or a data attribute for other variant properties. Layers only some variants draw stay hidden where absent. stateStylesToCSS writes a stylesheet with readable classes and stateStylesToTailwind writes utilities behind state variants.

* refactor(dom-css): build state stylesheets with the CSS object model

The stylesheet was assembled from strings with JSON-quoted attribute values. It is now built with @acemir/cssom, which rejects an invalid selector and prints the declarations, and attribute values are escaped as CSS strings by cssesc. The object model loads lazily, as for font-face rules, so stateStylesToCSS is async.

* refactor(dom-css): split state styles by step and require a rest variant

model.ts mixed reading conditions, projecting and merging variants, and comparing styles. They now live in conditions.ts, layers.ts, and model.ts, with the types in types.ts. A layer only some variants draw keeps the style of the variant that adds it, so no separate first-style pass is needed. A set with no rest variant now has no state styles, instead of using a checked or hovered variant as its rest look.
2026-10-07 21:15:40 +00:00

1.5 KiB

DOM/CSS

DOM, CSS, HTML, JSX, and Tailwind projection between documents and SceneGraph, with browser and headless CSS runtimes. Sources are grouped by direction:

  • src/import/ — HTML, CSS, JSX, and Tailwind to SceneGraph, including the jsx-runtime entries and CSS value parsing.
  • src/export/ — SceneGraph to HTML, Tailwind JSX, and Storybook: projection, CSS formatting, the HTML bundle, and printers. src/export/index.ts is the ./export entry.
  • src/behaviours/ — what a behaviour means in the DOM, shared by preview and export: controls and layer roles, story props, and state styles compiled from variants. Exported from ./export.
  • src/runtime/ — browser and headless CSS runtimes.
  • src/tokens/ — variables as design tokens: CSS custom property names, Tailwind namespaces from twirlwind, and units. Shared by both directions and exported from ./export.

Rules:

  • Depend only on @open-pencil/scene-graph and @open-pencil/emit. Engine services such as web-font resolution come in as options; Core registers the HTML and Tailwind JSX formats (packages/core/AGENTS.md).
  • Keep the ./export entry browser-safe: load node:* modules and the headless CSS object model lazily inside the functions that need them, so the app never bundles them.
  • Build generated code as syntax trees with @open-pencil/emit (es for TypeScript modules, jsx for JSX), not string fragments.
  • Imported documents are untrusted: check Base64 with js-base64's isValid before decoding.