improvement(spacing): make row Stack separators self-orienting (CUI-38) - #1182
Draft
JeanMarcMilletScality wants to merge 1 commit into
Draft
improvement(spacing): make row Stack separators self-orienting (CUI-38)#1182JeanMarcMilletScality wants to merge 1 commit into
JeanMarcMilletScality wants to merge 1 commit into
Conversation
Contributor
Hello jeanmarcmilletscality,My role is to assist you with the merge of this Available options
Available commands
Status report is not available. |
Contributor
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
Peer approvals must include at least 1 approval from the following list: |
Stack picked its separator element from the direction prop at render time, injecting HSeparator (a vertical rule) or VSeparator (a 24px horizontal dash). A CSS flex-direction flip — how container-query-driven responsive layouts work — left the separators pointing the wrong way, blocking responsive work in ARTESCA and every other repo consuming Stack. Only the row separator needs to change: a consumer collapsing a row into a column keeps direction="horizontal" as the base and flips in CSS, so the prop never changes. SelfOrientingSeparator replaces HSeparator using flex-basis for the main axis and align-self for the cross axis, which renders identically to the fixed width: 1px while the Stack stays a row and becomes a full-width rule once CSS flips it to a column. VSeparator (renamed DashSeparator) is kept as-is, so no existing vertical call site is restyled. Making it a full-width rule would have duplicated the page Form header's own 1px border, leaving no distinction between the form title and a section separator. No public API change: Separator was never exported. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
JeanMarcMilletScality
force-pushed
the
improvement/CUI-38-self-orienting-separator
branch
from
August 12, 2026 16:41
2dfb90d to
f5e87ef
Compare
JeanMarcMilletScality
marked this pull request as draft
August 13, 2026 07:21
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.
TL;DR — A
Stack's row separators now orient themselves from their flex parent instead of from thedirectionprop, so a consumer can collapse a row into a column in pure CSS (a container query) and the separators follow. Nothing renders differently today.Context / Why
Stackpicks its separator element from thedirectionprop, at render time. A CSSflex-directionflip — which is how container-query-driven responsive layouts work — leaves the separators pointing the wrong way. This blocks the ARTESCA overview page (clips its first KPI tile below ~875px, fixed by flipping aStackin a container query) and would block identity-ui, zenko-ui and metalk8s the moment they flip one. CUI-38🧩 Approach
Only the row separator needs to change. A consumer collapsing a row into a column keeps
direction="horizontal"as their base and flips in CSS — the prop never changes, so the vertical branch is never involved in the responsive case. That makes the fix behaviour-preserving rather than a restyle.The row separator becomes direction-agnostic by exploiting the fact that
flex-basisresolves against the main axis whilealign-selfresolves against the cross axis:Before — orientation hard-coded into the element:
After — orientation resolved by the parent's axis:
flex-directionflex-basis: 1pxsetsalign-self: stretchsetsrowcolumnflex: 0 0 1pxisflex-grow: 0; flex-shrink: 0; flex-basis: 1px— the same fixed, non-shrinking 1px the oldwidth+flex-shrinkpair produced, just expressed against the main axis instead of the horizontal one. Measured in a real browser, with the old CSS simulated by overriding the new declarations back on the same DOM:The vertical dash is deliberately left alone (
VSeparator→DashSeparator, rename only). An element with an explicit cross-axis size can't self-orient, so making the vertical case work in CSS would have meant turning it into a full-width rule — restyling all 5 vertical production call sites, adding 1.5rem of separation, and needing design sign-off. Worse, in a pageFormthe result duplicates the header's ownborder-bottom: 1px solid theme.border(Form.component.tsx:102): same weight, same colour, near-same width, so a section separator becomes indistinguishable from the form title's rule. A fix shouldn't introduce a new issue — so the vertical branch stays exactly as it is, and the responsive case doesn't need it.The direction flip was verified with no re-render — measured by mutating
container.style.widthand forcing reflow only; DOM node identity held and the separator count stayed at 2. Wide (700px):row, separators 1 × 38.75. Narrow (380px):column, separators 380 × 1.📷 Screenshots
🔧 Usage
No existing
Stackusage changes. What this enables is new — aStackwhose direction comes from CSS rather than the prop (from the story added in this PR):Two notes for consumers doing this:
&&is required — it doubles specificity to beat theflex-directionthatBoxemits fromStack'sdirectionprop.align-itemsas well asflex-direction.Stackstill derives both from the prop; the separator itself is immune, since itsalign-selfbeats the parent'salign-items.directionat its default (horizontal). Flipping adirection="vertical"Stack to a row in CSS is still unsupported — its dash can't self-orient — but that's the pre-existing behaviour, not something this PR changes.🔍 Review focus
src/lib/spacing.tsx › SelfOrientingSeparator— theflex: 0 0 1px+align-self: stretchpair is the mechanism, and the claim that it's a no-op in a row rests on it. Replacing either with an explicitwidth/heightsilently reintroduces the original bug, with no test to catch it (nothing asserts separator DOM).src/lib/spacing.tsx › Separator— thetypeprop and the two-branch wrapper are retained on purpose, so the vertical dash is untouched.HSeparator/VSeparatorare renamed toSelfOrientingSeparator/DashSeparator— the old names were inverted (HSeparatorwas used fordirection="horizontal"but drew a vertical rule). Both are file-local;Separatorwas never exported, so no public API changes.🧪 How to test
npm run storybook→ Components/Styling/Spacing Utils › Separators follow a CSS direction flip.development/1.0.page-form,tab-form,form-with-accordion) — the section separators there should be unchanged short dashes, still clearly subordinate to the form title's rule.🚧 Follow-up
@scality/core-uiinartesca/@artesca/ui/package.jsondirectly (@artesca/uiis built in-repo — notintegrate-components, notsolutions/*/variable.mk). That unblocks the ARTESCA overview-page and certificates responsive tickets.Stackstill can't be flipped to a row in CSS. No consumer needs it today; it would require the full-width-rule restyle plus a design decision on the page-Formrule collision described above. Not yet ticketed.Wrapis deliberately untouched — it does not wrap despite its name, deferred pending a usage audit. Not yet ticketed.🔗 References
IconWrapperdeforming into an ellipse), kept as its own PR so either can merge and release independently.What changed
src/lib/spacing.tsx—HSeparatorbecomesSelfOrientingSeparator, tradingwidth: 1px+flex-shrink: 0forflex: 0 0 1px(equivalent in a row, correct in a column).VSeparator→DashSeparatoris a rename with no CSS change. TheSeparator({ type })wrapper andStack'stype={direction}stay. The dropped in the row branch is inert — the element's height comes fromalign-self: stretch, not from content, which the bit-identical measurement above confirms.stories/spacing.stories.tsx— addsContainerQueryDirectionFlip, covering the case this change exists to enable and which nothing covered before: acontainer-type: inline-sizeresizable box wrapping astyled(Stack)that flips direction in a@containerquery.Deliberately not in this PR:
Wrap(out of scope per CUI-38), the full-width-rule restyle of vertical separators, and anyFormchange — with the dash retained there is no regression to fix there.tsc --noEmitclean; 317 tests / 35 suites green on the files related tospacing.tsx.