Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
10 changes: 10 additions & 0 deletions src/Button/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,13 @@
.nds-plain-button {
@extend %btn-kind-plain;
}

.nds-button--spread {
justify-content: stretch !important;

&.nds-button--xs .nds-button-content,
&.nds-button--s .nds-button-content,
&.nds-button--m .nds-button-content {
width: 100% !important;
}
Comment on lines +104 to +108
Copy link
Collaborator

@akdetrick akdetrick Aug 25, 2025

Choose a reason for hiding this comment

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

I think what we want to happen with isSpread is for the root element (the button or anchor) takes up 100% of parent width.

Expected

(we may also want to set a self-justification for the content area so it justifies start when isSpread)
Screenshot 2025-08-25 at 2 50 51 PM

Actual

Screenshot 2025-08-25 at 2 50 58 PM

}
22 changes: 22 additions & 0 deletions src/Button/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,33 @@ export const ButtonSizes = () => (
</>
);

export const SpreadLayoutWithIcon = () => (
<div
style={{
width: "240px",
padding: "22px",
display: "flex",
flexDirection: "column",
gap: "16px",
}}
>
<Button
label="Get started"
type="submit"
endIcon="arrow-right"
size="s"
isSpread={true}
/>
</div>
);


export default {
title: "Components/Button",
component: Button,
argTypes: {
startIcon: { options: ["", ...(VALID_ICON_NAMES as IconName)] },
endIcon: { options: ["", ...(VALID_ICON_NAMES as IconName)] },
isSpread: { control: "boolean" },
},
};
12 changes: 10 additions & 2 deletions src/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export interface ButtonProps {
startIcon?: IconName | null;
/** Name of Narmi icon to place at the end of the label */
endIcon?: IconName | null;
/** Spreads icon and text to opposite ends of the button */
isSpread?: boolean;
/** Optional value for `data-testid` attribute */
testId?: string;
/** Optional value for setting the aria-label. If unset label will be used. */
Expand Down Expand Up @@ -62,6 +64,7 @@ const Button = ({
size = "m",
startIcon = null,
endIcon = null,
isSpread = false,
testId,
children,
label,
Expand Down Expand Up @@ -107,6 +110,7 @@ const Button = ({
resetButton: as === "button",
"nds-button--disabled": disabled,
"nds-button--loading": isLoading,
"nds-button--spread": isSpread,
},
])}
disabled={(isButtonElement && disabled) || isLoading ? true : undefined}
Expand All @@ -122,13 +126,17 @@ const Button = ({
</div>
)}
<div style={{ visibility: isLoading ? "hidden" : "visible" }}>
<Row gapSize={gapSizeMap[size]} alignItems="center">
<Row
gapSize={isSpread ? "xs" : gapSizeMap[size]}
alignItems="center"
justifyContent={isSpread ? "space-between" : "center"}
>
{startIcon && (
<Row.Item shrink>
<Icon name={startIcon} />
</Row.Item>
)}
<Row.Item>
<Row.Item shrink={isSpread}>
<span className="nds-button-label">{buttonLabel}</span>
</Row.Item>
{endIcon && (
Expand Down
Loading