@dktunited-techoff/techoff-suite-ui 1.14.9 → 1.15.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.
@@ -11,6 +11,11 @@
11
11
  border: 1px solid #949494;
12
12
  cursor: pointer;
13
13
  }
14
+ .ts-dropdown-input .icon .ts-icon{
15
+ background-color: #3542ba;
16
+ color: #ffffff;
17
+ border-radius: 50%;
18
+ }
14
19
  .ts-dropdown-input--disabled {
15
20
  background: #fafafa;
16
21
  cursor: not-allowed;
@@ -1,4 +1,4 @@
1
1
  import * as React from 'react';
2
2
  import { TsDropdownProps } from './TsDropdown.types';
3
3
  import './TsDropdown.css';
4
- export declare const TsDropdown: <T>({ containerRef, error, errorAction, label, noItemFoundMessage, options, placeholder, reloadOptionsOn, searchPlaceholder, value, disabled, searchable, action, getOptionLabel, getOptionValue, loadOptions, onChange, }: TsDropdownProps<T>) => React.JSX.Element;
4
+ export declare const TsDropdown: <T>({ containerRef, error, errorAction, label, noItemFoundMessage, options, placeholder, reloadOptionsOn, searchPlaceholder, value, disabled, searchable, action, listMode, getOptionLabel, getOptionValue, loadOptions, onChange, onChangeList, }: TsDropdownProps<T>) => React.JSX.Element;
@@ -1,16 +1,19 @@
1
+ /* eslint-disable no-case-declarations */
1
2
  import * as React from 'react';
2
3
  import { useEffect, useRef, useState } from 'react';
3
4
  import { TsIcon } from '../../TsIcon/TsIcon';
4
5
  import { TsInput } from '../../TsInput/TsInput/TsInput';
5
6
  import { useClickOutside } from '../../../hooks/use-click-outside';
6
7
  import { TsLoader } from '../../TsLoader/TsLoader';
8
+ import { TsCheckbox } from '../../TsCheckbox/TsCheckbox';
7
9
  import './TsDropdown.css';
8
- export const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoundMessage, options, placeholder, reloadOptionsOn = [], searchPlaceholder, value, disabled, searchable, action, getOptionLabel, getOptionValue, loadOptions, onChange, }) => {
10
+ export const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoundMessage, options, placeholder, reloadOptionsOn = [], searchPlaceholder, value, disabled, searchable, action, listMode, getOptionLabel, getOptionValue, loadOptions, onChange, onChangeList, }) => {
9
11
  const [showDropdownMenu, setShowDropdownMenu] = useState(false);
10
12
  const [searchValue, setSearchValue] = useState('');
11
13
  const [items, setItems] = useState(options ?? []);
12
14
  const [isLoading, setIsLoading] = useState(false);
13
15
  const [isFetchError, setIsFetchError] = useState(false);
16
+ const [chosenItems, setChosenItems] = useState(value);
14
17
  const dropdownRef = useClickOutside(() => setShowDropdownMenu(false));
15
18
  const dropdownMenuRef = useRef(null);
16
19
  // ########
@@ -32,6 +35,27 @@ export const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoun
32
35
  onChange(item);
33
36
  };
34
37
  const handleToggleDropdownMenu = () => !disabled && setShowDropdownMenu(!showDropdownMenu);
38
+ const handleEmptyList = (event) => {
39
+ event.stopPropagation();
40
+ setChosenItems([]);
41
+ onChange(undefined);
42
+ };
43
+ const handleManageItem = (event, action, value) => {
44
+ if (onChangeList) {
45
+ event.stopPropagation();
46
+ switch (action) {
47
+ case 'remove':
48
+ const filteredList = chosenItems.filter(item => getOptionValue(item) !== getOptionValue(value));
49
+ setChosenItems(filteredList);
50
+ onChangeList(filteredList.length > 0 ? filteredList : undefined);
51
+ break;
52
+ case 'add':
53
+ const newValues = chosenItems ? [...chosenItems, value] : [value];
54
+ setChosenItems(newValues);
55
+ onChangeList(newValues);
56
+ }
57
+ }
58
+ };
35
59
  // ########
36
60
  // Watchers
