@nuskin/foundation-ui-components 1.0.0-develop.1 → 1.0.0-develop.2

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.
Files changed (117) hide show
  1. package/package.json +1 -1
  2. package/src/common/alert/NsAlert.spec.tsx +17 -16
  3. package/src/common/alert/NsAlert.styled.ts +20 -20
  4. package/src/common/alert/NsAlert.tsx +21 -40
  5. package/src/common/alert/index.ts +2 -2
  6. package/src/common/auth-dropdown/NsAuthDropdown.spec.tsx +1 -1
  7. package/src/common/auth-dropdown/NsAuthDropdown.tsx +1 -1
  8. package/src/common/auth-dropdown/index.ts +1 -1
  9. package/src/common/autocomplete/NsAutocomplete.spec.tsx +5 -5
  10. package/src/common/autocomplete/NsAutocomplete.stories.tsx +1 -1
  11. package/src/common/autocomplete/NsAutocomplete.tsx +1 -1
  12. package/src/common/autocomplete/index.ts +2 -1
  13. package/src/common/banner/NsBanner.spec.tsx +1 -1
  14. package/src/common/banner/NsBanner.styled.tsx +1 -1
  15. package/src/common/banner/NsBanner.tsx +1 -1
  16. package/src/common/banner/index.ts +1 -1
  17. package/src/common/brand-components/NsBrandComponent.tsx +1 -1
  18. package/src/common/brand-components/index.ts +1 -1
  19. package/src/common/breadcrumb/NsBreadcrumb.spec.tsx +1 -1
  20. package/src/common/breadcrumb/NsBreadcrumb.tsx +1 -1
  21. package/src/common/breadcrumb/index.ts +1 -1
  22. package/src/common/button/NsButton.spec.tsx +1 -1
  23. package/src/common/button/NsButton.styled.tsx +10 -13
  24. package/src/common/button/NsButton.tsx +1 -1
  25. package/src/common/button/index.ts +1 -1
  26. package/src/common/card/NsFfgCard.tsx +1 -1
  27. package/src/common/carousal/NsScrollingCarousal.tsx +37 -0
  28. package/src/common/carousal/index.ts +3 -0
  29. package/src/common/carousal/stories/NSCarousal.stories.tsx +1 -1
  30. package/src/common/carousal/stories/NsScrollingCarousal.stories.tsx +52 -0
  31. package/src/common/carousal/tests/NsCarousal.spec.tsx +2 -2
  32. package/src/common/carousal/tests/NsScrollingCarousal.spec.tsx +61 -0
  33. package/src/common/carousal/types.d.ts +21 -0
  34. package/src/common/cart-icon/NsCartIcon.spec.tsx +1 -1
  35. package/src/common/cart-icon/NsCartIcon.tsx +1 -1
  36. package/src/common/cart-icon/index.ts +1 -1
  37. package/src/common/checkbox/NsCheckbox.spec.tsx +2 -2
  38. package/src/common/checkbox/NsCheckbox.tsx +1 -1
  39. package/src/common/checkbox/index.ts +1 -1
  40. package/src/common/checkbox/types.d.ts +1 -7
  41. package/src/common/column-control/NsColumnControl.tsx +1 -1
  42. package/src/common/column-control/NsFlexColumns.tsx +27 -0
  43. package/src/common/column-control/NsGridColumns.tsx +27 -0
  44. package/src/common/column-control/index.ts +3 -1
  45. package/src/common/column-control/{NsColumnControl.spec.tsx → specs/NsColumnControl.spec.tsx} +3 -3
  46. package/src/common/column-control/specs/NsFlexColumns.spec.tsx +24 -0
  47. package/src/common/column-control/specs/NsGridColumns.spec.tsx +24 -0
  48. package/src/common/column-control/{NDivs.story.tsx → stories/NDivs.story.tsx} +1 -1
  49. package/src/common/column-control/{NsColumnControl.stories.tsx → stories/NsColumnControl.stories.tsx} +4 -14
  50. package/src/common/column-control/stories/NsFlexColumns.stories.tsx +59 -0
  51. package/src/common/column-control/stories/NsGridColumns.stories.tsx +59 -0
  52. package/src/common/column-control/stories/common.tsx +14 -0
  53. package/src/common/column-control/styled/StyledFlex.tsx +41 -0
  54. package/src/common/column-control/styled/StyledGrid.tsx +33 -0
  55. package/src/common/column-control/styled/common.ts +27 -0
  56. package/src/common/column-control/utils.ts +1 -1
  57. package/src/common/dropdown/NsDropdown.spec.tsx +1 -1
  58. package/src/common/dropdown/NsDropdown.tsx +1 -1
  59. package/src/common/dropdown/NsDropdownOption.tsx +1 -1
  60. package/src/common/dropdown/index.ts +1 -1
  61. package/src/common/flag/NsFlag.spec.tsx +1 -1
  62. package/src/common/flag/NsFlag.styled.tsx +3 -5
  63. package/src/common/flag/NsFlag.tsx +1 -1
  64. package/src/common/flag/index.ts +1 -1
  65. package/src/common/flag/types.d.ts +0 -2
  66. package/src/common/icon/NsIcon.spec.tsx +1 -1
  67. package/src/common/icon/NsIcon.styled.tsx +1 -1
  68. package/src/common/icon/NsIcon.tsx +1 -1
  69. package/src/common/icon/NsIconVariants.ts +8 -4
  70. package/src/common/icon/icons/AlertErrorIcon.tsx +15 -6
  71. package/src/common/icon/icons/HamburgerIcon.tsx +29 -0
  72. package/src/common/icon/icons/UserIcon.tsx +30 -0
  73. package/src/common/icon/icons/WarningIcon.tsx +14 -5
  74. package/src/common/icon/index.ts +1 -1
  75. package/src/common/image/NsImage.spec.tsx +1 -1
  76. package/src/common/image/NsImage.tsx +1 -1
  77. package/src/common/image/NsNextImage.spec.tsx +1 -1
  78. package/src/common/image/NsNextImage.tsx +1 -1
  79. package/src/common/image/index.ts +1 -1
  80. package/src/common/index.ts +7 -10
  81. package/src/common/input/InputWrapper.tsx +1 -1
  82. package/src/common/input/NsInputField.tsx +1 -1
  83. package/src/common/input/getAdornmentProps.tsx +1 -1
  84. package/src/common/input/index.ts +1 -1
  85. package/src/common/label/NsLabel.tsx +1 -1
  86. package/src/common/label/index.ts +1 -1
  87. package/src/common/link/NsLink.spec.tsx +1 -1
  88. package/src/common/link/NsLink.tsx +1 -1
  89. package/src/common/link/index.ts +1 -1
  90. package/src/common/nav-product-card/NsNavProductCard.spec.tsx +1 -1
  91. package/src/common/nav-product-card/NsNavProductCard.tsx +1 -1
  92. package/src/common/nav-product-card/index.ts +1 -1
  93. package/src/common/nav-tab/NsNavTab.spec.tsx +2 -2
  94. package/src/common/nav-tab/NsNavTab.tsx +1 -1
  95. package/src/common/nav-tab/index.ts +1 -1
  96. package/src/common/search-bar/NsSeachBar.spec.tsx +1 -1
  97. package/src/common/table/NsTable.spec.tsx +146 -0
  98. package/src/common/table/NsTable.stories.tsx +123 -0
  99. package/src/common/table/NsTable.styled.ts +33 -0
  100. package/src/common/table/NsTable.tsx +161 -0
  101. package/src/common/table/NsTableHeader.tsx +48 -0
  102. package/src/common/table/NsTablePagination.tsx +20 -0
  103. package/src/common/table/helper.ts +33 -0
  104. package/src/common/table/index.ts +2 -0
  105. package/src/common/table/types.d.ts +44 -0
  106. package/src/common/text-strip/NsTextStrip.spec.tsx +30 -0
  107. package/src/common/text-strip/NsTextStrip.stories.tsx +32 -0
  108. package/src/common/text-strip/NsTextStrip.tsx +41 -0
  109. package/src/common/text-strip/index.ts +2 -0
  110. package/src/common/text-strip/types.d.ts +14 -0
  111. package/src/common/typography/NsTypography.tsx +1 -1
  112. package/src/common/typography/Typography.styled.tsx +1 -1
  113. package/src/common/typography/index.ts +1 -1
  114. package/src/common/videos/NsVideo.tsx +1 -1
  115. package/src/common/videos/index.ts +1 -1
  116. /package/src/common/autocomplete/{types.ts → types.d.ts} +0 -0
  117. /package/src/common/{common.types.ts → common.types.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
- import { render, screen, fireEvent } from '../../../../test-utils';
2
- import NsCarousal from '../NsCarousal';
1
+ import { render, screen, fireEvent } from '@/test-utils/index';
2
+ import { NsCarousal } from '@/common/';
3
3
 
4
4
  const mockEntries = [
5
5
  { id: 1, title: 'First entry' },
@@ -0,0 +1,61 @@
1
+ import { render, screen, fireEvent } from '@/test-utils/index';
2
+ import { NsScrollingCarousal } from '@/common/';
3
+
4
+ const mockEntries = [
5
+ { id: 1, title: 'First entry' },
6
+ { id: 2, title: 'Second entry' },
7
+ { id: 3, title: 'Third entry' },
8
+ { id: 4, title: 'Fourth entry' },
9
+ { id: 5, title: 'Fifth entry' },
10
+ ];
11
+
12
+ const mockRenderEntry = (entry: any, index: number) => {
13
+ return <div key={index}>{entry.title}</div>;
14
+ };
15
+ const mockSettings = {
16
+ slidesToShow: 2,
17
+ slidesToScroll: 1,
18
+ };
19
+ const testId = 'scrolling-carousal';
20
+ describe('NsScrollingCarousal', () => {
21
+ it('should have slides', () => {
22
+ render(
23
+ <NsScrollingCarousal
24
+ slides={mockEntries}
25
+ renderSlide={mockRenderEntry}
26
+ settings={mockSettings}
27
+ scrollSeconds={1}
28
+ stillSeconds={9}
29
+ additionalProps={{
30
+ testid: testId,
31
+ }}
32
+ />
33
+ );
34
+ const el = screen.getAllByText(mockEntries[0].title);
35
+ expect(el).toHaveLength(2);
36
+ });
37
+
38
+ it('should change slides when clicking on prev or next buttons', () => {
39
+ const { container } = render(
40
+ <NsScrollingCarousal
41
+ slides={mockEntries}
42
+ renderSlide={mockRenderEntry}
43
+ settings={mockSettings}
44
+ scrollSeconds={1}
45
+ stillSeconds={9}
46
+ />
47
+ );
48
+
49
+ let currentSlide = container.querySelector('.slick-slide.slick-current');
50
+ expect(currentSlide!.attributes['data-index' as any].value).toEqual('0');
51
+
52
+ /* this is library's button, not our button, it is used for changing slides,
53
+ clicking svg is not making any slide change in this test */
54
+ const nextButton = screen.getByRole('button', { name: /next/i });
55
+ fireEvent.click(nextButton);
56
+
57
+ let slickTrack = container.querySelector('.slick-track');
58
+ currentSlide = slickTrack!.querySelector('.slick-slide.slick-current');
59
+ expect(currentSlide!.attributes['data-index' as any].value).toEqual('1');
60
+ });
61
+ });
@@ -0,0 +1,21 @@
1
+ import { ReactNode } from 'react';
2
+ import { AdditionalProps } from '../common.types';
3
+
4
+ export type NsCarousalProps<T = any> = {
5
+ entries: T[];
6
+ // eslint-disable-next-line no-unused-vars
7
+ renderEntry(entry: T, index: number): ReactNode;
8
+ allEntryLink: string;
9
+ settings: any;
10
+ };
11
+
12
+ export type NsScrollingCarousalProps<T = any> = {
13
+ slides: T;
14
+ // eslint-disable-next-line no-unused-vars
15
+ renderSlide(slide: T, index: number): ReactNode;
16
+ /* time it takes while scrolling */
17
+ scrollSeconds: number;
18
+ /* time for which slide stays still before scrolling */
19
+ stillSeconds: number;
20
+ settings: any;
21
+ } & AdditionalProps;
@@ -1,5 +1,5 @@
1
1
  import { NsCartIcon } from './';
2
- import { render, screen } from '../../../test-utils';
2
+ import { render, screen } from '@/test-utils/index';
3
3
 
4
4
  const { getByTestId } = screen;
5
5
  describe('NsCartIcon', () => {
@@ -1,6 +1,6 @@
1
1
  import { NsIcon } from '../icon';
2
2
  import { CartIconContainer, ItemCount } from './NsCartIcon.styled';
3
- import { NsCartIconProps } from './types';
3
+ import { NsCartIconProps } from './types.d';
4
4
 
5
5
  const NsCartIcon = ({ itemCount, size = 'large', color = 'primary' }: NsCartIconProps) => {
6
6
  return (
@@ -1,2 +1,2 @@
1
1
  export { default as NsCartIcon } from './NsCartIcon';
2
- export type { NsCartIconProps } from './types';
2
+ export type { NsCartIconProps } from './types.d';
@@ -6,7 +6,7 @@
6
6
 
7
7
  import React from 'react';
8
8
 
9
- import { render, fireEvent, noop } from '../../../test-utils';
9
+ import { render, fireEvent, noop } from '@/test-utils/index';
10
10
  import NsCheckbox from './NsCheckbox';
11
11
 
12
12
  // Test suite for CustomCheckbox
@@ -54,4 +54,4 @@ describe('CustomCheckbox', () => {
54
54
  // Assert that the handleChange function has been called
55
55
  expect(handleChange).toHaveBeenCalled();
56
56
  });
57
- });
57
+ });
@@ -9,7 +9,7 @@ import FormControlLabel from '@mui/material/FormControlLabel';
9
9
  import { default as MUICheckbox } from '@mui/material/Checkbox';
10
10
 
11
11
  import { BpCheckedIcon, BpIcon, StyledLabel, StyledFlagLabel } from './NsCheckbox.styled';
12
- import { NsCheckboxProps } from './types';
12
+ import { NsCheckboxProps } from './types.d';
13
13
 
14
14
  import { NsTypography } from '../';
15
15
 
@@ -1,2 +1,2 @@
1
1
  export { default as NsCheckbox } from './NsCheckbox';
2
- export type { NsCheckboxProps } from './types';
2
+ export type { NsCheckboxProps } from './types.d';
@@ -1,15 +1,9 @@
1
- /**
2
- * @author [vijayaprathap Kumar] (vpkumar@nuskin.com)
3
- * types.d.ts
4
- * @description NsCheckbox Props extending Mui CheckboxProps interface.
5
- */
6
-
7
1
  import { CheckboxProps as MUICheckboxProps } from '@material-ui/core/Checkbox';
8
2
 
9
3
  import { NsFlagProps } from '../flag';
10
4
 
11
5
  // Define the props for the custom checkbox component
12
- export type NsCheckboxProps = Pick<MUICheckboxProps, 'label' | 'onChange'> & {
6
+ export type NsCheckboxProps = Partial<Pick<MUICheckboxProps, 'label' | 'onChange'>> & {
13
7
  name: string;
14
8
  className?: string;
15
9
  checked: boolean;
@@ -1,7 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
  import { Box } from '@mui/material';
3
3
  import { styled } from '@nuskin/foundation-theme';
4
- import { NsColumnControlProps, sizeObjectType } from './types';
4
+ import { NsColumnControlProps, sizeObjectType } from './types.d';
5
5
  import { getColumnSizes } from './utils';
6
6
 
7
7
  const options = {
@@ -0,0 +1,27 @@
1
+ import { PropsWithChildren, useMemo } from 'react';
2
+ import { getColumnSizes } from './utils';
3
+ import { StyledFlex } from './styled/StyledFlex';
4
+ import { AdditionalProps } from '../common.types';
5
+
6
+ type NsFlexColumnsProps = PropsWithChildren<{
7
+ columnClass: string;
8
+ gap: number;
9
+ }> &
10
+ AdditionalProps;
11
+
12
+ const NsFlexColumns = ({ columnClass, children, gap, additionalProps }: NsFlexColumnsProps) => {
13
+ const sizes = useMemo(() => {
14
+ return getColumnSizes(columnClass ?? 'ns-col-lg-1-1');
15
+ }, [columnClass]);
16
+ return (
17
+ <StyledFlex
18
+ gap={gap}
19
+ sizes={sizes}
20
+ className="styled-flex"
21
+ data-testid={additionalProps?.testid ?? 'ns-flex-columns'}
22
+ >
23
+ {children}
24
+ </StyledFlex>
25
+ );
26
+ };
27
+ export default NsFlexColumns;
@@ -0,0 +1,27 @@
1
+ import { PropsWithChildren, useMemo } from 'react';
2
+ import { getColumnSizes } from './utils';
3
+ import { StyledGrid } from './styled/StyledGrid';
4
+ import { AdditionalProps } from '../common.types';
5
+
6
+ type NsGridColumnsProps = PropsWithChildren<{
7
+ columnClass: string;
8
+ gap: number;
9
+ }> &
10
+ AdditionalProps;
11
+
12
+ const NsGridColumns = ({ columnClass, children, gap, additionalProps }: NsGridColumnsProps) => {
13
+ const sizes = useMemo(() => {
14
+ return getColumnSizes(columnClass ?? 'ns-col-lg-1-1');
15
+ }, [columnClass]);
16
+ return (
17
+ <StyledGrid
18
+ gap={gap}
19
+ sizes={sizes}
20
+ className="styled-grid"
21
+ data-testid={additionalProps?.testid ?? 'ns-grid-columns'}
22
+ >
23
+ {children}
24
+ </StyledGrid>
25
+ );
26
+ };
27
+ export default NsGridColumns;
@@ -1,2 +1,4 @@
1
1
  export { default as NsColumnControl } from './NsColumnControl';
2
- export type { NsColumnControlProps } from './types';
2
+ export { default as NsFlexColumns } from './NsFlexColumns';
3
+ export { default as NsGridColumns } from './NsGridColumns';
4
+ export type { NsColumnControlProps } from './types.d';
@@ -1,6 +1,6 @@
1
- import { render, screen } from '../../../test-utils';
2
- import { NsColumnControl } from './';
3
- import { DivArray } from './NDivs.story';
1
+ import { NsColumnControl } from '@/common/index';
2
+ import { DivArray } from '../stories/NDivs.story';
3
+ import { render, screen } from '@/test-utils/index';
4
4
 
5
5
  describe('NsColumnControl component', () => {
6
6
  it('renders an column with proper grid value for tablet', () => {
@@ -0,0 +1,24 @@
1
+ import { render, screen } from '../../../../test-utils';
2
+ import { NsFlexColumns } from '@/common/index';
3
+ import { DivArray } from '../stories/NDivs.story';
4
+
5
+ describe('NsFlexColumns component', () => {
6
+ it('renders an column with proper grid value for tablet', () => {
7
+ render(
8
+ <NsFlexColumns columnClass="ns-col-lg-1-1-1" gap={16}>
9
+ <DivArray elementsCount={4} />
10
+ </NsFlexColumns>
11
+ );
12
+ const element = screen.getByTestId('ns-flex-columns');
13
+ expect(element).toBeInTheDocument();
14
+ });
15
+ it('renders an column with proper grid value', () => {
16
+ console.warn = jest.fn();
17
+ render(
18
+ <NsFlexColumns columnClass="" gap={16}>
19
+ <DivArray elementsCount={4} />
20
+ </NsFlexColumns>
21
+ );
22
+ expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('Received invalid className'));
23
+ });
24
+ });
@@ -0,0 +1,24 @@
1
+ import { render, screen } from '../../../../test-utils';
2
+ import { NsGridColumns } from '@/common/index';
3
+ import { DivArray } from '../stories/NDivs.story';
4
+
5
+ describe('NsGridColumns component', () => {
6
+ it('renders an column with proper grid value for tablet', () => {
7
+ render(
8
+ <NsGridColumns columnClass="ns-col-lg-1-1-1" gap={16}>
9
+ <DivArray elementsCount={4} />
10
+ </NsGridColumns>
11
+ );
12
+ const element = screen.getByTestId('ns-grid-columns');
13
+ expect(element).toBeInTheDocument();
14
+ });
15
+ it('renders an column with proper grid value', () => {
16
+ console.warn = jest.fn();
17
+ render(
18
+ <NsGridColumns columnClass="" gap={16}>
19
+ <DivArray elementsCount={4} />
20
+ </NsGridColumns>
21
+ );
22
+ expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('Received invalid className'));
23
+ });
24
+ });
@@ -1,5 +1,5 @@
1
1
  import type { StoryObj, Meta } from '@storybook/react';
2
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
2
+ import { withCenterDecorator } from '../../../stories/decorators/withCenterDecorator';
3
3
 
4
4
  type DivArrayProps = {
5
5
  elementsCount: number;
@@ -1,25 +1,15 @@
1
1
  import type { StoryObj, Meta } from '@storybook/react';
2
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
3
- import { NsColumnControl } from '.';
2
+ import { withCenterDecorator } from '../../../stories/decorators/withCenterDecorator';
3
+ import { NsColumnControl } from '@/common/index';
4
4
  import { DivArray } from './NDivs.story';
5
+ import { childrenMapping, selectDivOptions } from './common';
5
6
 
6
7
  type ComponentType = typeof NsColumnControl;
7
8
  type Story = StoryObj<ComponentType>;
8
9
  type MetaStory = Meta<ComponentType>;
9
10
 
10
- /* an array from 1 to n */
11
- const selectDivOptions = Array(16)
12
- .fill(0)
13
- .map((e, i) => i + 1);
14
- const childrenMapping = selectDivOptions.reduce((a, c) => {
15
- return {
16
- ...a,
17
- [c]: <DivArray elementsCount={c} />,
18
- };
19
- }, {});
20
-
21
11
  export default {
22
- title: 'Components/NsColumnControl',
12
+ title: 'Components/Column/NsColumnControl',
23
13
  component: NsColumnControl,
24
14
  decorators: [withCenterDecorator],
25
15
  argTypes: {
@@ -0,0 +1,59 @@
1
+ import type { StoryObj, Meta } from '@storybook/react';
2
+ import { withCenterDecorator } from '../../../stories/decorators/withCenterDecorator';
3
+ import { NsFlexColumns } from '..';
4
+ import { DivArray } from './NDivs.story';
5
+ import {childrenMapping, selectDivOptions } from './common';
6
+
7
+ type ComponentType = typeof NsFlexColumns;
8
+ type Story = StoryObj<ComponentType>;
9
+ type MetaStory = Meta<ComponentType>;
10
+
11
+ export default {
12
+ title: 'Components/Column/NsFlexColumns',
13
+ component: NsFlexColumns,
14
+ decorators: [withCenterDecorator],
15
+ argTypes: {
16
+ columnClass: {
17
+ control: 'text',
18
+ defaultValue: 'ns-col-lg-1-1-1 ns-col-md-1-1 ns-col-sm-1',
19
+ },
20
+ gap: {
21
+ control: 'number',
22
+ defaultValue: 16,
23
+ },
24
+ children: {
25
+ control: {
26
+ type: 'select',
27
+ options: selectDivOptions,
28
+ },
29
+ defaultValue: <DivArray elementsCount={8} />,
30
+ mapping: childrenMapping,
31
+ },
32
+ },
33
+ args: {
34
+ columnClass: 'ns-col-lg-1-1-1',
35
+ children: <DivArray elementsCount={12} />,
36
+ },
37
+ } as MetaStory;
38
+
39
+ export const SingleColumnControl: Story = {};
40
+ export const TwoColumn11: Story = {
41
+ args: { columnClass: 'ns-col-lg-1-1' },
42
+ };
43
+ export const TwoColumn21: Story = {
44
+ args: { columnClass: 'ns-col-lg-2-1' },
45
+ };
46
+
47
+ export const ThreeColumn211: Story = {
48
+ args: { columnClass: 'ns-col-lg-2-1-1' },
49
+ };
50
+ export const ThreeColumn121: Story = {
51
+ args: { columnClass: 'ns-col-lg-1-2-1' },
52
+ };
53
+ export const ThreeColumn111Responsive: Story = {
54
+ args: { columnClass: 'ns-col-lg-1-1-1' },
55
+ };
56
+
57
+ export const FourColumn1111Responsive: Story = {
58
+ args: { columnClass: 'ns-col-lg-1-1-1-1' },
59
+ };
@@ -0,0 +1,59 @@
1
+ import type { StoryObj, Meta } from '@storybook/react';
2
+ import { withCenterDecorator } from '../../../stories/decorators/withCenterDecorator';
3
+ import { NsGridColumns } from '..';
4
+ import { DivArray } from './NDivs.story';
5
+ import { childrenMapping, selectDivOptions } from './common';
6
+
7
+ type ComponentType = typeof NsGridColumns;
8
+ type Story = StoryObj<ComponentType>;
9
+ type MetaStory = Meta<ComponentType>;
10
+
11
+ export default {
12
+ title: 'Components/Column/NsGridColumns',
13
+ component: NsGridColumns,
14
+ decorators: [withCenterDecorator],
15
+ argTypes: {
16
+ columnClass: {
17
+ control: 'text',
18
+ defaultValue: 'ns-col-lg-1-1-1 ns-col-md-1-1 ns-col-sm-1',
19
+ },
20
+ gap: {
21
+ control: 'number',
22
+ defaultValue: 16,
23
+ },
24
+ children: {
25
+ control: {
26
+ type: 'select',
27
+ options: selectDivOptions,
28
+ },
29
+ defaultValue: <DivArray elementsCount={8} />,
30
+ mapping: childrenMapping,
31
+ },
32
+ },
33
+ args: {
34
+ columnClass: 'ns-col-lg-1-1-1',
35
+ children: <DivArray elementsCount={12} />,
36
+ },
37
+ } as MetaStory;
38
+
39
+ export const SingleColumnControl: Story = {};
40
+ export const TwoColumn11: Story = {
41
+ args: { columnClass: 'ns-col-lg-1-1' },
42
+ };
43
+ export const TwoColumn21: Story = {
44
+ args: { columnClass: 'ns-col-lg-2-1' },
45
+ };
46
+
47
+ export const ThreeColumn211: Story = {
48
+ args: { columnClass: 'ns-col-lg-2-1-1' },
49
+ };
50
+ export const ThreeColumn121: Story = {
51
+ args: { columnClass: 'ns-col-lg-1-2-1' },
52
+ };
53
+ export const ThreeColumn111Responsive: Story = {
54
+ args: { columnClass: 'ns-col-lg-1-1-1' },
55
+ };
56
+
57
+ export const FourColumn1111Responsive: Story = {
58
+ args: { columnClass: 'ns-col-lg-1-1-1-1' },
59
+ };
@@ -0,0 +1,14 @@
1
+ import { DivArray } from './NDivs.story';
2
+
3
+ /* an array from 1 to n */
4
+ export const selectDivOptions = Array(16)
5
+ .fill(0)
6
+ .map((_, index) => index + 1);
7
+
8
+ /* this component is used only as a utility to show column control in storybook */
9
+ export const childrenMapping = selectDivOptions.reduce((childrenMappingObject, elementCount) => {
10
+ return {
11
+ ...childrenMappingObject,
12
+ [elementCount]: <DivArray elementsCount={elementCount} />,
13
+ };
14
+ }, {});
@@ -0,0 +1,41 @@
1
+ import { Box } from '@mui/material';
2
+ import { styled } from '@nuskin/foundation-theme';
3
+ import { sizeObjectType } from '../types';
4
+ import { commonStyles, getPercentArray } from './common';
5
+
6
+ const options = {
7
+ shouldForwardProp: (propKey: string) => propKey !== 'sizes | gap',
8
+ };
9
+
10
+ type StyledFlexProps = {
11
+ sizes: sizeObjectType;
12
+ gap?: number;
13
+ };
14
+
15
+ /* main wrapper for column control using css flex */
16
+ export const StyledFlex = styled(
17
+ Box as any,
18
+ options
19
+ )<StyledFlexProps>(({ sizes, gap }: StyledFlexProps) => {
20
+ const gridGap = gap ? `${gap}px` : '2rem';
21
+ const fraction = getPercentArray(sizes.fractions);
22
+ const flexResponsive = { flexGrow: 1, flexShrink: 1 };
23
+ const style: any = {
24
+ gap: gridGap,
25
+ ...commonStyles,
26
+ display: 'flex',
27
+ paddingInline: '20px',
28
+ flexWrap: 'wrap',
29
+ justifyContent: 'center',
30
+ ' > *': {
31
+ display: 'flex',
32
+ },
33
+ };
34
+ fraction.forEach((f, i) => {
35
+ style[`> :nth-of-type(${fraction.length}n+${i + 1})`] = {
36
+ flexBasis: `calc(${fraction[i]} - ${gridGap})`,
37
+ ...flexResponsive,
38
+ };
39
+ });
40
+ return style;
41
+ });
@@ -0,0 +1,33 @@
1
+ import { Box } from '@mui/material';
2
+ import { styled } from '@nuskin/foundation-theme';
3
+ import { sizeObjectType } from '../types';
4
+ import { commonStyles, getPercentArray } from './common';
5
+
6
+ type StyledGridProps = {
7
+ sizes: sizeObjectType;
8
+ gap?: number;
9
+ };
10
+ const options = {
11
+ shouldForwardProp: (propKey: string) => propKey !== 'sizes | gap',
12
+ };
13
+
14
+ /* main wrapper for column control using css grid */
15
+ export const StyledGrid = styled(
16
+ Box as any,
17
+ options
18
+ )<StyledGridProps>(({ sizes, gap }: StyledGridProps) => {
19
+ const gridGap = gap ?? '2rem';
20
+ return {
21
+ gap: gridGap,
22
+ ...commonStyles,
23
+ display: 'grid',
24
+ /* here we are creating gridTemplateColumns as calc(40% - 20px) calc(40% - 20px), */
25
+ gridTemplateColumns: getPercentArray(sizes.fractions)
26
+ ?.map((fractionPercent) => `calc(${fractionPercent} - 20px)`)
27
+ .join(''),
28
+ justifyContent: 'center',
29
+ '.span-2': {
30
+ gridColumn: 'span 2',
31
+ },
32
+ } as any;
33
+ });
@@ -0,0 +1,27 @@
1
+ const mobileBreakPoint = '600px';
2
+ // TODO: we need to add a prop in the to allow full width of page instead of 1200px
3
+ export const commonStyles = {
4
+ maxWidth: '1200px',
5
+ margin: '32px auto',
6
+ [`@media (max-width: ${mobileBreakPoint})`]: {
7
+ display: 'flex',
8
+ flexDirection: 'column',
9
+ flexWrap: 'wrap',
10
+ margin: '2rem 1rem',
11
+ '> * ': {
12
+ flex: '1 1 0 !important',
13
+ },
14
+ },
15
+ };
16
+ /*
17
+ we have kept extra margin by taking 80% instead of 100%, because margins and padding,
18
+ and gaps also take up space, so we should be left with appropriate space
19
+ example:
20
+ ['1','1'] => ['40%','40%']
21
+ ['1','2'] => ['27%','53%']
22
+ */
23
+ export function getPercentArray(fractionArray?: string[] | number[]) {
24
+ let numbers = fractionArray?.map((numberString) => +numberString)?.filter((num) => 0 < num && num < 10) ?? [];
25
+ const sum = numbers.reduce((currentSum, currentNumber) => currentSum + currentNumber, 0);
26
+ return numbers.map((currentNumber) => ((currentNumber / sum) * 80).toFixed(2) + '%');
27
+ }
@@ -1,5 +1,5 @@
1
1
  import { ValueOf } from 'next/dist/shared/lib/constants';
2
- import { NsColumnControlProps, sizeObjectType } from './types';
2
+ import { NsColumnControlProps, sizeObjectType } from './types.d';
3
3
 
4
4
  export const columnClasses: NsColumnControlProps['columnClass'][] = [
5
5
  'ns-col-lg-2-1',
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { render, fireEvent, screen, waitFor } from '../../../test-utils';
2
+ import { render, fireEvent, screen, waitFor } from '@/test-utils/index';
3
3
  import NsDropdown from './NsDropdown';
4
4
  import NsDropdownOption from './NsDropdownOption';
5
5
 
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from 'react';
2
2
  import { DropdownContainer, DropdownButton, DropdownList, DropdownHead } from './NsDropdown.styled';
3
3
  import { NsIcon } from '../icon';
4
- import { DropdownProps } from './types';
4
+ import { DropdownProps } from './types.d';
5
5
 
6
6
  const NsDropdown: React.FC<DropdownProps> = ({
7
7
  selectedValue,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ListItem, ListItemContainer } from './NsDropdown.styled';
3
- import { DropdownOptionProps } from './types';
3
+ import { DropdownOptionProps } from './types.d';
4
4
 
5
5
  export const NsDropdownOption: React.FC<DropdownOptionProps> = ({
6
6
  value,
@@ -1,3 +1,3 @@
1
1
  export { default as NsDropdown } from './NsDropdown';
2
2
  export { default as NsDropdownOption } from './NsDropdownOption';
3
- export type { DropdownOptionProps, DropdownProps } from './types';
3
+ export type { DropdownOptionProps, DropdownProps } from './types.d';
@@ -8,7 +8,7 @@
8
8
  import React from 'react';
9
9
  import nuskinTheme from '@nuskin/foundation-theme/src/themes/genome-foundation';
10
10
 
11
- import { render } from '../../../test-utils/index';
11
+ import { render } from '@/test-utils/index';
12
12
  import NsFlag from './NsFlag';
13
13
 
14
14
  const { palette } = nuskinTheme;
@@ -7,7 +7,7 @@
7
7
  import { Theme } from '@mui/material';
8
8
  import { styled, ColorUtils, FoundationTheme } from '@nuskin/foundation-theme';
9
9
 
10
- import { NsFlagSize } from './types';
10
+ import { NsFlagSize } from './types.d';
11
11
 
12
12
  type NsFlagThemeParams = {
13
13
  $size: NsFlagSize;
@@ -33,11 +33,9 @@ const makeFlagSize = ({ $size }: { $size: NsFlagSize }) => {
33
33
  return sizeValue / FLAG_SCALE_VALUE;
34
34
  };
35
35
 
36
- const {
37
- getPaletteColor,
38
- } = ColorUtils;
36
+ const { getPaletteColor } = ColorUtils;
39
37
 
40
- const makeFlagBorder = ({ $size, $bgColor = 'accentColorA', theme}: NsFlagThemeParams) => {
38
+ const makeFlagBorder = ({ $size, $bgColor = 'accentColorA', theme }: NsFlagThemeParams) => {
41
39
  if (theme) {
42
40
  return `${makeFlagSize({ $size })}px solid ${getPaletteColor(theme, $bgColor)}`;
43
41
  }