Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ www/public

# Local Netlify folder
.netlify
.claude/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about "claude" as the section comment here but I figure making it clear this isn't part of the "Local Netlify folder" would be good

Suggested change
.claude/
# claude
.claude/

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's your recommendation? I don't have a strong commitment to this change.

33 changes: 33 additions & 0 deletions src/ActionRow/ActionRow.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { render } from '@testing-library/react';
import ActionRow from '.';

describe('<ActionRow />', () => {
describe('stacked mode', () => {
it('renders children in reverse DOM order so primary action leads focus', () => {
const { getAllByRole } = render(
<ActionRow isStacked>
<button type="button">Secondary</button>
<button type="button">Primary</button>
</ActionRow>,
);
const buttons = getAllByRole('button');
expect(buttons[0]).toHaveTextContent('Primary');
expect(buttons[1]).toHaveTextContent('Secondary');
});
});

describe('horizontal mode', () => {
it('renders children in original DOM order', () => {
const { getAllByRole } = render(
<ActionRow>
<button type="button">Secondary</button>
<button type="button">Primary</button>
</ActionRow>,
);
const buttons = getAllByRole('button');
expect(buttons[0]).toHaveTextContent('Secondary');
expect(buttons[1]).toHaveTextContent('Primary');
});
});
});
2 changes: 1 addition & 1 deletion src/ActionRow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ notes: |
A layout utility for the common use case of aligning buttons, links or text
in a row in a control bar or nav.

ActionRow assumes that its last child is the primary action and lays out actions so that the last item is in a primary location. If horizontal, the primary action sits on the right. If stacked, the primary action sits at the top of the stack (this is done via `flex-direction: column-reverse;`).
ActionRow assumes that its last child is the primary action and lays out actions so that the last item is in a primary location. If horizontal, the primary action sits on the right. If stacked, the primary action sits at the top of the stack — the component reverses the DOM order of children so that keyboard focus order matches the visual order (primary action is reached first).

## Basic Usage

Expand Down
4 changes: 2 additions & 2 deletions src/ActionRow/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
display: flex;
flex-grow: 1;
align-items: center;
flex-direction: column-reverse;
flex-direction: column;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fix stacked item spacing after switching to column flow

Changing pgn__action-row-stacked to flex-direction: column without updating the sibling spacing rule causes the vertical gap to be applied below later items (margin-bottom) instead of between adjacent actions. In stacked mode this makes controls visually bunch together (no inter-button gap) while adding extra trailing space at the bottom, so the layout regresses for any multi-action stack.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

@e0d e0d May 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codex Does the change at line 28 of this file resolve this issue satisfactorily?

justify-content: center;

& > * {
margin: 0;
}

& > * + * {
margin-bottom: var(--pgn-spacing-action-row-gap-y);
margin-top: var(--pgn-spacing-action-row-gap-y);
}
}

Expand Down
8 changes: 7 additions & 1 deletion src/ActionRow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ function ActionRow({
children,
...props
}: ActionRowProps) {
// Reverse DOM order when stacked so the primary action (last child) is first
// in the tab sequence, matching its visual position at the top of the stack.
const orderedChildren = isStacked
? React.Children.toArray(children).reverse()
: children;

return React.createElement(
as,
{
Expand All @@ -27,7 +33,7 @@ function ActionRow({
'pgn__action-row-stacked': isStacked,
}),
},
children,
orderedChildren,
);
}

Expand Down