37
61
  useEffect(() => {
@@ -79,8 +103,20 @@ export const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoun
79
103
  ${disabled ? 'ts-dropdown-input--disabled' : ''}
80
104
  ${error && error !== '' ? 'ts-dropdown-container--error' : ''}
81
105
  `, onClick: handleToggleDropdownMenu },
82
- !value && React.createElement("div", { className: "ts-dropdown-input--placeholder" }, placeholder),
83
- value && React.createElement("div", { className: "ts-dropdown-input--value" }, getOptionLabel(value)),
106
+ !value && (!chosenItems || chosenItems.length === 0) && (React.createElement("div", { className: "ts-dropdown-input--placeholder" }, placeholder)),
107
+ value && !listMode && React.createElement("div", { className: "ts-dropdown-input--value" }, getOptionLabel(value)),
108
+ listMode && chosenItems?.length > 0 && (React.createElement(React.Fragment, null,
109
+ chosenItems.length > 2 ? (React.createElement("div", { className: "ts-dropdown-input--value" },
110
+ chosenItems
111
+ .map(item => getOptionValue(item))
112
+ .slice(0, 2)
113
+ .join(', '),
114
+ ' ',
115
+ "& ",
116
+ chosenItems.length - 2,
117
+ " others")) : (React.createElement("div", { className: "ts-dropdown-input--value" }, chosenItems.map(item => getOptionValue(item)).join(', '))),
118
+ React.createElement("div", { className: "icon", onClick: event => handleEmptyList(event) },
119
+ React.createElement(TsIcon, { name: "close" })))),
84
120
  React.createElement("div", { className: "ts-dropdown-input--chevron" }, showDropdownMenu ? (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor" },
85
121
  React.createElement("path", { d: "M11.9999 10.8286L7.0502 15.7783L5.63599 14.3641L11.9999 7.99996L18.3639 14.3641L16.9497 15.7783L11.9999 10.8286Z" }))) : (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor" },
86
122
  React.createElement("path", { d: "M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z" })))))),
@@ -96,10 +132,30 @@ export const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoun
96
132
  React.createElement(TsLoader, { size: "sm" }))),
97
133
  !isLoading && isFetchError && (React.createElement("div", { className: "ts-dropdown-menu-error-text" }, "An error occured, try again later.")),
98
134
  !isLoading && !isFetchError && items.length === 0 && (React.createElement("div", { className: "ts-dropdown-menu-error-text" }, noItemFoundMessage ?? 'No option found.')),
99
- !isLoading &&
135
+ !listMode &&
136
+ !isLoading &&
100
137
  !isFetchError &&
101
138
  items.length > 0 &&
102
- items.map(item => (React.createElement("div", { key: getOptionValue(item), className: "ts-dropdown-menu-item", onClick: () => handleSelectItem(item) }, getOptionLabel(item))))),
139
+ items.map(item => (React.createElement("div", { key: getOptionValue(item), className: "ts-dropdown-menu-item", onClick: () => handleSelectItem(item) }, getOptionLabel(item)))),
140
+ listMode &&
141
+ !isLoading &&
142
+ !isFetchError &&
143
+ items
144
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
145
+ .concat(chosenItems ?? []).length > 0 &&
146
+ items
147
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
148
+ .concat(chosenItems ?? [])
149
+ .sort((a, b) => {
150
+ const aIncluded = chosenItems?.includes(a) ? 1 : 0;
151
+ const bIncluded = chosenItems?.includes(b) ? 1 : 0;
152
+ return bIncluded - aIncluded;
153
+ })
154
+ .map(item => (React.createElement("div", { key: getOptionLabel(item), className: "ts-dropdown-menu-item", onClick: event => handleManageItem(event, chosenItems && chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item))
155
+ ? 'remove'
156
+ : 'add', item) },
157
+ listMode && (React.createElement(TsCheckbox, { checked: chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item)), onChange: () => { } })),
158
+ getOptionValue(item))))),
103
159
  action && React.createElement("div", { className: "ts-dropdown-action" }, action)))));
104
160
  };
105
161
  //# sourceMappingURL=TsDropdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TsDropdown.js","sourceRoot":"","sources":["../../../../src/components/TsDropdowns/TsDropdown/TsDropdown.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TsDropdown.js","sourceRoot":"","sources":["../../../../src/components/TsDropdowns/TsDropdown/TsDropdown.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-case-declarations */
1
2
  import * as React from 'react';
2
3
  import { useEffect, useRef, useState } from 'react';
3
4
  import { TsDropdownProps } from './TsDropdown.types';
@@ -5,6 +6,7 @@ import { TsIcon } from '../../TsIcon/TsIcon';
5
6
  import { TsInput } from '../../TsInput/TsInput/TsInput';
6
7
  import { useClickOutside } from '../../../hooks/use-click-outside';
7
8
  import { TsLoader } from '../../TsLoader/TsLoader';
9
+ import { TsCheckbox } from '../../TsCheckbox/TsCheckbox';
8
10
  import './TsDropdown.css';
9
11
 
10
12
  export const TsDropdown = <T,>({
@@ -21,16 +23,19 @@ export const TsDropdown = <T,>({
21
23
  disabled,
22
24
  searchable,
23
25
  action,
26
+ listMode,
24
27
  getOptionLabel,
25
28
  getOptionValue,
26
29
  loadOptions,
27
30
  onChange,
31
+ onChangeList,
28
32
  }: TsDropdownProps<T>) => {
29
33
  const [showDropdownMenu, setShowDropdownMenu] = useState<boolean>(false);
30
34
  const [searchValue, setSearchValue] = useState<string>('');
31
35
  const [items, setItems] = useState<T[]>(options ?? []);
32
36
  const [isLoading, setIsLoading] = useState<boolean>(false);
33
37
  const [isFetchError, setIsFetchError] = useState<boolean>(false);
38
+ const [chosenItems, setChosenItems] = useState<T[]>(value as T[]);
34
39
  const dropdownRef = useClickOutside(() => setShowDropdownMenu(false));
35
40
  const dropdownMenuRef = useRef<HTMLDivElement>(null);
36
41
 
@@ -55,6 +60,29 @@ export const TsDropdown = <T,>({
55
60
  };
56
61
  const handleToggleDropdownMenu = () => !disabled && setShowDropdownMenu(!showDropdownMenu);
57
62
 
63
+ const handleEmptyList = (event: React.MouseEvent<HTMLDivElement>) => {
64
+ event.stopPropagation();
65
+ setChosenItems([]);
66
+ onChange(undefined);
67
+ };
68
+
69
+ const handleManageItem = (event: React.FormEvent<HTMLDivElement>, action: string, value: T) => {
70
+ if (onChangeList) {
71
+ event.stopPropagation();
72
+ switch (action) {
73
+ case 'remove':
74
+ const filteredList = chosenItems.filter(item => getOptionValue(item) !== getOptionValue(value));
75
+ setChosenItems(filteredList);
76
+ onChangeList(filteredList.length > 0 ? filteredList : undefined);
77
+ break;
78
+ case 'add':
79
+ const newValues = chosenItems ? [...chosenItems, value] : [value];
80
+ setChosenItems(newValues);
81
+ onChangeList(newValues);
82
+ }
83
+ }
84
+ };
85
+
58
86
  // ########
59
87
  // Watchers
60
88
  useEffect(() => {
@@ -106,8 +134,30 @@ export const TsDropdown = <T,>({
106
134
  `}
107
135
  onClick={handleToggleDropdownMenu}
108
136
  >
109
- {!value && <div className="ts-dropdown-input--placeholder">{placeholder}</div>}
110
- {value && <div className="ts-dropdown-input--value">{getOptionLabel(value)}</div>}
137
+ {!value && (!chosenItems || chosenItems.length === 0) && (
138
+ <div className="ts-dropdown-input--placeholder">{placeholder}</div>
139
+ )}
140
+ {value && !listMode && <div className="ts-dropdown-input--value">{getOptionLabel(value as T)}</div>}
141
+ {listMode && chosenItems?.length > 0 && (
142
+ <>
143
+ {chosenItems.length > 2 ? (
144
+ <div className="ts-dropdown-input--value">
145
+ {chosenItems
146
+ .map(item => getOptionValue(item))
147
+ .slice(0, 2)
148
+ .join(', ')}{' '}
149
+ & {chosenItems.length - 2} others
150
+ </div>
151
+ ) : (
152
+ <div className="ts-dropdown-input--value">
153
+ {chosenItems.map(item => getOptionValue(item)).join(', ')}
154
+ </div>
155
+ )}
156
+ <div className="icon" onClick={event => handleEmptyList(event)}>
157
+ <TsIcon name="close" />
158
+ </div>
159
+ </>
160
+ )}
111
161
  <div className="ts-dropdown-input--chevron">
112
162
  {showDropdownMenu ? (
113
163
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
@@ -161,7 +211,8 @@ export const TsDropdown = <T,>({
161
211
  {!isLoading && !isFetchError && items.length === 0 && (
162
212
  <div className="ts-dropdown-menu-error-text">{noItemFoundMessage ?? 'No option found.'}</div>
163
213
  )}
164
- {!isLoading &&
214
+ {!listMode &&
215
+ !isLoading &&
165
216
  !isFetchError &&
166
217
  items.length > 0 &&
167
218
  items.map(item => (
@@ -173,6 +224,43 @@ export const TsDropdown = <T,>({
173
224
  {getOptionLabel(item)}
174
225
  </div>
175
226
  ))}
227
+ {listMode &&
228
+ !isLoading &&
229
+ !isFetchError &&
230
+ items
231
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
232
+ .concat(chosenItems ?? []).length > 0 &&
233
+ items
234
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
235
+ .concat(chosenItems ?? [])
236
+ .sort((a, b) => {
237
+ const aIncluded = chosenItems?.includes(a) ? 1 : 0;
238
+ const bIncluded = chosenItems?.includes(b) ? 1 : 0;
239
+ return bIncluded - aIncluded;
240
+ })
241
+ .map(item => (
242
+ <div
243
+ key={getOptionLabel(item)}
244
+ className="ts-dropdown-menu-item"
245
+ onClick={event =>
246
+ handleManageItem(
247
+ event,
248
+ chosenItems && chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item))
249
+ ? 'remove'
250
+ : 'add',
251
+ item,
252
+ )
253
+ }
254
+ >
255
+ {listMode && (
256
+ <TsCheckbox
257
+ checked={chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item))}
258
+ onChange={() => {}}
259
+ />
260
+ )}
261
+ {getOptionValue(item)}
262
+ </div>
263
+ ))}
176
264
  </div>
177
265
  {action && <div className="ts-dropdown-action">{action}</div>}
178
266
  </div>
@@ -8,13 +8,15 @@ export type TsDropdownProps<T> = {
8
8
  placeholder?: string;
9
9
  reloadOptionsOn?: any[];
10
10
  searchPlaceholder?: string;
11
- value?: T;
11
+ value?: T | T[];
12
12
  disabled?: boolean;
13
13
  searchable?: boolean;
14
14
  action?: ReactNode;
15
15
  errorAction?: string;
16
+ listMode?: boolean;
16
17
  getOptionLabel: (option: T) => string;
17
18
  getOptionValue: (option: T) => string;
18
19
  loadOptions?: (search?: string) => Promise<T[]>;
19
20
  onChange: (value?: T) => void;
21
+ onChangeList?: (values?: T[]) => void;
20
22
  };
@@ -9,13 +9,15 @@ export type TsDropdownProps<T> = {
9
9
  placeholder?: string;
10
10
  reloadOptionsOn?: any[];
11
11
  searchPlaceholder?: string;
12
- value?: T;
12
+ value?: T | T[];
13
13
  disabled?: boolean;
14
14
  searchable?: boolean;
15
15
  action?: ReactNode;
16
16
  errorAction?: string;
17
+ listMode?: boolean;
17
18
  getOptionLabel: (option: T) => string;
18
19
  getOptionValue: (option: T) => string;
19
20
  loadOptions?: (search?: string) => Promise<T[]>;
20
21
  onChange: (value?: T) => void;
22
+ onChangeList?: (values?: T[]) => void;
21
23
  };
@@ -11,6 +11,11 @@
11
11
  border: 1px solid #949494;
12
12
  cursor: pointer;
13
13
  }
14
+ .ts-dropdown-input .icon .ts-icon{
15
+ background-color: #3542ba;
16
+ color: #ffffff;
17
+ border-radius: 50%;
18
+ }
14
19
  .ts-dropdown-input--disabled {
15
20
  background: #fafafa;
16
21
  cursor: not-allowed;
@@ -1,4 +1,4 @@
1
1
  import * as React from 'react';
2
2
  import { TsDropdownProps } from './TsDropdown.types';
3
3
  import './TsDropdown.css';
4
- export declare const TsDropdown: <T>({ containerRef, error, errorAction, label, noItemFoundMessage, options, placeholder, reloadOptionsOn, searchPlaceholder, value, disabled, searchable, action, getOptionLabel, getOptionValue, loadOptions, onChange, }: TsDropdownProps<T>) => React.JSX.Element;
4
+ export declare const TsDropdown: <T>({ containerRef, error, errorAction, label, noItemFoundMessage, options, placeholder, reloadOptionsOn, searchPlaceholder, value, disabled, searchable, action, listMode, getOptionLabel, getOptionValue, loadOptions, onChange, onChangeList, }: TsDropdownProps<T>) => React.JSX.Element;
@@ -1,19 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TsDropdown = void 0;
4
+ /* eslint-disable no-case-declarations */
4
5
  const React = require("react");
5
6
  const react_1 = require("react");
6
7
  const TsIcon_1 = require("../../TsIcon/TsIcon");
7
8
  const TsInput_1 = require("../../TsInput/TsInput/TsInput");
8
9
  const use_click_outside_1 = require("../../../hooks/use-click-outside");
9
10
  const TsLoader_1 = require("../../TsLoader/TsLoader");
11
+ const TsCheckbox_1 = require("../../TsCheckbox/TsCheckbox");
10
12
  require("./TsDropdown.css");
11
- const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoundMessage, options, placeholder, reloadOptionsOn = [], searchPlaceholder, value, disabled, searchable, action, getOptionLabel, getOptionValue, loadOptions, onChange, }) => {
13
+ const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoundMessage, options, placeholder, reloadOptionsOn = [], searchPlaceholder, value, disabled, searchable, action, listMode, getOptionLabel, getOptionValue, loadOptions, onChange, onChangeList, }) => {
12
14
  const [showDropdownMenu, setShowDropdownMenu] = (0, react_1.useState)(false);
13
15
  const [searchValue, setSearchValue] = (0, react_1.useState)('');
14
16
  const [items, setItems] = (0, react_1.useState)(options ?? []);
15
17
  const [isLoading, setIsLoading] = (0, react_1.useState)(false);
16
18
  const [isFetchError, setIsFetchError] = (0, react_1.useState)(false);
19
+ const [chosenItems, setChosenItems] = (0, react_1.useState)(value);
17
20
  const dropdownRef = (0, use_click_outside_1.useClickOutside)(() => setShowDropdownMenu(false));
18
21
  const dropdownMenuRef = (0, react_1.useRef)(null);
19
22
  // ########
@@ -35,6 +38,27 @@ const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoundMessag
35
38
  onChange(item);
36
39
  };
37
40
  const handleToggleDropdownMenu = () => !disabled && setShowDropdownMenu(!showDropdownMenu);
41
+ const handleEmptyList = (event) => {
42
+ event.stopPropagation();
43
+ setChosenItems([]);
44
+ onChange(undefined);
45
+ };
46
+ const handleManageItem = (event, action, value) => {
47
+ if (onChangeList) {
48
+ event.stopPropagation();
49
+ switch (action) {
50
+ case 'remove':
51
+ const filteredList = chosenItems.filter(item => getOptionValue(item) !== getOptionValue(value));
52
+ setChosenItems(filteredList);
53
+ onChangeList(filteredList.length > 0 ? filteredList : undefined);
54
+ break;
55
+ case 'add':
56
+ const newValues = chosenItems ? [...chosenItems, value] : [value];
57
+ setChosenItems(newValues);
58
+ onChangeList(newValues);
59
+ }
60
+ }
61
+ };
38
62
  // ########
39
63
  // Watchers
40
64
  (0, react_1.useEffect)(() => {
@@ -82,8 +106,20 @@ const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoundMessag
82
106
  ${disabled ? 'ts-dropdown-input--disabled' : ''}
83
107
  ${error && error !== '' ? 'ts-dropdown-container--error' : ''}
84
108
  `, onClick: handleToggleDropdownMenu },
85
- !value && React.createElement("div", { className: "ts-dropdown-input--placeholder" }, placeholder),
86
- value && React.createElement("div", { className: "ts-dropdown-input--value" }, getOptionLabel(value)),
109
+ !value && (!chosenItems || chosenItems.length === 0) && (React.createElement("div", { className: "ts-dropdown-input--placeholder" }, placeholder)),
110
+ value && !listMode && React.createElement("div", { className: "ts-dropdown-input--value" }, getOptionLabel(value)),
111
+ listMode && chosenItems?.length > 0 && (React.createElement(React.Fragment, null,
112
+ chosenItems.length > 2 ? (React.createElement("div", { className: "ts-dropdown-input--value" },
113
+ chosenItems
114
+ .map(item => getOptionValue(item))
115
+ .slice(0, 2)
116
+ .join(', '),
117
+ ' ',
118
+ "& ",
119
+ chosenItems.length - 2,
120
+ " others")) : (React.createElement("div", { className: "ts-dropdown-input--value" }, chosenItems.map(item => getOptionValue(item)).join(', '))),
121
+ React.createElement("div", { className: "icon", onClick: event => handleEmptyList(event) },
122
+ React.createElement(TsIcon_1.TsIcon, { name: "close" })))),
87
123
  React.createElement("div", { className: "ts-dropdown-input--chevron" }, showDropdownMenu ? (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor" },
88
124
  React.createElement("path", { d: "M11.9999 10.8286L7.0502 15.7783L5.63599 14.3641L11.9999 7.99996L18.3639 14.3641L16.9497 15.7783L11.9999 10.8286Z" }))) : (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor" },
89
125
  React.createElement("path", { d: "M11.9999 13.1714L16.9497 8.22168L18.3639 9.63589L11.9999 15.9999L5.63599 9.63589L7.0502 8.22168L11.9999 13.1714Z" })))))),
@@ -99,10 +135,30 @@ const TsDropdown = ({ containerRef, error, errorAction, label, noItemFoundMessag
99
135
  React.createElement(TsLoader_1.TsLoader, { size: "sm" }))),
100
136
  !isLoading && isFetchError && (React.createElement("div", { className: "ts-dropdown-menu-error-text" }, "An error occured, try again later.")),
101
137
  !isLoading && !isFetchError && items.length === 0 && (React.createElement("div", { className: "ts-dropdown-menu-error-text" }, noItemFoundMessage ?? 'No option found.')),
102
- !isLoading &&
138
+ !listMode &&
139
+ !isLoading &&
103
140
  !isFetchError &&
104
141
  items.length > 0 &&
105
- items.map(item => (React.createElement("div", { key: getOptionValue(item), className: "ts-dropdown-menu-item", onClick: () => handleSelectItem(item) }, getOptionLabel(item))))),
142
+ items.map(item => (React.createElement("div", { key: getOptionValue(item), className: "ts-dropdown-menu-item", onClick: () => handleSelectItem(item) }, getOptionLabel(item)))),
143
+ listMode &&
144
+ !isLoading &&
145
+ !isFetchError &&
146
+ items
147
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
148
+ .concat(chosenItems ?? []).length > 0 &&
149
+ items
150
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
151
+ .concat(chosenItems ?? [])
152
+ .sort((a, b) => {
153
+ const aIncluded = chosenItems?.includes(a) ? 1 : 0;
154
+ const bIncluded = chosenItems?.includes(b) ? 1 : 0;
155
+ return bIncluded - aIncluded;
156
+ })
157
+ .map(item => (React.createElement("div", { key: getOptionLabel(item), className: "ts-dropdown-menu-item", onClick: event => handleManageItem(event, chosenItems && chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item))
158
+ ? 'remove'
159
+ : 'add', item) },
160
+ listMode && (React.createElement(TsCheckbox_1.TsCheckbox, { checked: chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item)), onChange: () => { } })),
161
+ getOptionValue(item))))),
106
162
  action && React.createElement("div", { className: "ts-dropdown-action" }, action)))));
107
163
  };
108
164
  exports.TsDropdown = TsDropdown;
@@ -1 +1 @@
1
- {"version":3,"file":"TsDropdown.js","sourceRoot":"","sources":["../../../../src/components/TsDropdowns/TsDropdown/TsDropdown.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TsDropdown.js","sourceRoot":"","sources":["../../../../src/components/TsDropdowns/TsDropdown/TsDropdown.tsx"],"names":[],"mappings":";;;AAAA,yCAAyC;AACzC,+BAA+B;AAC/B,iCAAoD;AAEpD,gDAA6C;AAC7C,2DAAwD;AACxD,wEAAmE;AACnE,sDAAmD;AACnD,4DAAyD;AACzD,4BAA0B;AAEnB,MAAM,UAAU,GAAG,CAAK,EAC7B,YAAY,EACZ,KAAK,EACL,WAAW,EACX,KAAK,EACL,kBAAkB,EAClB,OAAO,EACP,WAAW,EACX,eAAe,GAAG,EAAE,EACpB,iBAAiB,EACjB,KAAK,EACL,QAAQ,EACR,UAAU,EACV,MAAM,EACN,QAAQ,EACR,cAAc,EACd,cAAc,EACd,WAAW,EACX,QAAQ,EACR,YAAY,GACO,EAAE,EAAE;IACvB,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,IAAA,gBAAQ,EAAU,KAAK,CAAC,CAAC;IACzE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAS,EAAE,CAAC,CAAC;IAC3D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAM,OAAO,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAA,gBAAQ,EAAU,KAAK,CAAC,CAAC;IAC3D,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,IAAA,gBAAQ,EAAU,KAAK,CAAC,CAAC;IACjE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAM,KAAY,CAAC,CAAC;IAClE,MAAM,WAAW,GAAG,IAAA,mCAAe,EAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,MAAM,eAAe,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAC;IAErD,WAAW;IACX,WAAW;IACX,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,CAAC,OAAO,IAAI,WAAW,EAAE;YAC3B,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,eAAe,CAAC,KAAK,CAAC,CAAC;YACvB,WAAW,CAAC,WAAW,CAAC;iBACrB,IAAI,CAAC,QAAQ,CAAC;iBACd,KAAK,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;iBAClC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;SACvC;IACH,CAAC,CAAC;IAEF,WAAW;IACX,WAAW;IACX,MAAM,gBAAgB,GAAG,CAAC,IAAO,EAAE,EAAE;QACnC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC,CAAC;IACF,MAAM,wBAAwB,GAAG,GAAG,EAAE,CAAC,CAAC,QAAQ,IAAI,mBAAmB,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAE3F,MAAM,eAAe,GAAG,CAAC,KAAuC,EAAE,EAAE;QAClE,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,cAAc,CAAC,EAAE,CAAC,CAAC;QACnB,QAAQ,CAAC,SAAS,CAAC,CAAC;IACtB,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CAAC,KAAsC,EAAE,MAAc,EAAE,KAAQ,EAAE,EAAE;QAC5F,IAAI,YAAY,EAAE;YAChB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,QAAQ,MAAM,EAAE;gBACd,KAAK,QAAQ;oBACX,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;oBAChG,cAAc,CAAC,YAAY,CAAC,CAAC;oBAC7B,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;oBACjE,MAAM;gBACR,KAAK,KAAK;oBACR,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;oBAClE,cAAc,CAAC,SAAS,CAAC,CAAC;oBAC1B,YAAY,CAAC,SAAS,CAAC,CAAC;aAC3B;SACF;IACH,CAAC,CAAC;IAEF,WAAW;IACX,WAAW;IACX,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ;YAAE,YAAY,EAAE,CAAC;IAChC,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,UAAU,IAAI,OAAO,EAAE;YACzB,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;SAC9G;QAED,IAAI,UAAU,IAAI,CAAC,OAAO,IAAI,WAAW,EAAE;YACzC,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,eAAe,CAAC,KAAK,CAAC,CAAC;YACvB,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YAChD,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;SACtC;QAED,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;IAClB,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAClB,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,UAAU,IAAI,CAAC,gBAAgB;YAAE,cAAc,CAAC,EAAE,CAAC,CAAC;QAExD,IAAI,gBAAgB,IAAI,YAAY,EAAE,OAAO,IAAI,eAAe,CAAC,OAAO,EAAE;YACxE,MAAM,gBAAgB,GAAG,eAAe,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YACzE,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YAEnE,IAAI,gBAAgB,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE;gBAClD,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;gBAC9C,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC;aAC5C;iBAAM;gBACL,IAAI,KAAK;oBAAE,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC;;oBACjD,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,MAAM,CAAC;gBAChD,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;aAC/C;SACF;IACH,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,YAAY;IACZ,YAAY;IACZ,OAAO,CACL,6BAAK,SAAS,EAAC,uBAAuB,EAAC,GAAG,EAAE,WAAW;QACrD,6BAAK,SAAS,EAAC,6BAA6B;YACzC,KAAK,IAAI,6BAAK,SAAS,EAAC,mBAAmB,IAAE,KAAK,CAAO;YAC1D,6BACE,SAAS,EAAE;;cAEP,QAAQ,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE;cAC7C,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,EAAE;WAC9D,EACD,OAAO,EAAE,wBAAwB;gBAEhC,CAAC,KAAK,IAAI,CAAC,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,CACvD,6BAAK,SAAS,EAAC,gCAAgC,IAAE,WAAW,CAAO,CACpE;gBACA,KAAK,IAAI,CAAC,QAAQ,IAAI,6BAAK,SAAS,EAAC,0BAA0B,IAAE,cAAc,CAAC,KAAU,CAAC,CAAO;gBAClG,QAAQ,IAAI,WAAW,EAAE,MAAM,GAAG,CAAC,IAAI,CACtC;oBACG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACxB,6BAAK,SAAS,EAAC,0BAA0B;wBACtC,WAAW;6BACT,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;6BACjC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;6BACX,IAAI,CAAC,IAAI,CAAC;wBAAE,GAAG;;wBACf,WAAW,CAAC,MAAM,GAAG,CAAC;kCACrB,CACP,CAAC,CAAC,CAAC,CACF,6BAAK,SAAS,EAAC,0BAA0B,IACtC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACrD,CACP;oBACD,6BAAK,SAAS,EAAC,MAAM,EAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC;wBAC5D,oBAAC,eAAM,IAAC,IAAI,EAAC,OAAO,GAAG,CACnB,CACL,CACJ;gBACD,6BAAK,SAAS,EAAC,4BAA4B,IACxC,gBAAgB,CAAC,CAAC,CAAC,CAClB,6BAAK,KAAK,EAAC,4BAA4B,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,cAAc;oBAC7E,8BAAM,CAAC,EAAC,kHAAkH,GAAQ,CAC9H,CACP,CAAC,CAAC,CAAC,CACF,6BAAK,KAAK,EAAC,4BAA4B,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,cAAc;oBAC7E,8BAAM,CAAC,EAAC,kHAAkH,GAAQ,CAC9H,CACP,CACG,CACF,CACF;QAEL,KAAK,IAAI,KAAK,KAAK,EAAE,IAAI,CACxB,6BAAK,SAAS,EAAC,mBAAmB;YAChC,6BAAK,SAAS,EAAC,yBAAyB;gBACtC,oBAAC,eAAM,IAAC,IAAI,EAAC,cAAc,EAAC,IAAI,EAAC,IAAI,GAAG,CACpC;YACN,6BAAK,SAAS,EAAC,0BAA0B,IAAE,KAAK,CAAO,CACnD,CACP;QAEA,CAAC,QAAQ,IAAI,gBAAgB,IAAI,CAChC,6BACE,SAAS,EAAE,8BAA8B,KAAK,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,EAAE,EAAE,EAC5F,GAAG,EAAE,eAAe;YAEnB,UAAU,IAAI,CACb,6BAAK,SAAS,EAAC,oBAAoB;gBACjC,oBAAC,iBAAO,IACN,KAAK,EAAE,WAAW,EAClB,IAAI,EAAC,QAAQ,EACb,WAAW,EAAE,iBAAiB,EAC9B,KAAK,EAAE,WAAW,EAClB,SAAS,QACT,QAAQ,EAAE,cAAc,GACxB,CACE,CACP;YAED,6BAAK,SAAS,EAAC,kBAAkB;gBAC9B,SAAS,IAAI,CACZ,6BAAK,SAAS,EAAC,yBAAyB;oBACtC,oBAAC,mBAAQ,IAAC,IAAI,EAAC,IAAI,GAAG,CAClB,CACP;gBACA,CAAC,SAAS,IAAI,YAAY,IAAI,CAC7B,6BAAK,SAAS,EAAC,6BAA6B,yCAAyC,CACtF;gBACA,CAAC,SAAS,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CACpD,6BAAK,SAAS,EAAC,6BAA6B,IAAE,kBAAkB,IAAI,kBAAkB,CAAO,CAC9F;gBACA,CAAC,QAAQ;oBACR,CAAC,SAAS;oBACV,CAAC,YAAY;oBACb,KAAK,CAAC,MAAM,GAAG,CAAC;oBAChB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAChB,6BACE,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EACzB,SAAS,EAAC,uBAAuB,EACjC,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAEpC,cAAc,CAAC,IAAI,CAAC,CACjB,CACP,CAAC;gBACH,QAAQ;oBACP,CAAC,SAAS;oBACV,CAAC,YAAY;oBACb,KAAK;yBACF,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;yBACrG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;oBACvC,KAAK;yBACF,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;yBACrG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;yBACzB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;wBACb,MAAM,SAAS,GAAG,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACnD,MAAM,SAAS,GAAG,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACnD,OAAO,SAAS,GAAG,SAAS,CAAC;oBAC/B,CAAC,CAAC;yBACD,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CACX,6BACE,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EACzB,SAAS,EAAC,uBAAuB,EACjC,OAAO,EAAE,KAAK,CAAC,EAAE,CACf,gBAAgB,CACd,KAAK,EACL,WAAW,IAAI,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;4BAC1F,CAAC,CAAC,QAAQ;4BACV,CAAC,CAAC,KAAK,EACT,IAAI,CACL;wBAGF,QAAQ,IAAI,CACX,oBAAC,uBAAU,IACT,OAAO,EAAE,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EACtF,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,GAClB,CACH;wBACA,cAAc,CAAC,IAAI,CAAC,CACjB,CACP,CAAC,CACF;YACL,MAAM,IAAI,6BAAK,SAAS,EAAC,oBAAoB,IAAE,MAAM,CAAO,CACzD,CACP,CACG,CACP,CAAC;AACJ,CAAC,CAAC;AAlQW,QAAA,UAAU,cAkQrB"}
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-case-declarations */
1
2
  import * as React from 'react';
2
3
  import { useEffect, useRef, useState } from 'react';
3
4
  import { TsDropdownProps } from './TsDropdown.types';
@@ -5,6 +6,7 @@ import { TsIcon } from '../../TsIcon/TsIcon';
5
6
  import { TsInput } from '../../TsInput/TsInput/TsInput';
6
7
  import { useClickOutside } from '../../../hooks/use-click-outside';
7
8
  import { TsLoader } from '../../TsLoader/TsLoader';
9
+ import { TsCheckbox } from '../../TsCheckbox/TsCheckbox';
8
10
  import './TsDropdown.css';
9
11
 
10
12
  export const TsDropdown = <T,>({
@@ -21,16 +23,19 @@ export const TsDropdown = <T,>({
21
23
  disabled,
22
24
  searchable,
23
25
  action,
26
+ listMode,
24
27
  getOptionLabel,
25
28
  getOptionValue,
26
29
  loadOptions,
27
30
  onChange,
31
+ onChangeList,
28
32
  }: TsDropdownProps<T>) => {
29
33
  const [showDropdownMenu, setShowDropdownMenu] = useState<boolean>(false);
30
34
  const [searchValue, setSearchValue] = useState<string>('');
31
35
  const [items, setItems] = useState<T[]>(options ?? []);
32
36
  const [isLoading, setIsLoading] = useState<boolean>(false);
33
37
  const [isFetchError, setIsFetchError] = useState<boolean>(false);
38
+ const [chosenItems, setChosenItems] = useState<T[]>(value as T[]);
34
39
  const dropdownRef = useClickOutside(() => setShowDropdownMenu(false));
35
40
  const dropdownMenuRef = useRef<HTMLDivElement>(null);
36
41
 
@@ -55,6 +60,29 @@ export const TsDropdown = <T,>({
55
60
  };
56
61
  const handleToggleDropdownMenu = () => !disabled && setShowDropdownMenu(!showDropdownMenu);
57
62
 
63
+ const handleEmptyList = (event: React.MouseEvent<HTMLDivElement>) => {
64
+ event.stopPropagation();
65
+ setChosenItems([]);
66
+ onChange(undefined);
67
+ };
68
+
69
+ const handleManageItem = (event: React.FormEvent<HTMLDivElement>, action: string, value: T) => {
70
+ if (onChangeList) {
71
+ event.stopPropagation();
72
+ switch (action) {
73
+ case 'remove':
74
+ const filteredList = chosenItems.filter(item => getOptionValue(item) !== getOptionValue(value));
75
+ setChosenItems(filteredList);
76
+ onChangeList(filteredList.length > 0 ? filteredList : undefined);
77
+ break;
78
+ case 'add':
79
+ const newValues = chosenItems ? [...chosenItems, value] : [value];
80
+ setChosenItems(newValues);
81
+ onChangeList(newValues);
82
+ }
83
+ }
84
+ };
85
+
58
86
  // ########
59
87
  // Watchers
60
88
  useEffect(() => {
@@ -106,8 +134,30 @@ export const TsDropdown = <T,>({
106
134
  `}
107
135
  onClick={handleToggleDropdownMenu}
108
136
  >
109
- {!value && <div className="ts-dropdown-input--placeholder">{placeholder}</div>}
110
- {value && <div className="ts-dropdown-input--value">{getOptionLabel(value)}</div>}
137
+ {!value && (!chosenItems || chosenItems.length === 0) && (
138
+ <div className="ts-dropdown-input--placeholder">{placeholder}</div>
139
+ )}
140
+ {value && !listMode && <div className="ts-dropdown-input--value">{getOptionLabel(value as T)}</div>}
141
+ {listMode && chosenItems?.length > 0 && (
142
+ <>
143
+ {chosenItems.length > 2 ? (
144
+ <div className="ts-dropdown-input--value">
145
+ {chosenItems
146
+ .map(item => getOptionValue(item))
147
+ .slice(0, 2)
148
+ .join(', ')}{' '}
149
+ & {chosenItems.length - 2} others
150
+ </div>
151
+ ) : (
152
+ <div className="ts-dropdown-input--value">
153
+ {chosenItems.map(item => getOptionValue(item)).join(', ')}
154
+ </div>
155
+ )}
156
+ <div className="icon" onClick={event => handleEmptyList(event)}>
157
+ <TsIcon name="close" />
158
+ </div>
159
+ </>
160
+ )}
111
161
  <div className="ts-dropdown-input--chevron">
112
162
  {showDropdownMenu ? (
113
163
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
@@ -161,7 +211,8 @@ export const TsDropdown = <T,>({
161
211
  {!isLoading && !isFetchError && items.length === 0 && (
162
212
  <div className="ts-dropdown-menu-error-text">{noItemFoundMessage ?? 'No option found.'}</div>
163
213
  )}
164
- {!isLoading &&
214
+ {!listMode &&
215
+ !isLoading &&
165
216
  !isFetchError &&
166
217
  items.length > 0 &&
167
218
  items.map(item => (
@@ -173,6 +224,43 @@ export const TsDropdown = <T,>({
173
224
  {getOptionLabel(item)}
174
225
  </div>
175
226
  ))}
227
+ {listMode &&
228
+ !isLoading &&
229
+ !isFetchError &&
230
+ items
231
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
232
+ .concat(chosenItems ?? []).length > 0 &&
233
+ items
234
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
235
+ .concat(chosenItems ?? [])
236
+ .sort((a, b) => {
237
+ const aIncluded = chosenItems?.includes(a) ? 1 : 0;
238
+ const bIncluded = chosenItems?.includes(b) ? 1 : 0;
239
+ return bIncluded - aIncluded;
240
+ })
241
+ .map(item => (
242
+ <div
243
+ key={getOptionLabel(item)}
244
+ className="ts-dropdown-menu-item"
245
+ onClick={event =>
246
+ handleManageItem(
247
+ event,
248
+ chosenItems && chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item))
249
+ ? 'remove'
250
+ : 'add',
251
+ item,
252
+ )
253
+ }
254
+ >
255
+ {listMode && (
256
+ <TsCheckbox
257
+ checked={chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item))}
258
+ onChange={() => {}}
259
+ />
260
+ )}
261
+ {getOptionValue(item)}
262
+ </div>
263
+ ))}
176
264
  </div>
177
265
  {action && <div className="ts-dropdown-action">{action}</div>}
178
266
  </div>
@@ -8,13 +8,15 @@ export type TsDropdownProps<T> = {
8
8
  placeholder?: string;
9
9
  reloadOptionsOn?: any[];
10
10
  searchPlaceholder?: string;
11
- value?: T;
11
+ value?: T | T[];
12
12
  disabled?: boolean;
13
13
  searchable?: boolean;
14
14
  action?: ReactNode;
15
15
  errorAction?: string;
16
+ listMode?: boolean;
16
17
  getOptionLabel: (option: T) => string;
17
18
  getOptionValue: (option: T) => string;
18
19
  loadOptions?: (search?: string) => Promise<T[]>;
19
20
  onChange: (value?: T) => void;
21
+ onChangeList?: (values?: T[]) => void;
20
22
  };
@@ -9,13 +9,15 @@ export type TsDropdownProps<T> = {
9
9
  placeholder?: string;
10
10
  reloadOptionsOn?: any[];
11
11
  searchPlaceholder?: string;
12
- value?: T;
12
+ value?: T | T[];
13
13
  disabled?: boolean;
14
14
  searchable?: boolean;
15
15
  action?: ReactNode;
16
16
  errorAction?: string;
17
+ listMode?: boolean;
17
18
  getOptionLabel: (option: T) => string;
18
19
  getOptionValue: (option: T) => string;
19
20
  loadOptions?: (search?: string) => Promise<T[]>;
20
21
  onChange: (value?: T) => void;
22
+ onChangeList?: (values?: T[]) => void;
21
23
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dktunited-techoff/techoff-suite-ui",
3
- "version": "1.14.9",
3
+ "version": "1.15.1",
4
4
  "main": "lib/index.js",
5
5
  "types": "./lib",
6
6
  "module": "esm/index.js",
@@ -11,6 +11,11 @@
11
11
  border: 1px solid #949494;
12
12
  cursor: pointer;
13
13
  }
14
+ .ts-dropdown-input .icon .ts-icon{
15
+ background-color: #3542ba;
16
+ color: #ffffff;
17
+ border-radius: 50%;
18
+ }
14
19
  .ts-dropdown-input--disabled {
15
20
  background: #fafafa;
16
21
  cursor: not-allowed;
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-case-declarations */
1
2
  import * as React from 'react';
2
3
  import { useEffect, useRef, useState } from 'react';
3
4
  import { TsDropdownProps } from './TsDropdown.types';
@@ -5,6 +6,7 @@ import { TsIcon } from '../../TsIcon/TsIcon';
5
6
  import { TsInput } from '../../TsInput/TsInput/TsInput';
6
7
  import { useClickOutside } from '../../../hooks/use-click-outside';
7
8
  import { TsLoader } from '../../TsLoader/TsLoader';
9
+ import { TsCheckbox } from '../../TsCheckbox/TsCheckbox';
8
10
  import './TsDropdown.css';
9
11
 
10
12
  export const TsDropdown = <T,>({
@@ -21,16 +23,19 @@ export const TsDropdown = <T,>({
21
23
  disabled,
22
24
  searchable,
23
25
  action,
26
+ listMode,
24
27
  getOptionLabel,
25
28
  getOptionValue,
26
29
  loadOptions,
27
30
  onChange,
31
+ onChangeList,
28
32
  }: TsDropdownProps<T>) => {
29
33
  const [showDropdownMenu, setShowDropdownMenu] = useState<boolean>(false);
30
34
  const [searchValue, setSearchValue] = useState<string>('');
31
35
  const [items, setItems] = useState<T[]>(options ?? []);
32
36
  const [isLoading, setIsLoading] = useState<boolean>(false);
33
37
  const [isFetchError, setIsFetchError] = useState<boolean>(false);
38
+ const [chosenItems, setChosenItems] = useState<T[]>(value as T[]);
34
39
  const dropdownRef = useClickOutside(() => setShowDropdownMenu(false));
35
40
  const dropdownMenuRef = useRef<HTMLDivElement>(null);
36
41
 
@@ -55,6 +60,29 @@ export const TsDropdown = <T,>({
55
60
  };
56
61
  const handleToggleDropdownMenu = () => !disabled && setShowDropdownMenu(!showDropdownMenu);
57
62
 
63
+ const handleEmptyList = (event: React.MouseEvent<HTMLDivElement>) => {
64
+ event.stopPropagation();
65
+ setChosenItems([]);
66
+ onChange(undefined);
67
+ };
68
+
69
+ const handleManageItem = (event: React.FormEvent<HTMLDivElement>, action: string, value: T) => {
70
+ if (onChangeList) {
71
+ event.stopPropagation();
72
+ switch (action) {
73
+ case 'remove':
74
+ const filteredList = chosenItems.filter(item => getOptionValue(item) !== getOptionValue(value));
75
+ setChosenItems(filteredList);
76
+ onChangeList(filteredList.length > 0 ? filteredList : undefined);
77
+ break;
78
+ case 'add':
79
+ const newValues = chosenItems ? [...chosenItems, value] : [value];
80
+ setChosenItems(newValues);
81
+ onChangeList(newValues);
82
+ }
83
+ }
84
+ };
85
+
58
86
  // ########
59
87
  // Watchers
60
88
  useEffect(() => {
@@ -106,8 +134,30 @@ export const TsDropdown = <T,>({
106
134
  `}
107
135
  onClick={handleToggleDropdownMenu}
108
136
  >
109
- {!value && <div className="ts-dropdown-input--placeholder">{placeholder}</div>}
110
- {value && <div className="ts-dropdown-input--value">{getOptionLabel(value)}</div>}
137
+ {!value && (!chosenItems || chosenItems.length === 0) && (
138
+ <div className="ts-dropdown-input--placeholder">{placeholder}</div>
139
+ )}
140
+ {value && !listMode && <div className="ts-dropdown-input--value">{getOptionLabel(value as T)}</div>}
141
+ {listMode && chosenItems?.length > 0 && (
142
+ <>
143
+ {chosenItems.length > 2 ? (
144
+ <div className="ts-dropdown-input--value">
145
+ {chosenItems
146
+ .map(item => getOptionValue(item))
147
+ .slice(0, 2)
148
+ .join(', ')}{' '}
149
+ & {chosenItems.length - 2} others
150
+ </div>
151
+ ) : (
152
+ <div className="ts-dropdown-input--value">
153
+ {chosenItems.map(item => getOptionValue(item)).join(', ')}
154
+ </div>
155
+ )}
156
+ <div className="icon" onClick={event => handleEmptyList(event)}>
157
+ <TsIcon name="close" />
158
+ </div>
159
+ </>
160
+ )}
111
161
  <div className="ts-dropdown-input--chevron">
112
162
  {showDropdownMenu ? (
113
163
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
@@ -161,7 +211,8 @@ export const TsDropdown = <T,>({
161
211
  {!isLoading && !isFetchError && items.length === 0 && (
162
212
  <div className="ts-dropdown-menu-error-text">{noItemFoundMessage ?? 'No option found.'}</div>
163
213
  )}
164
- {!isLoading &&
214
+ {!listMode &&
215
+ !isLoading &&
165
216
  !isFetchError &&
166
217
  items.length > 0 &&
167
218
  items.map(item => (
@@ -173,6 +224,43 @@ export const TsDropdown = <T,>({
173
224
  {getOptionLabel(item)}
174
225
  </div>
175
226
  ))}
227
+ {listMode &&
228
+ !isLoading &&
229
+ !isFetchError &&
230
+ items
231
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
232
+ .concat(chosenItems ?? []).length > 0 &&
233
+ items
234
+ .filter(item => !(chosenItems ?? []).map(item => getOptionValue(item)).includes(getOptionValue(item)))
235
+ .concat(chosenItems ?? [])
236
+ .sort((a, b) => {
237
+ const aIncluded = chosenItems?.includes(a) ? 1 : 0;
238
+ const bIncluded = chosenItems?.includes(b) ? 1 : 0;
239
+ return bIncluded - aIncluded;
240
+ })
241
+ .map(item => (
242
+ <div
243
+ key={getOptionLabel(item)}
244
+ className="ts-dropdown-menu-item"
245
+ onClick={event =>
246
+ handleManageItem(
247
+ event,
248
+ chosenItems && chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item))
249
+ ? 'remove'
250
+ : 'add',
251
+ item,
252
+ )
253
+ }
254
+ >
255
+ {listMode && (
256
+ <TsCheckbox
257
+ checked={chosenItems?.map(item => getOptionValue(item)).includes(getOptionValue(item))}
258
+ onChange={() => {}}
259
+ />
260
+ )}
261
+ {getOptionValue(item)}
262
+ </div>
263
+ ))}
176
264
  </div>
177
265
  {action && <div className="ts-dropdown-action">{action}</div>}
178
266
  </div>
@@ -9,13 +9,15 @@ export type TsDropdownProps<T> = {
9
9
  placeholder?: string;
10
10
  reloadOptionsOn?: any[];
11
11
  searchPlaceholder?: string;
12
- value?: T;
12
+ value?: T | T[];
13
13
  disabled?: boolean;
14
14
  searchable?: boolean;
15
15
  action?: ReactNode;
16
16
  errorAction?: string;
17
+ listMode?: boolean;
17
18
  getOptionLabel: (option: T) => string;
18
19
  getOptionValue: (option: T) => string;
19
20
  loadOptions?: (search?: string) => Promise<T[]>;
20
21
  onChange: (value?: T) => void;
22
+ onChangeList?: (values?: T[]) => void;
21
23
  };