Skip to content

Commit

Permalink
[CCUBE-1546][MAHI]Set up Layout component with container, section and…
Browse files Browse the repository at this point in the history
… content and its respective test and storybook test
  • Loading branch information
mahidhar-reddy09 committed Sep 19, 2024
1 parent e10348b commit 5c25380
Show file tree
Hide file tree
Showing 12 changed files with 695 additions and 0 deletions.
98 changes: 98 additions & 0 deletions src/layout/container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React from "react";
import styled, { css } from "styled-components";
import { MediaQuery } from "../theme/mediaquery/mediaquery-helper";
import { ContainerProps, ContainerType, DivRef } from "./types";

const Component = (props: ContainerProps, ref: DivRef): JSX.Element => {
const {
children,
"data-testid": testId = "container",
type = "flex",
stretch = false,
...otherProps
} = props;

return (
<StyledContainer
ref={ref}
data-testid={testId}
$type={type}
$stretch={stretch}
{...otherProps}
>
{children}
</StyledContainer>
);
};

export const Container = React.forwardRef(Component);

interface StyleProps {
$type: ContainerType;
$stretch: boolean;
}

const StyledContainer = styled.div<StyleProps>`
flex-grow: 1;
margin: 0 auto;
position: relative;
width: auto;
height: auto;
${(props) => {
if (props.$stretch) {
return css`
padding: 0 3rem;
`;
} else {
return css`
padding: 0 0.75rem;
/* Max width restrictions */
max-width: 1320px;
${MediaQuery.MaxWidth.xl} {
max-width: 1140px;
}
`;
}
}}
${MediaQuery.MaxWidth.md} {
max-width: 720px;
}
${MediaQuery.MaxWidth.sm} {
width: 100%;
padding: 0;
max-width: unset;
}
${(props) => {
switch (props.$type) {
case "grid":
return css`
column-gap: 2rem;
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
${MediaQuery.MaxWidth.md} {
column-gap: 1.5rem;
grid-template-columns: repeat(8, minmax(0, 1fr));
}
${MediaQuery.MaxWidth.sm} {
column-gap: 1rem;
grid-template-columns: repeat(4, minmax(0, 1fr));
}
`;
case "flex-column":
return css`
display: flex;
flex-direction: column;
`;
case "flex":
default:
return css`
display: flex;
`;
}
}}
`;
36 changes: 36 additions & 0 deletions src/layout/content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import { Container } from "./container";
import { ContentProps, DivRef } from "./types";
import { Section } from "./section";

const Component = (props: ContentProps, ref: DivRef): JSX.Element => {
const {
children,
"data-testid": testId = "content",
className,
type = "flex",
stretch = false,
...otherProps
} = props;

return (
<Section
ref={ref}
data-testid={testId}
className={className}
stretch={stretch}
{...otherProps}
>
<Container
data-testid={`${testId}-container`}
type={type}
data-id="container"
stretch={stretch}
>
{children}
</Container>
</Section>
);
};

export const Content = React.forwardRef(Component);
11 changes: 11 additions & 0 deletions src/layout/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Container } from "./container";
import { Content } from "./content";
import { Section } from "./section";

export const Layout = {
Section: Section,
Container: Container,
Content: Content,
};

export * from "./types";
55 changes: 55 additions & 0 deletions src/layout/section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from "react";
import styled, { css } from "styled-components";
import { MediaQuery } from "../theme/mediaquery/mediaquery-helper";
import { DivRef, SectionProps } from "./types";

const Component = (props: SectionProps, ref: DivRef): JSX.Element => {
const {
children,
"data-testid": testId = "section",
stretch = false,
...otherProps
} = props;

return (
<StyledSection
ref={ref}
data-testid={testId}
$stretch={stretch}
{...otherProps}
>
{children}
</StyledSection>
);
};

export const Section = React.forwardRef(Component);

interface StyleProps {
$stretch: boolean;
}

const StyledSection = styled.section<StyleProps>`
display: block;
position: relative;
${(props) => {
if (props.$stretch) {
return css`
${MediaQuery.MaxWidth.xl} {
padding: 0 1.5rem;
padding-left: 1.5rem !important;
padding-right: 1.5rem !important;
}
`;
} else {
return css`
padding: 0 1.5rem;
padding-left: 1.5rem !important;
padding-right: 1.5rem !important;
`;
}
}}
`;
19 changes: 19 additions & 0 deletions src/layout/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export interface CommonLayoutProps
extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
"data-testid"?: string | undefined;
stretch?: boolean;
}

export type ContainerType = "flex" | "flex-column" | "grid";

export interface ContainerProps extends CommonLayoutProps {
/** The type of display style. Values: "flex" | "flex-column" | "grid" */
type?: ContainerType | undefined;
}

export interface SectionProps extends CommonLayoutProps {}

export type DivRef = React.Ref<HTMLDivElement>;

