@nuskin/foundation-ui-components 1.0.0-develop.2 → 1.0.0-develop.4
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 +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 +91 -0
- package/src/common/accordion/specs/NsAccordionHeader.spec.tsx +47 -0
- package/src/common/accordion/specs/NsAccordionItem.spec.tsx +38 -0
- package/src/common/accordion/specs/NsCollapse.spec.tsx +37 -0
- package/src/common/accordion/specs/NsToggleSection.spec.tsx +33 -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.stories.tsx +15 -14
- package/src/common/alert/types.d.ts +22 -22
- package/src/common/auth-dropdown/NsAuthDropdown.stories.tsx +1 -1
- package/src/common/autocomplete/NsAutocomplete.spec.tsx +20 -8
- package/src/common/autocomplete/NsAutocomplete.stories.tsx +4 -1
- 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/banner/NsBanner.stories.tsx +1 -1
- package/src/common/brand-components/NsBrand.stories.tsx +1 -1
- package/src/common/breadcrumb/NsBreadcrumb.spec.tsx +1 -7
- package/src/common/breadcrumb/NsBreadcrumb.stories.tsx +2 -4
- package/src/common/breadcrumb/data.ts +7 -0
- package/src/common/button/NsButton.spec.tsx +10 -11
- package/src/common/button/NsButton.stories.tsx +1 -1
- package/src/common/card/stories/NsBgCard.stories.tsx +1 -3
- package/src/common/card/stories/NsBrandProductCard.stories.tsx +1 -1
- package/src/common/card/stories/NsFfgCard.stories.tsx +1 -1
- package/src/common/card/stories/{data.js → data.ts} +1 -25
- package/src/common/carousal/NsScrollingCarousal.tsx +26 -2
- package/src/common/carousal/stories/NsScrollingCarousal.stories.tsx +1 -1
- package/src/common/carousal/types.d.ts +2 -0
- package/src/common/cart-icon/NsCartIcon.stories.tsx +1 -1
- package/src/common/checkbox/NsCheckbox.stories.tsx +1 -1
- package/src/common/checkbox/NsCheckbox.styled.tsx +2 -2
- package/src/common/column-control/NsFlexColumns.tsx +5 -10
- package/src/common/column-control/NsGridColumns.tsx +5 -10
- package/src/common/column-control/specs/NsColumnControl.spec.tsx +1 -1
- package/src/common/column-control/specs/NsFlexColumns.spec.tsx +1 -1
- package/src/common/column-control/specs/NsGridColumns.spec.tsx +1 -1
- package/src/common/column-control/stories/DivArray.stories.tsx +18 -0
- package/src/common/column-control/stories/DivArray.tsx +63 -0
- package/src/common/column-control/stories/NsColumnControl.stories.tsx +6 -3
- package/src/common/column-control/stories/NsFlexColumns.stories.tsx +13 -9
- package/src/common/column-control/stories/NsGridColumns.stories.tsx +12 -8
- package/src/common/column-control/stories/common.tsx +1 -1
- package/src/common/column-control/styled/StyledFlex.tsx +7 -3
- package/src/common/column-control/styled/StyledGrid.tsx +9 -2
- package/src/common/column-control/styled/common.ts +2 -2
- package/src/common/column-control/types.d.ts +15 -16
- package/src/common/common.types.d.ts +1 -0
- package/src/common/dropdown/stories/NsDropdown.stories.tsx +1 -1
- package/src/common/dropdown/stories/NsDropdownCountry.stories.tsx +1 -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 -25
- package/src/common/flag/NsFlag.stories.tsx +1 -1
- package/src/common/flag/NsFlag.tsx +0 -2
- package/src/common/icon/NsIcon.stories.tsx +1 -1
- package/src/common/image/NsImage.stories.tsx +1 -1
- package/src/common/image/NsNextImage.stories.tsx +1 -1
- package/src/common/image/types.d.ts +1 -0
- package/src/common/index.ts +3 -0
- package/src/common/input/NsInputField.stories.tsx +13 -10
- package/src/common/input/NsInputField.tsx +12 -5
- package/src/common/input/getAdornmentProps.tsx +4 -0
- package/src/common/input/types.d.ts +18 -1
- package/src/common/label/NsLabel.stories.tsx +5 -0
- package/src/common/label/NsLabel.tsx +16 -19
- package/src/common/label/types.d.ts +2 -1
- package/src/common/link/NsLink.stories.tsx +1 -1
- package/src/common/nav-product-card/NsNavProductCard.stories.tsx +1 -1
- package/src/common/nav-tab/NsNavTab.spec.tsx +0 -5
- package/src/common/nav-tab/NsNavTab.stories.tsx +1 -1
- package/src/common/radiogroup/NsRadioGroup.spec.tsx +63 -0
- package/src/common/radiogroup/NsRadioGroup.stories.tsx +101 -0
- package/src/common/radiogroup/NsRadioGroup.styled.tsx +56 -0
- package/src/common/radiogroup/NsRadioGroup.tsx +46 -0
- package/src/common/radiogroup/index.ts +2 -0
- package/src/common/radiogroup/types.d.ts +19 -0
- package/src/common/select/NsSelect.spec.tsx +200 -0
- package/src/common/select/NsSelect.styled.tsx +89 -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 +48 -10
- package/src/common/table/NsTable.styled.ts +95 -4
- 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.stories.tsx +5 -4
- package/src/common/text-strip/NsTextStrip.tsx +5 -2
- package/src/common/text-strip/types.d.ts +7 -4
- package/src/common/typography/NsTypography.stories.tsx +1 -1
- package/src/common/validations/regex.ts +3 -0
- package/src/common/videos/NsVideo.stories.tsx +1 -1
- package/src/common/column-control/stories/NDivs.story.tsx +0 -35
- /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
|
@@ -8,28 +8,29 @@ const { palette } = nuskinTheme;
|
|
|
8
8
|
describe('<Button />', () => {
|
|
9
9
|
describe(' button primary', () => {
|
|
10
10
|
test('should render default button styles', () => {
|
|
11
|
+
const text = 'Click Me';
|
|
11
12
|
render(
|
|
12
13
|
<Button color="primary" variant="contained">
|
|
13
|
-
|
|
14
|
+
{text}
|
|
14
15
|
</Button>
|
|
15
16
|
);
|
|
16
17
|
|
|
17
|
-
const button = screen.getByText(
|
|
18
|
-
|
|
18
|
+
const button = screen.getByText(text);
|
|
19
19
|
expect(button).toBeInTheDocument();
|
|
20
|
-
expect(button).toHaveStyle(`color: ${palette
|
|
21
|
-
expect(button).toHaveStyle(`background-color: ${palette
|
|
20
|
+
expect(button).toHaveStyle(`color: ${palette?.primary?.contrastText ?? ''}`);
|
|
21
|
+
expect(button).toHaveStyle(`background-color: ${palette?.primary?.main ?? ''}`);
|
|
22
22
|
});
|
|
23
23
|
});
|
|
24
24
|
describe('button secondary', () => {
|
|
25
25
|
test('should render default button styles', () => {
|
|
26
|
+
const text = 'Click Me';
|
|
26
27
|
render(
|
|
27
28
|
<Button color="success" variant="contained" size="large">
|
|
28
|
-
|
|
29
|
+
{text}
|
|
29
30
|
</Button>
|
|
30
31
|
);
|
|
31
32
|
|
|
32
|
-
const button = screen.getByText(
|
|
33
|
+
const button = screen.getByText(text);
|
|
33
34
|
|
|
34
35
|
expect(button).toBeInTheDocument();
|
|
35
36
|
expect(button).toHaveStyle(`color: ${palette.success.contrastText}`);
|
|
@@ -37,7 +38,7 @@ describe('<Button />', () => {
|
|
|
37
38
|
});
|
|
38
39
|
});
|
|
39
40
|
describe('button outline success', () => {
|
|
40
|
-
test('should render outlined
|
|
41
|
+
test('should render outlined success button', () => {
|
|
41
42
|
render(
|
|
42
43
|
<Button color="success" variant="outlined" size="large">
|
|
43
44
|
Click Me
|
|
@@ -48,11 +49,10 @@ describe('<Button />', () => {
|
|
|
48
49
|
|
|
49
50
|
expect(button).toBeInTheDocument();
|
|
50
51
|
expect(button).toHaveStyle(`color: ${palette.success.main}`);
|
|
51
|
-
expect(button).toHaveStyle(`border-color: ${palette.success.main}`);
|
|
52
52
|
});
|
|
53
53
|
});
|
|
54
54
|
describe('button outline accentColorA', () => {
|
|
55
|
-
test('should render outlined
|
|
55
|
+
test('should render outlined success button', () => {
|
|
56
56
|
render(
|
|
57
57
|
<Button color="accentColorA" variant="outlined" size="large">
|
|
58
58
|
Click Me
|
|
@@ -63,7 +63,6 @@ describe('<Button />', () => {
|
|
|
63
63
|
|
|
64
64
|
expect(button).toBeInTheDocument();
|
|
65
65
|
expect(button).toHaveStyle(`color: ${palette?.accentColorA?.main}`);
|
|
66
|
-
expect(button).toHaveStyle(`border-color: ${palette?.accentColorA?.main}`);
|
|
67
66
|
});
|
|
68
67
|
});
|
|
69
68
|
});
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
3
3
|
import { NsButton } from './';
|
|
4
4
|
import { ShoppingCart } from '@mui/icons-material';
|
|
5
|
-
import { withCenterDecorator } from '
|
|
5
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
6
6
|
|
|
7
7
|
type ComponentType = typeof NsButton;
|
|
8
8
|
type Story = StoryObj<ComponentType>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
2
|
import { NsBgCard } from '../';
|
|
3
|
-
import { withCenterDecorator } from '
|
|
3
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
4
4
|
|
|
5
5
|
type ComponentType = typeof NsBgCard;
|
|
6
6
|
type Story = StoryObj<ComponentType>;
|
|
@@ -13,8 +13,6 @@ export default {
|
|
|
13
13
|
args: {
|
|
14
14
|
title: 'ageLOC LumiSpa',
|
|
15
15
|
backgroundImageUrl: 'https://media.nuskin.com/m/3604b5202b0b64c6/webimage-brand-lumispa-optweb.png',
|
|
16
|
-
// brandImageUrl:
|
|
17
|
-
// 'https://media.nuskin.com/m/2571a0407433a6e8/webimage-brand-lumispa.png',
|
|
18
16
|
},
|
|
19
17
|
decorators: [withCenterDecorator],
|
|
20
18
|
} as MetaStory;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
-
import { withCenterDecorator } from '
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
3
|
import { NsBrandProductCard } from '../';
|
|
4
4
|
|
|
5
5
|
type ComponentType = typeof NsBrandProductCard;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
2
|
import { within, userEvent } from '@storybook/testing-library';
|
|
3
3
|
import { expect } from '@storybook/jest';
|
|
4
|
-
import { withCenterDecorator } from '
|
|
4
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
5
5
|
import { NsFfgCard } from '../';
|
|
6
6
|
|
|
7
7
|
type ComponentType = typeof NsFfgCard;
|
|
@@ -8,14 +8,6 @@ export const brandImages = [
|
|
|
8
8
|
'https://media.nuskin.com/m/4bd7ab9b46bd456d/webimage-brand-pharmanex.png',
|
|
9
9
|
'https://media.nuskin.com/m/501d638a8af80087/webimage-brand-ap24.png',
|
|
10
10
|
'https://media.nuskin.com/m/f3a91129cbbae32/webimage-brand-nutricentials.png',
|
|
11
|
-
'https://media.nuskin.com/m/63a454ff90d038b4/webimage-brand-epoch.png',
|
|
12
|
-
'https://media.nuskin.com/m/3eb406f465d4b0fe/webimage-brand-sunright.png',
|
|
13
|
-
'https://media.nuskin.com/m/2d3276518912283b/webimage-brand-nu_colour.png',
|
|
14
|
-
'https://media.nuskin.com/m/3855d3836d920639/webimage-brand-nuskin180.png',
|
|
15
|
-
'https://media.nuskin.com/m/6245528b8f76ad32/webimage-brand-ageLOC.png',
|
|
16
|
-
'https://media.nuskin.com/m/2571a0407433a6e8/webimage-brand-lumispa.png',
|
|
17
|
-
'https://media.nuskin.com/m/4bd7ab9b46bd456d/webimage-brand-pharmanex.png',
|
|
18
|
-
'https://media.nuskin.com/m/501d638a8af80087/webimage-brand-ap24.png',
|
|
19
11
|
];
|
|
20
12
|
|
|
21
13
|
export const brandBackImages = [
|
|
@@ -28,34 +20,18 @@ export const brandBackImages = [
|
|
|
28
20
|
'https://media.nuskin.com/m/4a1245a63c595262/webimage-brand-pharmanex-optweb.png',
|
|
29
21
|
'https://media.nuskin.com/m/14a0fd6ef63e5dbb/webimage-brand-ap_24.png',
|
|
30
22
|
'https://media.nuskin.com/m/298104036e885b40/webimage-brand-nutricentials.png',
|
|
31
|
-
'https://media.nuskin.com/m/549aa3e5184434d8/webimage-brand-epoch-optweb.png',
|
|
32
|
-
'https://media.nuskin.com/m/14e238d7599e1811/webimage-brand-sunright.png',
|
|
33
|
-
'https://media.nuskin.com/m/2543e79419276727/webimage-brand-nu_colour-optweb.png',
|
|
34
|
-
'https://media.nuskin.com/m/446c7a2aad513f58/webimage-brand-nu_skin_180-optweb.png',
|
|
35
|
-
'https://media.nuskin.com/m/42911c8b05600476/webimage-brand-ageloc-optweb.png',
|
|
36
|
-
'https://media.nuskin.com/m/3604b5202b0b64c6/webimage-brand-lumispa-optweb.png',
|
|
37
|
-
'https://media.nuskin.com/m/4a1245a63c595262/webimage-brand-pharmanex-optweb.png',
|
|
38
|
-
'https://media.nuskin.com/m/14a0fd6ef63e5dbb/webimage-brand-ap_24.png',
|
|
39
23
|
];
|
|
40
24
|
|
|
41
25
|
export const brandTitles = [
|
|
42
26
|
'Epoch',
|
|
43
27
|
'Sunright',
|
|
44
|
-
'Nu
|
|
28
|
+
'Nu Color',
|
|
45
29
|
'180 System',
|
|
46
30
|
'ageLOC',
|
|
47
31
|
'ageLOC LumiSpa',
|
|
48
32
|
'Pharmanex',
|
|
49
33
|
'AP 24',
|
|
50
34
|
'Nutricentials',
|
|
51
|
-
'Epoch',
|
|
52
|
-
'Sunright',
|
|
53
|
-
'Nu Colour',
|
|
54
|
-
'180 System',
|
|
55
|
-
'ageLOC',
|
|
56
|
-
'ageLOC LumiSpa',
|
|
57
|
-
'Pharmanex',
|
|
58
|
-
'AP 24',
|
|
59
35
|
];
|
|
60
36
|
export const brandEntries = brandTitles.map((title, index) => {
|
|
61
37
|
return {
|
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import Slider from 'react-slick';
|
|
3
3
|
import { NsScrollingCarousalProps } from '../';
|
|
4
|
+
import { styled } from '@nuskin/foundation-theme';
|
|
5
|
+
|
|
6
|
+
const options = {
|
|
7
|
+
shouldForwardProp: (prop: string) => prop !== 'dotsBottomPixel',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const StyledDiv = styled(
|
|
11
|
+
'div',
|
|
12
|
+
options
|
|
13
|
+
)<{
|
|
14
|
+
dotsBottomPixel?: number;
|
|
15
|
+
}>(({ dotsBottomPixel }) => {
|
|
16
|
+
return {
|
|
17
|
+
'.slick-dots': {
|
|
18
|
+
zIndex: 9,
|
|
19
|
+
bottom: `${dotsBottomPixel ?? -25}px`,
|
|
20
|
+
opacity: '0.5',
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
});
|
|
4
24
|
|
|
5
25
|
const NsScrollingCarousal = ({
|
|
6
26
|
slides,
|
|
@@ -8,6 +28,7 @@ const NsScrollingCarousal = ({
|
|
|
8
28
|
stillSeconds,
|
|
9
29
|
renderSlide,
|
|
10
30
|
settings,
|
|
31
|
+
dotsBottomPixel,
|
|
11
32
|
additionalProps,
|
|
12
33
|
}: NsScrollingCarousalProps) => {
|
|
13
34
|
const defaultSettings = useMemo(() => {
|
|
@@ -28,9 +49,12 @@ const NsScrollingCarousal = ({
|
|
|
28
49
|
};
|
|
29
50
|
}, [stillSeconds, scrollSeconds, settings]);
|
|
30
51
|
return (
|
|
31
|
-
<
|
|
52
|
+
<StyledDiv
|
|
53
|
+
dotsBottomPixel={dotsBottomPixel}
|
|
54
|
+
data-testid={additionalProps?.testid ?? 'scrolling-carousal-test-id'}
|
|
55
|
+
>
|
|
32
56
|
<Slider {...defaultSettings}>{slides.map(renderSlide)}</Slider>
|
|
33
|
-
</
|
|
57
|
+
</StyledDiv>
|
|
34
58
|
);
|
|
35
59
|
};
|
|
36
60
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
7
|
-
import { withCenterDecorator } from '
|
|
7
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
8
8
|
import { NsScrollingCarousal, NsTextStrip } from '@/common/';
|
|
9
9
|
|
|
10
10
|
type ComponentType = typeof NsScrollingCarousal;
|
|
@@ -18,4 +18,6 @@ export type NsScrollingCarousalProps<T = any> = {
|
|
|
18
18
|
/* time for which slide stays still before scrolling */
|
|
19
19
|
stillSeconds: number;
|
|
20
20
|
settings: any;
|
|
21
|
+
/* value in number, specifying how much the dots should be from bottom of slides container */
|
|
22
|
+
dotsBottomPixel?: number;
|
|
21
23
|
} & AdditionalProps;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
-
import { withCenterDecorator } from '
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
3
|
import { NsCartIcon } from './';
|
|
4
4
|
|
|
5
5
|
type ComponentType = typeof NsCartIcon;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { within } from '@testing-library/react';
|
|
3
|
-
import { withCenterDecorator } from '
|
|
3
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
4
4
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
5
5
|
import { expect } from '@storybook/jest';
|
|
6
6
|
|
|
@@ -38,8 +38,8 @@ export const BpCheckedIcon = styled(BpIcon)(({ theme: { palette } }) => ({
|
|
|
38
38
|
path: {
|
|
39
39
|
display: 'block',
|
|
40
40
|
},
|
|
41
|
-
background: palette
|
|
42
|
-
color: palette
|
|
41
|
+
background: palette?.primary?.main ?? '#fff',
|
|
42
|
+
color: palette?.primary?.contrastText ?? '#000',
|
|
43
43
|
}));
|
|
44
44
|
|
|
45
45
|
export const StyledLabel = styled('span')<{ $hasDisabled: boolean }>`
|
|
@@ -1,23 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
2
|
import { getColumnSizes } from './utils';
|
|
3
3
|
import { StyledFlex } from './styled/StyledFlex';
|
|
4
|
-
import {
|
|
4
|
+
import { NsFlexColumnsProps } from './types';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
columnClass: string;
|
|
8
|
-
gap: number;
|
|
9
|
-
}> &
|
|
10
|
-
AdditionalProps;
|
|
11
|
-
|
|
12
|
-
const NsFlexColumns = ({ columnClass, children, gap, additionalProps }: NsFlexColumnsProps) => {
|
|
6
|
+
const NsFlexColumns = ({ columnClass, children, gap, additionalProps, isFullWidth }: NsFlexColumnsProps) => {
|
|
13
7
|
const sizes = useMemo(() => {
|
|
14
8
|
return getColumnSizes(columnClass ?? 'ns-col-lg-1-1');
|
|
15
9
|
}, [columnClass]);
|
|
16
10
|
return (
|
|
17
11
|
<StyledFlex
|
|
12
|
+
isFullWidth={isFullWidth || false}
|
|
18
13
|
gap={gap}
|
|
19
14
|
sizes={sizes}
|
|
20
|
-
className="
|
|
15
|
+
className="ns-flex-columns"
|
|
21
16
|
data-testid={additionalProps?.testid ?? 'ns-flex-columns'}
|
|
22
17
|
>
|
|
23
18
|
{children}
|
|
@@ -1,23 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
2
|
import { getColumnSizes } from './utils';
|
|
3
3
|
import { StyledGrid } from './styled/StyledGrid';
|
|
4
|
-
import {
|
|
4
|
+
import { NsGridColumnsProps } from './types';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
columnClass: string;
|
|
8
|
-
gap: number;
|
|
9
|
-
}> &
|
|
10
|
-
AdditionalProps;
|
|
11
|
-
|
|
12
|
-
const NsGridColumns = ({ columnClass, children, gap, additionalProps }: NsGridColumnsProps) => {
|
|
6
|
+
const NsGridColumns = ({ columnClass, children, gap, isFullWidth, additionalProps }: NsGridColumnsProps) => {
|
|
13
7
|
const sizes = useMemo(() => {
|
|
14
8
|
return getColumnSizes(columnClass ?? 'ns-col-lg-1-1');
|
|
15
9
|
}, [columnClass]);
|
|
16
10
|
return (
|
|
17
11
|
<StyledGrid
|
|
12
|
+
isFullWidth={isFullWidth || false}
|
|
18
13
|
gap={gap}
|
|
19
14
|
sizes={sizes}
|
|
20
|
-
className="
|
|
15
|
+
className="ns-grid-columns"
|
|
21
16
|
data-testid={additionalProps?.testid ?? 'ns-grid-columns'}
|
|
22
17
|
>
|
|
23
18
|
{children}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NsColumnControl } from '@/common/index';
|
|
2
|
-
import { DivArray } from '../stories/NDivs.story';
|
|
3
2
|
import { render, screen } from '@/test-utils/index';
|
|
3
|
+
import { DivArray } from '../stories/DivArray';
|
|
4
4
|
|
|
5
5
|
describe('NsColumnControl component', () => {
|
|
6
6
|
it('renders an column with proper grid value for tablet', () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { render, screen } from '../../../../test-utils';
|
|
2
2
|
import { NsFlexColumns } from '@/common/index';
|
|
3
|
-
import { DivArray } from '../stories/
|
|
3
|
+
import { DivArray } from '../stories/DivArray';
|
|
4
4
|
|
|
5
5
|
describe('NsFlexColumns component', () => {
|
|
6
6
|
it('renders an column with proper grid value for tablet', () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { render, screen } from '../../../../test-utils';
|
|
2
2
|
import { NsGridColumns } from '@/common/index';
|
|
3
|
-
import { DivArray } from '../stories/
|
|
3
|
+
import { DivArray } from '../stories/DivArray';
|
|
4
4
|
|
|
5
5
|
describe('NsGridColumns component', () => {
|
|
6
6
|
it('renders an column with proper grid value for tablet', () => {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
|
+
import {DivArray} from './DivArray';
|
|
4
|
+
|
|
5
|
+
type ComponentType = typeof DivArray;
|
|
6
|
+
type Story = StoryObj<ComponentType>;
|
|
7
|
+
type MetaStory = Meta<ComponentType>;
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: 'Components/Column/NDivs',
|
|
11
|
+
component: DivArray,
|
|
12
|
+
decorators: [withCenterDecorator],
|
|
13
|
+
args: {
|
|
14
|
+
elementsCount: 2,
|
|
15
|
+
},
|
|
16
|
+
} as MetaStory;
|
|
17
|
+
|
|
18
|
+
export const Basic: Story = {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
type DivArrayProps = {
|
|
4
|
+
elementsCount: number;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const getRandom = (n: number) => (Math.random() * n).toFixed(0);
|
|
8
|
+
|
|
9
|
+
type DivComponentProps = PropsWithChildren<{ style: Record<string, any>; index: number }>;
|
|
10
|
+
export const DivComponent = ({ style, index, children }: DivComponentProps) => {
|
|
11
|
+
const borderWidth = `${getRandom(5)}px`;
|
|
12
|
+
const padding = `${getRandom(20)}px`;
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
style={{
|
|
16
|
+
padding,
|
|
17
|
+
border: `${borderWidth} solid`,
|
|
18
|
+
borderColor: `hsl(${getRandom(359)},100%, 50%)`,
|
|
19
|
+
background: `hsla(${getRandom(359)},100%, 50%,0.3)`,
|
|
20
|
+
...style,
|
|
21
|
+
}}
|
|
22
|
+
>
|
|
23
|
+
{index}
|
|
24
|
+
{children}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* this component return a fragment containing n number of div, with each div numbered as per its index
|
|
30
|
+
* @param n: number of div to render
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
export const DivArray = ({ elementsCount }: DivArrayProps) => (
|
|
34
|
+
<>
|
|
35
|
+
{Array(elementsCount)
|
|
36
|
+
.fill(0)
|
|
37
|
+
.map((_, index) => (
|
|
38
|
+
<DivComponent key={index} index={index + 1} style={{}} />
|
|
39
|
+
))}
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
export const DivArrayRandom = ({ elementsCount }: DivArrayProps) => (
|
|
43
|
+
<>
|
|
44
|
+
{Array(elementsCount)
|
|
45
|
+
.fill(0)
|
|
46
|
+
.map((_, index) => {
|
|
47
|
+
const width = `${getRandom(700)}px`;
|
|
48
|
+
const height = `${getRandom(400)}px`;
|
|
49
|
+
return (
|
|
50
|
+
<DivComponent
|
|
51
|
+
key={index}
|
|
52
|
+
index={index + 1}
|
|
53
|
+
style={{
|
|
54
|
+
width,
|
|
55
|
+
height,
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
item no = {index + 1} with width = {width} and height = {height}
|
|
59
|
+
</DivComponent>
|
|
60
|
+
);
|
|
61
|
+
})}
|
|
62
|
+
</>
|
|
63
|
+
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
-
import { withCenterDecorator } from '
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
3
|
import { NsColumnControl } from '@/common/index';
|
|
4
|
-
import { DivArray } from './
|
|
4
|
+
import { DivArray } from './DivArray';
|
|
5
5
|
import { childrenMapping, selectDivOptions } from './common';
|
|
6
6
|
|
|
7
7
|
type ComponentType = typeof NsColumnControl;
|
|
@@ -32,7 +32,10 @@ export default {
|
|
|
32
32
|
},
|
|
33
33
|
} as MetaStory;
|
|
34
34
|
|
|
35
|
-
export const
|
|
35
|
+
export const ResponsiveColumnControl: Story = {};
|
|
36
|
+
export const SingleColumnControl: Story = {
|
|
37
|
+
args: { columnClass: '' },
|
|
38
|
+
};
|
|
36
39
|
export const TwoColumn11: Story = {
|
|
37
40
|
args: { columnClass: 'ns-col-lg-1-1' },
|
|
38
41
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
-
import { withCenterDecorator } from '
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
3
|
import { NsFlexColumns } from '..';
|
|
4
|
-
import { DivArray } from './
|
|
5
|
-
import {childrenMapping,
|
|
4
|
+
import { DivArray, DivArrayRandom } from './DivArray';
|
|
5
|
+
import { childrenMapping, selectDivOptions } from './common';
|
|
6
6
|
|
|
7
7
|
type ComponentType = typeof NsFlexColumns;
|
|
8
8
|
type Story = StoryObj<ComponentType>;
|
|
@@ -26,17 +26,21 @@ export default {
|
|
|
26
26
|
type: 'select',
|
|
27
27
|
options: selectDivOptions,
|
|
28
28
|
},
|
|
29
|
-
defaultValue: <
|
|
29
|
+
defaultValue: <DivArrayRandom elementsCount={8} />,
|
|
30
30
|
mapping: childrenMapping,
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
args: {
|
|
34
|
-
columnClass: '
|
|
35
|
-
children: <
|
|
34
|
+
columnClass: '',
|
|
35
|
+
children: <DivArrayRandom elementsCount={12} />,
|
|
36
36
|
},
|
|
37
37
|
} as MetaStory;
|
|
38
38
|
|
|
39
|
-
export const
|
|
39
|
+
export const DefaultColumnControl: Story = {
|
|
40
|
+
args: {
|
|
41
|
+
children: <DivArray elementsCount={8} />,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
40
44
|
export const TwoColumn11: Story = {
|
|
41
45
|
args: { columnClass: 'ns-col-lg-1-1' },
|
|
42
46
|
};
|
|
@@ -50,10 +54,10 @@ export const ThreeColumn211: Story = {
|
|
|
50
54
|
export const ThreeColumn121: Story = {
|
|
51
55
|
args: { columnClass: 'ns-col-lg-1-2-1' },
|
|
52
56
|
};
|
|
53
|
-
export const
|
|
57
|
+
export const ThreeColumn111: Story = {
|
|
54
58
|
args: { columnClass: 'ns-col-lg-1-1-1' },
|
|
55
59
|
};
|
|
56
60
|
|
|
57
|
-
export const
|
|
61
|
+
export const FourColumn1111: Story = {
|
|
58
62
|
args: { columnClass: 'ns-col-lg-1-1-1-1' },
|
|
59
63
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
-
import { withCenterDecorator } from '
|
|
2
|
+
import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
|
|
3
3
|
import { NsGridColumns } from '..';
|
|
4
|
-
import { DivArray } from './
|
|
4
|
+
import { DivArray, DivArrayRandom } from './DivArray';
|
|
5
5
|
import { childrenMapping, selectDivOptions } from './common';
|
|
6
6
|
|
|
7
7
|
type ComponentType = typeof NsGridColumns;
|
|
@@ -26,17 +26,21 @@ export default {
|
|
|
26
26
|
type: 'select',
|
|
27
27
|
options: selectDivOptions,
|
|
28
28
|
},
|
|
29
|
-
defaultValue: <
|
|
29
|
+
defaultValue: <DivArrayRandom elementsCount={8} />,
|
|
30
30
|
mapping: childrenMapping,
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
args: {
|
|
34
|
-
columnClass: '
|
|
35
|
-
children: <
|
|
34
|
+
columnClass: '',
|
|
35
|
+
children: <DivArrayRandom elementsCount={12} />,
|
|
36
36
|
},
|
|
37
37
|
} as MetaStory;
|
|
38
38
|
|
|
39
|
-
export const
|
|
39
|
+
export const DefaultColumnControl: Story = {
|
|
40
|
+
args: {
|
|
41
|
+
children: <DivArray elementsCount={8} />,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
40
44
|
export const TwoColumn11: Story = {
|
|
41
45
|
args: { columnClass: 'ns-col-lg-1-1' },
|
|
42
46
|
};
|
|
@@ -50,10 +54,10 @@ export const ThreeColumn211: Story = {
|
|
|
50
54
|
export const ThreeColumn121: Story = {
|
|
51
55
|
args: { columnClass: 'ns-col-lg-1-2-1' },
|
|
52
56
|
};
|
|
53
|
-
export const
|
|
57
|
+
export const ThreeColumn111: Story = {
|
|
54
58
|
args: { columnClass: 'ns-col-lg-1-1-1' },
|
|
55
59
|
};
|
|
56
60
|
|
|
57
|
-
export const
|
|
61
|
+
export const FourColumn1111: Story = {
|
|
58
62
|
args: { columnClass: 'ns-col-lg-1-1-1-1' },
|
|
59
63
|
};
|
|
@@ -4,31 +4,35 @@ import { sizeObjectType } from '../types';
|
|
|
4
4
|
import { commonStyles, getPercentArray } from './common';
|
|
5
5
|
|
|
6
6
|
const options = {
|
|
7
|
-
shouldForwardProp: (propKey: string) =>
|
|
7
|
+
shouldForwardProp: (propKey: string) => !['sizes', 'gap', 'isFullWidth'].includes(propKey),
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
type StyledFlexProps = {
|
|
11
11
|
sizes: sizeObjectType;
|
|
12
12
|
gap?: number;
|
|
13
|
+
isFullWidth: boolean;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
16
|
/* main wrapper for column control using css flex */
|
|
16
17
|
export const StyledFlex = styled(
|
|
17
18
|
Box as any,
|
|
18
19
|
options
|
|
19
|
-
)<StyledFlexProps>(({ sizes, gap }: StyledFlexProps) => {
|
|
20
|
+
)<StyledFlexProps>(({ sizes, gap, isFullWidth }: StyledFlexProps) => {
|
|
20
21
|
const gridGap = gap ? `${gap}px` : '2rem';
|
|
21
22
|
const fraction = getPercentArray(sizes.fractions);
|
|
22
23
|
const flexResponsive = { flexGrow: 1, flexShrink: 1 };
|
|
24
|
+
const maxWidth = isFullWidth ? '100%' : '1200px';
|
|
23
25
|
const style: any = {
|
|
24
26
|
gap: gridGap,
|
|
25
27
|
...commonStyles,
|
|
28
|
+
maxWidth,
|
|
26
29
|
display: 'flex',
|
|
27
30
|
paddingInline: '20px',
|
|
28
31
|
flexWrap: 'wrap',
|
|
29
32
|
justifyContent: 'center',
|
|
30
|
-
'
|
|
33
|
+
'> *': {
|
|
31
34
|
display: 'flex',
|
|
35
|
+
minWidth: '220px',
|
|
32
36
|
},
|
|
33
37
|
};
|
|
34
38
|
fraction.forEach((f, i) => {
|
|
@@ -6,26 +6,33 @@ import { commonStyles, getPercentArray } from './common';
|
|
|
6
6
|
type StyledGridProps = {
|
|
7
7
|
sizes: sizeObjectType;
|
|
8
8
|
gap?: number;
|
|
9
|
+
isFullWidth: boolean;
|
|
9
10
|
};
|
|
10
11
|
const options = {
|
|
11
|
-
shouldForwardProp: (propKey: string) =>
|
|
12
|
+
shouldForwardProp: (propKey: string) => !['sizes', 'gap', 'isFullWidth'].includes(propKey),
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
/* main wrapper for column control using css grid */
|
|
15
16
|
export const StyledGrid = styled(
|
|
16
17
|
Box as any,
|
|
17
18
|
options
|
|
18
|
-
)<StyledGridProps>(({ sizes, gap }: StyledGridProps) => {
|
|
19
|
+
)<StyledGridProps>(({ sizes, gap, isFullWidth }: StyledGridProps) => {
|
|
19
20
|
const gridGap = gap ?? '2rem';
|
|
21
|
+
const maxWidth = isFullWidth ? '100%' : '1200px';
|
|
20
22
|
return {
|
|
21
23
|
gap: gridGap,
|
|
22
24
|
...commonStyles,
|
|
25
|
+
maxWidth,
|
|
23
26
|
display: 'grid',
|
|
24
27
|
/* here we are creating gridTemplateColumns as calc(40% - 20px) calc(40% - 20px), */
|
|
25
28
|
gridTemplateColumns: getPercentArray(sizes.fractions)
|
|
26
29
|
?.map((fractionPercent) => `calc(${fractionPercent} - 20px)`)
|
|
27
30
|
.join(''),
|
|
28
31
|
justifyContent: 'center',
|
|
32
|
+
'> *': {
|
|
33
|
+
minWidth: '220px',
|
|
34
|
+
width: 'auto !important',
|
|
35
|
+
},
|
|
29
36
|
'.span-2': {
|
|
30
37
|
gridColumn: 'span 2',
|
|
31
38
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const mobileBreakPoint = '600px';
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
export const commonStyles = {
|
|
4
|
-
maxWidth: '1200px',
|
|
5
4
|
margin: '32px auto',
|
|
5
|
+
|
|
6
6
|
[`@media (max-width: ${mobileBreakPoint})`]: {
|
|
7
7
|
display: 'flex',
|
|
8
8
|
flexDirection: 'column',
|