Skip to content

Commit 10b1e6c

Browse files
frano-mclaude
andauthored
feat: collapsible terrasetupform with opt-in prop (#921) (#922)
* feat: collapsible terrasetupform with opt-in prop (#921) Closes #921. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: apply pr review fixes for collapsible terrasetupform (#921) - add jsdoc to collapseprovider - add aria-expanded and aria-controls to terrasetupform toggle button - add tests for terrasetupuiprovider - fix self-import in terrasetupuiprovider to use relative path Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: revert unintended third grid column in formstep section (#921) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Fran McDade <18710366+frano-m@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent efb112e commit 10b1e6c

22 files changed

Lines changed: 391 additions & 48 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import styled from "@emotion/styled";
2+
import { Button } from "@mui/material";
3+
4+
export const StyledButton = styled(Button)`
5+
align-self: center;
6+
text-transform: none;
7+
`;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { JSX } from "react";
2+
import { BUTTON_PROPS } from "../../../../../../../../styles/common/mui/button";
3+
import { useTerraSetUpUI } from "../../../../../../../../terra/setUpUI/provider/hook";
4+
import { STEPS_REGION_ID } from "../../constants";
5+
import { StyledButton } from "./button.styles";
6+
import { ButtonProps } from "./types";
7+
8+
export const Button = ({
9+
collapsible = false,
10+
}: ButtonProps): JSX.Element | null => {
11+
const { isOpen, onChange } = useTerraSetUpUI();
12+
13+
if (!collapsible) return null;
14+
15+
return (
16+
<StyledButton
17+
aria-controls={STEPS_REGION_ID}
18+
aria-expanded={isOpen}
19+
color={isOpen ? BUTTON_PROPS.COLOR.SECONDARY : BUTTON_PROPS.COLOR.PRIMARY}
20+
onClick={onChange}
21+
variant={BUTTON_PROPS.VARIANT.CONTAINED}
22+
>
23+
{isOpen ? "Save & continue later" : "Continue"}
24+
</StyledButton>
25+
);
26+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface ButtonProps {
2+
collapsible?: boolean;
3+
}

src/components/Export/components/ExportToTerra/components/TerraSetUpForm/components/FormStep/formStep.styles.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
import styled from "@emotion/styled";
2-
import { SectionContent as DXSectionContent } from "../../terraSetUpForm.styles";
2+
import { PALETTE } from "../../../../../../../../styles/common/constants/palette";
3+
import { sectionPadding } from "../../../../../../../common/Section/section.styles";
34

4-
export const SectionContent = styled(DXSectionContent)`
5+
export const Section = styled("div")`
6+
${sectionPadding};
7+
background-color: ${PALETTE.COMMON_WHITE};
8+
border-top: 1px solid ${PALETTE.SMOKE_MAIN};
9+
display: grid;
10+
gap: 16px;
11+
grid-template-columns: auto 1fr;
12+
`;
13+
14+
export const SectionContent = styled.div`
15+
display: grid;
516
gap: 2px;
17+
grid-row: 1;
18+
19+
.MuiTypography-body-400-2lines {
20+
p {
21+
margin: 0;
22+
}
23+
}
624
725
.MuiTypography-body-500 {
826
margin: 2px 0;

src/components/Export/components/ExportToTerra/components/TerraSetUpForm/components/FormStep/formStep.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@ import { StepIcon, Typography } from "@mui/material";
22
import { JSX, ReactNode } from "react";
33
import { TYPOGRAPHY_PROPS } from "../../../../../../../../styles/common/mui/typography";
44
import { FormStatusCompletedIcon } from "../../../../../../../common/CustomIcon/components/FormStatusCompletedIcon/formStatusCompletedIcon";
5-
import {
6-
Section,
7-
SectionActions,
8-
SectionStatus,
9-
} from "../../terraSetUpForm.styles";
10-
import { SectionContent } from "./formStep.styles";
5+
import { SectionActions, SectionStatus } from "../../terraSetUpForm.styles";
6+
import { Section, SectionContent } from "./formStep.styles";
117

128
export interface FormStepProps {
139
action: ReactNode;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* DOM id of the collapsible steps region. Used by the toggle button's
3+
* `aria-controls` so assistive tech can associate the toggle with the
4+
* region it expands/collapses.
5+
*/
6+
export const STEPS_REGION_ID = "terra-set-up-form-steps";
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { ComponentProps } from "react";
2+
import { AUTH_STATUS, AuthState } from "../../../../../../../auth/types/auth";
3+
import { REQUEST_STATUS } from "../../../../../../../terra/types/common";
4+
import { TerraProfileContextProps } from "../../../../../../../terra/types/context";
5+
import { TerraSetUpForm } from "../terraSetUpForm";
6+
7+
/**
8+
* Authenticated, settled auth state — used so `TerraSetUpForm` doesn't bail
9+
* early on its `isAuthenticated` / status guards.
10+
*/
11+
export const MOCK_AUTH_STATE: AuthState = {
12+
isAuthenticated: true,
13+
status: AUTH_STATUS.SETTLED,
14+
};
15+
16+
/**
17+
* Terra profile statuses where every onboarding step is supported but not yet
18+
* complete — produces three incomplete steps in the rendered form.
19+
*/
20+
export const MOCK_TERRA_PROFILE_INCOMPLETE: TerraProfileContextProps = {
21+
terraNIHProfileLoginStatus: {
22+
isSuccess: false,
23+
isSupported: true,
24+
requestStatus: REQUEST_STATUS.COMPLETED,
25+
response: undefined,
26+
},
27+
terraProfileLoginStatus: {
28+
isSuccess: false,
29+
isSupported: true,
30+
requestStatus: REQUEST_STATUS.COMPLETED,
31+
response: undefined,
32+
},
33+
terraTOSLoginStatus: {
34+
isSuccess: false,
35+
isSupported: true,
36+
requestStatus: REQUEST_STATUS.COMPLETED,
37+
response: undefined,
38+
},
39+
};
40+
41+
export const DEFAULT_TERRA_SET_UP_FORM_ARGS: ComponentProps<
42+
typeof TerraSetUpForm
43+
> = {
44+
collapsible: true,
45+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { ComponentProps } from "react";
2+
import { TerraSetUpForm } from "../terraSetUpForm";
3+
4+
export const BOOLEAN_CONTROLS: (keyof ComponentProps<typeof TerraSetUpForm>)[] =
5+
["collapsible"];
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Box } from "@mui/material";
2+
import type { Meta, StoryObj } from "@storybook/nextjs-vite";
3+
import { ComponentProps, JSX } from "react";
4+
import { AuthContext } from "../../../../../../../auth/contexts/auth";
5+
import { CONTROL_TYPE } from "../../../../../../../storybook/controls/types";
6+
import { configureControls } from "../../../../../../../storybook/controls/utils";
7+
import { TerraProfileContext } from "../../../../../../../terra/context";
8+
import { TerraSetUpUIProvider } from "../../../../../../../terra/setUpUI/provider/provider";
9+
import { TerraSetUpForm } from "../terraSetUpForm";
10+
import {
11+
DEFAULT_TERRA_SET_UP_FORM_ARGS,
12+
MOCK_AUTH_STATE,
13+
MOCK_TERRA_PROFILE_INCOMPLETE,
14+
} from "./args";
15+
import { BOOLEAN_CONTROLS } from "./constants";
16+
17+
const meta: Meta<typeof TerraSetUpForm> = {
18+
argTypes: {
19+
...configureControls<ComponentProps<typeof TerraSetUpForm>>(
20+
BOOLEAN_CONTROLS,
21+
CONTROL_TYPE.BOOLEAN,
22+
),
23+
},
24+
component: TerraSetUpForm,
25+
decorators: [
26+
(Story): JSX.Element => (
27+
<AuthContext.Provider
28+
value={{
29+
authDispatch: null,
30+
authState: MOCK_AUTH_STATE,
31+
service: undefined,
32+
}}
33+
>
34+
<TerraProfileContext.Provider value={MOCK_TERRA_PROFILE_INCOMPLETE}>
35+
<TerraSetUpUIProvider>
36+
<Box m={8}>
37+
<Story />
38+
</Box>
39+
</TerraSetUpUIProvider>
40+
</TerraProfileContext.Provider>
41+
</AuthContext.Provider>
42+
),
43+
],
44+
parameters: {
45+
layout: "fullscreen",
46+
},
47+
};
48+
49+
export default meta;
50+
51+
type Story = StoryObj<typeof meta>;
52+
53+
export const Default: Story = {
54+
args: DEFAULT_TERRA_SET_UP_FORM_ARGS,
55+
};
56+
57+
export const NotCollapsible: Story = {
58+
args: { ...DEFAULT_TERRA_SET_UP_FORM_ARGS, collapsible: false },
59+
};

src/components/Export/components/ExportToTerra/components/TerraSetUpForm/terraSetUpForm.styles.ts

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,16 @@
11
import styled from "@emotion/styled";
2+
import { Stack } from "@mui/material";
23
import { PALETTE } from "../../../../../../styles/common/constants/palette";
4+
import { FluidPaper } from "../../../../../common/Paper/components/FluidPaper/fluidPaper";
35
import { sectionPadding } from "../../../../../common/Section/section.styles";
46

5-
export const Section = styled("div")`
6-
${sectionPadding};
7+
export const StyledFluidPaper = styled(FluidPaper)`
78
background-color: ${PALETTE.COMMON_WHITE};
8-
display: grid;
9-
gap: 16px;
10-
grid-template-columns: auto 1fr;
119
`;
1210

13-
export const SectionContent = styled("div")`
14-
display: grid;
15-
gap: 4px;
16-
grid-row: 1;
17-
18-
.MuiTypography-body-400-2lines {
19-
p {
20-
margin: 0;
21-
}
22-
}
11+
export const StyledStack = styled(Stack)`
12+
${sectionPadding};
13+
justify-content: space-between;
2314
`;
2415

2516
export const SectionStatus = styled("div")`

0 commit comments

Comments
 (0)