@nuskin/foundation-ui-components 1.3.0 → 1.4.1

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 (38) hide show
  1. package/package.json +4 -4
  2. package/src/common/auth-dropdown/NsAuthDropdown.tsx +6 -6
  3. package/src/common/button/NsButton.stories.tsx +3 -2
  4. package/src/common/button/NsButton.tsx +27 -2
  5. package/src/common/button/types.d.ts +21 -17
  6. package/src/common/card/NsFfgCard.tsx +2 -2
  7. package/src/common/cart-icon/NsCartIcon.styled.tsx +14 -0
  8. package/src/common/dropdown/NsDropdown.tsx +6 -6
  9. package/src/common/email-simple/NsEmailSimple.tsx +1 -1
  10. package/src/common/flag/NsFlag.spec.tsx +14 -2
  11. package/src/common/flag/NsFlag.styled.tsx +2 -5
  12. package/src/common/hooks/useOnClickOutside.tsx +11 -14
  13. package/src/common/icon/NsIcon.spec.tsx +11 -2
  14. package/src/common/icon/NsIcon.stories.tsx +2 -1
  15. package/src/common/icon/NsIcon.styled.tsx +13 -10
  16. package/src/common/icon/NsIcon.tsx +9 -6
  17. package/src/common/icon/icons/UserIcon.tsx +8 -1
  18. package/src/common/icon/types.d.ts +3 -2
  19. package/src/common/progress/NsProgress.spec.tsx +2 -2
  20. package/src/common/progress/NsProgress.stories.tsx +10 -5
  21. package/src/common/progress/NsProgress.styled.tsx +30 -12
  22. package/src/common/progress/NsProgress.tsx +18 -16
  23. package/src/common/progress/types.d.ts +2 -2
  24. package/src/common/radiogroup/NsRadioGroup.spec.tsx +2 -2
  25. package/src/common/radiogroup/NsRadioGroup.stories.tsx +2 -2
  26. package/src/common/radiogroup/NsRadioGroup.tsx +5 -3
  27. package/src/common/radiogroup/types.d.ts +11 -12
  28. package/src/common/select/NsSelect.styled.tsx +37 -69
  29. package/src/common/select/NsSelect.tsx +86 -91
  30. package/src/common/select/NsSelectOption.tsx +10 -14
  31. package/src/common/select/specs/NsSelect.spec.tsx +183 -0
  32. package/src/common/select/specs/NsSelectOption.spec.tsx +32 -0
  33. package/src/common/select/stories/NsSelect.stories.tsx +25 -80
  34. package/src/common/select/stories/countries.ts +53 -0
  35. package/src/common/select/types.d.ts +21 -8
  36. package/src/common/table/NsTable.stories.tsx +1 -0
  37. package/src/common/cart-icon/NsCartIcon.styled.ts +0 -14
  38. package/src/common/select/NsSelect.spec.tsx +0 -274
@@ -1,26 +1,28 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { NsProgressProps } from './types';
4
- import StyledLinearProgress, { PercentDiv, StyledCheckCircle } from './NsProgress.styled';
4
+ import { StyledLinearProgress, ProgressInfo, StyledCheckCircle, StyledProgress } from './NsProgress.styled';
5
5
 
6
6
  const NsProgress = (props: NsProgressProps) => {
7
- const { color, backgroundColor, height, value, body } = props;
7
+ const { barColor, backgroundColor, height, value, body } = props;
8
8
  return (
9
- <>
10
- <PercentDiv>
9
+ <StyledProgress className="ns-progress">
10
+ <ProgressInfo variant="p-xs" className="progress-info">
11
11
  {value}
12
- {body}
13
- </PercentDiv>
14
- <StyledLinearProgress
15
- variant="determinate"
16
- role="progressbar"
17
- color={color}
18
- value={value}
19
- height={height}
20
- backgroundColor={backgroundColor}
21
- />
22
- <StyledCheckCircle />
23
- </>
12
+ <span>{body ?? ' % Complete'}</span>
13
+ </ProgressInfo>
14
+ <div className="progress-bar">
15
+ <StyledLinearProgress
16
+ variant="determinate"
17
+ role="progressbar"
18
+ value={value}
19
+ height={height}
20
+ barColor={barColor}
21
+ backgroundColor={backgroundColor}
22
+ />
23
+ <StyledCheckCircle />
24
+ </div>
25
+ </StyledProgress>
24
26
  );
25
27
  };
