Skip to content

Commit

Permalink
Merge branch 'main' into changeset-release/main
Browse files Browse the repository at this point in the history
  • Loading branch information
madhurisandbhor authored Jun 25, 2024
2 parents 566f953 + 61936d6 commit 0417435
Show file tree
Hide file tree
Showing 15 changed files with 401 additions and 368 deletions.
5 changes: 5 additions & 0 deletions .changeset/rotten-eagles-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@strapi/design-system': minor
---

chore: standardise forwardRefs across components
42 changes: 22 additions & 20 deletions packages/design-system/src/components/Breadcrumbs/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,27 @@ export interface BreadcrumbsProps extends FlexProps {
label?: string;
}

export const Breadcrumbs = ({ label, children, ...props }: BreadcrumbsProps) => {
const childrenArray = React.Children.toArray(children);

return (
<Box aria-label={label} tag="nav" {...props}>
<AlignedList tag="ol">
{React.Children.map(childrenArray, (child, index) => {
const shouldDisplayDivider = childrenArray.length > 1 && index + 1 < childrenArray.length;

return (
<Flex inline tag="li">
{child}
{shouldDisplayDivider && <Divider />}
</Flex>
);
})}
</AlignedList>
</Box>
);
};
export const Breadcrumbs = React.forwardRef<HTMLDivElement, BreadcrumbsProps>(
({ label, children, ...props }, forwardedRef) => {
const childrenArray = React.Children.toArray(children);

return (
<Box aria-label={label} tag="nav" {...props} ref={forwardedRef}>
<AlignedList tag="ol">
{React.Children.map(childrenArray, (child, index) => {
const shouldDisplayDivider = childrenArray.length > 1 && index + 1 < childrenArray.length;

return (
<Flex inline tag="li">
{child}
{shouldDisplayDivider && <Divider />}
</Flex>
);
})}
</AlignedList>
</Box>
);
},
);

Breadcrumbs.displayName = 'Breadcrumbs';
28 changes: 16 additions & 12 deletions packages/design-system/src/components/Breadcrumbs/Crumb.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import * as React from 'react';

import { Box } from '../Box';
import { Typography, TypographyProps } from '../Typography';

export interface CrumbProps extends TypographyProps {
isCurrent?: boolean;
}

