@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.
@@ -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,KAAmB,MAAM,OAAO,CAAC;AAUxC,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;CAC7B,CAAC;AAkCF,eAAO,MAAM,SAAS,mCAAoC,cAAc,4CAuDvE,CAAC"}
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(false);
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(0deg)' : 'rotate(180deg)',
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: true, children: title })] }) }) }), _jsx(AccordionContent, { ref: (element) => {
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@scality/core-ui",
3
- "version": "0.157.0",
3
+ "version": "0.159.0",
4
4
  "description": "Scality common React component library",
5
5
  "author": "Scality Engineering",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -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 = ({ title, id, style, children }: AccordionProps) => {
51
- const [isOpen, setIsOpen] = useState(false);
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(0deg)' : 'rotate(180deg)',
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 renderAccordion = () => {
13
+ const SUT = ({ open = false }) => {
14
14
  const queryClient = new QueryClient();
15
- render(
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
  });