export interface ContentProps extends ContainerProps {}
44 changes: 44 additions & 0 deletions stories/layout-test/Container.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ThemeProvider } from "styled-components";
import { Container } from "../../src/layout/container";
import { mockTheme } from "./mock-theme";

export default {
title: "Layout-Test/Container",
component: Container,
};

export const Default = () => (
<ThemeProvider theme={mockTheme}>
<Container>
<p>This is a container with default props.</p>
<p>Hello world for testing!</p>
</Container>
</ThemeProvider>
);

export const FlexColumn = () => (
<ThemeProvider theme={mockTheme}>
<Container type="flex-column">
<p>This container uses flex-column layout.</p>
<p>Hello world for testing!</p>
</Container>
</ThemeProvider>
);

export const GridLayout = () => (
<ThemeProvider theme={mockTheme}>
<Container type="grid">
<p>This container uses grid layout.</p>
<p>Hello world for testing!</p>
</Container>
</ThemeProvider>
);

export const Stretched = () => (
<ThemeProvider theme={mockTheme}>
<Container stretch>
<p>This container is stretched.</p>
<p>Hello world for testing!</p>
</Container>
</ThemeProvider>
);
89 changes: 89 additions & 0 deletions stories/layout-test/Content.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { ThemeProvider } from "styled-components";
import { Content } from "../../src/layout/content";
import { mockTheme } from "./mock-theme";

export default {
title: "Layout-Test/Content",
component: Content,
};

export const DefaultContent = () => (
<ThemeProvider theme={mockTheme}>
<Content>
<h1>Header Test</h1>
<p style={{ marginLeft: "1rem" }}>
This is some testing text in the paragraph tag.
</p>
<img
style={{ marginLeft: "1rem" }}
src="https://via.placeholder.com/150"
alt="Placeholder"
/>
<button style={{ marginLeft: "1rem" }}>Click Me</button>
</Content>
</ThemeProvider>
);

export const FlexContent = () => (
<ThemeProvider theme={mockTheme}>
<Content type="flex-column">
<h1>Header Test</h1>
<p style={{ marginTop: "1rem" }}>
This is some testing text in the paragraph tag.
</p>
<img
style={{ marginTop: "1rem" }}
src="https://via.placeholder.com/150"
alt="Placeholder"
/>
<button style={{ marginTop: "1rem" }}>Click Me</button>
</Content>
</ThemeProvider>
);

export const GridNormalContent = () => (
<ThemeProvider theme={mockTheme}>
<Content type="grid">
<h1>Header Test</h1>
<p>This is some testing text in the paragraph tag.</p>
<img src="https://via.placeholder.com/150" alt="Placeholder" />
<button style={{ marginLeft: "1rem" }}>Click Me</button>
</Content>
</ThemeProvider>
);

export const GridContentWithSpan = () => (
<ThemeProvider theme={mockTheme}>
<Content type="grid">
<h1 style={{ gridColumn: "span 12" }}>Header Test</h1>
<p style={{ gridColumn: "span 8" }}>
This is some testing text in the paragraph tag.
</p>
<img
style={{ gridColumn: "span 4" }}
src="https://via.placeholder.com/150"
alt="Placeholder"
/>
<button style={{ gridColumn: "span 2", marginLeft: "2rem" }}>
Click Me
</button>
</Content>
</ThemeProvider>
);

export const StretchContent = () => (
<ThemeProvider theme={mockTheme}>
<Content stretch>
<h1>Header Test</h1>
<p style={{ marginLeft: "1rem" }}>
This is some testing text in the paragraph tag.
</p>
<img
style={{ marginLeft: "1rem" }}
src="https://via.placeholder.com/150"
alt="Placeholder"
/>
<button style={{ marginLeft: "1rem" }}>Click Me</button>
</Content>
</ThemeProvider>
);
24 changes: 24 additions & 0 deletions stories/layout-test/Section.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ThemeProvider } from "styled-components";
import { Section } from "../../src/layout/section";
import { mockTheme } from "./mock-theme";

export default {
title: "Layout-Test/Section",
component: Section,
};

export const Default = () => (
<ThemeProvider theme={mockTheme}>
<Section>
<p>This is a section with default props.</p>
</Section>
</ThemeProvider>
);

export const Stretched = () => (
<ThemeProvider theme={mockTheme}>
<Section stretch>
<p>This section is stretched.</p>
</Section>
</ThemeProvider>
);
11 changes: 11 additions & 0 deletions stories/layout-test/mock-theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ThemeSpec } from "../../src/theme/types";

export const mockTheme: ThemeSpec = {
colourScheme: "lifesg",
fontScheme: "lifesg",
animationScheme: "lifesg",
borderScheme: "lifesg",
spacingScheme: "lifesg",
radiusScheme: "lifesg",
breakpointScheme: "lifesg",
};
Loading

0 comments on commit 5c25380

Please sign in to comment.