Skip to content

Commit

Permalink
chore: move all CMS components from DS to admin
Browse files Browse the repository at this point in the history
  • Loading branch information
madhurisandbhor authored and joshuaellis committed May 3, 2024
1 parent fb2834f commit d50e43b
Show file tree
Hide file tree
Showing 69 changed files with 678 additions and 437 deletions.
34 changes: 34 additions & 0 deletions packages/core/admin/admin/src/components/Layouts/ActionLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as React from 'react';

import { Flex } from '@strapi/design-system';

interface ActionLayoutProps {
endActions?: React.ReactNode;
startActions?: React.ReactNode;
}

const ActionLayout = ({ startActions, endActions }: ActionLayoutProps) => {
if (!startActions && !endActions) {
return null;
}

return (
<Flex
justifyContent="space-between"
alignItems="flex-start"
paddingBottom={4}
paddingLeft={10}
paddingRight={10}
>
<Flex gap={2} wrap="wrap">
{startActions}
</Flex>

<Flex gap={2} shrink={0} wrap="wrap">
{endActions}
</Flex>
</Flex>
);
};

export { ActionLayout, type ActionLayoutProps };
17 changes: 17 additions & 0 deletions packages/core/admin/admin/src/components/Layouts/ContentLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as React from 'react';

import { Box } from '@strapi/design-system';

interface ContentLayoutProps {
children: React.ReactNode;
}

const ContentLayout = ({ children }: ContentLayoutProps) => {
return (
<Box paddingLeft={10} paddingRight={10}>
{children}
</Box>
);
};

export { ContentLayout, type ContentLayoutProps };
37 changes: 37 additions & 0 deletions packages/core/admin/admin/src/components/Layouts/GridLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as React from 'react';

import { Box } from '@strapi/design-system';
import styled from 'styled-components';

interface GridColSize {
S: number;
M: number;
}

const GridColSize = {
S: 180,
M: 250,
};

type Size = keyof GridColSize;

const StyledGrid = styled(Box)<{ $size: Size }>`
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(${({ $size }: { $size: Size }) => `${GridColSize[$size]}px`}, 1fr)
);
grid-gap: ${({ theme }) => theme.spaces[4]};
`;

interface GridLayoutProps {
size: Size;
children: React.ReactNode;
}

const GridLayout = ({ size, children }: GridLayoutProps) => {
return <StyledGrid $size={size}>{children}</StyledGrid>;
};

export { GridLayout };
export type { GridColSize };
201 changes: 201 additions & 0 deletions packages/core/admin/admin/src/components/Layouts/HeaderLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
import * as React from 'react';

import { Box, Flex, Typography, TypographyProps, useCallbackRef } from '@strapi/design-system';

/* -------------------------------------------------------------------------------------------------
* BaseHeaderLayout
* -----------------------------------------------------------------------------------------------*/

interface BaseHeaderLayoutProps extends TypographyProps {
navigationAction?: React.ReactNode;
primaryAction?: React.ReactNode;
secondaryAction?: React.ReactNode;
subtitle?: React.ReactNode;
sticky?: boolean;
width?: number;
}

const BaseHeaderLayout = React.forwardRef<HTMLDivElement, BaseHeaderLayoutProps>(
(
{ navigationAction, primaryAction, secondaryAction, subtitle, title, sticky, width, ...props },
ref
) => {
const isSubtitleString = typeof subtitle === 'string';

if (sticky) {
return (
<Box
paddingLeft={6}
paddingRight={6}
paddingTop={3}
paddingBottom={3}
position="fixed"
top={0}
right={0}
background="neutral0"
shadow="tableShadow"
width={`${width}rem`}
zIndex={1}
data-strapi-header-sticky
>
<Flex justifyContent="space-between">
<Flex>
{navigationAction && <Box paddingRight={3}>{navigationAction}</Box>}
<Box>
<Typography variant="beta" as="h1" {...props}>
{title}
</Typography>
{isSubtitleString ? (
<Typography variant="pi" textColor="neutral600">
{subtitle}
</Typography>
) : (
subtitle
)}
</Box>
{secondaryAction ? <Box paddingLeft={4}>{secondaryAction}</Box> : null}
</Flex>
<Flex>{primaryAction ? <Box paddingLeft={2}>{primaryAction}</Box> : undefined}</Flex>
</Flex>
</Box>
);
}

return (
<Box
ref={ref}
paddingLeft={10}
paddingRight={10}
paddingBottom={8}
paddingTop={navigationAction ? 6 : 8}
background="neutral100"
data-strapi-header
>
{navigationAction ? <Box paddingBottom={2}>{navigationAction}</Box> : null}
<Flex justifyContent="space-between">
<Flex minWidth={0}>
<Typography as="h1" variant="alpha" {...props}>
{title}
</Typography>
{secondaryAction ? <Box paddingLeft={4}>{secondaryAction}</Box> : null}
</Flex>
{primaryAction}
</Flex>
{isSubtitleString ? (
<Typography variant="epsilon" textColor="neutral600" as="p">
{subtitle}
</Typography>
) : (
subtitle
)}
</Box>
);
}
);

/* -------------------------------------------------------------------------------------------------
* HeaderLayout
* -----------------------------------------------------------------------------------------------*/

interface HeaderLayoutProps extends BaseHeaderLayoutProps {}

