feat(core): add property() factory for typed custom properties#301
Merged
Conversation
Composes variable() with an @Property at-rule and returns the same Variable, so a typed custom property is one node in the reference graph. The @Property block is hoisted to root and de-duped by name; initial-value defaults to the variable's value. Transpiler untouched — CSS emission reuses the existing at-rule consumer.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 61f4d0f The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Adds the load-bearing case Étoile flagged: property() called inside a nested selector lands the value declaration in that container while the @Property registration hoists to root. Also documents the de-dup guard's initial-value/value desync.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 1 of the
@propertyspike (SF-10). Adds aproperty()factory to@styleframe/corefor typed custom properties. It composes the existingvariable()+atRule('property', …)and returns the sameVariable— one custom property, one node in the reference graph. No new token type, no type guard, transpiler untouched: CSS@propertyemission reuses the existing at-rule consumer.Design decisions (the three open questions)
1. Hoisting / de-dup. The
@propertyblock is only valid at the top level, so it is always registered onroot, regardless of the calling container. It is de-duped by custom-property name — callingproperty('space', …)twice emits one@property --spaceblock. The value declaration itself stays in the calling container via the normalvariable()path.--<instance.name>; it does not reflect customvariableNameFnprefixing or dotted-name transforms. Same limitation as the existing raw--hatch. Reconciling the two name-derivation paths is deferred to Phase 2.2.
initial-valuereconciliation.initialValuedefaults to the variable'svalue, soproperty('space', '0px', { syntax: '<length>' })yieldsinitial-value: 0px. Callers can override with an explicitinitialValue. Both the--x:declaration and the@propertyblock are emitted.3. syntax → TS type map. Out of scope here.
syntaxis an opaque string in Phase 1; the tighter,syntax-derived narrowing that would flow throughref()/Reference<Name>is the Phase 2 RFC (theVariable/Referencetype thread), not this PR.Output stability
Additive. Generated CSS/TS/DTS are byte-identical when
property()is unused — the factory only adds an at-rule node to the tree when called.Test plan
engine/core/src/tokens/property.test.ts— 7 unit tests (variable creation,@propertyregistration, inherits default/override, initial-value default/override, de-dup, numeric values)engine/transpiler/src/consume/css/property.test.ts— exact CSS output assertion for the@propertyblock + value declarationpnpm build:nodocs— 11 tasks successfulpnpm --filter @styleframe/core --filter @styleframe/transpiler test— core 706 passed, transpiler 883 passedpnpm typecheck— 15 successfuloxlint— clean on changed filesTwo pre-existing context-shape assertions (
declarations.test.ts,selector.test.ts) were updated to include the newpropertykey.Changeset:
@styleframe/coreminor.