Stage 4: Composites - #9
Conversation
Ship product composites on a compound-first dual API, serializable core models, registry sync, and a polished social-feed exit fixture. Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: 03156b1 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 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 |
Use h2 for SectionTitle so pages with an h1 do not skip a level under Storybook axe gating. Co-authored-by: Cursor <cursoragent@cursor.com>
…s loading state from an absent entry. PostCard.Root declared asChild but always rendered its own <article>, so a consumer element could never become the root. It now slots through Slot.Root and re-parents children with Slot.Slottable, keeping the Stack decoration inside the consumer's element. FeedItem treated `entry === undefined` as loading, so a genuinely empty slot rendered a skeleton that never resolved. Co-authored-by: Cursor <cursoragent@cursor.com>
…prop. Stack had a direction prop, so the same align/justify values silently swapped visual axis depending on a prop often set far from the alignment depending on it. Rather than renaming the props away from CSS, the flip trigger is removed: Stack is vertical-only and Inline owns horizontal flow, so the standard flexbox reading of align and justify is correct everywhere. - Stack loses direction, wrap, and collapseBelow; its recipe is now exactly gap, align, justify, rail, with flex-direction: column in the base class. collapseBelowRulesStack had to go with it: its stretch rule was guarded by :not([data-direction='column']), which would have matched unconditionally once Stack stopped emitting the attribute and silently overridden align. - Center is deleted. It was a strict subset of Stack/Inline, and Container already owns max-width measure centering. - Grid gains justify, mapped to justify-items to pair with align. Its columns always emit 1fr tracks, so justify-content would have been inert. - EmptyState.Root composes as a single element again, which is the bug that surfaced all of this. Horizontal Stack call sites move to Inline with align/wrap set explicitly where the differing defaults would otherwise change rendering. Co-authored-by: Cursor <cursoragent@cursor.com>
Share Stack/Inline flex keyword maps, drop Grid's identity placement map, always wrap PostCard children with Slottable, and trim redundant conformance guards. Co-authored-by: Cursor <cursoragent@cursor.com>
… onto @reactive/silk. Also gate CommentThread continue on onContinue and keep SocialFeed reduced-motion wrapping on the first entry. Co-authored-by: Cursor <cursoragent@cursor.com>
…in tests. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 03156b1. Configure here.
| </> | ||
| ) : null} | ||
| </StatGroupValue> | ||
| </StatGroupStat> |
There was a problem hiding this comment.
Invalid definition list markup
Medium Severity
The convenience StatGroup renders each stat as a div (StatGroupStat) directly under a dl, with dt/dd nested inside that wrapper. A dl may only contain dt and dd (plus script-support elements), so assistive tech and validators may not treat labels and values as paired description-list terms.
Reviewed by Cursor Bugbot for commit 03156b1. Configure here.


Summary
@reactive/silk-core/models.docs/COMPOSITES.md.asChildcontract where roots could not compose as a single element:EmptyState.Rootno longer wraps its slot in aCenter, andPostCard.Rootslots throughSlot.Rootwhile re-parenting children withSlot.Slottableinstead of always rendering its own<article>.FeedItemalso stops treating an absent entry as a loading state.Stackis vertical-only andInlineowns horizontal flow, soalign/justifykeep their standard flexbox meaning at every call site instead of silently swapping visual axis with adirectionprop.Layout primitive change (breaking, pre-1.0)
Surfaced by the
EmptyState.Rootbug: collapsing the strayCenterwrapper into the slotted element required ajustifyaxis onStack, which exposed that the layout layer had three spellings of centering and an axis that flipped under a prop.Stacklosesdirection,wrap, andcollapseBelow; its recipe is now exactlygap,align,justify,rail, withflex-direction: columnin the base class.collapseBelowRulesStackhad to go with it — its stretch rule was guarded by:not([data-direction='column']), which would have matched unconditionally onceStackstopped emitting the attribute and silently overridden a configuredalign.Centeris deleted (component,centerRecipe, exports,SilkDefaultskey, story). It was a strict subset ofStack/Inline, andContaineralready owns max-width measure centering.Gridgainsjustify, mapped tojustify-itemsto pair with its existingalign→align-items.columnsalways emits1frtracks, sojustify-contentwould have been inert on every configurationGridcan express. This meansjustifydistributes content on the flex primitives but places an item within its track onGrid; the nuance is documented in the "Layout axes" table inARCHITECTURE.md.Stackcall sites move toInline, withalign/wrapset explicitly wherever the differing defaults (stretch/nowrapvscenter/wrap) would otherwise change rendering.docs/PRINCIPLES.mdcarries an amendment entry, since the charter's rule-of-use requires one to dropCenterfrom the layer-1 vocabulary.Nothing has been published (both packages are at
0.0.0with no changelog), so the pending changesets describe the end state rather than a migration no consumer would have lived through.Test plan
yarn buildyarn typecheckyarn test(344 tests: silk-core 30, silk 150, docs 164)yarn test:perfyarn test:packedyarn workspace @reactive/silk-native-spike testnode scripts/sync-registry.mjsoutput matches committed registry sourcesMade with Cursor