@nuskin/foundation-ui-components 1.0.0-develop.3 → 1.0.0-develop.5
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/NsAccordion.tsx +77 -0
- package/src/common/accordion/NsAccordionHeader.tsx +56 -0
- package/src/common/accordion/NsAccordionItem.tsx +39 -0
- package/src/common/accordion/NsCollapse.tsx +56 -0
- package/src/common/accordion/NsToggleSection.tsx +30 -0
- package/src/common/accordion/ToggleSection.styled.tsx +28 -0
- package/src/common/accordion/index.ts +6 -0
- package/src/common/accordion/specs/NsAccordion.spec.tsx +93 -0
- package/src/common/accordion/specs/NsAccordionHeader.spec.tsx +63 -0
- package/src/common/accordion/specs/NsAccordionItem.spec.tsx +62 -0
- package/src/common/accordion/specs/NsCollapse.spec.tsx +37 -0
- package/src/common/accordion/specs/NsToggleSection.spec.tsx +38 -0
- package/src/common/accordion/stories/NsAccordion.stories.tsx +47 -0
- package/src/common/accordion/stories/NsAccordionHeader.stories.tsx +40 -0
- package/src/common/accordion/stories/NsAccordionItem.stories.tsx +40 -0
- package/src/common/accordion/stories/NsCollapse.stories.tsx +35 -0
- package/src/common/accordion/stories/NsToggleSection.stories.tsx +23 -0
- package/src/common/accordion/stories/data.tsx +22 -0
- package/src/common/accordion/types.d.ts +73 -0
- 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/alert/types.d.ts +22 -22
- 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 +20 -8
- package/src/common/autocomplete/NsAutocomplete.stories.tsx +3 -0
- package/src/common/autocomplete/NsAutocomplete.styled.tsx +12 -0
- package/src/common/autocomplete/NsAutocomplete.tsx +36 -18
- package/src/common/autocomplete/types.d.ts +7 -1
- package/src/common/brand-components/NsBrandComponent.tsx +3 -0
- package/src/common/breadcrumb/NsBreadcrumb.tsx +4 -2
- package/src/common/button/NsButton.spec.tsx +11 -12
- 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/checkbox/NsCheckbox.styled.tsx +2 -2
- package/src/common/common.types.d.ts +2 -0
- package/src/common/dropdown/types.d.ts +3 -1
- package/src/common/email-simple/NsEmailSimple.spec.tsx +145 -0
- package/src/common/email-simple/NsEmailSimple.stories.tsx +61 -0
- package/src/common/email-simple/NsEmailSimple.tsx +71 -0
- package/src/common/email-simple/index.ts +2 -0
- package/src/common/email-simple/types.d.ts +14 -0
- package/src/common/flag/NsFlag.spec.tsx +4 -24
- package/src/common/flag/NsFlag.styled.tsx +5 -5
- package/src/common/flag/NsFlag.tsx +0 -2
- package/src/common/icon/types.d.ts +1 -0
- package/src/common/image/types.d.ts +1 -0
- package/src/common/index.ts +3 -0
- package/src/common/input/InputFieldWrapper.tsx +4 -4
- package/src/common/input/NsInputField.stories.tsx +11 -9
- package/src/common/input/NsInputField.tsx +12 -5
- package/src/common/input/getAdornmentProps.tsx +4 -0
- package/src/common/input/types.d.ts +3 -1
- package/src/common/label/NsLabel.stories.tsx +3 -0
- package/src/common/label/NsLabel.tsx +18 -17
- package/src/common/label/types.d.ts +2 -1
- package/src/common/nav-tab/NsNavTab.spec.tsx +0 -5
- package/src/common/nav-tab/NsNavTab.styled.tsx +7 -4
- package/src/common/radiogroup/NsRadioGroup.spec.tsx +64 -0
- package/src/common/radiogroup/NsRadioGroup.stories.tsx +102 -0
- package/src/common/radiogroup/NsRadioGroup.styled.tsx +50 -0
- package/src/common/radiogroup/NsRadioGroup.tsx +61 -0
- package/src/common/radiogroup/index.ts +2 -0
- package/src/common/radiogroup/types.d.ts +20 -0
- package/src/common/select/NsSelect.spec.tsx +200 -0
- package/src/common/select/NsSelect.styled.tsx +85 -0
- package/src/common/select/NsSelect.tsx +117 -0
- package/src/common/select/NsSelectOption.tsx +30 -0
- package/src/common/select/index.ts +3 -0
- package/src/common/select/stories/NsSelect.stories.tsx +134 -0
- package/src/common/select/types.d.ts +34 -0
- package/src/common/table/NsExpandableRow.tsx +68 -0
- package/src/common/table/NsTable.spec.tsx +69 -41
- package/src/common/table/NsTable.stories.tsx +45 -7
- package/src/common/table/NsTable.styled.ts +106 -12
- package/src/common/table/NsTable.tsx +78 -89
- package/src/common/table/NsTableHeader.tsx +52 -38
- package/src/common/table/NsTablePagination.tsx +21 -13
- package/src/common/table/types.d.ts +21 -8
- package/src/common/text-strip/NsTextStrip.tsx +10 -7
- package/src/common/typography/Typography.styled.tsx +3 -3
- package/src/common/validations/regex.ts +3 -0
- /package/src/common/card/{tests → specs}/BrandLogo.spec.tsx +0 -0
- /package/src/common/card/{tests → specs}/NsBgCard.spec.tsx +0 -0
- /package/src/common/card/{tests → specs}/NsBrandProductCard.spec.tsx +0 -0
- /package/src/common/card/{tests → specs}/NsFfgCard.spec.tsx +0 -0
- /package/src/common/carousal/{tests → specs}/Chevron.spec.tsx +0 -0
- /package/src/common/carousal/{tests → specs}/NsCarousal.spec.tsx +0 -0
- /package/src/common/carousal/{tests → specs}/NsScrollingCarousal.spec.tsx +0 -0
- /package/src/common/carousal/{tests → specs}/RenderBrand.spec.tsx +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
+
import NsAccordion from '../NsAccordion';
|
|
4
|
+
import { contentArray } from './data';
|
|
5
|
+
import { AccordionVariant } from '../types.d';
|
|
6
|
+
|
|
7
|
+
type ComponentType = typeof NsAccordion;
|
|
8
|
+
type Story = StoryObj<ComponentType>;
|
|
9
|
+
type MetaStory = Meta<ComponentType>;
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
title: 'Components/Accordion/NsAccordion',
|
|
13
|
+
component: NsAccordion,
|
|
14
|
+
decorators: [withCenterDecorator],
|
|
15
|
+
argTypes: {
|
|
16
|
+
allowMultipleExpanded: {
|
|
17
|
+
control: 'boolean',
|
|
18
|
+
description: `if true, then multiple sections can remain open at a same time, and if false,
|
|
19
|
+
opening a section will close other sections of the accordion`,
|
|
20
|
+
},
|
|
21
|
+
contentArray: {
|
|
22
|
+
description: ` this should be an array of objects, each object should have 3 properties,
|
|
23
|
+
title, body and isDefaultOpen`,
|
|
24
|
+
},
|
|
25
|
+
variant: {
|
|
26
|
+
control: 'select',
|
|
27
|
+
options: [...Object.values(AccordionVariant)],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
args: {
|
|
31
|
+
variant: AccordionVariant.Basic,
|
|
32
|
+
},
|
|
33
|
+
} as MetaStory;
|
|
34
|
+
|
|
35
|
+
export const SingleOpen: Story = {
|
|
36
|
+
args: {
|
|
37
|
+
allowMultipleExpanded: false,
|
|
38
|
+
contentArray,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const MultipleOpen: Story = {
|
|
43
|
+
args: {
|
|
44
|
+
allowMultipleExpanded: true,
|
|
45
|
+
contentArray,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
+
import { NsAccordionHeader, NsIconVariants } from '../..';
|
|
4
|
+
|
|
5
|
+
type ComponentType = typeof NsAccordionHeader;
|
|
6
|
+
type Story = StoryObj<ComponentType>;
|
|
7
|
+
type MetaStory = Meta<ComponentType>;
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: 'Components/Accordion/NsAccordionHeader',
|
|
11
|
+
component: NsAccordionHeader,
|
|
12
|
+
decorators: [withCenterDecorator],
|
|
13
|
+
argTypes: {
|
|
14
|
+
title: { control: 'string' },
|
|
15
|
+
openedIconName: {
|
|
16
|
+
control: 'select',
|
|
17
|
+
options: Object.keys(NsIconVariants),
|
|
18
|
+
},
|
|
19
|
+
closedIconName: {
|
|
20
|
+
control: 'select',
|
|
21
|
+
options: Object.keys(NsIconVariants),
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
args: {
|
|
25
|
+
title: 'Nuskin',
|
|
26
|
+
onClick: () => {
|
|
27
|
+
console.log('accordion header clicked');
|
|
28
|
+
},
|
|
29
|
+
openedIconName: 'arrowUp',
|
|
30
|
+
closedIconName: 'arrowDown',
|
|
31
|
+
isOpen: false,
|
|
32
|
+
},
|
|
33
|
+
} as MetaStory;
|
|
34
|
+
|
|
35
|
+
export const ClosedHeader: Story = {};
|
|
36
|
+
export const OpenedHeader: Story = {
|
|
37
|
+
args: {
|
|
38
|
+
isOpen: true,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
+
import { NsAccordionItem } from '@/common/index';
|
|
4
|
+
|
|
5
|
+
type ComponentType = typeof NsAccordionItem;
|
|
6
|
+
type Story = StoryObj<ComponentType>;
|
|
7
|
+
type MetaStory = Meta<ComponentType>;
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: 'Components/Accordion/NsAccordionItem',
|
|
11
|
+
component: NsAccordionItem,
|
|
12
|
+
decorators: [withCenterDecorator],
|
|
13
|
+
argTypes: {
|
|
14
|
+
isOpen: {
|
|
15
|
+
control: 'boolean',
|
|
16
|
+
description: 'if true renders NsAccordionItem in open state, and close state otherwise',
|
|
17
|
+
},
|
|
18
|
+
content: {},
|
|
19
|
+
title: {
|
|
20
|
+
control: 'string',
|
|
21
|
+
description: 'text used for header of section',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
} as MetaStory;
|
|
25
|
+
|
|
26
|
+
export const OpenSection: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
isOpen: true,
|
|
29
|
+
content: 'Nuskin Description',
|
|
30
|
+
title: 'Nuskin',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const ClosedSection: Story = {
|
|
35
|
+
args: {
|
|
36
|
+
isOpen: false,
|
|
37
|
+
content: 'Nuskin Description',
|
|
38
|
+
title: 'Nuskin',
|
|
39
|
+
},
|
|
40
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
+
import { NsCollapse } from '../';
|
|
4
|
+
|
|
5
|
+
type ComponentType = typeof NsCollapse;
|
|
6
|
+
type Story = StoryObj<ComponentType>;
|
|
7
|
+
type MetaStory = Meta<ComponentType>;
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: 'Components/Accordion/NsCollapse',
|
|
11
|
+
component: NsCollapse,
|
|
12
|
+
decorators: [withCenterDecorator],
|
|
13
|
+
argTypes: {
|
|
14
|
+
isOpen: {
|
|
15
|
+
control: 'boolean',
|
|
16
|
+
description: 'if true renders NsCollapse in open state, and close state otherwise',
|
|
17
|
+
},
|
|
18
|
+
children: {
|
|
19
|
+
control: 'React Node',
|
|
20
|
+
description: 'Content for NsCollapse',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
} as MetaStory;
|
|
24
|
+
export const Closed: Story = {
|
|
25
|
+
args: {
|
|
26
|
+
isOpen: false,
|
|
27
|
+
children: 'Nuskin Description',
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
export const Open: Story = {
|
|
31
|
+
args: {
|
|
32
|
+
isOpen: true,
|
|
33
|
+
children: 'Nuskin Description',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
+
import { NsToggleSection } from '../..';
|
|
4
|
+
|
|
5
|
+
type ComponentType = typeof NsToggleSection;
|
|
6
|
+
type Story = StoryObj<ComponentType>;
|
|
7
|
+
type MetaStory = Meta<ComponentType>;
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: 'Components/Accordion/NsToggleSection',
|
|
11
|
+
component: NsToggleSection,
|
|
12
|
+
decorators: [withCenterDecorator],
|
|
13
|
+
argTypes: {
|
|
14
|
+
title: { control: 'string' },
|
|
15
|
+
},
|
|
16
|
+
args: {
|
|
17
|
+
title: 'Nuskin',
|
|
18
|
+
children: 'Nuskin Details',
|
|
19
|
+
|
|
20
|
+
},
|
|
21
|
+
} as MetaStory;
|
|
22
|
+
|
|
23
|
+
export const DefaultAccordion: Story = {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NsAccordionProps } from '../types';
|
|
2
|
+
|
|
3
|
+
export const contentArray: NsAccordionProps['contentArray'] = [
|
|
4
|
+
{
|
|
5
|
+
title: 'Nuskin',
|
|
6
|
+
body: <div>Nuskin Details</div>,
|
|
7
|
+
isDefaultOpen: true,
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
title: 'Nuskin',
|
|
11
|
+
body: <div>Nuskin Details</div>,
|
|
12
|
+
isDefaultOpen: true,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
title: 'Nuskin',
|
|
16
|
+
body: <div>Nuskin Details</div>,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
title: 'Nuskin',
|
|
20
|
+
body: <div>Nuskin Details</div>,
|
|
21
|
+
},
|
|
22
|
+
];
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { PropsWithChildren, ReactNode } from 'react';
|
|
2
|
+
import { AdditionalProps } from '../common.types';
|
|
3
|
+
import { NsIconNameType } from '../icon';
|
|
4
|
+
import { Variants } from '../typography';
|
|
5
|
+
|
|
6
|
+
export type NsAccordionHeaderProps = AdditionalProps & {
|
|
7
|
+
title: string | ReactNode;
|
|
8
|
+
// eslint-disable-next-line no-unused-vars
|
|
9
|
+
onClick: (...args: any[]) => void;
|
|
10
|
+
/** a flag for the header, based on which header can change properties */
|
|
11
|
+
isOpen?: boolean;
|
|
12
|
+
/** NsIcon's icon name to be shown in opened state */
|
|
13
|
+
openedIconName?: NsIconNameType;
|
|
14
|
+
/** NsIcon's icon name to be shown in closed state */
|
|
15
|
+
closedIconName?: NsIconNameType;
|
|
16
|
+
variant: AccordionVariant;
|
|
17
|
+
headerTypographyVariant?: Variants;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type NsCollapseProps = AdditionalProps &
|
|
21
|
+
PropsWithChildren<{
|
|
22
|
+
isOpen: boolean;
|
|
23
|
+
variant: AccordionVariant;
|
|
24
|
+
}>;
|
|
25
|
+
|
|
26
|
+
export type NsFramerCollapseProps = NsCollapseProps & {
|
|
27
|
+
transitionDetails?: {
|
|
28
|
+
duration?: number;
|
|
29
|
+
ease?: number[];
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type NsToggleSectionProps = AdditionalProps &
|
|
34
|
+
PropsWithChildren<{
|
|
35
|
+
title: string | ReactNode;
|
|
36
|
+
/** if true, NsToggle is rendered in open state, that collapsible section is visible */
|
|
37
|
+
defaultOpen?: boolean;
|
|
38
|
+
variant: AccordionVariant;
|
|
39
|
+
}>;
|
|
40
|
+
|
|
41
|
+
export type NsAccordionItemProps = AdditionalProps & {
|
|
42
|
+
isOpen: boolean;
|
|
43
|
+
// eslint-disable-next-line no-unused-vars
|
|
44
|
+
toggleOpen(index: number, isOpen: boolean): void;
|
|
45
|
+
title: string | ReactNode;
|
|
46
|
+
content: ReactNode;
|
|
47
|
+
variant: AccordionVariant;
|
|
48
|
+
headerTypographyVariant?: Variants;
|
|
49
|
+
/** NsIcon's icon name to be shown in opened state */
|
|
50
|
+
openedIconName?: NsIconNameType;
|
|
51
|
+
/** NsIcon's icon name to be shown in closed state */
|
|
52
|
+
closedIconName?: NsIconNameType;
|
|
53
|
+
};
|
|
54
|
+
export type NsAccordionProps = AdditionalProps & {
|
|
55
|
+
allowMultipleExpanded: boolean;
|
|
56
|
+
contentArray: {
|
|
57
|
+
title: string | ReactNode;
|
|
58
|
+
body: ReactNode;
|
|
59
|
+
isDefaultOpen?: boolean;
|
|
60
|
+
}[];
|
|
61
|
+
variant: AccordionVariant;
|
|
62
|
+
headerTypographyVariant?: Variants;
|
|
63
|
+
/** NsIcon's icon name to be shown in opened state */
|
|
64
|
+
openedIconName?: NsIconNameType;
|
|
65
|
+
/** NsIcon's icon name to be shown in closed state */
|
|
66
|
+
closedIconName?: NsIconNameType;
|
|
67
|
+
};
|
|
68
|
+
export enum AccordionVariant {
|
|
69
|
+
// eslint-disable-next-line no-unused-vars
|
|
70
|
+
Basic = 'basic', // basic is as per figma
|
|
71
|
+
// eslint-disable-next-line no-unused-vars
|
|
72
|
+
Compact = 'compact', // compact is as per test.nuskin.com
|
|
73
|
+
}
|
|
@@ -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,15 +1,15 @@
|
|
|
1
1
|
import { ReactNode, CSSProperties } from 'react';
|
|
2
2
|
|
|
3
3
|
export interface NsAlertProps {
|
|
4
|
-
context?: string
|
|
5
|
-
title?: string
|
|
6
|
-
threshhold?: number,
|
|
7
|
-
type?: string
|
|
8
|
-
visible?: boolean
|
|
9
|
-
head?: ReactNode
|
|
10
|
-
body?: ReactNode
|
|
11
|
-
onDismiss?: () => void
|
|
12
|
-
foot?: ReactNode
|
|
4
|
+
context?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
threshhold?: number; // TODO: update to threshold, i.e. remove extra h
|
|
7
|
+
type?: string;
|
|
8
|
+
visible?: boolean;
|
|
9
|
+
head?: ReactNode;
|
|
10
|
+
body?: ReactNode;
|
|
11
|
+
onDismiss?: () => void;
|
|
12
|
+
foot?: ReactNode;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface HeaderProps {
|
|
@@ -18,28 +18,28 @@ export interface HeaderProps {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export type AlertContainerParams = {
|
|
21
|
-
visible: boolean
|
|
21
|
+
visible: boolean;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
export type ContextType = 'error' | 'info' | 'notice'| 'success' | 'warning';
|
|
24
|
+
export type ContextType = 'error' | 'info' | 'notice' | 'success' | 'warning';
|
|
25
25
|
export type AlertType = 'auto' | 'banner' | 'card';
|
|
26
26
|
|
|
27
27
|
export type AlertParams = {
|
|
28
|
-
context: ContextType
|
|
29
|
-
type: AlertType
|
|
30
|
-
}
|
|
28
|
+
context: ContextType;
|
|
29
|
+
type: AlertType;
|
|
30
|
+
};
|
|
31
31
|
|
|
32
32
|
export type CustomCSSProperties = CSSProperties & {
|
|
33
33
|
'min-height'?: string;
|
|
34
|
-
'content-column-start'
|
|
35
|
-
'content-column-end'
|
|
36
|
-
'bar-position'
|
|
37
|
-
'foot-visibility'
|
|
38
|
-
'foot-display'
|
|
34
|
+
'content-column-start'?: string;
|
|
35
|
+
'content-column-end'?: string;
|
|
36
|
+
'bar-position'?: string;
|
|
37
|
+
'foot-visibility'?: string;
|
|
38
|
+
'foot-display'?: string;
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export interface TypeMapCSS {
|
|
42
|
-
banner: CustomCSSProperties
|
|
43
|
-
card: CustomCSSProperties
|
|
44
|
-
auto?: CustomCSSProperties
|
|
42
|
+
banner: CustomCSSProperties;
|
|
43
|
+
card: CustomCSSProperties;
|
|
44
|
+
auto?: CustomCSSProperties;
|
|
45
45
|
}
|
|
@@ -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;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render, screen, waitFor } from '
|
|
2
|
+
import { render, screen, waitFor } from '@/test-utils/index';
|
|
3
3
|
import { NsAutocomplete } from '@/common/index';
|
|
4
4
|
import { OptionUiComponent } from './mock/MockUI';
|
|
5
5
|
import { AutocompleteMockList } from './mock/MockData';
|
|
6
6
|
import userEvent from '@testing-library/user-event';
|
|
7
|
+
import { act } from 'react-dom/test-utils';
|
|
7
8
|
|
|
8
9
|
describe('CustomAutocomplete', () => {
|
|
9
10
|
test('should render autocomplete component', () => {
|
|
@@ -29,11 +30,16 @@ describe('CustomAutocomplete', () => {
|
|
|
29
30
|
/>
|
|
30
31
|
);
|
|
31
32
|
const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const option1 = screen.getByText('GS Facial Gels 2pk Subscription');
|
|
35
|
-
expect(option1).toBeInTheDocument();
|
|
33
|
+
act(() => {
|
|
34
|
+
userEvent.type(autocompleteInput, 'GS Facial');
|
|
36
35
|
});
|
|
36
|
+
await waitFor(
|
|
37
|
+
() => {
|
|
38
|
+
const option1 = screen.getByText('GS Facial Gels 2pk Subscription');
|
|
39
|
+
expect(option1).toBeInTheDocument();
|
|
40
|
+
},
|
|
41
|
+
{ timeout: 5000 }
|
|
42
|
+
);
|
|
37
43
|
}, 40000);
|
|
38
44
|
|
|
39
45
|
test('selects an option when clicking on it', async () => {
|
|
@@ -45,7 +51,9 @@ describe('CustomAutocomplete', () => {
|
|
|
45
51
|
/>
|
|
46
52
|
);
|
|
47
53
|
const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
|
|
48
|
-
|
|
54
|
+
act(() => {
|
|
55
|
+
userEvent.type(autocompleteInput, 'GS Facial');
|
|
56
|
+
});
|
|
49
57
|
await waitFor(() => {
|
|
50
58
|
const optionLi = screen.getByText('GS Facial Spa');
|
|
51
59
|
userEvent.click(optionLi);
|
|
@@ -66,7 +74,9 @@ describe('CustomAutocomplete', () => {
|
|
|
66
74
|
/>
|
|
67
75
|
);
|
|
68
76
|
const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
|
|
69
|
-
|
|
77
|
+
act(() => {
|
|
78
|
+
userEvent.type(autocompleteInput, 'GS Facial');
|
|
79
|
+
});
|
|
70
80
|
await waitFor(() => {
|
|
71
81
|
const loadMoreButton = screen.getByTestId('autocomplete-loadmore-id');
|
|
72
82
|
userEvent.click(loadMoreButton);
|
|
@@ -87,7 +97,9 @@ describe('CustomAutocomplete', () => {
|
|
|
87
97
|
/>
|
|
88
98
|
);
|
|
89
99
|
const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
|
|
90
|
-
|
|
100
|
+
act(() => {
|
|
101
|
+
userEvent.type(autocompleteInput, 'GS Facial');
|
|
102
|
+
});
|
|
91
103
|
await waitFor(() => {
|
|
92
104
|
const clearButton = screen.getByTestId('autocomplete-clear-id');
|
|
93
105
|
userEvent.click(clearButton);
|
|
@@ -12,6 +12,7 @@ import { NsAutocomplete } from './';
|
|
|
12
12
|
import { AutocompleteMockList } from './mock/MockData';
|
|
13
13
|
import { OptionUiComponent } from './mock/MockUI';
|
|
14
14
|
import { NsAutocompleteProps } from './types.d';
|
|
15
|
+
import { NsIcon } from '../icon';
|
|
15
16
|
|
|
16
17
|
type ComponentType = typeof NsAutocomplete;
|
|
17
18
|
type Story = StoryObj<ComponentType>;
|
|
@@ -42,6 +43,8 @@ export default {
|
|
|
42
43
|
throw new Error('Function not implemented.');
|
|
43
44
|
},
|
|
44
45
|
},
|
|
46
|
+
iconStart: <NsIcon name="search" />,
|
|
47
|
+
iconEnd: <NsIcon name="close" size='small'/>,
|
|
45
48
|
placeholder: 'search',
|
|
46
49
|
},
|
|
47
50
|
} as MetaStory;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { styled } from '@nuskin/foundation-theme';
|
|
2
|
+
|
|
3
|
+
import { NsInputField } from '../input';
|
|
4
|
+
|
|
5
|
+
export const StyledTextField = styled(NsInputField)`
|
|
6
|
+
.MuiAutocomplete-inputRoot {
|
|
7
|
+
padding-right: 10px !important;
|
|
8
|
+
}
|
|
9
|
+
.muiautocomplete-popupindicator {
|
|
10
|
+
display: none;
|
|
11
|
+
}
|
|
12
|
+
`;
|