export const Crumb = ({ children, isCurrent = false, ...props }: CrumbProps) => (
<Box paddingLeft={2} paddingRight={2} paddingTop={1} paddingBottom={1}>
<Typography
variant="pi"
textColor="neutral800"
fontWeight={isCurrent ? 'bold' : 'regular'}
aria-current={isCurrent}
{...props}
>
{children}
</Typography>
</Box>
export const Crumb = React.forwardRef<HTMLDivElement, CrumbProps>(
({ children, isCurrent = false, ...props }, forwardedRef) => (
<Box paddingLeft={2} paddingRight={2} paddingTop={1} paddingBottom={1} ref={forwardedRef}>
<Typography
variant="pi"
textColor="neutral800"
fontWeight={isCurrent ? 'bold' : 'regular'}
aria-current={isCurrent}
{...props}
>
{children}
</Typography>
</Box>
),
);

Crumb.displayName = 'Crumb';
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const StyledLink = styled(BaseLink)`
}
`;

export const CrumbLink = ({ children, ...props }: BaseLinkProps) => <StyledLink {...props}>{children}</StyledLink>;
export const CrumbLink = React.forwardRef<HTMLAnchorElement, BaseLinkProps>(({ children, ...props }, forwardedRef) => (
<StyledLink ref={forwardedRef} {...props}>
{children}
</StyledLink>
));

CrumbLink.displayName = 'CrumbLink';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';

import { styled } from 'styled-components';

import { SimpleMenu, SimpleMenuProps } from '../SimpleMenu';
import { SimpleMenu, type SimpleMenuProps } from '../SimpleMenu';

const StyledButton = styled(SimpleMenu)`
padding: ${({ theme }) => `${theme.spaces[1]} ${theme.spaces[2]}`};
Expand All @@ -20,10 +20,12 @@ export interface CrumbSimpleMenuProps extends SimpleMenuProps {
endIcon?: React.ReactNode;
}

export const CrumbSimpleMenu = ({ children, ...props }: CrumbSimpleMenuProps) => (
<StyledButton endIcon={null} size="S" {...props}>
{children}
</StyledButton>
export const CrumbSimpleMenu = React.forwardRef<HTMLButtonElement, CrumbSimpleMenuProps>(
({ children, ...props }, forwardedRef) => (
<StyledButton ref={forwardedRef} endIcon={null} size="S" {...props}>
{children}
</StyledButton>
),
);

CrumbSimpleMenu.displayName = 'CrumbSimpleMenu';
5 changes: 3 additions & 2 deletions packages/design-system/src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ export interface CardProps extends BoxProps {
id?: string;
}

export const Card = ({ id, ...props }: CardProps) => {
export const Card = React.forwardRef<HTMLDivElement, CardProps>(({ id, ...props }, forwardedRef) => {
const generatedId = useId(id);

const context = React.useMemo(() => ({ id: generatedId }), [generatedId]);

return (
<CardContext.Provider value={context}>
<Box
ref={forwardedRef}
id={id}
tabIndex={0}
hasRadius
Expand All @@ -31,4 +32,4 @@ export const Card = ({ id, ...props }: CardProps) => {
/>
</CardContext.Provider>
);
};
});
8 changes: 5 additions & 3 deletions packages/design-system/src/components/Card/CardAction.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as React from 'react';

import { styled } from 'styled-components';

import { PropsToTransientProps } from '../../types';
Expand All @@ -9,9 +11,9 @@ type CardActionProps = Omit<FlexProps<'div'>, 'direction' | 'gap' | 'position'>
position: CardActionPosition;
};

const CardActionImpl = ({ position, ...restProps }: CardActionProps) => {
return <CardAction $position={position} {...restProps} direction="row" gap={2} />;
};
const CardActionImpl = React.forwardRef<HTMLDivElement, CardActionProps>(({ position, ...restProps }, forwardedRef) => {
return <CardAction ref={forwardedRef} $position={position} {...restProps} direction="row" gap={2} />;
});

const CardAction = styled<FlexComponent>(Flex)<PropsToTransientProps<CardActionProps>>`
position: absolute;
Expand Down
8 changes: 5 additions & 3 deletions packages/design-system/src/components/Card/CardCheckbox.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import * as React from 'react';

import { Checkbox, CheckboxProps } from '../Checkbox';

import { CardAction } from './CardAction';
import { useCard } from './CardContext';

interface CardCheckboxProps extends CheckboxProps {}

const CardCheckbox = (props: CardCheckboxProps) => {
const CardCheckbox = React.forwardRef<HTMLButtonElement, CardCheckboxProps>((props, forwardedRef) => {
const { id } = useCard();

return (
<CardAction position="start">
<Checkbox aria-labelledby={`${id}-title`} {...props} />
<Checkbox aria-labelledby={`${id}-title`} {...props} ref={forwardedRef} />
</CardAction>
);
};
});

export { CardCheckbox };
export type { CardCheckboxProps };
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as React from 'react';

import { styled } from 'styled-components';

import { Box, BoxComponent } from '../Box';
Expand All @@ -16,35 +18,32 @@ const EmptyStateIconWrapper = styled<BoxComponent>(Box)`
}
`;

export const EmptyStateLayout = ({
icon,
content,
action,
hasRadius = true,
shadow = 'tableShadow',
}: EmptyStateLayoutProps) => {
return (
<Flex
alignItems="center"
direction="column"
padding={11}
background="neutral0"
hasRadius={hasRadius}
shadow={shadow}
>
{icon ? (
<EmptyStateIconWrapper paddingBottom={6} aria-hidden>
{icon}
</EmptyStateIconWrapper>
) : null}
export const EmptyStateLayout = React.forwardRef<HTMLDivElement, EmptyStateLayoutProps>(
({ icon, content, action, hasRadius = true, shadow = 'tableShadow' }: EmptyStateLayoutProps, forwardedRef) => {
return (
<Flex
ref={forwardedRef}
alignItems="center"
direction="column"
padding={11}
background="neutral0"
hasRadius={hasRadius}
shadow={shadow}
>
{icon ? (
<EmptyStateIconWrapper paddingBottom={6} aria-hidden>
{icon}
</EmptyStateIconWrapper>
) : null}

<Box paddingBottom={4}>
<Typography variant="delta" tag="p" textAlign="center" textColor="neutral600">
{content}
</Typography>
</Box>
<Box paddingBottom={4}>
<Typography variant="delta" tag="p" textAlign="center" textColor="neutral600">
{content}
</Typography>
</Box>

{action}
</Flex>
);
};
{action}
</Flex>
);
},
);
40 changes: 22 additions & 18 deletions packages/design-system/src/components/Popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as Popover from '@radix-ui/react-popover';
import { styled } from 'styled-components';

import { stripReactIdOfColon } from '../../helpers/strings';
import { useComposedRefs } from '../../hooks/useComposeRefs';
import { useId } from '../../hooks/useId';
import { useIntersection } from '../../hooks/useIntersection';
import { ANIMATIONS } from '../../styles/motion';
Expand Down Expand Up @@ -86,24 +87,27 @@ interface ScrollAreaImplProps extends ScrollAreaProps {
onReachEnd?: (entry: IntersectionObserverEntry) => void;
}

const ScrollAreaImpl = ({ children, intersectionId, onReachEnd, ...props }: ScrollAreaImplProps) => {
const popoverRef = React.useRef<HTMLDivElement>(null!);

const generatedIntersectionId = useId();
useIntersection(popoverRef, onReachEnd ?? (() => {}), {
selectorToWatch: `#${stripReactIdOfColon(generatedIntersectionId)}`,
skipWhen: !intersectionId || !onReachEnd,
});

return (
<PopoverScrollArea ref={popoverRef} {...props}>
{children}
{intersectionId && onReachEnd && (
<Box id={stripReactIdOfColon(generatedIntersectionId)} width="100%" height="1px" />
)}
</PopoverScrollArea>
);
};
const ScrollAreaImpl = React.forwardRef<HTMLDivElement, ScrollAreaImplProps>(
({ children, intersectionId, onReachEnd, ...props }, forwardedRef) => {
const popoverRef = React.useRef<HTMLDivElement>(null!);
const composedRef = useComposedRefs(popoverRef, forwardedRef);

const generatedIntersectionId = useId();
useIntersection(popoverRef, onReachEnd ?? (() => {}), {
selectorToWatch: `#${stripReactIdOfColon(generatedIntersectionId)}`,
skipWhen: !intersectionId || !onReachEnd,
});

return (
<PopoverScrollArea ref={composedRef} {...props}>
{children}
{intersectionId && onReachEnd && (
<Box id={stripReactIdOfColon(generatedIntersectionId)} width="100%" height="1px" />
)}
</PopoverScrollArea>
);
},
);

const PopoverScrollArea = styled(ScrollArea)`
height: 20rem;
Expand Down
Loading

0 comments on commit 0417435

Please sign in to comment.