Pin the large-QR grid track to a shared size token so long under-QR copy (relay-degraded notice) cannot max-content the auto column and collapse the pairing step to one glyph per line. Constrain the QR stack for wrap and lock the layout contract in tests.
This commit is contained in:
parent
c24ebcade5
commit
7cf052bcab
|
|
@ -0,0 +1,33 @@
|
|||
import fs from 'node:fs'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const mobilePageCss = fs.readFileSync(new URL('./mobile-page.css', import.meta.url), 'utf8')
|
||||
|
||||
describe('mobile page QR grid layout (#9700)', () => {
|
||||
it('defines a shared large-QR size token used by the box and grid tracks', () => {
|
||||
expect(mobilePageCss).toMatch(/--mp-qr-large-size:\s*184px/)
|
||||
expect(mobilePageCss).toMatch(
|
||||
/\.mobile-page-root \.mp-qr-large\s*{[^}]*width:\s*var\(--mp-qr-large-size\)/s
|
||||
)
|
||||
})
|
||||
|
||||
// Why: `auto` sized the QR track to the unwrapped relay-degraded notice and
|
||||
// starved the copy column so CJK wrapped one glyph per line (#9700).
|
||||
it('pins step and pairing QR columns to the QR size instead of auto', () => {
|
||||
expect(mobilePageCss).toMatch(
|
||||
/\.mobile-page-root \.mp-step2-layout\s*{[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\)\s+var\(--mp-qr-large-size\)/s
|
||||
)
|
||||
expect(mobilePageCss).toMatch(
|
||||
/\.mobile-page-root \.mp-pairing-layout\s*{[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\)\s+var\(--mp-qr-large-size\)/s
|
||||
)
|
||||
expect(mobilePageCss).not.toMatch(
|
||||
/\.mobile-page-root \.mp-(?:step2|pairing)-layout\s*{[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\)\s+auto/s
|
||||
)
|
||||
})
|
||||
|
||||
it('lets under-QR stack children shrink so long notices wrap inside the track', () => {
|
||||
expect(mobilePageCss).toMatch(
|
||||
/\.mobile-page-root \.mp-qr-stack\s*>\s*\*\s*{[^}]*max-width:\s*100%[^}]*min-width:\s*0/s
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
--mp-flow-card-border-width: 1px;
|
||||
--mp-flow-card-inset: calc(var(--mp-flow-card-padding) + var(--mp-flow-card-border-width));
|
||||
--mp-flow-shell-height: 400px;
|
||||
--mp-qr-large-size: 184px;
|
||||
--m-bg-base: #111111;
|
||||
--m-bg-panel: #1a1a1a;
|
||||
--m-bg-raised: #242424;
|
||||
|
|
@ -583,14 +584,15 @@
|
|||
|
||||
.mobile-page-root .mp-qr-large {
|
||||
box-sizing: border-box;
|
||||
width: 184px;
|
||||
height: 184px;
|
||||
width: var(--mp-qr-large-size);
|
||||
height: var(--mp-qr-large-size);
|
||||
/* Why: keep img size in lockstep with the box (padding 10px each side). */
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.mobile-page-root .mp-qr-large img {
|
||||
width: 164px;
|
||||
height: 164px;
|
||||
width: calc(var(--mp-qr-large-size) - 20px);
|
||||
height: calc(var(--mp-qr-large-size) - 20px);
|
||||
}
|
||||
|
||||
.mobile-page-root .mp-qr-refreshing {
|
||||
|
|
@ -615,6 +617,19 @@
|
|||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
/* Why: stack sits in a fixed QR grid track; fill the track so under-QR copy
|
||||
has a definite width to wrap against. */
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Why: align-items:center sizes children to max-content. Cap width AND set
|
||||
min-width:0 so max-width can actually win over flex/grid min-size:auto and
|
||||
long under-QR copy (relay-degraded notice, regenerate label) wraps. */
|
||||
.mobile-page-root .mp-qr-stack > * {
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.mobile-page-root .mp-link-under {
|
||||
|
|
@ -639,17 +654,24 @@
|
|||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Step 1 (Get the app) — borderless layout, page-1 typography */
|
||||
/* Step 1 (Get the app) + Step 2 (Pair) — QR column width */
|
||||
/* Why: pin the QR column to the QR's own width rather than `auto`. When the flow
|
||||
card is narrow (mp-hero pins it to minmax(360px,560px)) an `auto` track grows
|
||||
to its content's max-content — the relay-degraded notice under the pairing QR
|
||||
is an unwrapped single line — starving the minmax(0,1fr) copy column to ~1 char
|
||||
wide, so CJK copy wrapped one glyph per line (#9700). A fixed track stops that
|
||||
starvation; .mp-qr-stack min-width:0 + max-width:100% (and the notice's
|
||||
min-w-0 text span) stop the notice overflowing the track. */
|
||||
.mobile-page-root .mp-step2-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
grid-template-columns: minmax(0, 1fr) var(--mp-qr-large-size);
|
||||
gap: 28px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.mobile-page-root .mp-pairing-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
grid-template-columns: minmax(0, 1fr) var(--mp-qr-large-size);
|
||||
grid-template-areas:
|
||||
'copy qr'
|
||||
'relay qr'
|
||||
|
|
@ -661,10 +683,12 @@
|
|||
|
||||
.mobile-page-root .mp-pairing-copy {
|
||||
grid-area: copy;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.mobile-page-root .mp-pairing-qr {
|
||||
grid-area: qr;
|
||||
min-width: 0;
|
||||
/* Why: the QR belongs to the pairing heading, not the paragraph below it. */
|
||||
margin-top: 48px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,9 +138,12 @@ describe('HeroFlow height', () => {
|
|||
pairQrDataUrl: 'data:image/png;base64,qr',
|
||||
relayDegraded: true
|
||||
})
|
||||
expect(screen.getByTestId('relay-degraded-notice')).toHaveTextContent(
|
||||
'only works on your local network'
|
||||
)
|
||||
const notice = screen.getByTestId('relay-degraded-notice')
|
||||
expect(notice).toHaveTextContent('only works on your local network')
|
||||
// Why: wrap-capable text item inside the fixed QR track (#9700); bare text
|
||||
// nodes in a flex row cannot shrink below max-content and overflow the track.
|
||||
expect(notice.querySelector('.min-w-0')).not.toBeNull()
|
||||
expect(notice.className).toMatch(/\bmin-w-0\b/)
|
||||
expect(screen.getByText('Orca Relay is in beta.')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -290,14 +290,17 @@ export function HeroFlow({
|
|||
</button>
|
||||
{relayDegraded ? (
|
||||
<p
|
||||
className="flex items-start gap-1.5 text-xs text-muted-foreground"
|
||||
className="flex w-full min-w-0 items-start gap-1.5 text-xs text-muted-foreground"
|
||||
data-testid="relay-degraded-notice"
|
||||
>
|
||||
<CircleAlert className="mt-0.5 size-3.5 shrink-0" aria-hidden />
|
||||
{translate(
|
||||
'auto.components.mobile.MobileHero.relayDegradedNotice',
|
||||
'Relay couldn’t be reached — this code only works on your local network.'
|
||||
)}
|
||||
{/* Why: min-w-0 so the flex text item can wrap inside the fixed QR track (#9700). */}
|
||||
<span className="min-w-0">
|
||||
{translate(
|
||||
'auto.components.mobile.MobileHero.relayDegradedNotice',
|
||||
'Relay couldn’t be reached — this code only works on your local network.'
|
||||
)}
|
||||
</span>
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue