@nuskin/foundation-ui-components 1.0.0-develop.8 → 1.0.0-develop.9
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 +1 -1
- package/src/common/accordion/NsAccordion.tsx +2 -0
- package/src/common/accordion/NsAccordionHeader.tsx +2 -1
- package/src/common/accordion/NsAccordionItem.tsx +8 -0
- package/src/common/accordion/NsCollapse.tsx +29 -11
- package/src/common/accordion/NsToggleSection.tsx +2 -0
- package/src/common/accordion/specs/NsAccordion.spec.tsx +1 -0
- package/src/common/accordion/specs/NsAccordionItem.spec.tsx +4 -0
- package/src/common/accordion/specs/NsCollapse.spec.tsx +23 -20
- package/src/common/accordion/specs/NsToggleSection.spec.tsx +4 -0
- package/src/common/accordion/stories/NsAccordionHeader.stories.tsx +2 -1
- package/src/common/accordion/stories/NsAccordionItem.stories.tsx +6 -1
- package/src/common/accordion/stories/NsCollapse.stories.tsx +17 -2
- package/src/common/accordion/stories/NsToggleSection.stories.tsx +5 -1
- package/src/common/accordion/stories/data.tsx +66 -83
- package/src/common/accordion/types.d.ts +13 -12
- package/src/common/card/NsFfgCard.tsx +13 -7
- package/src/common/card/specs/NsFfgCard.spec.tsx +18 -8
- package/src/common/card/stories/NsFfgCard.stories.tsx +47 -17
- package/src/common/card/styled/NsFfgStyled.tsx +9 -7
- package/src/common/card/types.d.ts +7 -4
- package/src/common/common.types.d.ts +3 -4
- package/src/common/nav-tab/types.d.ts +2 -2
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.9",
|
|
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",
|
|
@@ -44,6 +44,8 @@ const NsAccordion: FC<NsAccordionProps> = ({
|
|
|
44
44
|
const isOpen = itemStateMap[key] ?? false;
|
|
45
45
|
return (
|
|
46
46
|
<NsAccordionItem
|
|
47
|
+
allowMultipleExpanded={item.allowMultipleExpanded}
|
|
48
|
+
type={item.type}
|
|
47
49
|
closedIconName={closedIconName}
|
|
48
50
|
content={item.content}
|
|
49
51
|
headerTypographyVariant={headerTypographyVariant}
|
|
@@ -43,6 +43,7 @@ const NsAccordionHeader = ({
|
|
|
43
43
|
headerTypographyVariant,
|
|
44
44
|
startIcon,
|
|
45
45
|
invert,
|
|
46
|
+
cslp,
|
|
46
47
|
}: NsAccordionHeaderProps) => {
|
|
47
48
|
return (
|
|
48
49
|
<StyledHeader
|
|
@@ -55,7 +56,7 @@ const NsAccordionHeader = ({
|
|
|
55
56
|
>
|
|
56
57
|
<HeaderIcon {...startIcon} />
|
|
57
58
|
{typeof title === 'string' ? (
|
|
58
|
-
<NsTypography variant={headerTypographyVariant ?? 'h4'} weight="bold">
|
|
59
|
+
<NsTypography variant={headerTypographyVariant ?? 'h4'} weight="bold" {...(cslp?.header ?? {})}>
|
|
59
60
|
{title}
|
|
60
61
|
</NsTypography>
|
|
61
62
|
) : (
|
|
@@ -6,6 +6,7 @@ import { StyledToggleSection } from './ToggleSection.styled';
|
|
|
6
6
|
/**
|
|
7
7
|
* this component is used by accordion to pass title
|
|
8
8
|
* and content
|
|
9
|
+
* cslp:{header:CslpTag, content:CslpTag}
|
|
9
10
|
*/
|
|
10
11
|
const NsAccordionItem = ({
|
|
11
12
|
isOpen,
|
|
@@ -21,6 +22,9 @@ const NsAccordionItem = ({
|
|
|
21
22
|
level,
|
|
22
23
|
additionalProps,
|
|
23
24
|
invert,
|
|
25
|
+
type,
|
|
26
|
+
cslp,
|
|
27
|
+
allowMultipleExpanded,
|
|
24
28
|
}: NsAccordionItemProps) => {
|
|
25
29
|
return (
|
|
26
30
|
<StyledToggleSection variant={variant}>
|
|
@@ -35,14 +39,18 @@ const NsAccordionItem = ({
|
|
|
35
39
|
title={title}
|
|
36
40
|
variant={variant}
|
|
37
41
|
startIcon={startIcon}
|
|
42
|
+
cslp={cslp}
|
|
38
43
|
/>
|
|
39
44
|
<NsCollapse
|
|
45
|
+
type={type}
|
|
40
46
|
isChild={isChild}
|
|
41
47
|
isOpen={isOpen}
|
|
42
48
|
variant={variant}
|
|
43
49
|
level={level}
|
|
44
50
|
invert={invert}
|
|
45
51
|
content={content}
|
|
52
|
+
cslp={cslp}
|
|
53
|
+
allowMultipleExpanded={allowMultipleExpanded}
|
|
46
54
|
/>
|
|
47
55
|
</StyledToggleSection>
|
|
48
56
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { styled } from '@nuskin/foundation-theme';
|
|
2
|
-
import { AccordionVariant, AccordionVariantType, NsCollapseProps,
|
|
2
|
+
import { AccordionVariant, AccordionVariantType, NsCollapseProps, AccordionItem, NsAccordion } from '../';
|
|
3
3
|
import { getAccordionColor } from './colorMap';
|
|
4
4
|
import { ReactElement, isValidElement, useMemo } from 'react';
|
|
5
5
|
|
|
@@ -52,31 +52,49 @@ export const StyledCollapse = styled(
|
|
|
52
52
|
* NsCollapse component adds css animation while showing children items if prop `isOpen` is true,
|
|
53
53
|
* and while removing children if prop `isOpen` is false
|
|
54
54
|
*/
|
|
55
|
-
const NsCollapse = ({
|
|
55
|
+
const NsCollapse = ({
|
|
56
|
+
isOpen,
|
|
57
|
+
content,
|
|
58
|
+
additionalProps,
|
|
59
|
+
variant,
|
|
60
|
+
level,
|
|
61
|
+
invert,
|
|
62
|
+
isChild,
|
|
63
|
+
type,
|
|
64
|
+
cslp,
|
|
65
|
+
allowMultipleExpanded,
|
|
66
|
+
}: NsCollapseProps) => {
|
|
56
67
|
const body = useMemo(() => {
|
|
57
68
|
if (isValidElement(content)) {
|
|
58
69
|
return content as ReactElement;
|
|
59
70
|
}
|
|
60
|
-
|
|
61
|
-
if (contentVar?.type === 'html') {
|
|
71
|
+
if (type === 'html') {
|
|
62
72
|
return (
|
|
63
|
-
<div
|
|
73
|
+
<div
|
|
74
|
+
className="nsa-content-padded"
|
|
75
|
+
dangerouslySetInnerHTML={{ __html: content as string }}
|
|
76
|
+
{...(cslp?.content ?? {})}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
} else if (type === 'text') {
|
|
80
|
+
return (
|
|
81
|
+
<div className="p-4" {...(cslp?.content ?? {})}>
|
|
82
|
+
{content as string}
|
|
83
|
+
</div>
|
|
64
84
|
);
|
|
65
|
-
} else if (
|
|
66
|
-
return <div className="p-4">{contentVar?.data as string}</div>;
|
|
67
|
-
} else if (contentVar?.type === 'accordion') {
|
|
85
|
+
} else if (type === 'accordion') {
|
|
68
86
|
return (
|
|
69
87
|
<NsAccordion
|
|
70
88
|
isChild={true}
|
|
71
89
|
invert={invert}
|
|
72
90
|
level={level}
|
|
73
91
|
variant={AccordionVariant.Gray}
|
|
74
|
-
items={
|
|
75
|
-
allowMultipleExpanded={
|
|
92
|
+
items={content as AccordionItem[]}
|
|
93
|
+
allowMultipleExpanded={allowMultipleExpanded ?? false}
|
|
76
94
|
/>
|
|
77
95
|
);
|
|
78
96
|
}
|
|
79
|
-
}, [content, invert, level]);
|
|
97
|
+
}, [allowMultipleExpanded, content, cslp?.content, invert, level, type]);
|
|
80
98
|
return (
|
|
81
99
|
<StyledCollapse
|
|
82
100
|
isChild={isChild}
|
|
@@ -17,6 +17,7 @@ const NsToggleSection = ({
|
|
|
17
17
|
variant,
|
|
18
18
|
invert,
|
|
19
19
|
isChild,
|
|
20
|
+
type,
|
|
20
21
|
}: NsToggleSectionProps) => {
|
|
21
22
|
const [isExpanded, setIsExpanded] = useState(defaultOpen ?? false);
|
|
22
23
|
|
|
@@ -25,6 +26,7 @@ const NsToggleSection = ({
|
|
|
25
26
|
};
|
|
26
27
|
return (
|
|
27
28
|
<NsAccordionItem
|
|
29
|
+
type={type}
|
|
28
30
|
level={2}
|
|
29
31
|
variant={variant}
|
|
30
32
|
additionalProps={additionalProps}
|
|
@@ -9,6 +9,7 @@ describe('NsAccordionItem', () => {
|
|
|
9
9
|
it('1. renders title correctly', () => {
|
|
10
10
|
const { getByText } = render(
|
|
11
11
|
<NsAccordionItem
|
|
12
|
+
type="jsx"
|
|
12
13
|
variant={AccordionVariant.Basic}
|
|
13
14
|
isOpen={false}
|
|
14
15
|
toggleOpen={() => {}}
|
|
@@ -26,6 +27,7 @@ describe('NsAccordionItem', () => {
|
|
|
26
27
|
const toggleOpen = jest.fn();
|
|
27
28
|
const { getByText } = render(
|
|
28
29
|
<NsAccordionItem
|
|
30
|
+
type="jsx"
|
|
29
31
|
variant={AccordionVariant.Basic}
|
|
30
32
|
isOpen={false}
|
|
31
33
|
toggleOpen={toggleOpen}
|
|
@@ -47,6 +49,7 @@ describe('NsAccordionItem', () => {
|
|
|
47
49
|
isOpen={true}
|
|
48
50
|
toggleOpen={() => {}}
|
|
49
51
|
title={title}
|
|
52
|
+
type="jsx"
|
|
50
53
|
content={contentElement}
|
|
51
54
|
isChild={false}
|
|
52
55
|
invert={false}
|
|
@@ -59,6 +62,7 @@ describe('NsAccordionItem', () => {
|
|
|
59
62
|
it('4. when isOpen is false, renders jsx dom content within container with 0 height', () => {
|
|
60
63
|
const { queryByText } = render(
|
|
61
64
|
<NsAccordionItem
|
|
65
|
+
type="jsx"
|
|
62
66
|
variant={AccordionVariant.Basic}
|
|
63
67
|
isOpen={false}
|
|
64
68
|
toggleOpen={() => {}}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, screen } from '@/test-utils/index';
|
|
3
|
-
import { NsCollapse, AccordionVariant,
|
|
4
|
-
import { createAccordionItem3_1
|
|
3
|
+
import { NsCollapse, AccordionVariant, AccordionItem } from '@/common/index';
|
|
4
|
+
import { createAccordionItem3_1 } from '../stories/data';
|
|
5
5
|
|
|
6
6
|
describe('NsCollapse', () => {
|
|
7
7
|
it('1. renders children when isOpen is true', () => {
|
|
@@ -15,6 +15,7 @@ describe('NsCollapse', () => {
|
|
|
15
15
|
<div>Child 2</div>
|
|
16
16
|
</>
|
|
17
17
|
}
|
|
18
|
+
type="jsx"
|
|
18
19
|
isChild={false}
|
|
19
20
|
invert={false}
|
|
20
21
|
level={0}
|
|
@@ -24,11 +25,11 @@ describe('NsCollapse', () => {
|
|
|
24
25
|
expect(getByText('Child 2')).toBeInTheDocument();
|
|
25
26
|
});
|
|
26
27
|
it('2. renders children when isOpen is true and isChild is true', () => {
|
|
27
|
-
const
|
|
28
|
-
const content = { ...getTextContent(text) };
|
|
28
|
+
const content = 'renders children when isOpen is true and isChild is true';
|
|
29
29
|
const { getByText } = render(
|
|
30
30
|
<NsCollapse
|
|
31
31
|
isOpen
|
|
32
|
+
type="text"
|
|
32
33
|
variant={AccordionVariant.Basic}
|
|
33
34
|
content={content}
|
|
34
35
|
isChild={true}
|
|
@@ -36,60 +37,62 @@ describe('NsCollapse', () => {
|
|
|
36
37
|
level={0}
|
|
37
38
|
/>
|
|
38
39
|
);
|
|
39
|
-
expect(getByText(
|
|
40
|
+
expect(getByText(content)).toBeInTheDocument();
|
|
40
41
|
});
|
|
41
42
|
it('3. renders children when isOpen is true and variant is compact and content is of type accordion', () => {
|
|
43
|
+
const accItem = createAccordionItem3_1();
|
|
44
|
+
const content = accItem.content as AccordionItem[];
|
|
42
45
|
const { getByText } = render(
|
|
43
46
|
<NsCollapse
|
|
44
47
|
isOpen
|
|
45
48
|
variant={AccordionVariant.Compact}
|
|
46
|
-
content={
|
|
49
|
+
content={content}
|
|
50
|
+
type={accItem.type}
|
|
47
51
|
isChild={true}
|
|
48
52
|
invert={false}
|
|
49
53
|
level={0}
|
|
50
54
|
/>
|
|
51
55
|
);
|
|
52
|
-
expect(getByText(
|
|
53
|
-
expect(getByText(
|
|
56
|
+
expect(getByText(content[0].title)).toBeInTheDocument();
|
|
57
|
+
expect(getByText(content[1].title)).toBeInTheDocument();
|
|
54
58
|
});
|
|
55
59
|
|
|
56
60
|
it('4. does not render children when isOpen is false', () => {
|
|
61
|
+
const content = '<h2>Lorem ipsum dolor sit amet.</h2>';
|
|
57
62
|
render(
|
|
58
63
|
<NsCollapse
|
|
59
64
|
isOpen={false}
|
|
60
65
|
variant={AccordionVariant.Basic}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
data: '<h2>Lorem ipsum dolor sit amet.</h2>',
|
|
64
|
-
}}
|
|
66
|
+
type="html"
|
|
67
|
+
content={content}
|
|
65
68
|
isChild={false}
|
|
66
69
|
invert={true}
|
|
67
70
|
level={0}
|
|
68
71
|
/>
|
|
69
72
|
);
|
|
70
|
-
expect(screen.queryByText(
|
|
73
|
+
expect(screen.queryByText(content)).toBeNull();
|
|
71
74
|
});
|
|
72
75
|
it('5. renders html children when isOpen is true', () => {
|
|
76
|
+
const content = '<h2>Lorem ipsum dolor sit amet.</h2>';
|
|
73
77
|
render(
|
|
74
78
|
<NsCollapse
|
|
75
79
|
isOpen={true}
|
|
76
80
|
variant={AccordionVariant.Compact}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
data: '<h2>Lorem ipsum dolor sit amet.</h2>',
|
|
80
|
-
}}
|
|
81
|
+
type="html"
|
|
82
|
+
content={content}
|
|
81
83
|
isChild={false}
|
|
82
84
|
invert={true}
|
|
83
85
|
level={0}
|
|
84
86
|
/>
|
|
85
87
|
);
|
|
86
|
-
expect(screen.queryByText(
|
|
88
|
+
expect(screen.queryByText(content)).toBeDefined();
|
|
87
89
|
});
|
|
88
90
|
|
|
89
91
|
it('6. renders with additional class name', () => {
|
|
90
92
|
const additionalClassName = 'custom-class';
|
|
91
93
|
const { container } = render(
|
|
92
94
|
<NsCollapse
|
|
95
|
+
type="jsx"
|
|
93
96
|
isOpen
|
|
94
97
|
variant={AccordionVariant.Gray}
|
|
95
98
|
content={
|
|
@@ -107,11 +110,11 @@ describe('NsCollapse', () => {
|
|
|
107
110
|
expect(container.querySelector('section')).toHaveClass(`ns-collapse ${additionalClassName}`);
|
|
108
111
|
});
|
|
109
112
|
it('7. skipping allowMultipleExpanded in child data', () => {
|
|
110
|
-
const { content } = createAccordionItem3_1();
|
|
111
|
-
delete (content as ItemContent).allowMultipleExpanded;
|
|
113
|
+
const { content, type } = createAccordionItem3_1();
|
|
112
114
|
const additionalClassName = 'custom-class';
|
|
113
115
|
const { container } = render(
|
|
114
116
|
<NsCollapse
|
|
117
|
+
type={type}
|
|
115
118
|
isOpen
|
|
116
119
|
variant={AccordionVariant.Gray}
|
|
117
120
|
content={content}
|
|
@@ -16,6 +16,7 @@ describe('NsToggleSection', () => {
|
|
|
16
16
|
content={content}
|
|
17
17
|
invert={false}
|
|
18
18
|
isChild={false}
|
|
19
|
+
type="jsx"
|
|
19
20
|
/>
|
|
20
21
|
);
|
|
21
22
|
expect(getByText(title)).toBeInTheDocument();
|
|
@@ -28,6 +29,7 @@ describe('NsToggleSection', () => {
|
|
|
28
29
|
content={content}
|
|
29
30
|
invert={false}
|
|
30
31
|
isChild={false}
|
|
32
|
+
type="jsx"
|
|
31
33
|
/>
|
|
32
34
|
);
|
|
33
35
|
expect(getByText(title)).toBeInTheDocument();
|
|
@@ -41,6 +43,7 @@ describe('NsToggleSection', () => {
|
|
|
41
43
|
content={content}
|
|
42
44
|
invert={false}
|
|
43
45
|
isChild={false}
|
|
46
|
+
type="jsx"
|
|
44
47
|
/>
|
|
45
48
|
);
|
|
46
49
|
const el = queryByText(contentText);
|
|
@@ -62,6 +65,7 @@ describe('NsToggleSection', () => {
|
|
|
62
65
|
invert={false}
|
|
63
66
|
isChild={false}
|
|
64
67
|
defaultOpen
|
|
68
|
+
type="jsx"
|
|
65
69
|
/>
|
|
66
70
|
);
|
|
67
71
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
2
|
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
-
import { NsAccordionHeader, NsIconVariants } from '../..';
|
|
3
|
+
import { AccordionVariant, NsAccordionHeader, NsIconVariants } from '../..';
|
|
4
4
|
|
|
5
5
|
type ComponentType = typeof NsAccordionHeader;
|
|
6
6
|
type Story = StoryObj<ComponentType>;
|
|
@@ -23,6 +23,7 @@ export default {
|
|
|
23
23
|
},
|
|
24
24
|
args: {
|
|
25
25
|
title: 'Nuskin',
|
|
26
|
+
variant: AccordionVariant.Compact,
|
|
26
27
|
onClick: () => {
|
|
27
28
|
console.log('accordion header clicked');
|
|
28
29
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
2
|
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
-
import { NsAccordionItem } from '
|
|
3
|
+
import { AccordionVariant, NsAccordionItem } from '../../';
|
|
4
|
+
import NsAccordionStory from './NsAccordion.stories';
|
|
4
5
|
|
|
5
6
|
type ComponentType = typeof NsAccordionItem;
|
|
6
7
|
type Story = StoryObj<ComponentType>;
|
|
@@ -20,11 +21,14 @@ export default {
|
|
|
20
21
|
control: 'string',
|
|
21
22
|
description: 'text used for header of section',
|
|
22
23
|
},
|
|
24
|
+
level: NsAccordionStory.argTypes.level,
|
|
25
|
+
variant: NsAccordionStory.argTypes.variant,
|
|
23
26
|
},
|
|
24
27
|
} as MetaStory;
|
|
25
28
|
|
|
26
29
|
export const OpenSection: Story = {
|
|
27
30
|
args: {
|
|
31
|
+
variant: AccordionVariant.Compact,
|
|
28
32
|
isOpen: true,
|
|
29
33
|
content: <div className="p-2">Nuskin Description</div>,
|
|
30
34
|
title: 'Nuskin',
|
|
@@ -33,6 +37,7 @@ export const OpenSection: Story = {
|
|
|
33
37
|
|
|
34
38
|
export const ClosedSection: Story = {
|
|
35
39
|
args: {
|
|
40
|
+
variant: AccordionVariant.Compact,
|
|
36
41
|
isOpen: false,
|
|
37
42
|
content: <div className="p-2">Nuskin Description</div>,
|
|
38
43
|
title: 'Nuskin',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
2
|
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
-
import { NsCollapse } from '../';
|
|
3
|
+
import { AccordionVariant, NsCollapse } from '../';
|
|
4
|
+
import NsAccordionStory from './NsAccordion.stories';
|
|
4
5
|
|
|
5
6
|
type ComponentType = typeof NsCollapse;
|
|
6
7
|
type Story = StoryObj<ComponentType>;
|
|
@@ -15,10 +16,24 @@ export default {
|
|
|
15
16
|
control: 'boolean',
|
|
16
17
|
description: 'if true renders NsCollapse in open state, and close state otherwise',
|
|
17
18
|
},
|
|
18
|
-
|
|
19
|
+
content: {
|
|
19
20
|
control: 'React Node',
|
|
20
21
|
description: 'Content for NsCollapse',
|
|
21
22
|
},
|
|
23
|
+
allowMultipleExpanded: {
|
|
24
|
+
control: 'boolean',
|
|
25
|
+
description: 'This prop is useful when content is an array of accordion items',
|
|
26
|
+
},
|
|
27
|
+
type: {
|
|
28
|
+
control: 'select',
|
|
29
|
+
values: ['jsx', 'html', 'text', 'accordion'],
|
|
30
|
+
description: 'This type should exactly match the content type to have accordion work correctly',
|
|
31
|
+
},
|
|
32
|
+
level: NsAccordionStory.argTypes.level,
|
|
33
|
+
variant: NsAccordionStory.argTypes.variant,
|
|
34
|
+
},
|
|
35
|
+
args: {
|
|
36
|
+
variant: AccordionVariant.Compact,
|
|
22
37
|
},
|
|
23
38
|
} as MetaStory;
|
|
24
39
|
export const Closed: Story = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
2
|
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
-
import { NsToggleSection } from '../..';
|
|
3
|
+
import { AccordionVariant, NsToggleSection } from '../..';
|
|
4
|
+
import NsAccordionStory from './NsAccordion.stories';
|
|
4
5
|
|
|
5
6
|
type ComponentType = typeof NsToggleSection;
|
|
6
7
|
type Story = StoryObj<ComponentType>;
|
|
@@ -11,9 +12,12 @@ export default {
|
|
|
11
12
|
component: NsToggleSection,
|
|
12
13
|
decorators: [withCenterDecorator],
|
|
13
14
|
argTypes: {
|
|
15
|
+
level: NsAccordionStory.argTypes.level,
|
|
16
|
+
variant: NsAccordionStory.argTypes.variant,
|
|
14
17
|
title: { control: 'string' },
|
|
15
18
|
},
|
|
16
19
|
args: {
|
|
20
|
+
variant: AccordionVariant.Compact,
|
|
17
21
|
title: 'Nuskin',
|
|
18
22
|
content: <div className="p-2">Nuskin Details</div>,
|
|
19
23
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NsIconProps } from '../..';
|
|
2
|
-
import { AccordionItem
|
|
2
|
+
import { AccordionItem } from '../types';
|
|
3
3
|
|
|
4
4
|
const getItem = () => {
|
|
5
5
|
return {
|
|
@@ -14,8 +14,8 @@ const getIcon = (name = '', color = '') => {
|
|
|
14
14
|
};
|
|
15
15
|
export const getTextContent = (text = '') => {
|
|
16
16
|
return {
|
|
17
|
-
type: 'text' as
|
|
18
|
-
|
|
17
|
+
type: 'text' as AccordionItem['type'],
|
|
18
|
+
content: text || dummyText,
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
21
|
const getJsxContent = (text = '') => {
|
|
@@ -33,6 +33,7 @@ function createAccordionItem1(): AccordionItem {
|
|
|
33
33
|
icon: getIcon(),
|
|
34
34
|
title: 'Example - 1 JSX',
|
|
35
35
|
content: getJsxContent(),
|
|
36
|
+
type: 'jsx',
|
|
36
37
|
isDefaultOpen: true,
|
|
37
38
|
};
|
|
38
39
|
}
|
|
@@ -42,18 +43,17 @@ function createAccordionItem2(): AccordionItem {
|
|
|
42
43
|
isDefaultOpen: true,
|
|
43
44
|
icon: getIcon(),
|
|
44
45
|
title: 'Example - 2',
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
},
|
|
46
|
+
type: 'accordion',
|
|
47
|
+
content: [
|
|
48
|
+
{ ...getItem(), title: 'Example - 2.1', ...getTextContent() },
|
|
49
|
+
{
|
|
50
|
+
...getItem(),
|
|
51
|
+
icon: getIcon('hamburgerIcon', 'success'),
|
|
52
|
+
title: 'Example - 2.2',
|
|
53
|
+
type: 'jsx',
|
|
54
|
+
content: <div className="p-2">Example 2.2 Content</div>,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
function createAccordionItem3(): AccordionItem {
|
|
@@ -61,21 +61,17 @@ function createAccordionItem3(): AccordionItem {
|
|
|
61
61
|
...getItem(),
|
|
62
62
|
icon: getIcon('hamburgerIcon', 'success'),
|
|
63
63
|
title: 'Example - 3',
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
...getItem(),
|
|
64
|
+
type: 'accordion',
|
|
65
|
+
content: [
|
|
66
|
+
createAccordionItem3_1(),
|
|
67
|
+
{
|
|
68
|
+
...getItem(),
|
|
70
69
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
},
|
|
77
|
-
],
|
|
78
|
-
},
|
|
70
|
+
title: 'Example - 3.2',
|
|
71
|
+
type: 'text',
|
|
72
|
+
content: dummyText,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
79
75
|
};
|
|
80
76
|
}
|
|
81
77
|
|
|
@@ -83,28 +79,22 @@ export function createAccordionItem3_1(): AccordionItem {
|
|
|
83
79
|
return {
|
|
84
80
|
...getItem(),
|
|
85
81
|
title: 'Example - 3.1',
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
type: 'text',
|
|
103
|
-
data: dummyText,
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
],
|
|
107
|
-
},
|
|
82
|
+
allowMultipleExpanded: true,
|
|
83
|
+
type: 'accordion',
|
|
84
|
+
content: [
|
|
85
|
+
{
|
|
86
|
+
...getItem(),
|
|
87
|
+
title: 'Example - 3.1.1',
|
|
88
|
+
type: 'text',
|
|
89
|
+
content: dummyText,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
...getItem(),
|
|
93
|
+
title: 'Example - 3.1.2',
|
|
94
|
+
type: 'text',
|
|
95
|
+
content: dummyText,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
108
98
|
};
|
|
109
99
|
}
|
|
110
100
|
|
|
@@ -113,20 +103,16 @@ function createAccordionItem4(): AccordionItem {
|
|
|
113
103
|
...getItem(),
|
|
114
104
|
icon: getIcon(),
|
|
115
105
|
title: 'Example - 4',
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
],
|
|
129
|
-
},
|
|
106
|
+
type: 'accordion',
|
|
107
|
+
content: [
|
|
108
|
+
createAccordionItem4_1(),
|
|
109
|
+
{
|
|
110
|
+
...getItem(),
|
|
111
|
+
title: 'Example - 4.2',
|
|
112
|
+
type: 'html',
|
|
113
|
+
content: '<h2>Lorem ipsum dolor sit amet.</h2>',
|
|
114
|
+
},
|
|
115
|
+
],
|
|
130
116
|
};
|
|
131
117
|
}
|
|
132
118
|
|
|
@@ -134,25 +120,22 @@ function createAccordionItem4_1(): AccordionItem {
|
|
|
134
120
|
return {
|
|
135
121
|
...getItem(),
|
|
136
122
|
title: 'Example - 4.1',
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
...getItem(),
|
|
123
|
+
type: 'accordion',
|
|
124
|
+
content: [
|
|
125
|
+
{
|
|
126
|
+
...getItem(),
|
|
142
127
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
],
|
|
155
|
-
},
|
|
128
|
+
title: 'Example - 4.1.1',
|
|
129
|
+
type: 'text',
|
|
130
|
+
content: dummyText,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
...getItem(),
|
|
134
|
+
type: 'jsx',
|
|
135
|
+
content: <div className="p-3">Example 4.1.2. content</div>,
|
|
136
|
+
title: 'Example - 4.1.2',
|
|
137
|
+
},
|
|
138
|
+
],
|
|
156
139
|
};
|
|
157
140
|
}
|
|
158
141
|
export function getAccordionData(): AccordionItem[] {
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import {ReactElement, ReactNode} from 'react';
|
|
2
|
-
import {AdditionalProps} from '../common.types';
|
|
3
|
-
import {NsIconNameType, NsIconProps} from '../icon';
|
|
4
|
-
import {Variants} from '../typography';
|
|
5
|
-
import {AccordionVariantType} from './enums';
|
|
6
|
-
|
|
7
|
-
export interface ItemContent {
|
|
8
|
-
type: 'text' | 'html' | 'accordion' | 'jsx';
|
|
9
|
-
allowMultipleExpanded?: boolean;
|
|
10
|
-
data: string | AccordionItem[];
|
|
11
|
-
}
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
|
+
import { AdditionalProps } from '../common.types';
|
|
3
|
+
import { NsIconNameType, NsIconProps } from '../icon';
|
|
4
|
+
import { Variants } from '../typography';
|
|
5
|
+
import { AccordionVariantType } from './enums';
|
|
12
6
|
|
|
13
7
|
export type AccordionItem = {
|
|
8
|
+
allowMultipleExpanded?: boolean;
|
|
9
|
+
type: 'text' | 'html' | 'accordion' | 'jsx';
|
|
14
10
|
id: string;
|
|
15
|
-
content:
|
|
11
|
+
content: string | AccordionItem[] | ReactElement;
|
|
16
12
|
icon?: NsIconProps;
|
|
17
13
|
title: string;
|
|
18
14
|
isDefaultOpen?: boolean;
|
|
@@ -56,6 +52,8 @@ export type NsAccordionHeaderProps = AdditionalProps & {
|
|
|
56
52
|
export type NsCollapseProps = AdditionalProps & {
|
|
57
53
|
isOpen: boolean;
|
|
58
54
|
isChild: boolean;
|
|
55
|
+
allowMultipleExpanded?: boolean;
|
|
56
|
+
type: 'text' | 'html' | 'accordion' | 'jsx';
|
|
59
57
|
} & CommonAccordionType;
|
|
60
58
|
|
|
61
59
|
export type NsToggleSectionProps = AdditionalProps & {
|
|
@@ -63,6 +61,7 @@ export type NsToggleSectionProps = AdditionalProps & {
|
|
|
63
61
|
/** if true, NsToggle is rendered in open state, that collapsible section is visible */
|
|
64
62
|
defaultOpen?: boolean;
|
|
65
63
|
isChild: boolean;
|
|
64
|
+
type: 'text' | 'html' | 'accordion' | 'jsx';
|
|
66
65
|
} & Pick<CommonAccordionType, 'invert' | 'variant' | 'content'>;
|
|
67
66
|
|
|
68
67
|
export type NsAccordionItemProps = AdditionalProps & {
|
|
@@ -77,4 +76,6 @@ export type NsAccordionItemProps = AdditionalProps & {
|
|
|
77
76
|
closedIconName?: NsIconNameType;
|
|
78
77
|
startIcon?: NsIconProps;
|
|
79
78
|
isChild: boolean;
|
|
79
|
+
type: 'text' | 'html' | 'accordion' | 'jsx';
|
|
80
|
+
allowMultipleExpanded?: boolean;
|
|
80
81
|
} & CommonAccordionType;
|
|
@@ -2,15 +2,21 @@ import { NsNextImage, NsLink } from '../';
|
|
|
2
2
|
import { NsFfgStyled } from './styled/NsFfgStyled';
|
|
3
3
|
import { NsFfgCardProps } from './types.d';
|
|
4
4
|
|
|
5
|
-
const NsFfgCard = ({
|
|
5
|
+
const NsFfgCard = ({ cardLink, text, topImageUrl, topImageAlt, additionalProps, cslp, onClick }: NsFfgCardProps) => {
|
|
6
6
|
return (
|
|
7
|
-
<NsFfgStyled
|
|
8
|
-
|
|
7
|
+
<NsFfgStyled
|
|
8
|
+
data-testid={additionalProps?.testid}
|
|
9
|
+
onClick={onClick}
|
|
10
|
+
className={additionalProps?.className ?? ''}
|
|
11
|
+
>
|
|
12
|
+
<header className="top-image">
|
|
9
13
|
<NsNextImage height={192} width={288} alt={topImageAlt} src={topImageUrl} />
|
|
10
|
-
</
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
</header>
|
|
15
|
+
<article className="body-text" {...cslp?.card_text}>
|
|
16
|
+
{text}
|
|
17
|
+
</article>
|
|
18
|
+
<NsLink className="action-link" href={cardLink.href} additionalProps={cslp?.action_text}>
|
|
19
|
+
{cardLink.title || 'LEARN MORE'}
|
|
14
20
|
</NsLink>
|
|
15
21
|
</NsFfgStyled>
|
|
16
22
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
1
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
2
|
import NsFfgCard from '../NsFfgCard';
|
|
3
3
|
|
|
4
4
|
describe('NsFfgCard component', () => {
|
|
@@ -6,18 +6,28 @@ describe('NsFfgCard component', () => {
|
|
|
6
6
|
topImageUrl: 'https://media.nuskin.com/m/6245528b8f76ad32/webimage-brand-ageLOC.png',
|
|
7
7
|
topImageAlt: 'alt-text',
|
|
8
8
|
text: 'card text',
|
|
9
|
-
|
|
9
|
+
cardLink: { href: 'https://www.google.com', title: 'Test' },
|
|
10
|
+
onClick: jest.fn(),
|
|
10
11
|
};
|
|
11
|
-
it('renders with background image', () => {
|
|
12
|
+
it('1. renders with background image', () => {
|
|
12
13
|
render(<NsFfgCard {...props} additionalProps={{ testid: 'ffg-card' }} />);
|
|
13
14
|
const card = screen.getByTestId('ffg-card');
|
|
14
15
|
expect(card).toHaveStyle(`
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
background-color: #fff;
|
|
17
|
+
`);
|
|
17
18
|
});
|
|
18
|
-
it('renders with cover size', () => {
|
|
19
|
-
render(<NsFfgCard {...props} additionalProps={{ testid: 'ffg-card-1' }}
|
|
20
|
-
const card = screen.getByText(
|
|
19
|
+
it('2. renders with cover size', () => {
|
|
20
|
+
render(<NsFfgCard {...props} additionalProps={{ testid: 'ffg-card-1' }} />);
|
|
21
|
+
const card = screen.getByText(props.cardLink.title);
|
|
21
22
|
expect(card).toBeInTheDocument();
|
|
22
23
|
});
|
|
24
|
+
it('3. calls onclick', () => {
|
|
25
|
+
const handler = jest.fn();
|
|
26
|
+
const { getByTestId } = render(
|
|
27
|
+
<NsFfgCard {...props} onClick={handler} additionalProps={{ testid: 'ffg-card-1' }} />
|
|
28
|
+
);
|
|
29
|
+
const card = getByTestId('ffg-card-1');
|
|
30
|
+
fireEvent.click(card);
|
|
31
|
+
expect(handler).toHaveBeenCalled();
|
|
32
|
+
});
|
|
23
33
|
});
|
|
@@ -11,33 +11,63 @@ type MetaStory = Meta<ComponentType>;
|
|
|
11
11
|
export default {
|
|
12
12
|
component: NsFfgCard,
|
|
13
13
|
title: 'Components/Containers/Card/NsFfgCard',
|
|
14
|
-
argTypes: {
|
|
14
|
+
argTypes: {
|
|
15
|
+
onClick: {
|
|
16
|
+
action: 'clicked',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
15
19
|
decorators: [withCenterDecorator],
|
|
16
20
|
} as MetaStory;
|
|
17
21
|
|
|
22
|
+
const text = `Every child deserves a chance to shine. Through our Nu Skin Force for Good Foundation,
|
|
23
|
+
we’re empowering children around the world with hope for a brighter future.`;
|
|
24
|
+
const host = 'https://images.contentstack.io/v3/assets';
|
|
25
|
+
|
|
18
26
|
export const Default: Story = {
|
|
19
27
|
args: {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
cardLink: {
|
|
29
|
+
href: 'https://www.forceforgood.org/',
|
|
30
|
+
title: 'LEARN MORE',
|
|
31
|
+
},
|
|
32
|
+
text,
|
|
33
|
+
topImageUrl: `${host}/blt594f30e2dc643eae/blt34cdb300dc9b93ff/645ccaa7520ba1a1af13a08a/nsffg-foundation.webp`,
|
|
34
|
+
topImageAlt: 'Force for Good Foundation',
|
|
35
|
+
additionalProps: {
|
|
36
|
+
testid: 'ffg-card',
|
|
37
|
+
},
|
|
38
|
+
onClick: () => {
|
|
39
|
+
console.log('onClick called');
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
play: async ({ canvasElement }: any) => {
|
|
43
|
+
const canvas = within(canvasElement);
|
|
44
|
+
userEvent.hover(canvas.getByTestId('ffg-card'));
|
|
45
|
+
userEvent.hover(canvas.getByRole('link'));
|
|
46
|
+
expect(canvas.getByText(text)).toBeInTheDocument();
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
const d = { count: -1 };
|
|
50
|
+
export const OnClick: Story = {
|
|
51
|
+
args: {
|
|
52
|
+
cardLink: {
|
|
53
|
+
href: 'https://www.forceforgood.org/',
|
|
54
|
+
title: 'LEARN MORE',
|
|
55
|
+
},
|
|
56
|
+
text,
|
|
57
|
+
topImageUrl: `${host}/blt594f30e2dc643eae/blt34cdb300dc9b93ff/645ccaa7520ba1a1af13a08a/nsffg-foundation.webp`,
|
|
27
58
|
topImageAlt: 'Force for Good Foundation',
|
|
28
59
|
additionalProps: {
|
|
29
60
|
testid: 'ffg-card',
|
|
30
61
|
},
|
|
62
|
+
onClick: () => {
|
|
63
|
+
d.count = 1;
|
|
64
|
+
console.log('on click called');
|
|
65
|
+
},
|
|
31
66
|
},
|
|
32
|
-
play: async ({ canvasElement }) => {
|
|
67
|
+
play: async ({ canvasElement }: any) => {
|
|
68
|
+
d.count = 0;
|
|
33
69
|
const canvas = within(canvasElement);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
expect(
|
|
37
|
-
canvas.getByText(
|
|
38
|
-
// eslint-disable-next-line max-len
|
|
39
|
-
'Every child deserves a chance to shine. Through our Nu Skin Force for Good Foundation, we’re empowering children around the world with hope for a brighter future.'
|
|
40
|
-
)
|
|
41
|
-
).toBeInTheDocument();
|
|
70
|
+
userEvent.click(canvas.getByTestId('ffg-card'));
|
|
71
|
+
expect(d.count).toEqual(1);
|
|
42
72
|
},
|
|
43
73
|
};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Box } from '@mui/material';
|
|
2
2
|
import { styled } from '@nuskin/foundation-theme';
|
|
3
3
|
|
|
4
|
-
const options = {};
|
|
5
|
-
|
|
6
4
|
const Component = () => {
|
|
7
5
|
return {
|
|
8
6
|
backgroundClip: 'border-box',
|
|
@@ -10,9 +8,10 @@ const Component = () => {
|
|
|
10
8
|
border: '1px solid #eff2f7',
|
|
11
9
|
borderRadius: '1rem',
|
|
12
10
|
boxShadow: '0 0.75rem 1.5rem rgba(18, 38, 63, .03)',
|
|
11
|
+
cursor: 'pointer',
|
|
13
12
|
display: 'flex',
|
|
14
13
|
flexDirection: 'column' as 'column', // https://github.com/cssinjs/jss/issues/1344
|
|
15
|
-
marginBottom: '
|
|
14
|
+
marginBottom: '16px',
|
|
16
15
|
transition: 'all .2s ease',
|
|
17
16
|
textAlign: 'center' as 'center',
|
|
18
17
|
wordWrap: 'break-word' as 'break-word',
|
|
@@ -25,12 +24,15 @@ const Component = () => {
|
|
|
25
24
|
},
|
|
26
25
|
},
|
|
27
26
|
'.body-text': {
|
|
28
|
-
padding: '0 1.5rem
|
|
29
|
-
fontSize: '
|
|
27
|
+
padding: '0 1.5rem 4rem',
|
|
28
|
+
fontSize: '16px',
|
|
30
29
|
color: '#8492a6',
|
|
31
30
|
},
|
|
32
31
|
'.top-image': {
|
|
33
|
-
padding: '1.5rem
|
|
32
|
+
padding: '3rem 1.5rem',
|
|
33
|
+
img: {
|
|
34
|
+
maxWidth: '100%',
|
|
35
|
+
},
|
|
34
36
|
},
|
|
35
37
|
'.action-link': {
|
|
36
38
|
color: '#3c4858',
|
|
@@ -41,4 +43,4 @@ const Component = () => {
|
|
|
41
43
|
},
|
|
42
44
|
};
|
|
43
45
|
};
|
|
44
|
-
export const NsFfgStyled = styled(Box
|
|
46
|
+
export const NsFfgStyled = styled(Box)(Component);
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { AdditionalProps } from '../common.types';
|
|
2
|
-
|
|
1
|
+
import { AdditionalProps, CslpTag } from '../common.types';
|
|
3
2
|
export type NsFfgCardProps = AdditionalProps & {
|
|
4
3
|
topImageUrl: string;
|
|
5
4
|
topImageAlt: string;
|
|
6
5
|
text: string;
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
cardLink: { href: string; title: string };
|
|
7
|
+
onClick(): void;
|
|
8
|
+
cslp?: {
|
|
9
|
+
card_text: CslpTag;
|
|
10
|
+
action_text: CslpTag;
|
|
11
|
+
};
|
|
9
12
|
};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { FoundationTheme } from '@nuskin/foundation-theme';
|
|
2
2
|
|
|
3
|
-
export type
|
|
4
|
-
'data-cslp'?: string;
|
|
5
|
-
};
|
|
3
|
+
export type CslpTag = { 'data-cslp': string };
|
|
6
4
|
|
|
7
5
|
export type AdditionalProps = {
|
|
8
6
|
additionalProps?: {
|
|
@@ -10,7 +8,8 @@ export type AdditionalProps = {
|
|
|
10
8
|
testid?: string;
|
|
11
9
|
className?: string;
|
|
12
10
|
'data-testid'?: string;
|
|
13
|
-
} &
|
|
11
|
+
} & Partial<CslpTag>;
|
|
12
|
+
cslp?: Record<string, CslpTag>;
|
|
14
13
|
} & DarkModeEnabledOption;
|
|
15
14
|
|
|
16
15
|
export type Themed = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { FoundationTheme } from '@nuskin/foundation-theme';
|
|
3
3
|
import { Variants } from '../typography/types';
|
|
4
|
-
import { AdditionalProps,
|
|
4
|
+
import { AdditionalProps, CslpTag } from '../common.types';
|
|
5
5
|
|
|
6
6
|
export type NavTabs = {
|
|
7
7
|
tabName: string;
|
|
@@ -9,7 +9,7 @@ export type NavTabs = {
|
|
|
9
9
|
activeColor: FoundationTheme.PaletteColors;
|
|
10
10
|
color?: FoundationTheme.PaletteColors;
|
|
11
11
|
textVariant: Variants;
|
|
12
|
-
liveTag?:
|
|
12
|
+
liveTag?: CslpTag;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export type NSNavTabComponentProps = {
|