Commit graph

10 commits

Author SHA1 Message Date
Danila Poyarkov 37bc706a59
fix: lay out fill text and repeat() grid tracks (#866)
* fix(core): let fill text share an auto-layout row

Fill frames grow and shrink from a zero flex basis, so fill siblings split a row's free space. Fill text only got flexGrow, and its measure function capped it at its stored width, 100px for new text, so seven fill labels in a 280px row each kept 100px and overflowed. Without a measurer, the fallback pinned that width and set no grow at all. Fill text now uses the same zero basis as fill frames on both paths.

* fix(design-jsx): read repeat() and minmax() in grid tracks

Track lists were split on whitespace, so columns="repeat(7, 1fr)" became the tracks repeat(7, and 1fr), read as fixed 0px and 1px columns that collapsed the grid. Tokens inside parentheses now stay together, repeat() expands its tracks, minmax() grows like its maximum, and a track the grid cannot express sizes to its content instead of to 0.

* refactor(scene-graph): parse CSS grid tracks with postcss-value-parser

design-jsx read repeat() and minmax() with a hand-written tokenizer and regexes, while dom-css already parses CSS values with postcss-value-parser. Track lists are now parsed in @open-pencil/scene-graph/css on that library, where both packages can use it, and design-jsx calls it. dom-css's hand-written declaration of the library's types is replaced by the types the library ships, which the shared module needs. The Scene Graph guide records that CSS values are parsed there.
2026-10-05 14:06:07 +00:00
Danila Poyarkov 6a05e30f15
fix(design-jsx): say what gradient helpers expect when stops are not an array (#881)
* fix(design-jsx): say what gradient helpers expect when stops are not an array

An AI agent called linearGradient with something other than an array of stops, and render failed with 'stops.map is not a function', which does not tell it how to fix the call. The helpers now validate their stops with Valibot and name the expected form, and the authoring reference shows the signature.

* fix(design-jsx): describe stops that cannot be shown as JSON

Review follow-up. JSON.stringify throws on a bigint or a circular object, so such a call failed with that error instead of the gradient's expected form.

* fix(design-jsx): word gradient stop errors from the Valibot issue

Review follow-up. The message now names the helper as a call, as the paint helper option warnings do, and ends with Valibot's description of what was wrong, which already says what it received without serializing the value. A stop that is neither [color, position] nor { color, position } names both forms and its index.
2026-10-04 18:28:44 +00:00
Danila Poyarkov 67dbd7156f
feat(design-jsx): export every property the renderer accepts (#814)
* feat(design-jsx): export every property the renderer accepts

JSX export wrote only part of a layer: one solid fill, one stroke
without its alignment, shadows as repeated attributes, background blurs
as layer blurs, and nothing for hidden children, constraints, size
limits, absolute positioning, vertical text alignment, masks, or
variable bindings. Rendering an export lost those properties, and JSX
diffs could not see changes to them.

The export now writes them, using paint and effect helper calls when a
shorthand cannot express a value exactly, and leaves out values the
renderer would infer, so ordinary output stays as it was. Prop values
can now hold objects, arrays, and helper calls, printed through
@open-pencil/codegen's builders, which gain a call expression. The
language gains `visible`, `locked`, `constraints` (Figma's constraints
object with lowercase values, as `blendMode` uses), `italic`,
`strokes`, `strokeWeights`, `strokeCap`, and `strokeJoin`, and now
applies `strokeAlign`, `strokeDash`, and the size limits, which it
accepted but ignored. Per-corner radii are written even when the
uniform radius is 0. A round-trip test renders each case's export and
checks the fields and that exporting again changes nothing.

* docs(fig): name the saved-glyph fixture by its repository path

The observation note linked the fixture with a relative path climbing four directories. Other notes name fixtures by their repository path, which reads the same from anywhere.

* fix(design-jsx): export the node-level dash pattern

A node's own dashPattern was not written, so a node dashed at node level
came back solid and the DOM/CSS export chose a solid border. It now
round-trips as a separate dashPattern prop; strokeDash stays the
stroke-local dash.
2026-10-03 15:40:21 +04:00
Danila Poyarkov 8404cee664
refactor(design-jsx): extract design JSX into its own package (#793)
* refactor(design-jsx): extract design JSX into its own package

Design JSX elements, helpers, schema, reference, and JSX export only need
the scene graph, yet lived in Core, so every consumer of the authoring API
pulled in the renderer, layout, and file formats.

@open-pencil/design-jsx now owns them and depends only on scene-graph. The
renderer takes icon lookup, SVG conversion, vector creation, and layout as
DesignJSXServices; Core binds its own and exports the bound renderJSX and
renderTree from @open-pencil/core/design-jsx.

* feat(design-jsx): export the JSX runtime for TSX authoring

The package already had a JSX runtime, but nothing exported it, so design
trees could only be written as function calls or JSX strings. Export
`./jsx-runtime` and `./jsx-dev-runtime` so `jsxImportSource` works, and make
`Fragment` produce the same empty-type node as `<>` in `renderJSX` strings.

* fix(design-jsx): render fragments nested in other elements

A fragment builds a node with an empty type, which only renderJSX expanded, and only at the root. Nested fragments and fragments passed to renderTree failed with 'Unknown element: <>'. Inline fragment children when trees are built, and share root expansion between renderTree and renderJSX.
2026-09-30 20:55:27 +04:00
mrhard9090 4faf20bab8
fix(design-jsx): warn about unsupported paint and effect helper options (#762)
* fix(design-jsx): accept blur in effect helpers and warn about unknown options

dropShadow({ blur: 12 }) silently used the default radius, although the shadow shorthand and the blur prop both call that value the blur, and any misspelled option was dropped without a word. The shadow and blur helpers now take blur as the radius, and renderJSX reports any other option they ignore, next to the existing unsupported-prop warnings.

Fixes #736

* refactor(design-jsx): check options for every paint and effect helper

The option check covered only effect helpers, and its key lists repeated
the option types by hand, so a new option could turn into a false
warning. One wrapper in `design-jsx/helpers.ts` now checks every paint
and effect helper that evaluated JSX can call, with key lists typed
against their option interfaces. Only plain objects are checked, and
repeated warnings are collapsed once. The authoring reference documents
the `blur` alias and the warnings.

* docs(design-jsx): scope helper option warnings to rendered JSX

* fix(design-jsx): name effect radius as Figma does and hint at it for blur

Accepting both `radius` and `blur` gave effect helpers two names for one
value, and when both were set `blur` was dropped without a warning.
Figma's effects only have `radius`, so the helpers take `radius` alone
and `blur` now warns with a pointer to it. The default radius is named
once instead of repeated.

---------

Co-authored-by: Danila Poyarkov <dev@dannote.net>
2026-09-30 09:59:45 +04:00
Danila Poyarkov e50df9ffda test: cover and document inherited instance dimensions 2026-09-14 00:24:52 +03:00
Danila Poyarkov b4f119a01b Merge branch 'native-authoring' into jsx-component-properties
# Conflicts:
#	packages/core/src/design-jsx/reference/authoring.md
#	packages/docs/reference/design-authoring.md
#	skills/open-pencil/references/design-authoring.md
2026-09-13 20:55:05 +03:00
Danila Poyarkov 8189c08e0b docs: clarify scalar modes and instance sizing guidance 2026-09-13 20:54:27 +03:00
Danila Poyarkov becc4f7432 feat: author scoped component properties in Design JSX 2026-09-13 19:27:06 +03:00
Danila Poyarkov 863b1e6c6a refactor: share design authoring guidance across agents 2026-09-13 19:08:27 +03:00