Skip to content

Commit 475dab0

Browse files
authored
Merge pull request #891 from strapi/release/1.6.3
2 parents cbe09a1 + 1671f5b commit 475dab0

File tree

16 files changed

+113
-136
lines changed

16 files changed

+113
-136
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto eol=lf

docs/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@strapi/design-system-docs",
3-
"version": "1.6.2",
3+
"version": "1.6.3",
44
"license": "MIT",
55
"private": true,
66
"dependencies": {
@@ -10,8 +10,8 @@
1010
"@storybook/builder-webpack5": "^6.5.15",
1111
"@storybook/manager-webpack5": "^6.5.15",
1212
"@storybook/react": "^6.5.15",
13-
"@strapi/design-system": "^1.6.2",
14-
"@strapi/icons": "^1.6.2",
13+
"@strapi/design-system": "^1.6.3",
14+
"@strapi/icons": "^1.6.3",
1515
"qs": "^6.11.0",
1616
"react": "17",
1717
"react-copy-to-clipboard": "^5.1.0",

lerna.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"packages": ["packages/*", "docs"],
3-
"version": "1.6.2",
3+
"version": "1.6.3",
44
"npmClient": "yarn",
55
"useWorkspaces": true
66
}

packages/strapi-design-system/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@strapi/design-system",
3-
"version": "1.6.2",
3+
"version": "1.6.3",
44
"license": "MIT",
55
"type": "module",
66
"sideEffects": false,
@@ -29,7 +29,7 @@
2929
"devDependencies": {
3030
"@juggle/resize-observer": "^3.4.0",
3131
"@playwright/test": "1.27.1",
32-
"@strapi/icons": "^1.6.2",
32+
"@strapi/icons": "^1.6.3",
3333
"@swc/core": "^1.3.11",
3434
"@swc/jest": "^0.2.23",
3535
"@testing-library/jest-dom": "5.16.5",

packages/strapi-design-system/src/Avatar/__tests__/Avatar.spec.tsx

-8
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,9 @@ describe('Avatar', () => {
6363
/>
6464
<div
6565
class="c1"
66-
height="32px"
67-
width="32px"
6866
>
6967
<div
7068
class="c2 c3"
71-
height="32px"
72-
width="32px"
7369
/>
7470
<img
7571
alt="marvin frachet"
@@ -145,13 +141,9 @@ describe('Avatar', () => {
145141
/>
146142
<div
147143
class="c1"
148-
height="32px"
149-
width="32px"
150144
>
151145
<div
152146
class="c2 c3"
153-
height="32px"
154-
width="32px"
155147
/>
156148
<img
157149
alt="marvin frachet"

packages/strapi-design-system/src/Box/Box.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ export type BoxProps<TElement extends HTMLElement = HTMLDivElement> = Pick<
125125
*/
126126
const transientProps: Partial<Record<keyof BoxProps, boolean>> = {
127127
color: true,
128+
cursor: true,
129+
height: true,
130+
width: true,
128131
};
129132

130133
export const Box = styled.div.withConfig<BoxProps>({
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,34 @@
1-
import * as React from 'react';
2-
import { render, screen } from '@testing-library/react';
1+
import { render } from '@testing-library/react';
32
import { ThemeProvider } from 'styled-components';
43
import { Box } from '../Box';
54
import { lightTheme } from '../../themes';
65

6+
const setup = (props = {}) =>
7+
render(
8+
<ThemeProvider theme={lightTheme}>
9+
<Box {...props} />
10+
</ThemeProvider>,
11+
);
12+
713
describe('Box', () => {
814
it.each(['color', 'background'])('retrieves the theme value corresponding to the %s props', (colorProp) => {
9-
const props = { [colorProp]: 'primary500' };
10-
11-
render(
12-
<ThemeProvider theme={lightTheme}>
13-
<Box {...props}>Hello world</Box>
14-
</ThemeProvider>,
15-
);
16-
17-
const el = screen.getByText('Hello world');
18-
expect(el).toHaveStyle(`${colorProp}: #7b79ff`);
15+
const { container } = setup({ [colorProp]: 'primary500' });
16+
expect(container.children[0]).toHaveStyle(`${colorProp}: #7b79ff`);
1917
});
2018

2119
it.each(['padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'])(
2220
'retrieves the theme value corresponding to the %s props',
2321
(spacingProp) => {
24-
const props = { [spacingProp]: 4 };
25-
26-
render(
27-
<ThemeProvider theme={lightTheme}>
28-
<Box {...props}>Hello world</Box>
29-
</ThemeProvider>,
30-
);
22+
const { container } = setup({ [spacingProp]: 4 });
23+
expect(container.children[0]).toHaveStyle(`${spacingProp}: 16px`);
24+
},
25+
);
3126

32-
const el = screen.getByText('Hello world');
33-
expect(el).toHaveStyle(`${spacingProp}: 16px`);
27+
it.each(['color', 'cursor', 'height', 'width'])(
28+
'does not render color or cursor props as HTML attributes',
29+
(prop) => {
30+
const { container } = setup({ [prop]: 'something' });
31+
expect(container.children[0]).not.toHaveAttribute(prop);
3432
},
3533
);
3634
});
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import * as React from 'react';
2-
import PropTypes from 'prop-types';
32
import styled from 'styled-components';
4-
import { useFloating, flip, shift, offset, autoUpdate } from '@floating-ui/react-dom';
3+
import { useFloating, flip, shift, offset, autoUpdate, Placement } from '@floating-ui/react-dom';
54

6-
import { Box } from '../Box';
5+
import { Box, BoxProps } from '../Box';
76
import { Portal } from '../Portal';
87

98
import { useIntersection } from '../helpers/useIntersection';
@@ -21,7 +20,7 @@ export const POPOVER_PLACEMENTS = [
2120
'left',
2221
'left-start',
2322
'left-end',
24-
];
23+
] as const;
2524

2625
const PopoverWrapper = styled(Box)`
2726
box-shadow: ${({ theme }) => theme.shadows.filterShadow};
@@ -30,41 +29,24 @@ const PopoverWrapper = styled(Box)`
3029
background: ${({ theme }) => theme.colors.neutral0};
3130
`;
3231

33-
const PopoverScrollable = styled(Box)`
34-
// 16 is base base size, 3 is the factor to get closer to 40px and 5 is the number of elements visible in the list
35-
max-height: ${3 * 5}rem;
36-
overflow-y: auto;
37-
overflow-x: hidden;
38-
39-
&::-webkit-scrollbar {
40-
-webkit-appearance: none;
41-
width: 4px;
42-
}
43-
44-
&::-webkit-scrollbar-track {
45-
background: ${({ theme }) => theme.colors.neutral0};
46-
}
32+
interface ContentProps extends BoxProps<HTMLDivElement> {
33+
source: React.MutableRefObject<HTMLElement>;
34+
placement?: Placement;
35+
fullWidth?: boolean;
36+
centered?: boolean;
37+
spacing?: number;
38+
}
4739

48-
&::-webkit-scrollbar-thumb {
49-
background: ${({ theme }) => theme.colors.neutral150};
50-
border-radius: ${({ theme }) => theme.borderRadius};
51-
margin-right: 10px;
52-
}
53-
`;
54-
55-
const PopoverContent = ({
40+
export const Content = ({
5641
source,
5742
children,
58-
spacing,
59-
fullWidth,
60-
placement,
61-
onReachEnd,
62-
intersectionId,
63-
centered,
43+
spacing = 0,
44+
fullWidth = false,
45+
placement = 'bottom-start',
46+
centered = false,
6447
...props
65-
}) => {
66-
const popoverRef = React.useRef(null);
67-
const [width, setWidth] = React.useState(undefined);
48+
}: ContentProps) => {
49+
const [width, setWidth] = React.useState<number | undefined>(undefined);
6850
const { x, y, reference, floating, strategy } = useFloating({
6951
strategy: 'fixed',
7052
placement: centered ? 'bottom' : placement,
@@ -88,11 +70,6 @@ const PopoverContent = ({
8870
}
8971
}, [fullWidth, source]);
9072

91-
useIntersection(popoverRef, onReachEnd, {
92-
selectorToWatch: `#${intersectionId}`,
93-
skipWhen: !intersectionId || !onReachEnd,
94-
});
95-
9673
return (
9774
<PopoverWrapper
9875
ref={floating}
@@ -105,64 +82,64 @@ const PopoverContent = ({
10582
hasRadius
10683
background="neutral0"
10784
padding={1}
85+
{...props}
10886
>
109-
<PopoverScrollable ref={popoverRef} {...props}>
110-
{children}
111-
{intersectionId && onReachEnd && <Box id={intersectionId} width="100%" height="1px" />}
112-
</PopoverScrollable>
87+
{children}
11388
</PopoverWrapper>
11489
);
11590
};
11691

117-
export const Popover = (props) => {
92+
export interface ScrollingProps extends BoxProps<HTMLDivElement> {
93+
intersectionId?: string;
94+
onReachEnd?: (entry: IntersectionObserverEntry) => void;
95+
}
96+
97+
export const Scrolling = ({ children, intersectionId, onReachEnd, ...props }: ScrollingProps) => {
98+
const popoverRef = React.useRef<HTMLDivElement>(null!);
99+
100+
useIntersection(popoverRef, onReachEnd ?? (() => {}), {
101+
selectorToWatch: `#${intersectionId}`,
102+
skipWhen: !intersectionId || !onReachEnd,
103+
});
104+
118105
return (
119-
<Portal>
120-
<PopoverContent {...props} />
121-
</Portal>
106+
<PopoverScrollable ref={popoverRef} {...props}>
107+
{children}
108+
{intersectionId && onReachEnd && <Box id={intersectionId} width="100%" height="1px" />}
109+
</PopoverScrollable>
122110
);
123111
};
124112

125-
const popoverDefaultProps = {
126-
fullWidth: false,
127-
intersectionId: undefined,
128-
onReachEnd: undefined,
129-
centered: false,
130-
placement: 'bottom-start',
131-
spacing: 0,
132-
};
113+
const PopoverScrollable = styled(Box)`
114+
// 16 is base base size, 3 is the factor to get closer to 40px and 5 is the number of elements visible in the list
115+
max-height: ${3 * 5}rem;
116+
overflow-y: auto;
117+
overflow-x: hidden;
133118
134-
const popoverProps = {
135-
/**
136-
* Horizontally center the popover
137-
*/
138-
centered: PropTypes.bool,
139-
children: PropTypes.node.isRequired,
140-
/**
141-
* Display full width popover
142-
*/
143-
fullWidth: PropTypes.bool,
144-
/**
145-
* Element id to watch for the onReachEnd event
146-
*/
147-
intersectionId: PropTypes.string,
148-
/**
149-
* The callback invoked after a scroll to the bottom of the popover content.
150-
*/
151-
onReachEnd: PropTypes.func,
152-
/**
153-
* The popover position
154-
*/
155-
placement: PropTypes.oneOf(POPOVER_PLACEMENTS),
156-
/**
157-
* A React ref. Used to defined the position of the popover.
158-
*/
159-
source: PropTypes.shape({
160-
current: (typeof Element === 'undefined' ? PropTypes.any : PropTypes.instanceOf(Element)).isRequired,
161-
}).isRequired,
162-
spacing: PropTypes.number,
163-
};
119+
&::-webkit-scrollbar {
120+
-webkit-appearance: none;
121+
width: 4px;
122+
}
123+
124+
&::-webkit-scrollbar-track {
125+
background: ${({ theme }) => theme.colors.neutral0};
126+
}
164127
165-
PopoverContent.propTypes = popoverProps;
166-
PopoverContent.defaultProps = popoverDefaultProps;
167-
Popover.propTypes = popoverProps;
168-
Popover.defaultProps = popoverDefaultProps;
128+
&::-webkit-scrollbar-thumb {
129+
background: ${({ theme }) => theme.colors.neutral150};
130+
border-radius: ${({ theme }) => theme.borderRadius};
131+
margin-right: 10px;
132+
}
133+
`;
134+
135+
type PopoverProps = ScrollingProps & Pick<ContentProps, 'source' | 'spacing' | 'fullWidth' | 'placement' | 'centered'>;
136+
137+
export const Popover = ({ children, source, spacing, fullWidth, placement, centered, ...restProps }: PopoverProps) => {
138+
return (
139+
<Portal>
140+
<Content source={source} spacing={spacing} fullWidth={fullWidth} placement={placement} centered={centered}>
141+
<Scrolling {...restProps}>{children}</Scrolling>
142+
</Content>
143+
</Portal>
144+
);
145+
};

packages/strapi-design-system/src/Popover/__tests__/Popover.spec.js packages/strapi-design-system/src/Popover/__tests__/Popover.spec.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { lightTheme } from '../../themes';
77
describe('Popover', () => {
88
it('snapshots the component', () => {
99
const Component = () => {
10-
const divRef = React.useRef(null);
10+
const divRef = React.useRef<HTMLDivElement>(null!);
1111
const [visible] = React.useState(true);
1212

1313
return (
@@ -123,7 +123,7 @@ describe('Popover', () => {
123123

124124
it('should render the popover when visible is true', () => {
125125
const Component = () => {
126-
const divRef = React.useRef(null);
126+
const divRef = React.useRef<HTMLButtonElement>(null!);
127127
const [isVisible, setIsVisible] = React.useState(false);
128128

129129
return (

packages/strapi-design-system/src/Popover/index.js

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export { Popover, POPOVER_PLACEMENTS } from './Popover';
2+
3+
import { Content, Scrolling } from './Popover';
4+
export const PopoverPrimitives = {
5+
Content,
6+
Scrolling,
7+
};

packages/strapi-design-system/src/helpers/useIntersection.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { MutableRefObject, useEffect } from 'react';
55
import { useCallbackRef } from '@radix-ui/react-use-callback-ref';
66

77
interface UseIntersectionOptions {
8-
selectorToWatch: keyof HTMLElementTagNameMap;
8+
selectorToWatch: string;
99
skipWhen?: boolean;
1010
}
1111

+3-3
Loading

packages/strapi-icons/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@strapi/icons",
3-
"version": "1.6.2",
3+
"version": "1.6.3",
44
"license": "MIT",
55
"type": "module",
66
"main": "./dist/index.cjs",

0 commit comments

Comments
 (0)