Skip to content

Commit

Permalink
fix: resolve layout issues with sticky footer forms inside Carbon mod…
Browse files Browse the repository at this point in the history
…al components

Fixes other layout issues observed when a sticky footer `Form` is placed inside of a Carbon modal
component such as `Dialog`, `DialogFullscreen`, or `Sidebar`.
  • Loading branch information
Parsium committed Oct 23, 2024
1 parent a98fd09 commit 0fe249d
Show file tree
Hide file tree
Showing 18 changed files with 225 additions and 451 deletions.
19 changes: 0 additions & 19 deletions src/components/advanced-color-picker/advanced-color-picker.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -396,25 +396,6 @@ test.describe(
await elementToBlur.blur();
expect(callbackCount).toBe(0);
});

test("should call onBlur callback when a blur event is triggered", async ({
mount,
page,
}) => {
let callbackCount = 0;
await mount(
<AdvancedColorPickerCustom
onBlur={() => {
callbackCount += 1;
}}
/>
);

const elementToFocus = simpleColorPickerInput(page, 7);
await elementToFocus.focus();
await page.locator("body").click({ position: { x: 0, y: 0 } });
expect(callbackCount).toBe(1);
});
}
);

Expand Down
70 changes: 28 additions & 42 deletions src/components/dialog-full-screen/content.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,45 @@ type StyledContentProps = {
disableContentPadding?: boolean;
};

const generatePaddingVariables = (px: number) => css`
padding-top: 0;
padding-left: ${px}px;
padding-right: ${px}px;
padding-bottom: 0;
`;

const stickyFormOverrides = (px: number) => css`
${StyledForm}.sticky {
margin-left: calc(-1 * ${px}px);
margin-right: calc(-1 * ${px}px);
${StyledFormContent} {
${generatePaddingVariables(px)};
function computePadding() {
return css`
padding: 0 16px;
@media screen and (min-width: 600px) {
padding: 0 24px;
}
}
`;
@media screen and (min-width: 960px) {
padding: 0 32px;
}
@media screen and (min-width: 1260px) {
padding: 0 40px;
}
`;
}

