@nuskin/foundation-ui-components 1.0.0-develop.4 → 1.0.0-develop.6
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/package.json +9 -4
- package/src/common/accordion/specs/NsAccordion.spec.tsx +3 -1
- package/src/common/accordion/specs/NsAccordionHeader.spec.tsx +21 -5
- package/src/common/accordion/specs/NsAccordionItem.spec.tsx +29 -5
- package/src/common/accordion/specs/NsCollapse.spec.tsx +4 -4
- package/src/common/accordion/specs/NsToggleSection.spec.tsx +10 -5
- package/src/common/alert/NsAlert.spec.tsx +0 -1
- package/src/common/alert/NsAlert.styled.ts +10 -10
- package/src/common/alert/NsAlert.tsx +4 -3
- package/src/common/auth-dropdown/NsAuthDropdown.styled.ts +12 -11
- package/src/common/auth-dropdown/NsAuthDropdown.tsx +2 -1
- package/src/common/auth-dropdown/types.d.ts +3 -1
- package/src/common/autocomplete/NsAutocomplete.spec.tsx +10 -0
- package/src/common/autocomplete/NsAutocomplete.stories.tsx +44 -6
- package/src/common/autocomplete/NsAutocomplete.tsx +18 -15
- package/src/common/autocomplete/types.d.ts +8 -6
- package/src/common/brand-components/NsBrandComponent.tsx +3 -0
- package/src/common/breadcrumb/NsBreadcrumb.tsx +4 -2
- package/src/common/button/NsButton.spec.tsx +1 -1
- package/src/common/button/NsButton.stories.tsx +1 -1
- package/src/common/button/NsButton.styled.tsx +25 -23
- package/src/common/button/NsButton.tsx +9 -2
- package/src/common/button/types.d.ts +1 -0
- package/src/common/common.types.d.ts +1 -0
- package/src/common/dropdown/types.d.ts +3 -1
- package/src/common/flag/NsFlag.spec.tsx +1 -0
- package/src/common/flag/NsFlag.styled.tsx +5 -5
- package/src/common/icon/types.d.ts +1 -0
- package/src/common/input/InputFieldWrapper.tsx +4 -4
- package/src/common/label/NsLabel.tsx +11 -7
- package/src/common/nav-tab/NsNavTab.styled.tsx +7 -4
- package/src/common/radiogroup/NsRadioGroup.spec.tsx +2 -1
- package/src/common/radiogroup/NsRadioGroup.stories.tsx +2 -1
- package/src/common/radiogroup/NsRadioGroup.styled.tsx +26 -32
- package/src/common/radiogroup/NsRadioGroup.tsx +20 -5
- package/src/common/radiogroup/types.d.ts +4 -3
- package/src/common/select/NsSelect.styled.tsx +19 -23
- package/src/common/table/NsTable.styled.ts +69 -66
- package/src/common/text-strip/NsTextStrip.tsx +10 -7
- package/src/common/typography/Typography.styled.tsx +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuskin/foundation-ui-components",
|
|
3
|
-
"version": "1.0.0-develop.
|
|
3
|
+
"version": "1.0.0-develop.6",
|
|
4
4
|
"description": "It is a foundation library written in react, that provides common components to all UI pages",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "src/common/index.ts",
|
|
@@ -31,7 +31,10 @@
|
|
|
31
31
|
"test:coverage": "yarn test --coverage",
|
|
32
32
|
"test:watch": "jest --watch",
|
|
33
33
|
"storybook": "storybook dev -p 6007",
|
|
34
|
-
"build-storybook": "storybook build"
|
|
34
|
+
"build-storybook": "storybook build",
|
|
35
|
+
"export": "next export",
|
|
36
|
+
"prepare": "husky install",
|
|
37
|
+
"types:check": "tsc --pretty --noEmit"
|
|
35
38
|
},
|
|
36
39
|
"dependencies": {
|
|
37
40
|
"@emotion/react": "^11.10.6",
|
|
@@ -39,8 +42,7 @@
|
|
|
39
42
|
"@mui/icons-material": "^5.11.11",
|
|
40
43
|
"@mui/material": "5.4.2",
|
|
41
44
|
"@next/font": "13.2.4",
|
|
42
|
-
"@nuskin/foundation-theme": "1.0.0-
|
|
43
|
-
"@types/jest": "^29.5.0",
|
|
45
|
+
"@nuskin/foundation-theme": "1.0.0-develop.5",
|
|
44
46
|
"framer-motion": "^10.8.5",
|
|
45
47
|
"next": "13.2.4",
|
|
46
48
|
"react": "18.2.0",
|
|
@@ -69,8 +71,10 @@
|
|
|
69
71
|
"@storybook/testing-library": "^0.1.0",
|
|
70
72
|
"@testing-library/jest-dom": "^5.16.5",
|
|
71
73
|
"@testing-library/react": "^14.0.0",
|
|
74
|
+
"@types/jest": "^29.5.0",
|
|
72
75
|
"@types/lodash": "^4.14.191",
|
|
73
76
|
"@types/node": "18.15.0",
|
|
77
|
+
"@types/ramda": "^0.29.3",
|
|
74
78
|
"@types/react": "18.0.28",
|
|
75
79
|
"@types/react-dom": "18.0.11",
|
|
76
80
|
"@types/react-slick": "^0.23.10",
|
|
@@ -86,6 +90,7 @@
|
|
|
86
90
|
"eslint-plugin-json": "^3.1.0",
|
|
87
91
|
"eslint-plugin-prettier": "^4.2.1",
|
|
88
92
|
"eslint-plugin-storybook": "^0.6.11",
|
|
93
|
+
"husky": "^8.0.0",
|
|
89
94
|
"jest": "^29.5.0",
|
|
90
95
|
"jest-environment-jsdom": "^29.5.0",
|
|
91
96
|
"storybook": "^7.0.7"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, fireEvent, screen } from '@/test-utils/index';
|
|
3
|
-
import { NsAccordion, NsAccordionProps } from '@/common/index';
|
|
3
|
+
import { AccordionVariant, NsAccordion, NsAccordionProps } from '@/common/index';
|
|
4
4
|
|
|
5
5
|
const generateContentArray = (count: number) => {
|
|
6
6
|
const arr = [] as NsAccordionProps['contentArray'];
|
|
@@ -22,6 +22,7 @@ describe('NsAccordion', () => {
|
|
|
22
22
|
},
|
|
23
23
|
allowMultipleExpanded: false,
|
|
24
24
|
contentArray,
|
|
25
|
+
variant: AccordionVariant.Basic,
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
it('renders without error', () => {
|
|
@@ -68,6 +69,7 @@ describe('NsAccordion', () => {
|
|
|
68
69
|
},
|
|
69
70
|
allowMultipleExpanded: false,
|
|
70
71
|
contentArray,
|
|
72
|
+
variant: AccordionVariant.Basic,
|
|
71
73
|
};
|
|
72
74
|
const { getAllByText } = render(<NsAccordion {...defaultProps} allowMultipleExpanded />);
|
|
73
75
|
const [title1, title2, title3] = getAllByText(/Title /i);
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, fireEvent } from '@/test-utils/index';
|
|
3
|
-
import { NsAccordionHeader } from '@/common/index';
|
|
3
|
+
import { NsAccordionHeader, AccordionVariant } from '@/common/index';
|
|
4
4
|
|
|
5
5
|
describe('NsAccordionHeader', () => {
|
|
6
6
|
it('renders title correctly', () => {
|
|
7
7
|
const onClick = jest.fn();
|
|
8
8
|
const title = 'Section Header';
|
|
9
|
-
const { getByText } = render(
|
|
9
|
+
const { getByText } = render(
|
|
10
|
+
<NsAccordionHeader
|
|
11
|
+
variant={AccordionVariant.Basic}
|
|
12
|
+
title={title}
|
|
13
|
+
onClick={onClick}
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
10
16
|
expect(getByText(title)).toBeInTheDocument();
|
|
11
17
|
});
|
|
12
18
|
|
|
13
19
|
it('calls onClick handler when clicked', () => {
|
|
14
20
|
const onClick = jest.fn();
|
|
15
|
-
const { container } = render(
|
|
21
|
+
const { container } = render(
|
|
22
|
+
<NsAccordionHeader
|
|
23
|
+
variant={AccordionVariant.Basic}
|
|
24
|
+
title="Section Header"
|
|
25
|
+
onClick={onClick}
|
|
26
|
+
/>);
|
|
16
27
|
const header = container.querySelector('header');
|
|
17
28
|
if (header) {
|
|
18
29
|
fireEvent.click(header);
|
|
@@ -25,6 +36,7 @@ describe('NsAccordionHeader', () => {
|
|
|
25
36
|
const onClick = jest.fn();
|
|
26
37
|
const { container } = render(
|
|
27
38
|
<NsAccordionHeader
|
|
39
|
+
variant={AccordionVariant.Basic}
|
|
28
40
|
title="Section Header"
|
|
29
41
|
additionalProps={{ className: additionalClassName }}
|
|
30
42
|
onClick={onClick}
|
|
@@ -35,13 +47,17 @@ describe('NsAccordionHeader', () => {
|
|
|
35
47
|
|
|
36
48
|
it('renders with expanded class when isOpen is true', () => {
|
|
37
49
|
const onClick = jest.fn();
|
|
38
|
-
const { container } = render(
|
|
50
|
+
const { container } = render(
|
|
51
|
+
<NsAccordionHeader variant={AccordionVariant.Basic} title="Section Header" isOpen onClick={onClick} />
|
|
52
|
+
);
|
|
39
53
|
expect(container.querySelector('header')).toHaveClass('expanded');
|
|
40
54
|
});
|
|
41
55
|
|
|
42
56
|
it('renders with header icon', () => {
|
|
43
57
|
const onClick = jest.fn();
|
|
44
|
-
const { getByTestId } = render(
|
|
58
|
+
const { getByTestId } = render(
|
|
59
|
+
<NsAccordionHeader variant={AccordionVariant.Basic} title="Section Header" onClick={onClick} />
|
|
60
|
+
);
|
|
45
61
|
expect(getByTestId('icon')).toBeInTheDocument();
|
|
46
62
|
});
|
|
47
63
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, fireEvent } from '@/test-utils/index';
|
|
3
|
-
import { NsAccordionItem } from '@/common/index';
|
|
3
|
+
import { NsAccordionItem, AccordionVariant } from '@/common/index';
|
|
4
4
|
|
|
5
5
|
describe('NsAccordionItem', () => {
|
|
6
6
|
const title = 'Accordion Section Title';
|
|
@@ -8,7 +8,13 @@ describe('NsAccordionItem', () => {
|
|
|
8
8
|
|
|
9
9
|
it('renders title correctly', () => {
|
|
10
10
|
const { getByText } = render(
|
|
11
|
-
<NsAccordionItem
|
|
11
|
+
<NsAccordionItem
|
|
12
|
+
variant={AccordionVariant.Basic}
|
|
13
|
+
isOpen={false}
|
|
14
|
+
toggleOpen={() => {}}
|
|
15
|
+
title={title}
|
|
16
|
+
content={content}
|
|
17
|
+
/>
|
|
12
18
|
);
|
|
13
19
|
expect(getByText(title)).toBeInTheDocument();
|
|
14
20
|
});
|
|
@@ -16,7 +22,13 @@ describe('NsAccordionItem', () => {
|
|
|
16
22
|
it('calls toggleOpen function when clicked on the section header', () => {
|
|
17
23
|
const toggleOpen = jest.fn();
|
|
18
24
|
const { getByText } = render(
|
|
19
|
-
<NsAccordionItem
|
|
25
|
+
<NsAccordionItem
|
|
26
|
+
variant={AccordionVariant.Basic}
|
|
27
|
+
isOpen={false}
|
|
28
|
+
toggleOpen={toggleOpen}
|
|
29
|
+
title={title}
|
|
30
|
+
content={content}
|
|
31
|
+
/>
|
|
20
32
|
);
|
|
21
33
|
fireEvent.click(getByText(title));
|
|
22
34
|
expect(toggleOpen).toHaveBeenCalledTimes(1);
|
|
@@ -24,14 +36,26 @@ describe('NsAccordionItem', () => {
|
|
|
24
36
|
|
|
25
37
|
it('renders content when isOpen is true', () => {
|
|
26
38
|
const { getByText } = render(
|
|
27
|
-
<NsAccordionItem
|
|
39
|
+
<NsAccordionItem
|
|
40
|
+
variant={AccordionVariant.Basic}
|
|
41
|
+
isOpen={true}
|
|
42
|
+
toggleOpen={() => {}}
|
|
43
|
+
title={title}
|
|
44
|
+
content={content}
|
|
45
|
+
/>
|
|
28
46
|
);
|
|
29
47
|
expect(getByText(content)).toBeInTheDocument();
|
|
30
48
|
});
|
|
31
49
|
|
|
32
50
|
it('does not render content when isOpen is false', () => {
|
|
33
51
|
const { queryByText } = render(
|
|
34
|
-
<NsAccordionItem
|
|
52
|
+
<NsAccordionItem
|
|
53
|
+
variant={AccordionVariant.Basic}
|
|
54
|
+
isOpen={false}
|
|
55
|
+
toggleOpen={() => {}}
|
|
56
|
+
title={title}
|
|
57
|
+
content={content}
|
|
58
|
+
/>
|
|
35
59
|
);
|
|
36
60
|
expect(queryByText(content)).toBeNull();
|
|
37
61
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, screen } from '@/test-utils/index';
|
|
3
|
-
import { NsCollapse } from '@/common/index';
|
|
3
|
+
import { NsCollapse, AccordionVariant } from '@/common/index';
|
|
4
4
|
|
|
5
5
|
describe('NsCollapse', () => {
|
|
6
6
|
it('renders children when isOpen is true', () => {
|
|
7
7
|
const { getByText } = render(
|
|
8
|
-
<NsCollapse isOpen>
|
|
8
|
+
<NsCollapse isOpen variant={AccordionVariant.Basic}>
|
|
9
9
|
<div>Child 1</div>
|
|
10
10
|
<div>Child 2</div>
|
|
11
11
|
</NsCollapse>
|
|
@@ -16,7 +16,7 @@ describe('NsCollapse', () => {
|
|
|
16
16
|
|
|
17
17
|
it('does not render children when isOpen is false', () => {
|
|
18
18
|
render(
|
|
19
|
-
<NsCollapse isOpen={false}>
|
|
19
|
+
<NsCollapse isOpen={false} variant={AccordionVariant.Basic}>
|
|
20
20
|
<div>Child 1</div>
|
|
21
21
|
<div>Child 2</div>
|
|
22
22
|
</NsCollapse>
|
|
@@ -27,7 +27,7 @@ describe('NsCollapse', () => {
|
|
|
27
27
|
it('renders with additional class name', () => {
|
|
28
28
|
const additionalClassName = 'custom-class';
|
|
29
29
|
const { container } = render(
|
|
30
|
-
<NsCollapse additionalProps={{ className: additionalClassName }} isOpen>
|
|
30
|
+
<NsCollapse additionalProps={{ className: additionalClassName }} isOpen variant={AccordionVariant.Basic}>
|
|
31
31
|
<div>Child 1</div>
|
|
32
32
|
<div>Child 2</div>
|
|
33
33
|
</NsCollapse>
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { AccordionVariant, NsToggleSection } from '@/common/index';
|
|
4
|
+
|
|
2
5
|
import { render, fireEvent } from '@/test-utils/index';
|
|
3
|
-
import { NsToggleSection } from '@/common/index';
|
|
4
6
|
|
|
5
7
|
describe('NsToggleSection', () => {
|
|
6
8
|
const title = 'Toggle Section Title';
|
|
7
9
|
const content = 'Toggle Section Content';
|
|
8
10
|
|
|
9
11
|
it('renders title correctly', () => {
|
|
10
|
-
const { getByText } = render(
|
|
12
|
+
const { getByText } = render(
|
|
13
|
+
<NsToggleSection variant={AccordionVariant.Basic} title={title}>{content}</NsToggleSection>
|
|
14
|
+
);
|
|
11
15
|
expect(getByText(title)).toBeInTheDocument();
|
|
12
16
|
});
|
|
13
17
|
|
|
14
18
|
it('toggles content visibility when clicked on the section header', () => {
|
|
15
|
-
const { getByText, queryByText } = render(
|
|
16
|
-
|
|
19
|
+
const { getByText, queryByText } = render(
|
|
20
|
+
<NsToggleSection variant={AccordionVariant.Basic} title={title}>{content}</NsToggleSection>
|
|
21
|
+
);
|
|
17
22
|
expect(queryByText(content)).toBeNull();
|
|
18
23
|
fireEvent.click(getByText(title));
|
|
19
24
|
expect(getByText(content)).toBeInTheDocument();
|
|
@@ -23,7 +28,7 @@ describe('NsToggleSection', () => {
|
|
|
23
28
|
|
|
24
29
|
it('sets defaultOpen prop correctly', () => {
|
|
25
30
|
const { getByText } = render(
|
|
26
|
-
<NsToggleSection title={title} defaultOpen>
|
|
31
|
+
<NsToggleSection variant={AccordionVariant.Basic} title={title} defaultOpen>
|
|
27
32
|
{content}
|
|
28
33
|
</NsToggleSection>
|
|
29
34
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
|
-
import { styled, css } from '@nuskin/foundation-theme';
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { styled, css, ColorUtils, FoundationTheme } from '@nuskin/foundation-theme';
|
|
3
|
+
|
|
4
|
+
const { color } = ColorUtils;
|
|
5
5
|
|
|
6
6
|
import type { AlertContainerParams, AlertType, AlertParams, TypeMapCSS } from './types.d';
|
|
7
7
|
const gutter_width = '10px';
|
|
@@ -43,7 +43,7 @@ export const AlertContainer = styled.div<AlertContainerParams>`
|
|
|
43
43
|
}
|
|
44
44
|
text-align: left;
|
|
45
45
|
`;
|
|
46
|
-
|
|
46
|
+
//[Todo-Arun] - Fonts should be driven through @next/font and according to theme
|
|
47
47
|
const fontFamilyStyles = css`
|
|
48
48
|
font-family: 'proxima-nova', 'OpenSans', 'Pridi', 'NotoSans', 'NotoSansSC', 'NotoSansHebrew', 'NotoSansJapanese',
|
|
49
49
|
'Hiragino Kaku Gothic Pro', 'Yu Gothic Medium', 'Yu Gothic', Meiryo, 'source-han-sans-japanese',
|
|
@@ -57,11 +57,11 @@ export const Alert = styled.div<AlertParams>`
|
|
|
57
57
|
grid-template-rows: [row1] auto;
|
|
58
58
|
grid-auto-row: auto;
|
|
59
59
|
grid-auto-flow: row;
|
|
60
|
-
background-color: ${(
|
|
61
|
-
border: 1px solid ${(
|
|
60
|
+
background-color: ${color('primary', 'white')};
|
|
61
|
+
border: 1px solid ${color('primary', 'black')};
|
|
62
62
|
min-height: ${({ type }) => TypeMap?.[type]?.['min-height']};
|
|
63
63
|
padding: ${({ type }) => TypeMap?.[type]?.['padding']};
|
|
64
|
-
color: ${(
|
|
64
|
+
color: ${(props) => color(contextType?.[props?.context] as FoundationTheme.AppColors, '40')(props)} };
|
|
65
65
|
`;
|
|
66
66
|
|
|
67
67
|
export const AlertCloseButton = styled.div`
|
|
@@ -92,7 +92,7 @@ export const AlertHead = styled.div`
|
|
|
92
92
|
justify-content: center;
|
|
93
93
|
span {
|
|
94
94
|
${fontFamilyStyles}
|
|
95
|
-
color: ${(
|
|
95
|
+
color: ${color('primary', 'black')};
|
|
96
96
|
font-weight: 600;
|
|
97
97
|
font-size: 18px;
|
|
98
98
|
line-height: 20px;
|
|
@@ -101,14 +101,14 @@ export const AlertHead = styled.div`
|
|
|
101
101
|
|
|
102
102
|
export const AlertContent = styled.div<{ type: AlertType }>`
|
|
103
103
|
margin-top: 8px;
|
|
104
|
-
color: ${(
|
|
104
|
+
color: ${color('primary', 'black')};
|
|
105
105
|
grid-column-start: ${({ type }) => TypeMap?.[type]?.['content-column-start']};
|
|
106
106
|
grid-column-end: ${({ type }) => TypeMap?.[type]?.['content-column-end']};
|
|
107
107
|
`;
|
|
108
108
|
|
|
109
109
|
export const AlertFoot = styled.div<{ type: AlertType }>`
|
|
110
110
|
margin-top: 8px;
|
|
111
|
-
color: ${(
|
|
111
|
+
color: ${color('primary', 'black')};
|
|
112
112
|
display: ${({ type }) => TypeMap?.[type]?.['foot-display']};
|
|
113
113
|
${fontFamilyStyles}
|
|
114
114
|
font-weight: 300;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
/* eslint-disable react/require-default-props */
|
|
2
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { FoundationTheme } from '@nuskin/foundation-theme';
|
|
3
|
+
|
|
3
4
|
import {
|
|
4
5
|
AlertContainer,
|
|
5
6
|
Alert,
|
|
@@ -13,7 +14,6 @@ import {
|
|
|
13
14
|
import type { NsAlertProps, HeaderProps, ContextType, AlertType } from './types.d';
|
|
14
15
|
import { NsIcon } from '../icon';
|
|
15
16
|
import { NsIconNameType } from '../icon/types';
|
|
16
|
-
import { FoundationTheme } from '@nuskin/foundation-theme/src/themes';
|
|
17
17
|
|
|
18
18
|
const Header: React.FC<HeaderProps> = ({ children, head }) => (
|
|
19
19
|
<>
|
|
@@ -57,7 +57,7 @@ export default function NsAlert({
|
|
|
57
57
|
onDismiss = undefined,
|
|
58
58
|
}: NsAlertProps) {
|
|
59
59
|
const [alertType, setAlertType] = useState('banner');
|
|
60
|
-
const [windowWidth, setWindowWidth] = useState(
|
|
60
|
+
const [windowWidth, setWindowWidth] = useState(0);
|
|
61
61
|
|
|
62
62
|
const hasDismissListener = typeof onDismiss === 'function';
|
|
63
63
|
|
|
@@ -106,6 +106,7 @@ export default function NsAlert({
|
|
|
106
106
|
}, [context, type]);
|
|
107
107
|
|
|
108
108
|
useEffect(() => {
|
|
109
|
+
setWindowWidth(window?.innerWidth);
|
|
109
110
|
window.addEventListener('resize', handleResize);
|
|
110
111
|
return () => {
|
|
111
112
|
window.removeEventListener('resize', handleResize);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { styled, ColorUtils } from '@nuskin/foundation-theme';
|
|
2
|
-
import { getAppColor } from '@nuskin/foundation-theme/src/utils/color-utils';
|
|
3
|
-
const { getPaletteColor } = ColorUtils;
|
|
4
2
|
|
|
3
|
+
//[TODO-Arun] - Use from custom color variables
|
|
5
4
|
const MAGENTA_COLOR = '#bb29bb';
|
|
6
5
|
|
|
6
|
+
const { color, paletteColor } = ColorUtils;
|
|
7
|
+
|
|
7
8
|
export const AuthDropdownContainer = styled.div`
|
|
8
9
|
position: relative;
|
|
9
10
|
display: inline-block;
|
|
@@ -19,7 +20,7 @@ export const AuthDropdown = styled.div`
|
|
|
19
20
|
z-index: 600;
|
|
20
21
|
top: calc(100% + 18px);
|
|
21
22
|
right: 5%;
|
|
22
|
-
box-shadow: 0 0 5px 0 ${(
|
|
23
|
+
box-shadow: 0 0 5px 0 ${color('neutral', '20')};
|
|
23
24
|
transition: all 0.15s ease-in-out;
|
|
24
25
|
padding: 25px;
|
|
25
26
|
`;
|
|
@@ -39,21 +40,21 @@ export const Triangle = styled.div`
|
|
|
39
40
|
position: absolute;
|
|
40
41
|
width: 14px;
|
|
41
42
|
height: 14px;
|
|
42
|
-
background-color: ${(
|
|
43
|
+
background-color: ${color('primary', 'white')};
|
|
43
44
|
transform: rotate(45deg);
|
|
44
45
|
top: 17px;
|
|
45
46
|
left: 5px;
|
|
46
|
-
box-shadow: 0 0 5px 0 ${(
|
|
47
|
+
box-shadow: 0 0 5px 0 ${color('neutral', '20')};
|
|
47
48
|
}
|
|
48
49
|
`;
|
|
49
50
|
|
|
50
|
-
export const AuthHead = styled.div
|
|
51
|
+
export const AuthHead = styled.div<{ darkModeEnabled: boolean }>`
|
|
51
52
|
cursor: pointer;
|
|
52
53
|
padding: 5px 10px;
|
|
53
54
|
display: flex;
|
|
54
55
|
justify-content: space-between;
|
|
55
56
|
align-items: center;
|
|
56
|
-
color: ${(
|
|
57
|
+
color: ${paletteColor('primary')};
|
|
57
58
|
`;
|
|
58
59
|
|
|
59
60
|
export const Button = styled.div`
|
|
@@ -69,17 +70,17 @@ export const SignInButton = styled(Link)`
|
|
|
69
70
|
padding: 13px;
|
|
70
71
|
width: 100%;
|
|
71
72
|
background-color: ${MAGENTA_COLOR};
|
|
72
|
-
color: ${(
|
|
73
|
+
color: ${color('primary', 'white')};
|
|
73
74
|
border: 0;
|
|
74
75
|
font-size: 16px;
|
|
75
76
|
&:hover {
|
|
76
|
-
background-color: ${(
|
|
77
|
+
background-color: ${color('neutral', '70')};
|
|
77
78
|
}
|
|
78
79
|
`;
|
|
79
80
|
|
|
80
81
|
export const SignUpLinkContainer = styled.div`
|
|
81
82
|
margin-top: 15px;
|
|
82
|
-
color: ${(
|
|
83
|
+
color: ${color('primary', 'main')};
|
|
83
84
|
font-size: 13px;
|
|
84
85
|
line-height: 16px;
|
|
85
86
|
text-align: left;
|
|
@@ -95,7 +96,7 @@ export const SignUpLink = styled(Link)`
|
|
|
95
96
|
position: relative;
|
|
96
97
|
transition: all 0.15s ease-in-out;
|
|
97
98
|
&:hover {
|
|
98
|
-
color: ${(
|
|
99
|
+
color: ${color('neutral', '70')};
|
|
99
100
|
font-size: 14px;
|
|
100
101
|
}
|
|
101
102
|
&:hover::after {
|
|
@@ -20,6 +20,7 @@ const NsAuthDropdown = ({
|
|
|
20
20
|
signUpLinkPrefixText,
|
|
21
21
|
titleText,
|
|
22
22
|
closeOnMouseLeave = false,
|
|
23
|
+
darkModeEnabled = true,
|
|
23
24
|
}: NsAuthDropdownProps) => {
|
|
24
25
|
const [isOpen, setIsOpen] = useState(false);
|
|
25
26
|
|
|
@@ -35,7 +36,7 @@ const NsAuthDropdown = ({
|
|
|
35
36
|
|
|
36
37
|
return (
|
|
37
38
|
<AuthDropdownContainer>
|
|
38
|
-
<AuthHead data-testid="auth-head" onClick={handleToggle}>
|
|
39
|
+
<AuthHead data-testid="auth-head" onClick={handleToggle} darkModeEnabled={darkModeEnabled}>
|
|
39
40
|
<Button>{titleText}</Button>
|
|
40
41
|
<NsIcon testId="chevron-icon" name={isOpen ? 'arrowUp' : 'arrowDown'} color="primary" />
|
|
41
42
|
{isOpen ? (
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { AdditionalProps } from '../common.types';
|
|
2
|
+
|
|
1
3
|
export type NsAuthDropdownProps = {
|
|
2
4
|
signInRedirectLink: string;
|
|
3
5
|
signUpRedirectLink: string;
|
|
@@ -6,4 +8,4 @@ export type NsAuthDropdownProps = {
|
|
|
6
8
|
signUpLinkPrefixText: string;
|
|
7
9
|
titleText: string;
|
|
8
10
|
closeOnMouseLeave?: boolean;
|
|
9
|
-
};
|
|
11
|
+
} & AdditionalProps;
|
|
@@ -14,6 +14,8 @@ describe('CustomAutocomplete', () => {
|
|
|
14
14
|
onSelect={() => {}}
|
|
15
15
|
placeholder="autocomplete-input"
|
|
16
16
|
renderOptions={OptionUiComponent}
|
|
17
|
+
inputValue=""
|
|
18
|
+
value=""
|
|
17
19
|
/>
|
|
18
20
|
);
|
|
19
21
|
const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
|
|
@@ -27,6 +29,8 @@ describe('CustomAutocomplete', () => {
|
|
|
27
29
|
onSelect={() => {}}
|
|
28
30
|
renderOptions={OptionUiComponent}
|
|
29
31
|
placeholder="autocomplete-input"
|
|
32
|
+
inputValue=""
|
|
33
|
+
value=""
|
|
30
34
|
/>
|
|
31
35
|
);
|
|
32
36
|
const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
|
|
@@ -48,6 +52,8 @@ describe('CustomAutocomplete', () => {
|
|
|
48
52
|
options={AutocompleteMockList}
|
|
49
53
|
renderOptions={OptionUiComponent}
|
|
50
54
|
placeholder="autocomplete-input"
|
|
55
|
+
inputValue=""
|
|
56
|
+
value=""
|
|
51
57
|
/>
|
|
52
58
|
);
|
|
53
59
|
const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
|
|
@@ -71,6 +77,8 @@ describe('CustomAutocomplete', () => {
|
|
|
71
77
|
show: true,
|
|
72
78
|
onSeeMore: () => ({}),
|
|
73
79
|
}}
|
|
80
|
+
inputValue=""
|
|
81
|
+
value=""
|
|
74
82
|
/>
|
|
75
83
|
);
|
|
76
84
|
const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
|
|
@@ -94,6 +102,8 @@ describe('CustomAutocomplete', () => {
|
|
|
94
102
|
show: true,
|
|
95
103
|
onClear: () => ({}),
|
|
96
104
|
}}
|
|
105
|
+
inputValue=""
|
|
106
|
+
value=""
|
|
97
107
|
/>
|
|
98
108
|
);
|
|
99
109
|
const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
|
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
* @description NsAutocomplete component.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React from 'react';
|
|
7
|
+
import React, { useState } from 'react';
|
|
8
8
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
9
9
|
|
|
10
10
|
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
11
11
|
import { NsAutocomplete } from './';
|
|
12
12
|
import { AutocompleteMockList } from './mock/MockData';
|
|
13
13
|
import { OptionUiComponent } from './mock/MockUI';
|
|
14
|
-
import { NsAutocompleteProps } from './types.d';
|
|
14
|
+
import { NsAutocompleteProps, OptionsProps } from './types.d';
|
|
15
15
|
import { NsIcon } from '../icon';
|
|
16
|
+
import { IconButton } from '@mui/material';
|
|
16
17
|
|
|
17
18
|
type ComponentType = typeof NsAutocomplete;
|
|
18
19
|
type Story = StoryObj<ComponentType>;
|
|
@@ -31,24 +32,61 @@ export default {
|
|
|
31
32
|
options: AutocompleteMockList,
|
|
32
33
|
seeMore: {
|
|
33
34
|
text: 'See More Results',
|
|
34
|
-
show:
|
|
35
|
+
show: true,
|
|
35
36
|
onSeeMore: () => {
|
|
36
37
|
throw new Error('Function not implemented.');
|
|
37
38
|
},
|
|
38
39
|
},
|
|
39
40
|
clear: {
|
|
40
41
|
text: 'Clear Recent Searches',
|
|
41
|
-
show:
|
|
42
|
+
show: true,
|
|
42
43
|
onClear: () => {
|
|
43
44
|
throw new Error('Function not implemented.');
|
|
44
45
|
},
|
|
45
46
|
},
|
|
46
47
|
iconStart: <NsIcon name="search" />,
|
|
47
|
-
iconEnd: <NsIcon name="close" size=
|
|
48
|
+
iconEnd: <NsIcon name="close" size="small" />,
|
|
48
49
|
placeholder: 'search',
|
|
49
50
|
},
|
|
50
51
|
} as MetaStory;
|
|
51
52
|
|
|
53
|
+
const RenderAutocomplete = (args: NsAutocompleteProps) => {
|
|
54
|
+
const [selectedOption, setSelectedOption] = useState<string | OptionsProps | null>(null);
|
|
55
|
+
const [searchTerms, setSearchTerms] = useState<string>('');
|
|
56
|
+
|
|
57
|
+
const onSelect = (value: string | OptionsProps | null) => {
|
|
58
|
+
setSelectedOption(value);
|
|
59
|
+
setSearchTerms((value = ''));
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const handleInputChange = (newValue: string) => {
|
|
63
|
+
setSearchTerms(newValue);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const onInputClear = () => {
|
|
67
|
+
setSelectedOption(null);
|
|
68
|
+
setSearchTerms('');
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<div>
|
|
73
|
+
<NsAutocomplete
|
|
74
|
+
{...args}
|
|
75
|
+
onChange={handleInputChange}
|
|
76
|
+
onSelect={onSelect}
|
|
77
|
+
renderOptions={OptionUiComponent}
|
|
78
|
+
iconEnd={
|
|
79
|
+
<IconButton onClick={onInputClear}>
|
|
80
|
+
<NsIcon name="close" size="small" />
|
|
81
|
+
</IconButton>
|
|
82
|
+
}
|
|
83
|
+
value={selectedOption}
|
|
84
|
+
inputValue={searchTerms}
|
|
85
|
+
/>
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
52
90
|
export const Autocomplete: Story = {
|
|
53
|
-
render:
|
|
91
|
+
render: RenderAutocomplete,
|
|
54
92
|
};
|