@scality/core-ui 0.157.0 → 0.159.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/accordion/Accordion.component.d.ts +3 -1
- package/dist/components/accordion/Accordion.component.d.ts.map +1 -1
- package/dist/components/accordion/Accordion.component.js +20 -6
- package/package.json +1 -1
- package/src/lib/components/accordion/Accordion.component.tsx +36 -6
- package/src/lib/components/accordion/Accordion.test.tsx +32 -5
|
@@ -4,6 +4,8 @@ export type AccordionProps = {
|
|
|
4
4
|
id: string;
|
|
5
5
|
children: React.ReactNode;
|
|
6
6
|
style?: React.CSSProperties;
|
|
7
|
+
open?: boolean;
|
|
8
|
+
isEmphazed?: boolean;
|
|
7
9
|
};
|
|
8
|
-
export declare const Accordion: ({ title, id, style, children }: AccordionProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare const Accordion: ({ title, id, style, children, open, isEmphazed, }: AccordionProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
11
|
//# sourceMappingURL=Accordion.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Accordion.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/accordion/Accordion.component.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Accordion.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/accordion/Accordion.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAUjD,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAkDF,eAAO,MAAM,SAAS,sDAOnB,cAAc,4CA4DhB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
3
3
|
import { spacing, Stack } from '../../spacing';
|
|
4
4
|
import { Box } from '../box/Box';
|
|
5
5
|
import { Icon } from '../icon/Icon.component';
|
|
@@ -8,6 +8,11 @@ import { Text } from '../text/Text.component';
|
|
|
8
8
|
const AccordionContainer = styled(Box) `
|
|
9
9
|
width: 100%;
|
|
10
10
|
height: auto;
|
|
11
|
+
${({ theme }) => `
|
|
12
|
+
border: 0.5px solid ${theme.border};
|
|
13
|
+
border-radius: 4px;
|
|
14
|
+
padding: ${spacing.r16};
|
|
15
|
+
`}
|
|
11
16
|
`;
|
|
12
17
|
const AccordionHeader = styled.button `
|
|
13
18
|
-webkit-appearance: none;
|
|
@@ -20,6 +25,12 @@ const AccordionHeader = styled.button `
|
|
|
20
25
|
color: ${(props) => props.theme.textPrimary};
|
|
21
26
|
padding: 0;
|
|
22
27
|
font-family: 'Lato';
|
|
28
|
+
${({ isOpen, theme }) => isOpen &&
|
|
29
|
+
`
|
|
30
|
+
border-bottom: 0.5px solid ${theme.border};
|
|
31
|
+
padding-bottom: ${spacing.r16};
|
|
32
|
+
margin-bottom: ${spacing.r8};
|
|
33
|
+
`}
|
|
23
34
|
`;
|
|
24
35
|
const AccordionContent = styled.div `
|
|
25
36
|
overflow: hidden;
|
|
@@ -33,15 +44,18 @@ const AccordionContent = styled.div `
|
|
|
33
44
|
const Wrapper = styled.div `
|
|
34
45
|
padding: ${spacing.r8} 0 ${spacing.r8} 0;
|
|
35
46
|
`;
|
|
36
|
-
export const Accordion = ({ title, id, style, children }) => {
|
|
37
|
-
const [isOpen, setIsOpen] = useState(
|
|
47
|
+
export const Accordion = ({ title, id, style, children, open = false, isEmphazed = true, }) => {
|
|
48
|
+
const [isOpen, setIsOpen] = useState(open);
|
|
49
|
+
useMemo(() => {
|
|
50
|
+
setIsOpen(open);
|
|
51
|
+
}, [open]);
|
|
38
52
|
const handleToggleContent = (e) => {
|
|
39
53
|
setIsOpen((prev) => !prev);
|
|
40
54
|
};
|
|
41
|
-
return (_jsxs(AccordionContainer, { children: [_jsx("h3", { style: { margin: 0 }, children: _jsx(AccordionHeader, { type: "button", id: `Accordion-header-${id}`, onClick: handleToggleContent, "aria-controls": id, "aria-expanded": isOpen, onKeyDown: (e) => (e.key === 'Enter' || e.key === ' ') && handleToggleContent, children: _jsxs(Stack, { direction: "horizontal", gap: "r8", children: [_jsx(Icon, { name: "Chevron-up", size: "lg", style: {
|
|
42
|
-
transform: isOpen ? 'rotate(
|
|
55
|
+
return (_jsxs(AccordionContainer, { children: [_jsx("h3", { style: { margin: 0 }, children: _jsx(AccordionHeader, { isOpen: isOpen, type: "button", id: `Accordion-header-${id}`, onClick: handleToggleContent, "aria-controls": id, "aria-expanded": isOpen, onKeyDown: (e) => (e.key === 'Enter' || e.key === ' ') && handleToggleContent, children: _jsxs(Stack, { direction: "horizontal", gap: "r8", children: [_jsx(Icon, { name: "Chevron-up", size: "lg", style: {
|
|
56
|
+
transform: isOpen ? 'rotate(180deg)' : 'rotate(90deg)',
|
|
43
57
|
transition: 'transform 0.3s ease-in',
|
|
44
|
-
} }), _jsx(Text, { isEmphazed:
|
|
58
|
+
} }), _jsx(Text, { isEmphazed: isEmphazed, children: title })] }) }) }), _jsx(AccordionContent, { ref: (element) => {
|
|
45
59
|
if (isOpen) {
|
|
46
60
|
element === null || element === void 0 ? void 0 : element.style.setProperty('height', element.scrollHeight + 'px');
|
|
47
61
|
}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { spacing, Stack } from '../../spacing';
|
|
4
4
|
import { Box } from '../box/Box';
|
|
@@ -13,14 +13,24 @@ export type AccordionProps = {
|
|
|
13
13
|
id: string;
|
|
14
14
|
children: React.ReactNode;
|
|
15
15
|
style?: React.CSSProperties;
|
|
16
|
+
open?: boolean;
|
|
17
|
+
isEmphazed?: boolean;
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
const AccordionContainer = styled(Box)`
|
|
19
21
|
width: 100%;
|
|
20
22
|
height: auto;
|
|
23
|
+
${({ theme }) =>
|
|
24
|
+
`
|
|
25
|
+
border: 0.5px solid ${theme.border};
|
|
26
|
+
border-radius: 4px;
|
|
27
|
+
padding: ${spacing.r16};
|
|
28
|
+
`}
|
|
21
29
|
`;
|
|
22
30
|
|
|
23
|
-
const AccordionHeader = styled.button
|
|
31
|
+
const AccordionHeader = styled.button<{
|
|
32
|
+
isOpen?: boolean;
|
|
33
|
+
}>`
|
|
24
34
|
-webkit-appearance: none;
|
|
25
35
|
-moz-appearance: none;
|
|
26
36
|
appearance: none;
|
|
@@ -31,7 +41,15 @@ const AccordionHeader = styled.button`
|
|
|
31
41
|
color: ${(props) => props.theme.textPrimary};
|
|
32
42
|
padding: 0;
|
|
33
43
|
font-family: 'Lato';
|
|
44
|
+
${({ isOpen, theme }) =>
|
|
45
|
+
isOpen &&
|
|
46
|
+
`
|
|
47
|
+
border-bottom: 0.5px solid ${theme.border};
|
|
48
|
+
padding-bottom: ${spacing.r16};
|
|
49
|
+
margin-bottom: ${spacing.r8};
|
|
50
|
+
`}
|
|
34
51
|
`;
|
|
52
|
+
|
|
35
53
|
const AccordionContent = styled.div<{
|
|
36
54
|
isOpen: boolean;
|
|
37
55
|
}>`
|
|
@@ -47,8 +65,19 @@ const Wrapper = styled.div`
|
|
|
47
65
|
padding: ${spacing.r8} 0 ${spacing.r8} 0;
|
|
48
66
|
`;
|
|
49
67
|
|
|
50
|
-
export const Accordion = ({
|
|
51
|
-
|
|
68
|
+
export const Accordion = ({
|
|
69
|
+
title,
|
|
70
|
+
id,
|
|
71
|
+
style,
|
|
72
|
+
children,
|
|
73
|
+
open = false,
|
|
74
|
+
isEmphazed = true,
|
|
75
|
+
}: AccordionProps) => {
|
|
76
|
+
const [isOpen, setIsOpen] = useState(open);
|
|
77
|
+
|
|
78
|
+
useMemo(() => {
|
|
79
|
+
setIsOpen(open);
|
|
80
|
+
}, [open]);
|
|
52
81
|
|
|
53
82
|
const handleToggleContent = (
|
|
54
83
|
e:
|
|
@@ -62,6 +91,7 @@ export const Accordion = ({ title, id, style, children }: AccordionProps) => {
|
|
|
62
91
|
<AccordionContainer>
|
|
63
92
|
<h3 style={{ margin: 0 }}>
|
|
64
93
|
<AccordionHeader
|
|
94
|
+
isOpen={isOpen}
|
|
65
95
|
type="button"
|
|
66
96
|
id={`Accordion-header-${id}`}
|
|
67
97
|
onClick={handleToggleContent}
|
|
@@ -76,11 +106,11 @@ export const Accordion = ({ title, id, style, children }: AccordionProps) => {
|
|
|
76
106
|
name="Chevron-up"
|
|
77
107
|
size="lg"
|
|
78
108
|
style={{
|
|
79
|
-
transform: isOpen ? 'rotate(
|
|
109
|
+
transform: isOpen ? 'rotate(180deg)' : 'rotate(90deg)',
|
|
80
110
|
transition: 'transform 0.3s ease-in',
|
|
81
111
|
}}
|
|
82
112
|
/>
|
|
83
|
-
<Text isEmphazed>{title}</Text>
|
|
113
|
+
<Text isEmphazed={isEmphazed}>{title}</Text>
|
|
84
114
|
</Stack>
|
|
85
115
|
</AccordionHeader>
|
|
86
116
|
</h3>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
3
|
import { Accordion } from './Accordion.component';
|
|
4
4
|
import userEvent from '@testing-library/user-event';
|
|
5
5
|
import { QueryClient, QueryClientProvider } from 'react-query';
|
|
@@ -10,16 +10,19 @@ describe('Accordion', () => {
|
|
|
10
10
|
accordionContainer: () => screen.getByRole('region'),
|
|
11
11
|
accordionContent: () => screen.queryByText(/Test content/i),
|
|
12
12
|
};
|
|
13
|
-
const
|
|
13
|
+
const SUT = ({ open = false }) => {
|
|
14
14
|
const queryClient = new QueryClient();
|
|
15
|
-
|
|
15
|
+
return (
|
|
16
16
|
<QueryClientProvider client={queryClient}>
|
|
17
|
-
<Accordion title="Advanced Testings" id="test-accordion">
|
|
17
|
+
<Accordion title="Advanced Testings" id="test-accordion" open={open}>
|
|
18
18
|
<div>Test content</div>
|
|
19
19
|
</Accordion>
|
|
20
|
-
</QueryClientProvider
|
|
20
|
+
</QueryClientProvider>
|
|
21
21
|
);
|
|
22
22
|
};
|
|
23
|
+
const renderAccordion = (open = false) => {
|
|
24
|
+
render(<SUT open={open} />);
|
|
25
|
+
};
|
|
23
26
|
it('should render the Accordion component with title and content', () => {
|
|
24
27
|
renderAccordion();
|
|
25
28
|
|
|
@@ -49,4 +52,28 @@ describe('Accordion', () => {
|
|
|
49
52
|
userEvent.keyboard('{space}');
|
|
50
53
|
expect(accordionContent).not.toBeVisible();
|
|
51
54
|
});
|
|
55
|
+
|
|
56
|
+
it('should toggle the content when open prop changes', () => {
|
|
57
|
+
const queryClient = new QueryClient();
|
|
58
|
+
const TestWrapper = () => {
|
|
59
|
+
const [isOpen, setisOpen] = useState(false);
|
|
60
|
+
return (
|
|
61
|
+
<>
|
|
62
|
+
<button onClick={() => setisOpen(!isOpen)}>Test button</button>
|
|
63
|
+
<SUT open={isOpen} />
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
render(
|
|
69
|
+
<QueryClientProvider client={queryClient}>
|
|
70
|
+
<TestWrapper />
|
|
71
|
+
</QueryClientProvider>,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
userEvent.click(screen.getByRole('button', { name: /Test button/i }));
|
|
75
|
+
expect(selectors.accordionContent()).toBeInTheDocument();
|
|
76
|
+
userEvent.click(screen.getByRole('button', { name: /Test button/i }));
|
|
77
|
+
expect(selectors.accordionContent()).not.toBeVisible();
|
|
78
|
+
});
|
|
52
79
|
});
|