26
28
 
@@ -13,8 +13,8 @@ declare module '@mui/material/LinearProgress' {
13
13
  }
14
14
 
15
15
  export type NsProgressProps = {
16
- color?: FoundationTheme.PaletteColors;
17
- backgroundColor?: string;
16
+ barColor?: FoundationTheme.PaletteColors;
17
+ backgroundColor?: FoundationTheme.PaletteColors;
18
18
  height?: string;
19
19
  value: number;
20
20
  body?: ReactNode;
@@ -16,7 +16,7 @@ describe('NsRadioGroup', () => {
16
16
  name: 'test',
17
17
  label: 'I choose to signup as',
18
18
  color: '#272525' as FoundationTheme.PaletteColors,
19
- additionalSlot: 'An additional slot allows for more text',
19
+ helperText: 'help text for more information',
20
20
  size: 24,
21
21
  labelFontSize: 16,
22
22
  additionalProps: {
@@ -35,7 +35,7 @@ describe('NsRadioGroup', () => {
35
35
  });
36
36
  });
37
37
  it('2. renders options correctly without additional slot', () => {
38
- render(<NsRadioGroup {...props} onChange={onChange} additionalSlot={''} />);
38
+ render(<NsRadioGroup {...props} onChange={onChange} helperText={''} />);
39
39
 
40
40
  options.forEach((option) => {
41
41
  const radioOption = screen.getByLabelText(option.label) as HTMLInputElement;
@@ -33,7 +33,7 @@ export default {
33
33
  labelFontSize: {
34
34
  description: 'Used to change font-size of the label',
35
35
  },
36
- additionalSlot: {
36
+ helperText: {
37
37
  description: 'An additional slot allows for more text',
38
38
  },
39
39
  },
@@ -64,7 +64,7 @@ export const RadioGroup: Story = {
64
64
  name: 'test',
65
65
  label: 'I choose to signup as',
66
66
  color: '#272525' as FoundationTheme.PaletteColors,
67
- additionalSlot: 'An additional slot allows for more text',
67
+ helperText: 'An additional slot allows for more text',
68
68
  size: 10,
69
69
  labelFontSize: 16,
70
70
  additionalProps: {
@@ -14,7 +14,7 @@ import { NsRadioGroupProps } from './types';
14
14
  const NsRadioGroup = (props: NsRadioGroupProps) => {
15
15
  const {
16
16
  items,
17
- additionalSlot,
17
+ helperText,
18
18
  label,
19
19
  onChange,
20
20
  color,
@@ -23,6 +23,7 @@ const NsRadioGroup = (props: NsRadioGroupProps) => {
23
23
  additionalProps,
24
24
  labelFontSize,
25
25
  darkModeEnabled = true,
26
+ row,
26
27
  } = props;
27
28
 
28
29
  return (
@@ -30,6 +31,7 @@ const NsRadioGroup = (props: NsRadioGroupProps) => {
30
31
  <FormControl data-testid={additionalProps?.testid}>
31
32
  <NsLabel size={labelFontSize}>{label}</NsLabel>
32
33
  <StyledRadioGroup
34
+ row={row}
33
35
  aria-labelledby="radio-buttons-group-label"
34
36
  defaultValue={items?.[0]?.value}
35
37
  name="radio-buttons-group"
@@ -50,9 +52,9 @@ const NsRadioGroup = (props: NsRadioGroupProps) => {
50
52
  ))}
51
53
  </StyledRadioGroup>
52
54
  </FormControl>
53
- {additionalSlot ? (
55
+ {helperText ? (
54
56
  <StyledHelperText className={`ml-${size}`}>
55
- <StyledSpan className="text-sm">{additionalSlot}</StyledSpan>
57
+ <StyledSpan className="text-sm">{helperText}</StyledSpan>
56
58
  </StyledHelperText>
57
59
  ) : null}
58
60
  </>
@@ -1,20 +1,19 @@
1
1
  import { FoundationTheme } from '@nuskin/foundation-theme';
2
+ import { RadioGroupProps } from '@mui/material';
2
3
  import { AdditionalProps } from '../common.types';
3
4
 
4
- export type NsRadioGroupProps = {
5
- disable : boolean ;
6
- name : string;
7
- additionalSlot : string;
8
- label : string ;
9
- items: RadioItems[] ;
5
+ export type NsRadioGroupProps = Pick<RadioGroupProps, 'name' | 'onChange' | 'value' | 'defaultValue' | 'row'> & {
6
+ disable: boolean;
7
+ helperText: string;
8
+ label: string;
9
+ items: RadioItems[];
10
10
  color: FoundationTheme.PaletteColors;
11
- size : number;
12
- labelFontSize:number,
13
- onChange : () => void;
11
+ size: number;
12
+ labelFontSize: number;
14
13
  } & AdditionalProps;
15
14
 
16
15
  export type RadioItems = {
17
- label : string ;
18
- value :string | number ;
16
+ label: string;
17
+ value: string | number;
19
18
  id: string | number;
20
- }
19
+ };
@@ -1,8 +1,9 @@
1
+ import { ColorUtils, FoundationTheme, styled } from '@nuskin/foundation-theme';
1
2
  import { HTMLAttributes } from 'react';
2
- import { styled, ColorUtils, FoundationTheme } from '@nuskin/foundation-theme';
3
- import { Themed } from '../common.types';
3
+
4
4
  import { getDropdownHeadBorder } from '../dropdown/NsDropdown.styled';
5
- const { color, paletteColor, isDarkMode } = ColorUtils;
5
+
6
+ const { paletteColor, themeColor } = ColorUtils;
6
7
 
7
8
  interface SelectLabelProps extends HTMLAttributes<HTMLLabelElement> {
8
9
  errorMessage?: string;
@@ -30,7 +31,8 @@ export const SelectHead = styled.div<{ type: string; disabled: boolean }>`
30
31
  display: flex;
31
32
  justify-content: space-between;
32
33
  align-items: center;
33
- border: ${getDropdownHeadBorder}
34
+ border: ${getDropdownHeadBorder};
35
+ background: ${paletteColor('primary', 'contrastText')};
34
36
  color: ${paletteColor('primary')};
35
37
  width: 207px;
36
38
  position: relative;
@@ -41,13 +43,7 @@ export const SelectButton = styled.div`
41
43
  padding-right: 10px;
42
44
  `;
43
45
 
44
- export const LeftArrowContainer = styled.div`
45
- display: flex;
46
- align-items: center;
47
- padding-top: 30px;
48
- `;
49
-
50
- export const RightArrowContainer = styled.div`
46
+ export const StyledArrowContainer = styled.div`
51
47
  display: flex;
52
48
  align-items: center;
53
49
  padding-top: 30px;
@@ -66,54 +62,6 @@ export const SelectList = styled.div<{ borderColor: FoundationTheme.PaletteColor
66
62
  overflow-y: auto;
67
63
  `;
68
64
 
69
- const getDividerColor = ({ theme }: Themed) =>
70
- isDarkMode({ theme }) ? color('neutral', '20')({ theme }) : color('neutral', '30')({ theme });
71
- const getListBgColor = (props: Themed) => {
72
- return !isDarkMode(props) ? color('accentColorB', '10')(props) : color('accentColorB', '50')(props);
73
- };
74
- type ContainerParam = { borderBottom: string; bgColor: string; color: string; hoveredBg: string };
75
-
76
- export const ListItemContainer = styled.div<{ showListDivider: boolean; isSelected: boolean }>`
77
- ${({ showListDivider, isSelected, theme }) => {
78
- const borderBottom = showListDivider ? getDividerColor({ theme }) : 'none';
79
- const bgColor = isSelected ? paletteColor('primary')({ theme }) : 'white';
80
- const color = isSelected ? 'white' : 'black';
81
- const hoveredBg = getListBgColor({ theme });
82
- return createListContainerStyle({ borderBottom, bgColor, color, hoveredBg });
83
- }}
84
- `;
85
- function createListContainerStyle({ borderBottom, bgColor, color, hoveredBg }: ContainerParam) {
86
- return `
87
- cursor: pointer;
88
- padding: 5px 0;
89
- border-bottom: 1px solid ${borderBottom};
90
- background-color: ${bgColor};
91
- color: ${color};
92
-
93
- &:hover {
94
- background-color: ${hoveredBg};
95
- }
96
-
97
- &:last-child {
98
- border-bottom: none;
99
- }
100
- `;
101
- }
102
- const getListItemBgColor = ({ isSelected, theme }: { isSelected: boolean } & Themed) => {
103
- if (isSelected) {
104
- return paletteColor('primary')({ theme });
105
- }
106
- return getListBgColor({ theme });
107
- };
108
-
109
- const getListItemBorderLeftColor = ({ isSelected, theme }: { isSelected: boolean } & Themed) => {
110
- if (isSelected) {
111
- const color = paletteColor('primary')({ theme });
112
- return `2px solid ${color}`;
113
- }
114
- return 'none';
115
- };
116
-
117
65
  export const SelectLabel = styled.label<SelectLabelProps>`
118
66
  display: block;
119
67
  margin-bottom: 5px;
@@ -121,14 +69,34 @@ export const SelectLabel = styled.label<SelectLabelProps>`
121
69
  errorMessage ? paletteColor('error')({ theme }) : paletteColor('primary')({ theme })};
122
70
  }
123
71
  `;
72
+ type StyledSelectOptionType = { showListDivider: boolean };
73
+ export const StyledSelectOption = styled('div')<StyledSelectOptionType>(({ showListDivider, theme }) => {
74
+ const dividerColor = themeColor(
75
+ { colorType: 'neutral', variant: '30' },
76
+ { colorType: 'neutral', variant: '20' }
77
+ )({ theme });
78
+ const borderBottom = showListDivider ? dividerColor : 'none';
79
+ const hoveredBg = themeColor(
80
+ { colorType: 'accentColorB', variant: '20' },
81
+ { colorType: 'accentColorB', variant: '40' }
82
+ )({ theme });
124
83
 
125
- export const ListItem = styled.div<{ isSelected: boolean }>(({ isSelected, theme }) => ({
126
- padding: '5px 10px',
127
- borderLeft: getListItemBorderLeftColor({ isSelected, theme }),
128
- backgroundColor: isSelected ? paletteColor('primary', 'main')({ theme }) : 'white',
129
- color: isSelected ? 'white' : 'black',
130
- '&:hover': {
131
- backgroundColor: getListItemBgColor({ isSelected, theme }),
132
- fontWeight: 'bold',
133
- },
134
- }));
84
+ return {
85
+ cursor: 'pointer',
86
+ borderBottom: `1px solid ${borderBottom}`,
87
+ backgroundColor: 'white',
88
+ color: 'black',
89
+ padding: '5px 10px',
90
+ '&.selected-option': {
91
+ backgroundColor: paletteColor('accentColorA')({ theme }),
92
+ color: 'white',
93
+ },
94
+ '&:hover': {
95
+ color: 'white',
96
+ backgroundColor: hoveredBg,
97
+ },
98
+ '&:last-child': {
99
+ borderBottom: 'none',
100
+ },
101
+ };
102
+ });
@@ -1,22 +1,53 @@
1
- import React, { useState, useRef, useEffect, Children } from 'react';
1
+ import React, { MouseEvent, useCallback, useMemo, useRef, useState } from 'react';
2
+
3
+ import { useOnClickOutside } from '../hooks/useOnClickOutside';
4
+ import { NsIcon } from '../icon';
5
+ import { Show } from '../utility';
2
6
  import {
3
- SelectContainer,
7
+ ErrorContainer,
8
+ StyledArrowContainer,
4
9
  SelectButton,
5
- SelectList,
10
+ SelectContainer,
6
11
  SelectHead,
7
12
  SelectLabel,
13
+ SelectList,
8
14
  SelectMain,
9
- LeftArrowContainer,
10
- RightArrowContainer,
11
- ErrorContainer,
12
15
  } from './NsSelect.styled';
13
- import { NsIcon } from '../icon';
14
- import { SelectProps } from './types.d';
16
+ import { LabelValueType, SelectProps } from './types.d';
17
+
18
+ const factorMap: any = {
19
+ reverse: {
20
+ right: -1,
21
+ left: 1,
22
+ },
23
+ forward: {
24
+ right: 1,
25
+ left: -1,
26
+ },
27
+ };
28
+
29
+ const arrowVisibility = (
30
+ total: number,
31
+ direction: 'left' | 'right',
32
+ reverse: boolean = false,
33
+ currentIndex: number | undefined = -1
34
+ ) => {
35
+ if (direction === 'left') {
36
+ if (!reverse) {
37
+ return currentIndex < 1 ? 'hidden' : 'visible';
38
+ } else {
39
+ return currentIndex >= total - 1 ? 'hidden' : 'visible';
40
+ }
41
+ }
42
+ if (!reverse) {
43
+ return currentIndex >= total - 1 ? 'hidden' : 'visible';
44
+ } else {
45
+ return currentIndex < 1 ? 'hidden' : 'visible';
46
+ }
47
+ };
15
48
  const NsSelect: React.FC<SelectProps> = ({
16
- selectedValue,
17
- selectedLabel,
49
+ selected,
18
50
  onSelect,
19
- children,
20
51
  disabled = false,
21
52
  type = 'outlined',
22
53
  placeholder = '',
@@ -30,32 +61,33 @@ const NsSelect: React.FC<SelectProps> = ({
30
61
  // eslint-disable-next-line no-unused-vars
31
62
  rules,
32
63
  reverseArrowControls,
64
+ renderOption,
65
+ options,
33
66
  }) => {
34
67
  const [isOpen, setIsOpen] = useState(false);
35
- const [value, setValue] = useState(selectedValue || '');
36
- const [selectedIndex, setSelectedIndex] = useState(-1);
68
+ const optionIndex = useMemo(() => {
69
+ if (typeof selected?.index === 'number') return selected.index;
70
+ return options.findIndex((option) => option.value === selected.value);
71
+ }, [options, selected]);
72
+ const [value, setValue] = useState<LabelValueType>({ ...selected, index: optionIndex });
37
73
  const selectContainerRef = useRef<HTMLDivElement>(null);
38
74
  const selectHeadRef = useRef<HTMLDivElement>(null);
39
75
 
40
- const closeSelect = () => {
76
+ const closeMenuOnMouseLeave = useCallback(() => {
41
77
  if (closeOnMouseLeave) {
42
78
  setIsOpen(false);
43
79
  }
44
- };
80
+ }, [closeOnMouseLeave]);
45
81
 
46
- const handleSelect = (input: string, index: number) => {
47
- onSelect(input);
82
+ const handleSelect = (val: LabelValueType) => {
83
+ onSelect(val);
48
84
  setIsOpen(false);
49
- setValue(input);
50
- setSelectedIndex(index);
51
- };
52
-
53
- // eslint-disable-next-line react-hooks/exhaustive-deps
54
- const handleClickOutside = (event: MouseEvent) => {
55
- if (selectContainerRef.current && !selectContainerRef.current.contains(event.target as Node) && isOpen) {
56
- setIsOpen(false);
57
- }
85
+ setValue(val);
58
86
  };
87
+ const closeMenu = useCallback(() => {
88
+ setIsOpen(false);
89
+ }, []);
90
+ useOnClickOutside(selectContainerRef.current, closeMenu);
59
91
 
60
92
  const handleMouseClick = () => {
61
93
  if (disabled) return;
@@ -66,61 +98,27 @@ const NsSelect: React.FC<SelectProps> = ({
66
98
  }, 0);
67
99
  }
68
100
  };
69
- const handleArrowRightClick = () => {
70
- if (selectedIndex !== -1) {
71
- const nextIndex = reverseArrowControls ? selectedIndex - 1 : selectedIndex + 1;
72
- const childrenArray = Children.toArray(children);
73
- const optionAtIndex = childrenArray[nextIndex];
74
- const { value } = (optionAtIndex as any)?.props ?? {};
75
- handleSelect(value, nextIndex);
76
- } else {
77
- if (!reverseArrowControls) {
78
- const nextIndex = selectedIndex + 1;
79
- const childrenArray = Children.toArray(children);
80
- const optionAtIndex = childrenArray[nextIndex];
81
- const { value } = (optionAtIndex as any)?.props ?? {};
82
- handleSelect(value, nextIndex);
83
- }
84
- }
85
- };
86
- const handleArrowLeftClick = () => {
87
- if (selectedIndex !== -1) {
88
- const nextIndex = reverseArrowControls ? selectedIndex + 1 : selectedIndex - 1;
89
- const childrenArray = Children.toArray(children);
90
- const optionAtIndex = childrenArray[nextIndex];
91
- const { value } = (optionAtIndex as any)?.props ?? {};
92
- handleSelect(value, nextIndex);
93
- } else {
94
- if (reverseArrowControls) {
95
- const nextIndex = selectedIndex + 1;
96
- const childrenArray = Children.toArray(children);
97
- const optionAtIndex = childrenArray[nextIndex];
98
- const { value } = (optionAtIndex as any)?.props ?? {};
99
- handleSelect(value, nextIndex);
100
- }
101
+ const handleArrowClick = (event: MouseEvent) => {
102
+ const direction = event.currentTarget?.className.includes('Right') ? 'right' : 'left';
103
+ const adder = factorMap[reverseArrowControls ? 'reverse' : 'forward'][direction];
104
+ const nextIndex = (selected?.index ?? -1) + adder;
105
+ if (nextIndex > -1 && nextIndex < options.length) {
106
+ handleSelect({ ...options[nextIndex], index: nextIndex });
101
107
  }
102
108
  };
103
109
 
104
- useEffect(() => {
105
- document.addEventListener('click', handleClickOutside);
106
- return () => {
107
- document.removeEventListener('click', handleClickOutside);
108
- };
109
- }, [handleClickOutside, isOpen]);
110
-
111
110
  return (
112
111
  <SelectMain>
113
112
  {hasArrows && (
114
- <LeftArrowContainer
115
- onClick={handleArrowLeftClick}
113
+ <StyledArrowContainer
114
+ onClick={handleArrowClick}
116
115
  className="LeftArrow"
117
116
  style={{
118
- visibility:
119
- !reverseArrowControls && (selectedIndex === 0 || selectedIndex < 0) ? 'hidden' : 'visible',
117
+ visibility: arrowVisibility(options.length, 'left', reverseArrowControls, value?.index),
120
118
  }}
121
119
  >
122
120
  <NsIcon name="arrowLeft" color="primary" />
123
- </LeftArrowContainer>
121
+ </StyledArrowContainer>
124
122
  )}
125
123
  <SelectContainer
126
124
  data-testid="select-container"
@@ -137,43 +135,40 @@ const NsSelect: React.FC<SelectProps> = ({
137
135
  tabIndex={0}
138
136
  ref={selectHeadRef}
139
137
  >
140
- <SelectButton>{selectedLabel || placeholder}</SelectButton>
138
+ <SelectButton>{value?.label || placeholder}</SelectButton>
141
139
  {!readOnly && <NsIcon name={isOpen ? 'arrowUp' : 'arrowDown'} color="primary" />}
142
140
  </SelectHead>
143
- {isOpen ? (
141
+ <Show when={isOpen}>
144
142
  <SelectList
145
- data-testid="select-list"
146
- onMouseLeave={closeSelect}
143
+ data-testid="select-menu-list"
144
+ onMouseLeave={closeMenuOnMouseLeave}
147
145
  borderColor={selectBorderColor}
148
146
  className="selectList"
149
147
  >
150
- {React.Children.map(children, (child, index) => {
151
- if (React.isValidElement(child)) {
152
- return React.cloneElement(child, {
153
- // @ts-ignore
154
- onSelect: (input: string) => handleSelect(input, index),
155
- selectedValue: value,
156
- showListDivider,
157
- index,
158
- });
159
- }
160
- return null;
148
+ {options.map((opt, optionIndex) => {
149
+ return renderOption({
150
+ value: opt.value,
151
+ label: opt.label,
152
+ index: optionIndex,
153
+ onClick: () => handleSelect({ label: opt.label, value: opt.value, index: optionIndex }),
154
+ selected: value,
155
+ showListDivider,
156
+ });
161
157
  })}
162
158
  </SelectList>
163
- ) : null}
159
+ </Show>
164
160
  {errorMessage && <ErrorContainer>{errorMessage}</ErrorContainer>}
165
161
  </SelectContainer>
166
162
  {hasArrows && (
167
- <RightArrowContainer
168
- onClick={handleArrowRightClick}
163
+ <StyledArrowContainer
164
+ onClick={handleArrowClick}
169
165
  className="RightArrow"
170
166
  style={{
171
- visibility:
172
- reverseArrowControls && (selectedIndex === 0 || selectedIndex < 0) ? 'hidden' : 'visible',
167
+ visibility: arrowVisibility(options.length, 'right', reverseArrowControls, selected?.index),
173
168
  }}
174
169
  >
175
170
  <NsIcon name="arrowRight" color="primary" />
176
- </RightArrowContainer>
171
+ </StyledArrowContainer>
177
172
  )}
178
173
  </SelectMain>
179
174
  );
@@ -1,29 +1,25 @@
1
1
  import React from 'react';
2
- import { ListItem, ListItemContainer } from './NsSelect.styled';
2
+
3
+ import { StyledSelectOption } from './NsSelect.styled';
3
4
  import { SelectOptionProps } from './types.d';
4
5
 
5
6
  export const NsSelectOption: React.FC<SelectOptionProps> = ({
6
7
  value,
7
8
  label,
8
- onSelect,
9
- selectedValue,
9
+ onClick,
10
+ selected,
10
11
  showListDivider = true,
11
12
  }) => {
12
- const handleClick = () => {
13
- if (onSelect && typeof onSelect === 'function') {
14
- onSelect(value);
15
- }
16
- };
17
-
13
+ const isSelected = value === selected?.value;
18
14
  return (
19
- <ListItemContainer
15
+ <StyledSelectOption
16
+ className={isSelected ? 'selected-option' : ''}
20
17
  data-testid={`option-${value}`}
21
- isSelected={value === selectedValue}
22
18
  showListDivider={showListDivider}
23
- onClick={handleClick}
19
+ onClick={onClick}
24
20
  >
25
- <ListItem isSelected={value === selectedValue}>{label}</ListItem>
26
- </ListItemContainer>
21
+ {label}
22
+ </StyledSelectOption>
27
23
  );
28
24
  };
29
25
  export default NsSelectOption;