fix(SDK-1171): keep payroll review actions from overflowing at narrow widths - #2608
Merged
Merged
Conversation
…abled The mobile action grid hardcoded two minmax(0, 1fr) tracks for any unprocessed payroll, but Edit is conditional on canEdit. With canEdit=false (readOnly mode) only Submit renders, leaving it pinned to a half-width column with an empty second track. Size the columns off canEdit so the lone action gets the full-width single-column grid instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
dmortal
marked this pull request as ready for review
September 15, 2026 13:26
dmortal
enabled auto-merge
September 15, 2026 14:31
serikjensen
approved these changes
Sep 16, 2026
Comment on lines
+108
to
+181
| describe('base layout', () => { | ||
| beforeEach(() => { | ||
| mockUseContainerBreakpoints.mockReturnValue(['base']) | ||
| }) | ||
|
|
||
| it('keeps the heading before enabled Edit and Submit actions in a shrink-safe row', async () => { | ||
| const user = userEvent.setup() | ||
| const onEdit = vi.fn() | ||
| const onSubmit = vi.fn() | ||
|
|
||
| renderWithProviders( | ||
| <PayrollOverviewPresentation {...defaultProps} onEdit={onEdit} onSubmit={onSubmit} />, | ||
| ) | ||
|
|
||
| const heading = await screen.findByRole('heading', { level: 1, name: /Review payroll/i }) | ||
| const editButton = screen.getByRole('button', { name: /^Edit$/i }) | ||
| const submitButton = screen.getByRole('button', { name: /^Submit$/i }) | ||
| const actionGrid = editButton.parentElement | ||
|
|
||
| expect(heading.compareDocumentPosition(editButton) & Node.DOCUMENT_POSITION_FOLLOWING).toBe( | ||
| Node.DOCUMENT_POSITION_FOLLOWING, | ||
| ) | ||
| expect(submitButton.parentElement).toBe(actionGrid) | ||
| expect(actionGrid?.style.getPropertyValue('--g-grid-template-columns-base')).toBe( | ||
| 'minmax(0, 1fr) minmax(0, 1fr)', | ||
| ) | ||
| expect(editButton).toBeEnabled() | ||
| expect(submitButton).toBeEnabled() | ||
|
|
||
| await user.click(editButton) | ||
| await user.click(submitButton) | ||
|
|
||
| expect(onEdit).toHaveBeenCalledTimes(1) | ||
| expect(onSubmit).toHaveBeenCalledTimes(1) | ||
| }) | ||
|
|
||
| it('keeps the lone Submit action full-width when editing is disabled', async () => { | ||
| renderWithProviders(<PayrollOverviewPresentation {...defaultProps} canEdit={false} />) | ||
|
|
||
| const submitButton = await screen.findByRole('button', { name: /^Submit$/i }) | ||
| const actionGrid = submitButton.parentElement | ||
|
|
||
| expect(screen.queryByRole('button', { name: /^Edit$/i })).toBeNull() | ||
| expect(actionGrid?.style.getPropertyValue('--g-grid-template-columns-base')).toBe('1fr') | ||
| }) | ||
|
|
||
| it('keeps Submit visible and disabled while a blocker has no selected resolution', async () => { | ||
| renderWithProviders( | ||
| <PayrollOverviewPresentation | ||
| {...defaultProps} | ||
| submissionBlockers={[mockFastAchBlocker]} | ||
| onUnblockOptionChange={vi.fn()} | ||
| />, | ||
| ) | ||
|
|
||
| expect(await screen.findByRole('button', { name: /^Submit$/i })).toBeDisabled() | ||
| }) | ||
|
|
||
| it('keeps processed payroll actions stacked in a single-column grid', async () => { | ||
| renderWithProviders( | ||
| <PayrollOverviewPresentation {...defaultProps} isProcessed={true} canCancel={true} />, | ||
| ) | ||
|
|
||
| const receiptButton = await screen.findByRole('button', { | ||
| name: /^View payroll receipt$/i, | ||
| }) | ||
| const cancelButton = screen.getByRole('button', { name: /^Cancel payroll$/i }) | ||
| const actionGrid = receiptButton.parentElement | ||
|
|
||
| expect(cancelButton.parentElement).toBe(actionGrid) | ||
| expect(actionGrid?.style.getPropertyValue('--g-grid-template-columns-base')).toBe('1fr') | ||
| }) | ||
| }) | ||
|
|
Member
There was a problem hiding this comment.
Nit: I'm not sure these tests are super valuable for something that is presentational
Merged
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
Fixes the Payroll Overview at narrow reflow widths by keeping the unprocessed payroll Edit and Submit actions in one shrink-safe, equal-width row. The change preserves heading-first semantic order, desktop behavior, submission state and callbacks, while leaving processed payroll receipt/cancel actions stacked for their longer labels.
Changes
minmax(0, 1fr)tracks for unprocessed base/mobile actions while retaining a single track for processed payroll actions.320x256Storybook regression story using the existing wire-funds fixture.Demo
Chromium verification at an exact
320x256inspection region showed no horizontal overflow. Edit and Submit render on the same row at156x40each, both remain operable, the heading precedes the actions, and all later content is vertically reachable. The blocked state and the639px/640pxbreakpoint transition were also verified.Safari with VoiceOver was not available in the execution environment. That browser and assistive-technology combination remains a manual verification item before merge.
Related
Testing
npm run test -- --run --exclude '.claude/**' src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.test.tsx- 32/32 passing after synchronization withorigin/main.npm run tsc,npm run build,npm run build-storybook, scoped ESLint/Prettier, and diff checks passed during implementation verification..claude/worktrees: 3,736 passing, 1 expected failure, and 5 unrelated date/time-boundary failures in untouched files.320x256: no horizontal overflow; Edit and Submit each measured156x40, shared one row, remained operable, and followed the heading in semantic order.639pxand640px: no duplicate or missing action group across the base/desktop breakpoint. The blocked Submit state remained visible and disabled, and processed mobile actions remained stacked.320x256reflow, focus order, accessible names, disabled state, and vertical reachability in Safari with VoiceOver.