const StyledContent = styled.div<StyledContentProps>`
box-sizing: border-box;
display: flex;
flex-direction: column;
display: block;
overflow-y: auto;
flex: 1;
width: 100%;
${generatePaddingVariables(16)}
${stickyFormOverrides(16)}
${({ disableContentPadding }) =>
disableContentPadding ? "padding: 0" : computePadding()}
${({ disableContentPadding }) => css`
${!disableContentPadding &&
css`
@media screen and (min-width: 600px) {
${generatePaddingVariables(24)}
${stickyFormOverrides(24)}
}
@media screen and (min-width: 960px) {
${generatePaddingVariables(32)}
${stickyFormOverrides(32)}
}
@media screen and (min-width: 1260px) {
${generatePaddingVariables(40)}
${stickyFormOverrides(40)}
}
`}
&:has(${StyledForm}.sticky) {
display: flex;
flex-direction: column;
overflow-y: hidden;
padding: 0;
${disableContentPadding &&
css`
${generatePaddingVariables(0)}
${stickyFormOverrides(0)}
`}
`}
${StyledForm}.sticky {
${StyledFormContent} {
${({ disableContentPadding }) =>
disableContentPadding ? "padding: 0" : computePadding()}
}
}
}
${({ hasHeader }) =>
!hasHeader &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const Default: StoryType = {
return <DialogFullScreen {...rest}>{children}</DialogFullScreen>;
},
args: {
children: "Content",
children: <Button onClick={() => {}}>Button</Button>,
open: true,
title: "Example Dialog",
subtitle: "Example Subtitle",
Expand Down Expand Up @@ -216,3 +216,33 @@ WithTwoDifferentNodes.decorators = [
WithTwoDifferentNodes.parameters = {
layout: "fullscreen",
};

export const WithWrappedStickyForm: StoryType = {
args: {
children: (
<Box p="0px 40px" minHeight="0">
<Form
stickyFooter
leftSideButtons={<Button onClick={() => {}}>Cancel</Button>}
saveButton={
<Button buttonType="primary" type="submit">
Save
</Button>
}
>
<Textbox label="First Name" />
<Textbox label="Middle Name" />
<Textbox label="Surname" />
<Textbox label="Birth Place" />
<Textbox label="Favourite Colour" />
<Textbox label="Address" />
</Form>
</Box>
),
open: true,
onCancel: () => {},
title: "Title",
subtitle: "Subtitle",
},
parameters: { chromatic: { disableSnapshot: true } },
};
4 changes: 0 additions & 4 deletions src/components/dialog-full-screen/dialog-full-screen.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ to have a possibility to manage active `Tabs` group

<Canvas of={DialogFullScreenStories.WithHideableHeaderChildren} />

### With `Box`

<Canvas of={DialogFullScreenStories.WithBox} />

### Overriding the first focused element

By default, when a dialog is opened it will automatically focus the first element within its children that can be focussed.
Expand Down
4 changes: 3 additions & 1 deletion src/components/dialog-full-screen/dialog-full-screen.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,9 @@ test.describe("Accessibility for DialogFullScreen", () => {
.getByRole("button")
.filter({ hasText: "Open DialogFullScreen" });
await openButton.click();
await checkAccessibility(page);

// color-contrast ignored until we can investigate and fix FE-6245
await checkAccessibility(page, page.getByRole("dialog"), "color-contrast");
});

test("should check accessibility using autoFocus", async ({
Expand Down
42 changes: 0 additions & 42 deletions src/components/dialog-full-screen/dialog-full-screen.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -718,47 +718,6 @@ WithHideableHeaderChildren.parameters = {
chromatic: { disableSnapshot: true },
};

export const WithBox: Story = () => {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<Button onClick={() => setIsOpen(true)}>Open DialogFullScreen</Button>
<DialogFullScreen
open={isOpen}
onCancel={() => setIsOpen(false)}
title="Title"
subtitle="Subtitle"
>
<Box p="0px 40px">
<Form
stickyFooter
leftSideButtons={
<Button onClick={() => setIsOpen(false)}>Cancel</Button>
}
saveButton={
<Button buttonType="primary" type="submit">
Save
</Button>
}
>
<Box>
This is an example of a full screen Dialog with a Form as content
</Box>
<Textbox label="First Name" />
<Textbox label="Middle Name" />
<Textbox label="Surname" />
<Textbox label="Birth Place" />
<Textbox label="Favourite Colour" />
<Textbox label="Address" />
</Form>
</Box>
</DialogFullScreen>
</>
);
};
WithBox.storyName = "With Box";
WithBox.parameters = { chromatic: { disableSnapshot: true } };

export const FocusingADifferentFirstElement: Story = () => {
const [isOpenOne, setIsOpenOne] = useState(false);
const [isOpenTwo, setIsOpenTwo] = useState(false);
Expand Down Expand Up @@ -839,7 +798,6 @@ export const OtherFocusableContainers: Story = () => {
>
<Form
stickyFooter
height="500px"
leftSideButtons={
<Button onClick={() => setIsDialogOpen(false)}>Cancel</Button>
}
Expand Down
6 changes: 0 additions & 6 deletions src/components/dialog/components.test-pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,6 @@ export const DefaultStory = () => {
>
<Form
stickyFooter
height="500px"
leftSideButtons={
<Button onClick={() => setIsOpen(false)}>Cancel</Button>
}
Expand Down Expand Up @@ -269,7 +268,6 @@ export const Editable = () => {
>
<Form
stickyFooter
height="500px"
leftSideButtons={
<Button onClick={() => setIsOpen(false)}>Cancel</Button>
}
Expand Down Expand Up @@ -335,7 +333,6 @@ export const WithHelp = () => {
>
<Form
stickyFooter
height="500px"
leftSideButtons={
<Button onClick={() => setIsOpen(false)}>Cancel</Button>
}
Expand Down Expand Up @@ -470,7 +467,6 @@ export const OverridingContentPadding = () => {
>
<Form
stickyFooter
height="500px"
leftSideButtons={
<Button onClick={() => setIsOpen(false)}>Cancel</Button>
}
Expand Down Expand Up @@ -520,7 +516,6 @@ export const OtherFocusableContainers = () => {
>
<Form
stickyFooter
height="500px"
leftSideButtons={
<Button onClick={() => setIsDialogOpen(false)}>Cancel</Button>
}
Expand Down Expand Up @@ -592,7 +587,6 @@ export const Responsive = () => {
>
<Form
stickyFooter
height="500px"
leftSideButtons={
<Button onClick={() => setIsOpen(false)}>Cancel</Button>
}
Expand Down
36 changes: 35 additions & 1 deletion src/components/dialog/dialog-test.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
FlexTileDivider,
Tile,
} from "../tile";
import { allModes } from "../../../.storybook/modes";

export default {
title: "Dialog/Test",
Expand Down Expand Up @@ -299,11 +300,34 @@ MaxSizeTestNonOverflowedForm.decorators = [

MaxSizeTestNonOverflowedForm.parameters = {
themeProvider: { chromatic: { theme: "none" } },
chromatic: { disableSnapshot: false, viewports: [1200, 900] },
chromatic: {
disableSnapshot: false,
modes: {
lg: allModes.lg,
xsm: allModes.xsm,
},
},
layout: "fullscreen",
};

export const DialogWithLongHeaderContent: StoryType = {
parameters: {
chromatic: {
disableSnapshot: false,
modes: {
lg: allModes.lg,
xsm: allModes.xsm,
},
},
layout: "fullscreen",
},
decorators: [
(Story) => (
<div style={{ height: "100vh", width: "100vw" }}>
<Story />
</div>
),
],
render: ({ size, ...args }) => (
<Dialog
{...args}
Expand Down Expand Up @@ -460,3 +484,13 @@ export const DialogWithLongHeaderContent: StoryType = {
</Dialog>
),
};

export const WithButton = {
render: () => {
return (
<Dialog open title="Dialog with Button">
<Button onClick={() => {}}>This is a button</Button>
</Dialog>
);
},
};
2 changes: 0 additions & 2 deletions src/components/dialog/dialog.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ export const Dialog = forwardRef<DialogHandle, DialogProps>(
const locale = useLocale();

const containerRef = useRef<HTMLDivElement>(null);
const innerContentRef = useRef(null);
const titleRef = useRef(null);
const { current: titleId } = useRef(createGuid());
const { current: subtitleId } = useRef(createGuid());
Expand Down Expand Up @@ -242,7 +241,6 @@ export const Dialog = forwardRef<DialogHandle, DialogProps>(
{...contentPadding}
data-role="dialog-content"
tabIndex={-1}
ref={innerContentRef}
>
{children}
</StyledDialogContent>
Expand Down
3 changes: 0 additions & 3 deletions src/components/dialog/dialog.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,5 @@ export const DIALOG_SIZES = [
"extra-large",
"maximise",
] as const;
export const CONTENT_TOP_PADDING = 24;
export const HORIZONTAL_PADDING = 32;
export const CONTENT_BOTTOM_PADDING = 30;

export type DialogSizes = typeof DIALOG_SIZES[number];
Loading

0 comments on commit 0fe249d

Please sign in to comment.