ConstrainedText: align the text, and style it without a nested Text - #1221
Conversation
… styling props Alignment could only be inherited from the container or forced to centre, so a caller had no way to state it. Add `align: 'start' | 'center' | 'end'`, keeping `centered` as a deprecated alias; with neither set the rule stays `inherit`. Accept the Text props natively and forward them to the internal wrapper, so `variant` and its neighbours no longer need a second Text nested inside `text` while `color` arrives as a prop. Removing the file's `// @ts-nocheck` surfaced an import of `utility-types`, which is not a dependency of this package and had no other importer. It is replaced with a native indexed access type. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Hello jeanmarcmilletscality,My role is to assist you with the merge of this Available options
Available commands
Status report is not available. |
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: |
|
/approve |
In the queueThe changeset has received all authorizations and has been added to the The changeset will be merged in:
There is no action required on your side. You will be notified here once IMPORTANT Please do not attempt to modify this pull request.
If you need this pull request to be removed from the queue, please contact a The following options are set: approve |
|
I have successfully merged the changeset of this pull request
Please check the status of the associated issue None. Goodbye jeanmarcmilletscality. |
TL;DR —
ConstrainedTextcould only inherit its alignment or be forced to centre, and ignored everyTextstyling prop butcolor; it now takes an explicitalignand the wholeTextprop set.Constrained Text → Defaultstory,text="Aligned"in its fixed 100px box — the dashed outline is a capture-time annotation marking the box edges, not something the component draws.alignset tostart,center,end; measured text offsets inside the box are 0/53.5px, 26.8/26.8px and 53.5/0px.Context / Why
ConstrainedTextis the library's truncate-and-tooltip primitive, and two things kept callers from reaching for it.Alignment could not be stated — only inherited from the container, or forced to centre by
centered— so a caller wanting the text on a specific edge had to arrange it from the outside.And styling arrived through two doors:
colorwas a prop, butvariant,isEmphazed,isGentleEmphazedandcompactwere only reachable by nesting a second<Text>inside thetextprop.Since the prop is named
text, passing a string is the obvious reading — and it silently gave you the default size.🧩 Approach
One prop surface, rewritten once.
alignis added,centeredstays as a deprecated alias that resolves to it, andTextPropsis mixed into the props and forwarded to the internal wrapper:coloris not dropped — it arrives viaTextPropsinstead, so every existing call keeps compiling. With neitheralignnorcenteredset the rule staystext-align: inherit, exactly as before.The component used to build its
<Text><ConstrainedTextContainer>subtree twice, once in each branch of the tooltip conditional, through a four-positional-argument helper. It is now built once and wrapped conditionally, so a forwarded prop cannot land on the tooltip branch and miss the bare one.Removing the file's
// @ts-nochecksurfaced a dead import:$PropertyTypefromutility-types, a package that is not a dependency of this repo and had no other importer. It never failed at runtime because TypeScript elides type-only imports. It is replaced with a native indexed access type.The nested-
<Text>form still works — an inner element's own props win over the wrapper's — so the one in-repo call site written that way (charts/common/SharedComponents.tsx) is untouched and keeps rendering identically.📷 Screenshots
Same story and box.
text="Aligned"passed as a plain string withvariant="Smaller"— computed font-size 9.94px against the 14px default. Before this changevariantwas ignored unless a<Text>was nested insidetext.🔍 Review focus
constrainedtext/Constrainedtext.component.tsx›ConstrainedText— the...textPropsrest spread forwards anything not destructured to the internalText, where extra props were previously dropped. TypeScript rejects unknown props for a typed caller, so the guard here is the type, not the runtime.constrainedtext/Constrainedtext.component.tsx›ConstrainedTextContainer— thetext-alignfallback has to stayinheritwhen neither prop is set; an in-repo caller (theHeatmaprow-label gutter) relies on that inheritance rather than passing alignment itself.text/Text.component.tsx›TextProps— the type was declared but not exported, and is now exported from the package index too.🧪 How to test
npm run storybook, then open Components → Constrained Text → Default. The text sits in a fixed 100px-wide box.textto something short (Aligned) and stepalignthroughstart,centerandend— the text moves to the matching edge of the box.alignand tickcentered— still centred, since the deprecated alias resolves toalign: 'center'.centered, leavetexta plain string, and setvarianttoSmaller— the text gets smaller. Before this change that needed a<Text>nested insidetext.Follow-up
Two parts of this component's known gaps are deliberately not in this PR:
BlockTooltipis still unconditionallywidth: stretch, so the label fills its container rather than being shrink-to-fit, and a flex parent'sjustify-contentcannot govern it. Five in-repo call sites were written against that, so changing it needs a before/after pass over each.text. There is noResizeObserver, so a container that resizes after mount can leave the tooltip stale — which matters most where a column resizes with its content.Table headers still truncate without a tooltip; adopting this component there is the follow-on that the
alignprop was needed for.What changed
Three files. The component itself carries the prop-surface change and the
@ts-nocheckremoval.Text.component.tsxchanges by one word (TextPropsbecomes exported) andindex.tsby one line (re-exporting that type for consumers typing their own wrappers).No call site is changed, so no story or test needed updating — this is an additive prop surface, verified against the existing
Constrained Textstories rather than a new one.🤖 Generated with Claude Code