const HeaderLayout = (props: HeaderLayoutProps) => {
const baseHeaderLayoutRef = React.useRef<HTMLDivElement>(null);
const [headerSize, setHeaderSize] = React.useState<DOMRect | null>(null);

const [containerRef, isVisible] = useElementOnScreen<HTMLDivElement>({
root: null,
rootMargin: '0px',
threshold: 0,
});

useResizeObserver(containerRef, () => {
if (containerRef.current) {
setHeaderSize(containerRef.current.getBoundingClientRect());
}
});

React.useEffect(() => {
if (baseHeaderLayoutRef.current) {
setHeaderSize(baseHeaderLayoutRef.current.getBoundingClientRect());
}
}, [baseHeaderLayoutRef]);

return (
<>
<div style={{ height: headerSize?.height }} ref={containerRef}>
{isVisible && <BaseHeaderLayout ref={baseHeaderLayoutRef} {...props} />}
</div>

{!isVisible && <BaseHeaderLayout {...props} sticky width={headerSize?.width} />}
</>
);
};

HeaderLayout.displayName = 'HeaderLayout';

/**
* useElementOnScreen: hook that returns a ref to an element and a boolean indicating if the element is in the viewport.
*/
const useElementOnScreen = <TElement extends HTMLElement = HTMLElement>(
// eslint-disable-next-line
options?: IntersectionObserverInit
): [containerRef: React.RefObject<TElement>, isVisible: boolean] => {
const containerRef = React.useRef<TElement>(null);

const [isVisible, setIsVisible] = React.useState<boolean>(true);

// eslint-disable-next-line
const callback: IntersectionObserverCallback = ([entry]) => {
setIsVisible(entry.isIntersecting);
};

React.useEffect(() => {
const containerEl = containerRef.current;
const observer = new IntersectionObserver(callback, options);

if (containerEl) {
observer.observe(containerRef.current);
}

return () => {
if (containerEl) {
observer.disconnect();
}
};
}, [containerRef, options]);

return [containerRef, isVisible];
};

/**
* useResizeObserver: hook that observes the size of an element and calls a callback when it changes.
*/
const useResizeObserver = (
sources: React.RefObject<HTMLElement> | React.RefObject<HTMLElement>[],
// eslint-disable-next-line
onResize: ResizeObserverCallback
) => {
const handleResize = useCallbackRef(onResize);

React.useLayoutEffect(() => {
const resizeObs = new ResizeObserver(handleResize);

if (Array.isArray(sources)) {
sources.forEach((source) => {
if (source.current) {
resizeObs.observe(source.current);
}
});
} else if (sources.current) {
resizeObs.observe(sources.current);
}

return () => {
resizeObs.disconnect();
};
}, [sources, handleResize]);
};

export type { HeaderLayoutProps, BaseHeaderLayoutProps };
export { HeaderLayout, BaseHeaderLayout };
43 changes: 43 additions & 0 deletions packages/core/admin/admin/src/components/Layouts/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from 'react';

import { Box } from '@strapi/design-system';
import styled from 'styled-components';

import { ActionLayout } from './ActionLayout';
import { ContentLayout } from './ContentLayout';
import { GridLayout } from './GridLayout';
import { HeaderLayout, BaseHeaderLayout } from './HeaderLayout';

interface LayoutProps {
children: React.ReactNode;
sideNav?: React.ReactNode;
}

const GridContainer = styled(Box)<{ hasSideNav: boolean }>`
display: grid;
grid-template-columns: ${({ hasSideNav }) => (hasSideNav ? `auto 1fr` : '1fr')};
`;

const OverflowingItem = styled(Box)`
overflow-x: hidden;
`;

const RootLayout = ({ sideNav, children }: LayoutProps) => {
return (
<GridContainer hasSideNav={Boolean(sideNav)}>
{sideNav}
<OverflowingItem paddingBottom={10}>{children}</OverflowingItem>
</GridContainer>
);
};

const Layouts = {
Root: RootLayout,
Header: HeaderLayout,
BaseHeader: BaseHeaderLayout,
Grid: GridLayout,
Action: ActionLayout,
Content: ContentLayout,
};

export { Layouts, type LayoutProps };
6 changes: 6 additions & 0 deletions packages/core/admin/admin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,9 @@ export type { RBACContext, RBACMiddleware } from './core/apis/rbac';
*/
export { translatedErrors } from './utils/translatedErrors';
export { getFetchClient } from './utils/getFetchClient';

/**
* Components
*/

export { Layouts, type LayoutProps } from './components/Layouts/Layout';
18 changes: 14 additions & 4 deletions packages/core/admin/admin/src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import * as React from 'react';

import { Box, Button, Flex, Grid, GridItem, Layout, Main, Typography } from '@strapi/design-system';
import { Link, LinkButton } from '@strapi/design-system/v2';
import {
Box,
Button,
Flex,
Grid,
GridItem,
Main,
Typography,
Link,
LinkButton,
} from '@strapi/design-system';
import {
ArrowRight,
CodeSquare,
Expand All @@ -23,6 +32,7 @@ import styled from 'styled-components';
import { ContentBox } from '../components/ContentBox';
import { GuidedTourHomepage } from '../components/GuidedTour/Homepage';
import { useGuidedTour } from '../components/GuidedTour/Provider';
import { Layouts } from '../components/Layouts/Layout';
import { Page } from '../components/PageHelpers';
import { useAppInfo } from '../features/AppInfo';
import { useTracking } from '../features/Tracking';
Expand Down Expand Up @@ -65,7 +75,7 @@ const HomePageCE = () => {
}

return (
<Layout>
<Layouts.Root>
<Page.Title>
{formatMessage({
id: 'HomePage.head.title',
Expand Down Expand Up @@ -136,7 +146,7 @@ const HomePageCE = () => {
</Grid>
</Box>
</Main>
</Layout>
</Layouts.Root>
);
};

Expand Down

0 comments on commit d50e43b

Please sign in to comment.