Skip to content

Commit

Permalink
feat(multi-action-button): add position prop
Browse files Browse the repository at this point in the history
Adds position prop to allow consumers to specify on which side the menu is aligned to when opened.

fix #6705
  • Loading branch information
nuria1110 committed May 16, 2024
1 parent 716bed3 commit 0a152b5
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import MultiActionButton, {
MultiActionButtonProps,
} from "./multi-action-button.component";
import Button from "../button";
import Box from "../box";
import {
MULTI_ACTION_BUTTON_ALIGNMENTS,
MULTI_ACTION_BUTTON_SIZES,
MULTI_ACTION_BUTTON_THEMES,
MULTI_ACTION_BUTTON_POSITIONS,
} from "./multi-action-button.config";

export default {
Expand Down Expand Up @@ -38,6 +40,12 @@ export default {
type: "select",
},
},
position: {
options: MULTI_ACTION_BUTTON_POSITIONS,
control: {
type: "select",
},
},
},
};

Expand All @@ -54,17 +62,19 @@ export const MultiActionButtonStory = ({
subtext,
...args
}: MultiActionButtonStoryArgs) => (
<MultiActionButton
buttonType={buttonType}
text={text}
subtext={subtext}
onClick={action("click")}
{...args}
>
<Button {...args}>Example Button</Button>
<Button {...args}>Example Button with long text</Button>
<Button {...args}>Short</Button>
</MultiActionButton>
<Box height={400} mt={100} ml={100}>
<MultiActionButton
buttonType={buttonType}
text={text}
subtext={subtext}
onClick={action("click")}
{...args}
>
<Button {...args}>Example Button</Button>
<Button {...args}>Example Button with long text</Button>
<Button {...args}>Short</Button>
</MultiActionButton>
</Box>
);

MultiActionButtonStory.story = {
Expand All @@ -74,6 +84,7 @@ MultiActionButtonStory.story = {
buttonType: "secondary",
size: "medium",
subtext: "",
text: "Example Multi Action Button",
text: "Multi Action Button",
position: "left",
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface MultiActionButtonProps

export const MultiActionButton = ({
align = "left",
position = "left",
disabled,
buttonType,
size,
Expand Down Expand Up @@ -78,7 +79,11 @@ export const MultiActionButton = ({

const renderAdditionalButtons = () => (
<Popover
placement="bottom-end"
placement={
position === "left"
? "bottom-start"
: /* istanbul ignore next */ "bottom-end"
}
reference={buttonNode}
middleware={[
offset(6),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const MULTI_ACTION_BUTTON_ALIGNMENTS = ["left", "right"];
export const MULTI_ACTION_BUTTON_SIZES = ["small", "medium", "large"];
export const MULTI_ACTION_BUTTON_THEMES = ["primary", "secondary", "tertiary"];
export const MULTI_ACTION_BUTTON_POSITIONS = ["left", "right"];
12 changes: 11 additions & 1 deletion src/components/multi-action-button/multi-action-button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,20 @@ Buttons used as a content of `MultiActionButton` can be of any type.

<Canvas of={MultiActionButtonStories.Sizes} />

### Alignment
### Button text alignment

Use the `align` prop to change the alignment of the text in the menu Buttons.

<Canvas of={MultiActionButtonStories.Alignment} />

### Menu position

By default, the menu will open aligned to the "left" of the main button, but you can use the `position` prop to change this to the "right".

Note: The position of the menu will also be automatically adjusted to fit within the viewport.

<Canvas of={MultiActionButtonStories.Position} />

### Subtext

Subtext only works when `size` is `large`
Expand Down
23 changes: 22 additions & 1 deletion src/components/multi-action-button/multi-action-button.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ test.describe("Prop tests", () => {

(["left", "right"] as MultiActionButtonProps["align"][]).forEach(
(alignment) => {
test(`should render with button aligned to the ${alignment}`, async ({
test(`should render with button text aligned to the ${alignment}`, async ({
mount,
page,
}) => {
Expand All @@ -104,6 +104,27 @@ test.describe("Prop tests", () => {
}
);

([
["left", 200],
["right", 153],
] as [MultiActionButtonProps["position"], number][]).forEach(
([position, value]) => {
test(`should render with menu position to the ${position}`, async ({
mount,
page,
}) => {
await mount(<MultiActionButtonList ml="200px" position={position} />);

const actionButton = getComponent(page, "multi-action-button");
await actionButton.click();
const listContainer = getDataElementByValue(page, "additional-buttons");
await expect(listContainer).toHaveCSS("position", "absolute");
await assertCssValueIsApproximately(listContainer, "top", 45);
await assertCssValueIsApproximately(listContainer, "left", value);
});
}
);

test(`should render with button disabled`, async ({ mount, page }) => {
await mount(<MultiActionButtonList disabled />);

Expand Down
20 changes: 20 additions & 0 deletions src/components/multi-action-button/multi-action-button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,26 @@ export const Alignment: Story = () => {
Alignment.storyName = "Alignment";
Alignment.parameters = { chromatic: { disableSnapshot: true } };

export const Position: Story = () => {
return (
<Box display="flex" justifyContent="space-around">
<MultiActionButton position="left" text="Left position">
<Button href="#">Button 1 with longer text</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</MultiActionButton>

<MultiActionButton position="right" text="Right position">
<Button href="#">Button 1 with longer text</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</MultiActionButton>
</Box>
);
};
Position.storyName = "Position";
Position.parameters = { chromatic: { disableSnapshot: true } };

export const Subtext: Story = {
...DefaultStory,
args: {
Expand Down

0 comments on commit 0a152b5

Please sign in to comment.