Skip to content

Commit

Permalink
feat: pageTemplate and Layout component (#2219)
Browse files Browse the repository at this point in the history
OKTA-721245 feat: start layout component
feat: more work on layout component
feat: documentation and syntax updates
fix: update to storybook and component
feat: add more to Storybook
fix: remove unncessary MUI ScopedCssBaseline
feat: add full-width story
feat(odyssey-react-mui): create surface component
feat(odyssey-react-mui): create stories for Grid
feat(odyssey-react-mui): remove surface styling from Grid
fix: small nit fixes
feat(odyssey-react-mui): panes => regions
fix(odyssey-react-mui): rename components and add disclaimer
fix: standardize vertical layout distance
refactor: update css
refactor: alphabetize the imports
feat: add rudimentary responsiveness to Layout
refactor: improve nested selectors
refactor: update based on code review
Merge branch 'main' into ti-OKTA-721245-layout-component
fix: update redundant type export
  • Loading branch information
trevoring-okta authored and bryancunningham-okta committed Jul 25, 2024
1 parent c8d1330 commit 0d1aa97
Show file tree
Hide file tree
Showing 12 changed files with 1,445 additions and 15 deletions.
48 changes: 48 additions & 0 deletions packages/odyssey-react-mui/src/Surface.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*!
* Copyright (c) 2022-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*/

import { memo, ReactNode } from "react";
import styled from "@emotion/styled";
import { Paper as MuiPaper } from "@mui/material";

import {
DesignTokens,
useOdysseyDesignTokens,
} from "./OdysseyDesignTokensContext";

const StyledContainer = styled(MuiPaper, {
shouldForwardProp: (prop) => prop !== "odysseyDesignTokens",
})<{
odysseyDesignTokens: DesignTokens;
}>(({ odysseyDesignTokens }) => ({
borderRadius: odysseyDesignTokens.Spacing4,
padding: odysseyDesignTokens.Spacing4,
}));

export type SurfaceProps = {
children: ReactNode;
};

const Surface = ({ children }: SurfaceProps) => {
const odysseyDesignTokens = useOdysseyDesignTokens();

return (
<StyledContainer odysseyDesignTokens={odysseyDesignTokens}>
{children}
</StyledContainer>
);
};

const MemoizedSurface = memo(Surface);
MemoizedSurface.displayName = "Surface";

export { MemoizedSurface as Surface };
1 change: 1 addition & 0 deletions packages/odyssey-react-mui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export * from "./ScreenReaderText";
export * from "./SearchField";
export * from "./Select";
export * from "./Status";
export * from "./Surface";
export * from "./Tabs";
export * from "./Tag";
export * from "./TagList";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
densityValues,
} from "./constants";
import {
Layout,
DataLayout,
UniversalProps,
ViewProps,
TableState,
Expand All @@ -47,7 +47,7 @@ import {
} from "../../OdysseyDesignTokensContext";
import styled from "@emotion/styled";

export type DataViewProps = UniversalProps & ViewProps<Layout>;
export type DataViewProps = UniversalProps & ViewProps<DataLayout>;

const DataViewContainer = styled("div", {
shouldForwardProp: (prop) => prop !== "odysseyDesignTokens",
Expand Down Expand Up @@ -100,7 +100,7 @@ const DataView = ({
const odysseyDesignTokens = useOdysseyDesignTokens();
const { t } = useTranslation();

const [currentLayout, setCurrentLayout] = useState<Layout>(
const [currentLayout, setCurrentLayout] = useState<DataLayout>(
initialLayout ?? availableLayouts[0],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
import { Dispatch, memo, useCallback, SetStateAction, useMemo } from "react";
import { useTranslation } from "react-i18next";

import { AvailableLayouts, Layout } from "./componentTypes";
import { AvailableLayouts, DataLayout } from "./componentTypes";
import { MenuButton } from "../../MenuButton";
import { MenuItem } from "../../MenuItem";

export type LayoutSwitcherProps = {
availableLayouts: AvailableLayouts;
currentLayout: Layout;
setCurrentLayout: Dispatch<SetStateAction<Layout>>;
currentLayout: DataLayout;
setCurrentLayout: Dispatch<SetStateAction<DataLayout>>;
};

const LayoutSwitcher = ({
Expand All @@ -31,15 +31,15 @@ const LayoutSwitcher = ({
const { t } = useTranslation();

const changeLayout = useCallback(
(value: Layout) => {
(value: DataLayout) => {
setCurrentLayout(value);
},
[setCurrentLayout],
);

const memoizedMenuItems = useMemo(
() =>
availableLayouts.map((value: Layout) => ({
availableLayouts.map((value: DataLayout) => ({
value,
onClick: () => changeLayout(value),
label: t(`dataview.layout.${value}`),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ import { paginationTypeValues } from "../DataTablePagination";
import { ReactNode } from "react";
import { StackCardProps } from "./StackCard";

export type Layout = (typeof availableLayouts)[number];
export type DataLayout = (typeof availableLayouts)[number];
export type StackLayout = (typeof availableStackLayouts)[number];

export type AvailableLayouts = Layout[];
export type AvailableLayouts = DataLayout[];
export type AvailableStackLayouts = StackLayout[];

export type UniversalProps = {
Expand Down Expand Up @@ -97,7 +97,7 @@ export type StackProps = {
rowActionMenuItems?: DataTableRowActionsProps["rowActionMenuItems"];
};

export type ViewProps<L extends Layout> = {
export type ViewProps<L extends DataLayout> = {
availableLayouts?: L[];
initialLayout?: L;
stackOptions?: StackProps;
Expand Down
85 changes: 85 additions & 0 deletions packages/odyssey-react-mui/src/labs/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*!
* Copyright (c) 2024-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*/

import { Children, ReactNode, memo } from "react";
import styled from "@emotion/styled";

import { Box } from "../Box";
import {
DesignTokens,
useOdysseyDesignTokens,
} from "../OdysseyDesignTokensContext";

type SupportedRegionRatios =
| [1]
| [1, 1]
| [1, 2]
| [2, 1]
| [1, 3]
| [3, 1]
| [1, 1, 1]
| [1, 1, 1, 1];

export type LayoutProps = {
/**
* The supported region ratios for the Grid. Each number is a fractional unit that is mapped to the 'fr' CSS unit.
* e.g. [2, 1] defines a 2/3, 1/3 layout and [1, 1, 1] defines a 1/3, 1/3, 1/3 layout
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout#the_fr_unit
*/
regions: SupportedRegionRatios;
/**
* The content of the Grid. May be a `string` or any other `ReactNode` or array of `ReactNode`s.
*/
children?: ReactNode;
};

interface LayoutContentProps {
odysseyDesignTokens: DesignTokens;
regions: string;
}

const LayoutContent = styled("div", {
shouldForwardProp: (prop) =>
!["odysseyDesignTokens", "regions"].includes(prop),
})<LayoutContentProps>(({ odysseyDesignTokens, regions }) => ({
display: "grid",
gridTemplateColumns: regions,
gridColumnGap: odysseyDesignTokens.Spacing4,
columnGap: odysseyDesignTokens.Spacing4,

"& + &": {
marginBlockStart: odysseyDesignTokens.Spacing4,
},
}));

const Layout = ({ regions, children }: LayoutProps) => {
const odysseyDesignTokens = useOdysseyDesignTokens();
const mappedRegions = regions
.map((region) => `minmax(0, ${region}fr)`)
.join(" ");

return (
<Box>
<LayoutContent
odysseyDesignTokens={odysseyDesignTokens}
regions={mappedRegions}
>
{Children.toArray(children).map((child) => child)}
</LayoutContent>
</Box>
);
};

const MemoizedLayout = memo(Layout);
MemoizedLayout.displayName = "Layout";

export { MemoizedLayout as Layout };
Loading

0 comments on commit 0d1aa97

Please sign in to comment.