@xqmsg/ui-core 0.9.3 → 0.11.0

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 (67) hide show
  1. package/dist/components/button/index.d.ts +3 -7
  2. package/dist/components/input/Input.stories.d.ts +4 -0
  3. package/dist/components/input/InputTypes.d.ts +5 -3
  4. package/dist/components/input/StackedInput/StackedInput.d.ts +0 -3
  5. package/dist/components/input/StackedMultiSelect/index.d.ts +1 -1
  6. package/dist/components/input/StackedSelect/StackedSelect.d.ts +7 -3
  7. package/dist/components/input/components/dropdown/index.d.ts +10 -0
  8. package/dist/components/input/components/label/index.d.ts +9 -0
  9. package/dist/components/input/components/token/Token.stories.d.ts +5 -0
  10. package/dist/components/input/components/token/index.d.ts +7 -0
  11. package/dist/components/input/index.d.ts +1 -3
  12. package/dist/theme/components/button.d.ts +68 -207
  13. package/dist/theme/components/form-error.d.ts +3 -3
  14. package/dist/theme/components/form-label.d.ts +4 -6
  15. package/dist/theme/components/form.d.ts +3 -3
  16. package/dist/theme/components/input.d.ts +32 -161
  17. package/dist/theme/components/select.d.ts +27 -153
  18. package/dist/theme/components/textarea.d.ts +10 -117
  19. package/dist/theme/foundations/colors.d.ts +68 -16
  20. package/dist/ui-core.cjs.development.js +594 -860
  21. package/dist/ui-core.cjs.development.js.map +1 -1
  22. package/dist/ui-core.cjs.production.min.js +1 -1
  23. package/dist/ui-core.cjs.production.min.js.map +1 -1
  24. package/dist/ui-core.esm.js +598 -864
  25. package/dist/ui-core.esm.js.map +1 -1
  26. package/package.json +1 -2
  27. package/src/components/banner/index.tsx +7 -1
  28. package/src/components/button/Button.stories.tsx +19 -7
  29. package/src/components/button/index.tsx +7 -19
  30. package/src/components/button/spinner/index.tsx +2 -7
  31. package/src/components/input/Input.stories.tsx +60 -58
  32. package/src/components/input/InputTypes.ts +7 -1
  33. package/src/components/input/StackedInput/StackedInput.tsx +3 -15
  34. package/src/components/input/StackedMultiSelect/components/MultiValue/index.tsx +2 -2
  35. package/src/components/input/StackedMultiSelect/index.tsx +88 -92
  36. package/src/components/input/StackedPilledInput/index.tsx +139 -56
  37. package/src/components/input/StackedSelect/StackedSelect.tsx +63 -20
  38. package/src/components/input/StackedSelect/assets/svg/subtract.svg +3 -0
  39. package/src/components/input/components/dropdown/index.tsx +80 -0
  40. package/src/components/input/components/label/index.tsx +24 -0
  41. package/src/components/input/components/token/Token.stories.tsx +22 -0
  42. package/src/components/input/components/token/assets/svg/close.svg +3 -0
  43. package/src/components/input/components/token/index.tsx +37 -0
  44. package/src/components/input/index.tsx +7 -20
  45. package/src/components/loading/index.tsx +1 -1
  46. package/src/components/table/Table.stories.tsx +9 -1
  47. package/src/components/table/index.tsx +1 -1
  48. package/src/components/table/loading/index.tsx +2 -2
  49. package/src/components/tabs/index.tsx +1 -1
  50. package/src/components/text/index.tsx +1 -1
  51. package/src/theme/components/alert.ts +4 -4
  52. package/src/theme/components/button.ts +45 -186
  53. package/src/theme/components/form-error.ts +11 -14
  54. package/src/theme/components/form-label.ts +8 -8
  55. package/src/theme/components/form.ts +10 -13
  56. package/src/theme/components/input.ts +17 -191
  57. package/src/theme/components/link.ts +2 -1
  58. package/src/theme/components/select.ts +5 -10
  59. package/src/theme/components/tabs.ts +3 -3
  60. package/src/theme/components/textarea.ts +2 -38
  61. package/src/theme/customXQChakraTheme.ts +0 -2
  62. package/src/theme/foundations/colors.ts +31 -10
  63. package/src/theme/foundations/shadows.ts +3 -3
  64. package/dist/components/input/components/InputTag/index.d.ts +0 -7
  65. package/dist/theme/components/menu.d.ts +0 -48
  66. package/src/components/input/components/InputTag/index.tsx +0 -24
  67. package/src/theme/components/menu.ts +0 -70
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.9.3",
2
+ "version": "0.11.0",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -98,7 +98,6 @@
98
98
  "@hookform/resolvers": "^2.9.7",
99
99
  "axios": "^0.27.2",
100
100
  "framer-motion": "6.3.0",
101
- "ip-regex": "^5.0.0",
102
101
  "react": "^18.0.0",
103
102
  "react-dom": "^18.0.0",
104
103
  "react-hook-form": "^7.34.0",
@@ -11,6 +11,7 @@ import ErrorIcon from './assets/svg/error.svg';
11
11
  import PositiveIcon from './assets/svg/positive.svg';
12
12
  import NeutralIcon from './assets/svg/neutral.svg';
13
13
  import WarningIcon from './assets/svg/warning.svg';
14
+ import colors from 'src/theme/foundations/colors';
14
15
 
15
16
  export type BannerVariant = 'positive' | 'warning' | 'error' | 'neutral';
16
17
 
@@ -52,7 +53,12 @@ export const Banner: React.FC<BannerProps> = ({
52
53
  {message}
53
54
  {onClick && buttonText && (
54
55
  <Flex pt="8px" justifyContent="flex-end">
55
- <Button size="sm" bg="white" color="blue.500" onClick={onClick}>
56
+ <Button
57
+ size="sm"
58
+ bg="white"
59
+ color={colors.fill.action}
60
+ onClick={onClick}
61
+ >
56
62
  {buttonText}
57
63
  </Button>
58
64
  </Flex>
@@ -1,11 +1,17 @@
1
1
  import React from 'react';
2
2
  import { Meta, Story } from '@storybook/react';
3
3
  import { Button, ButtonProps } from '.';
4
+ import { Box, Flex } from '@chakra-ui/react';
4
5
 
5
6
  const meta: Meta<ButtonProps> = {
6
7
  title: 'Button example',
7
8
  component: Button,
8
9
  argTypes: {
10
+ width: {
11
+ control: null,
12
+ description:
13
+ '`variable` adopts 100% of the width of the parent component, whereas `fixed` fits the label content to the button',
14
+ },
9
15
  text: {
10
16
  control: {
11
17
  type: 'text',
@@ -24,23 +30,29 @@ const meta: Meta<ButtonProps> = {
24
30
  control: 'boolean',
25
31
  description: 'Disabled state of the button',
26
32
  },
27
- size: {
28
- control: 'select',
29
- options: ['xs', 'sm', 'md', 'lg'],
30
- description: 'The chakra based size prop for the button',
31
- },
32
33
  },
33
34
  parameters: {
34
35
  controls: { expanded: true },
35
36
  },
36
37
  };
37
38
  export default meta;
38
- const Template: Story<ButtonProps> = args => <Button {...args} />;
39
+ const Template: Story<ButtonProps> = args => (
40
+ <Flex flexDir="column" height="200px" justifyContent="space-between">
41
+ <Button {...args} text="Solid Fixed" variant="solid" width="fixed" />
42
+ <Button {...args} text="Outline Fixed" variant="outline" width="fixed" />
43
+ <Button {...args} text="Solid Variable" variant="solid" width="variable" />
44
+ <Button
45
+ {...args}
46
+ text="Outline Variable"
47
+ variant="outline"
48
+ width="variable"
49
+ />
50
+ </Flex>
51
+ );
39
52
 
40
53
  export const Default = Template.bind({});
41
54
  Default.args = {
42
55
  onClick: () => alert('This is a button click!'),
43
- text: 'Button',
44
56
  type: 'button',
45
57
  disabled: false,
46
58
  };
@@ -1,52 +1,40 @@
1
1
  import React from 'react';
2
- import {
3
- Button as ChakraButton,
4
- ButtonProps as ChakraButtonProps,
5
- } from '@chakra-ui/react';
2
+ import { Button as ChakraButton } from '@chakra-ui/react';
6
3
  import buttonTheme from '../../theme/components/button';
7
4
 
8
5
  export interface ButtonProps {
9
6
  text: string;
10
7
  onClick?: () => void;
8
+ width: 'variable' | 'fixed';
11
9
  variant?: keyof typeof buttonTheme.variants;
12
- colorScheme?: string;
13
- type: 'button' | 'submit' | 'reset' | undefined;
10
+ type?: 'button' | 'submit' | 'reset';
14
11
  ariaLabel: string;
15
- size?: 'sm' | 'md' | 'lg' | 'xs';
16
12
  disabled?: boolean;
17
13
  className?: string;
18
- style?: React.CSSProperties;
19
- width?: string | number;
20
14
  }
21
15
 
22
16
  /**
23
17
  * A functional React component utilized to render the `Button` component
24
18
  */
25
- export const Button: React.FC<ButtonProps & ChakraButtonProps> = ({
19
+ export const Button: React.FC<ButtonProps> = ({
26
20
  onClick,
27
21
  text,
28
- type,
22
+ type = 'button',
29
23
  ariaLabel,
30
24
  variant = 'solid',
31
- colorScheme = 'primary',
32
- style,
33
- size = 'md',
34
25
  disabled,
35
26
  className,
36
- ...props
27
+ width,
37
28
  }) => {
38
29
  return (
39
30
  <ChakraButton
40
31
  onClick={onClick}
41
32
  type={type}
42
33
  variant={variant}
43
- colorScheme={colorScheme}
44
- size={size}
45
34
  disabled={disabled}
46
35
  aria-label={ariaLabel}
47
- style={style}
48
36
  className={className}
49
- {...props}
37
+ width={width === 'variable' ? '100%' : 'fit-content'}
50
38
  >
51
39
  {text}
52
40
  </ChakraButton>
@@ -15,25 +15,20 @@ export const SpinnerButton: React.FC<SpinnerButtonProps> = ({
15
15
  onClick,
16
16
  type,
17
17
  ariaLabel,
18
- style,
19
18
  variant = 'solid',
20
- colorScheme = 'primary',
21
- size = 'md',
19
+
22
20
  disabled,
23
21
  className,
24
22
  }) => {
25
23
  return (
26
24
  <Button
27
- spinner={<Spinner size={size} />}
25
+ spinner={<Spinner size={'md'} />}
28
26
  isLoading={isLoading}
29
27
  onClick={onClick}
30
28
  type={type}
31
29
  variant={variant}
32
- colorScheme={colorScheme}
33
- size={size}
34
30
  disabled={disabled}
35
31
  aria-label={ariaLabel}
36
- style={style}
37
32
  className={className}
38
33
  >
39
34
  {text}
@@ -5,8 +5,7 @@ import { Input, InputProps } from '.';
5
5
  import { useFormHandler } from '../form/hooks/useFormHandler';
6
6
  import * as Yup from 'yup';
7
7
  import { Form } from '../form';
8
- import ipRegex from 'ip-regex';
9
- import { useEffect, useMemo } from '@storybook/addons';
8
+ import { useMemo } from '@storybook/addons';
10
9
 
11
10
  const meta: Meta<InputProps<StoryFormSchema>> = {
12
11
  title: 'Input example',
@@ -19,17 +18,6 @@ const meta: Meta<InputProps<StoryFormSchema>> = {
19
18
  description: 'The label for the input',
20
19
  },
21
20
  inputType: {
22
- control: 'select',
23
- options: [
24
- 'text',
25
- 'textarea',
26
- 'radio',
27
- 'select',
28
- 'checkbox',
29
- 'multi-select',
30
- 'pilled-text',
31
- 'switch',
32
- ],
33
21
  description: 'The type of the input',
34
22
  },
35
23
  options: {
@@ -70,47 +58,28 @@ const meta: Meta<InputProps<StoryFormSchema>> = {
70
58
 
71
59
  interface StoryFormSchema {
72
60
  prop?: string;
61
+ prop2?: string;
62
+ prop3?: string;
63
+ prop4?: string;
64
+ prop5?: string;
73
65
  }
74
66
 
75
67
  const onStubbedSubmit = () => null;
76
68
 
77
69
  const storyFormDefaultValues: StoryFormSchema = {
78
70
  prop: '',
71
+ prop2: '',
72
+ prop3: '',
73
+ prop4: '',
74
+ prop5: '',
79
75
  };
80
76
 
81
77
  const storyFormSchema: Yup.SchemaOf<StoryFormSchema> = Yup.object().shape({
82
- prop: Yup.string().test(
83
- 'Valid IP',
84
- 'Please enter a valid IP address.',
85
- (value, testContext) => {
86
- if (value) {
87
- const ipStringsToArray = value.split(',');
88
- const isIPValidArray = ipStringsToArray.map(ip => {
89
- return ipRegex({ exact: true }).test(ip as string);
90
- });
91
-
92
- if (isIPValidArray && isIPValidArray.includes(false)) {
93
- const malformedIPList = isIPValidArray
94
- // eslint-disable-next-line
95
- .map((testedIP, i) => {
96
- if (testedIP === false) {
97
- const malformedIP = ipStringsToArray[i];
98
-
99
- return malformedIP.trim();
100
- }
101
- })
102
- .filter(invalidIP => invalidIP !== undefined);
103
-
104
- const errorMessage = `Malformed IPs: ${malformedIPList.join(', ')}`;
105
- return testContext.createError({
106
- message:
107
- errorMessage.length <= 45 ? errorMessage : `${errorMessage}...`,
108
- });
109
- }
110
- }
111
- return true;
112
- }
113
- ),
78
+ prop: Yup.string(),
79
+ prop2: Yup.string(),
80
+ prop3: Yup.string(),
81
+ prop4: Yup.string(),
82
+ prop5: Yup.string(),
114
83
  });
115
84
 
116
85
  export default meta;
@@ -125,23 +94,37 @@ const Template: Story<InputProps<StoryFormSchema>> = args => {
125
94
 
126
95
  const { form } = formHandler;
127
96
 
128
- const valueErrorMessage = useMemo(() => {
129
- if (form.formState.errors) return form.formState.errors.prop?.message;
130
- }, [form.formState.errors]);
131
-
132
- console.log(form.watch('prop'));
133
-
134
- useEffect(() => {
135
- form.resetField('prop');
136
- }, [args.inputType]);
137
-
138
97
  return (
139
98
  <Form formHandler={formHandler}>
140
99
  <Input
141
100
  {...args}
101
+ inputType="multi-select"
102
+ setValue={form.setValue}
103
+ name="prop5"
104
+ />
105
+ <Input
106
+ {...args}
107
+ inputType="select"
108
+ setValue={form.setValue}
109
+ name="prop4"
110
+ />
111
+ <Input
112
+ {...args}
113
+ inputType="text"
114
+ name="prop3"
115
+ onChange={e => form.setValue('prop3', e.target.value)}
116
+ />
117
+ <Input
118
+ {...args}
119
+ inputType="textarea"
120
+ name="prop2"
121
+ onChange={e => form.setValue('prop2', e.target.value)}
122
+ />
123
+ <Input
124
+ {...args}
125
+ name="prop"
126
+ inputType="pilled-text"
142
127
  setValue={form.setValue}
143
- errorText={valueErrorMessage}
144
- isInvalid={!!valueErrorMessage}
145
128
  />
146
129
  </Form>
147
130
  );
@@ -151,19 +134,38 @@ export const Default = Template.bind({});
151
134
  Default.args = {
152
135
  label: 'Input Label',
153
136
  inputType: 'text',
154
- name: 'prop',
155
137
  options: [
138
+ { value: 'section_header', label: 'Section 1', sortValue: 0 },
156
139
  {
157
140
  value: 'value1',
158
141
  label: 'Value 1',
142
+ sortValue: 1,
159
143
  },
160
144
  {
161
145
  value: 'value2',
162
146
  label: 'Value 2',
147
+ sortValue: 2,
163
148
  },
164
149
  {
165
150
  value: 'value3',
166
151
  label: 'Value 3',
152
+ sortValue: 3,
153
+ },
154
+ {
155
+ value: 'value4',
156
+ label: 'Value 4',
157
+ sortValue: 4,
158
+ },
159
+ { value: 'section_header', label: 'Section 2', sortValue: 5 },
160
+ {
161
+ value: 'value5',
162
+ label: 'Value 5',
163
+ sortValue: 6,
164
+ },
165
+ {
166
+ value: 'value6',
167
+ label: 'Value 6',
168
+ sortValue: 7,
167
169
  },
168
170
  ],
169
171
  isRequired: true,
@@ -18,7 +18,13 @@ export type InputType =
18
18
  | 'checkbox'
19
19
  | 'switch';
20
20
 
21
- export type FieldOptions = { label: string; value: string }[];
21
+ export type FieldOption = {
22
+ label: string;
23
+ value: string | 'section_header';
24
+ sortValue: number;
25
+ };
26
+
27
+ export type FieldOptions = FieldOption[];
22
28
 
23
29
  export interface ValidationProps {
24
30
  isRequired: boolean;
@@ -1,29 +1,17 @@
1
1
  import React from 'react';
2
- import { Input, InputGroup } from '@chakra-ui/react';
2
+ import { Input } from '@chakra-ui/react';
3
3
  import { InputFieldProps } from '../InputTypes';
4
4
 
5
5
  export interface StackedInputProps extends InputFieldProps {
6
- label?: string;
7
6
  isRequired?: boolean;
8
- leftElement?: React.ReactNode;
9
- rightElement?: React.ReactNode;
10
7
  }
11
8
 
12
9
  /**
13
10
  * A functional React component utilized to render the `StackedInput` component.
14
11
  */
15
12
  const StackedInput = React.forwardRef<HTMLInputElement, StackedInputProps>(
16
- (
17
- { type = 'text', isRequired, leftElement, rightElement, ...props },
18
- _ref
19
- ) => {
20
- return (
21
- <InputGroup>
22
- {leftElement && leftElement}
23
- <Input ref={_ref} type={type} isRequired={isRequired} {...props} />
24
- {rightElement && rightElement}
25
- </InputGroup>
26
- );
13
+ ({ type = 'text', isRequired, ...props }, _ref) => {
14
+ return <Input ref={_ref} type={type} isRequired={isRequired} {...props} />;
27
15
  }
28
16
  );
29
17
 
@@ -1,6 +1,6 @@
1
1
  import { Box } from '@chakra-ui/react';
2
2
  import React, { PropsWithChildren } from 'react';
3
- import InputTag from '../../../components/InputTag';
3
+ import InputTag from '../../../components/token';
4
4
 
5
5
  interface MultiValueProps extends PropsWithChildren {
6
6
  clearValue: () => void;
@@ -13,7 +13,7 @@ interface MultiValueProps extends PropsWithChildren {
13
13
  const MultiValue: React.FC<MultiValueProps> = ({ children, clearValue }) => {
14
14
  return (
15
15
  <Box marginRight="5px">
16
- <InputTag value={children} onDelete={clearValue} />
16
+ <InputTag label={children} onDelete={clearValue} />
17
17
  </Box>
18
18
  );
19
19
  };
@@ -1,15 +1,20 @@
1
- import React, { useEffect, useState } from 'react';
2
- import { Flex } from '@chakra-ui/react';
3
- import { FieldOptions, ReactSelectFieldProps } from '../InputTypes';
4
- import ReactSelect from 'react-select';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { Box, Flex, Text, Image, useOutsideClick } from '@chakra-ui/react';
3
+ import {
4
+ FieldOption,
5
+ FieldOptions,
6
+ ReactSelectFieldProps,
7
+ } from '../InputTypes';
5
8
  import colors from '../../../theme/foundations/colors';
6
- import MultiValue from './components/MultiValue';
7
9
  import {
8
10
  Control,
9
11
  FieldValues,
10
12
  UseFormSetValue,
11
13
  useWatch,
12
14
  } from 'react-hook-form';
15
+ import SubtractIcon from '../StackedSelect/assets/svg/subtract.svg';
16
+ import { Dropdown } from '../components/dropdown';
17
+ import Token from '../components/token';
13
18
 
14
19
  export interface StackedMultiSelectProps extends ReactSelectFieldProps {
15
20
  options: FieldOptions;
@@ -21,22 +26,26 @@ export interface StackedMultiSelectProps extends ReactSelectFieldProps {
21
26
  * A functional React component utilized to render the `StackedMultiSelect` component.
22
27
  */
23
28
  const StackedMultiSelect = React.forwardRef<
24
- HTMLSelectElement,
29
+ HTMLInputElement,
25
30
  StackedMultiSelectProps
26
- >(({ options, setValue, control, name }, _ref) => {
31
+ >(({ options, setValue, control, name, placeholder, disabled }, _ref) => {
27
32
  const watchedValue = useWatch({ control, name: name as string });
33
+ const dropdownRef = useRef(null);
34
+
35
+ const [localValues, setLocalValues] = useState<FieldOptions>([]);
36
+ const [localOptions, setLocalOptions] = useState<FieldOptions>(options);
37
+ const [isFocussed, setIsFocussed] = useState(false);
28
38
 
29
- const [inputValue, setInputValue] = useState('');
30
- const [localValue, setLocalValue] = useState([]);
39
+ useOutsideClick({ ref: dropdownRef, handler: () => setIsFocussed(false) });
31
40
 
32
41
  // gets latest watched form value (common delimited) from RHF state and creates a list
33
42
  useEffect(() => {
34
43
  if (watchedValue !== undefined && !watchedValue.length) {
35
- setLocalValue([]);
44
+ setLocalValues([]);
36
45
  }
37
46
 
38
47
  if (watchedValue !== undefined && watchedValue?.length) {
39
- setLocalValue(
48
+ setLocalValues(
40
49
  watchedValue
41
50
  .split(',')
42
51
  .filter(Boolean)
@@ -47,98 +56,85 @@ const StackedMultiSelect = React.forwardRef<
47
56
  }
48
57
  }, [options, watchedValue]);
49
58
 
50
- const component = {
51
- DropdownIndicator: null,
52
- MultiValue: (props: any) => (
53
- <MultiValue
54
- clearValue={() => {
55
- const arrayValue = watchedValue
56
- .split(',')
57
- .filter((_: string, index: number) => index !== props.index);
58
-
59
- setLocalValue(
60
- arrayValue.map((value: string) =>
61
- options.find(option => option.value === value)
62
- )
63
- );
64
-
65
- setValue(name as string, arrayValue.join(','), {
66
- shouldValidate: true,
67
- shouldDirty: true,
68
- });
69
- }}
70
- >
71
- {props.children}
72
- </MultiValue>
73
- ),
74
- };
59
+ const handleChange = (option: FieldOption) => {
60
+ const newValue = [...localValues, option]
61
+ .map(({ value }) => value)
62
+ .join(',');
75
63
 
76
- const handleChange = (values: any) => {
77
- setValue(
78
- name as string,
79
- values.map(({ value }: { value: string }) => value).join(','),
80
- {
81
- shouldValidate: true,
82
- shouldDirty: true,
83
- }
64
+ setValue(name as string, newValue, {
65
+ shouldValidate: true,
66
+ shouldDirty: true,
67
+ });
68
+
69
+ setLocalOptions(prevLocalOptions =>
70
+ prevLocalOptions.filter(prevLocalOption => prevLocalOption !== option)
84
71
  );
72
+
73
+ setLocalValues(prevLocalValues => [...prevLocalValues, option]);
85
74
  };
86
75
 
87
- const handleInputChange = (value: string, action: any) => {
88
- if (action.action === 'input-change' && action !== 'set-value') {
89
- return setInputValue(value);
90
- }
76
+ const handleDelete = (option: FieldOption) => {
77
+ const newValue = localValues
78
+ .filter(localValue => localValue !== option)
79
+ .map(({ value }) => value)
80
+ .join(',');
91
81
 
92
- // reset on select of an option
93
- return setInputValue('');
94
- };
82
+ setValue(name as string, newValue, {
83
+ shouldValidate: true,
84
+ shouldDirty: true,
85
+ });
95
86
 
96
- const formatGroupLabel = (data: any) => {
97
- return (
98
- <Flex alignItems="center" justifyContent="space-between">
99
- <span>{data.label}</span>
100
- </Flex>
87
+ setLocalOptions(prevLocalOptions =>
88
+ [...prevLocalOptions, option].sort((a, b) => a.sortValue - b.sortValue)
101
89
  );
102
- };
103
90
 
104
- const customStyles = {
105
- control: () => ({
106
- borderRadius: '6px',
107
- fontSize: '16px',
108
- color: '#202020',
109
- backgroundColor: '#FFFFFF',
110
- border: '1px solid',
111
- borderColor: colors.gray[200],
112
- minHeight: '48px',
113
- display: 'flex',
114
- padding: '2px 6px',
115
- }),
116
- menu: () => ({
117
- boxShadow: '0 5px 5px 0 rgba(16, 27, 79, 0.15)',
118
- borderRadius: '6px',
119
- backgroundColor: 'white',
120
- }),
121
- indicatorsContainer: () => ({ display: 'none' }),
122
- placeholder: () => ({ color: '#CBCDCF', fontSize: '16px' }),
91
+ setLocalValues(prevLocalValues =>
92
+ prevLocalValues.filter(prevLocalValue => prevLocalValue !== option)
93
+ );
123
94
  };
124
95
 
125
96
  return (
126
- <ReactSelect
127
- components={component}
128
- inputValue={inputValue}
129
- value={localValue}
130
- isClearable
131
- isSearchable
132
- isMulti
133
- menuPortalTarget={document.body}
134
- menuPosition={'fixed'}
135
- onChange={handleChange}
136
- onInputChange={handleInputChange}
137
- styles={customStyles}
138
- options={options}
139
- placeholder={false}
140
- formatGroupLabel={formatGroupLabel}
141
- />
97
+ <Box ref={dropdownRef} position="relative">
98
+ <Flex
99
+ fontSize="13px"
100
+ border={isFocussed ? '2px solid' : '1px solid'}
101
+ borderColor={isFocussed ? colors.border.focus : colors.border.default}
102
+ py="5px"
103
+ pl="8px"
104
+ borderRadius="4px"
105
+ alignItems="center"
106
+ justifyContent="space-between"
107
+ onClick={() => !disabled && setIsFocussed(true)}
108
+ bg={disabled ? colors.fill.light.quaternary : '#ffffff'}
109
+ cursor={disabled ? 'not-allowed' : 'pointer'}
110
+ >
111
+ <Flex height="28px" alignItems="center">
112
+ {localValues.length ? (
113
+ localValues.map(option => (
114
+ <Box mr="4px">
115
+ <Token
116
+ label={option.label}
117
+ onDelete={() => handleDelete(option)}
118
+ />
119
+ </Box>
120
+ ))
121
+ ) : (
122
+ <Text color={colors.label.secondary.light} fontSize="13px">
123
+ {placeholder}
124
+ </Text>
125
+ )}
126
+ </Flex>
127
+ <Flex width="39px" justifyContent="center" alignItems="center">
128
+ <Image src={SubtractIcon} alt="subtract" boxSize="16px" />
129
+ </Flex>
130
+ </Flex>
131
+ {isFocussed && (
132
+ <Dropdown
133
+ onSelectItem={option => handleChange(option)}
134
+ options={localOptions}
135
+ />
136
+ )}
137
+ </Box>
142
138
  );
143
139
  });
144
140