funda-ui 4.5.666 → 4.5.671

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 (65) hide show
  1. package/ColorPicker/index.js +3 -1
  2. package/Date/index.js +14 -1
  3. package/DragDropList/index.css +188 -0
  4. package/DragDropList/index.d.ts +44 -0
  5. package/DragDropList/index.js +1587 -0
  6. package/Input/index.d.ts +2 -0
  7. package/Input/index.js +14 -1
  8. package/LICENSE +21 -0
  9. package/MultipleSelect/index.css +237 -144
  10. package/MultipleSelect/index.d.ts +24 -10
  11. package/MultipleSelect/index.js +2240 -1225
  12. package/README.md +3 -1
  13. package/RangeSlider/index.js +14 -1
  14. package/Textarea/index.d.ts +2 -0
  15. package/Textarea/index.js +14 -1
  16. package/Tree/index.d.ts +1 -0
  17. package/Tree/index.js +29 -0
  18. package/Utils/useBoundedDrag.d.ts +125 -0
  19. package/Utils/useBoundedDrag.js +380 -0
  20. package/Utils/useDragDropPosition.d.ts +169 -0
  21. package/Utils/useDragDropPosition.js +456 -0
  22. package/Utils/useIsMobile.d.ts +2 -0
  23. package/Utils/useIsMobile.js +168 -0
  24. package/all.d.ts +1 -0
  25. package/all.js +1 -1
  26. package/lib/cjs/ColorPicker/index.js +3 -1
  27. package/lib/cjs/Date/index.js +14 -1
  28. package/lib/cjs/DragDropList/index.d.ts +44 -0
  29. package/lib/cjs/DragDropList/index.js +1587 -0
  30. package/lib/cjs/Input/index.d.ts +2 -0
  31. package/lib/cjs/Input/index.js +14 -1
  32. package/lib/cjs/MultipleSelect/index.d.ts +24 -10
  33. package/lib/cjs/MultipleSelect/index.js +2240 -1225
  34. package/lib/cjs/RangeSlider/index.js +14 -1
  35. package/lib/cjs/Textarea/index.d.ts +2 -0
  36. package/lib/cjs/Textarea/index.js +14 -1
  37. package/lib/cjs/Tree/index.d.ts +1 -0
  38. package/lib/cjs/Tree/index.js +29 -0
  39. package/lib/cjs/Utils/useBoundedDrag.d.ts +125 -0
  40. package/lib/cjs/Utils/useBoundedDrag.js +380 -0
  41. package/lib/cjs/Utils/useDragDropPosition.d.ts +169 -0
  42. package/lib/cjs/Utils/useDragDropPosition.js +456 -0
  43. package/lib/cjs/Utils/useIsMobile.d.ts +2 -0
  44. package/lib/cjs/Utils/useIsMobile.js +168 -0
  45. package/lib/cjs/index.d.ts +1 -0
  46. package/lib/cjs/index.js +1 -1
  47. package/lib/css/DragDropList/index.css +188 -0
  48. package/lib/css/MultipleSelect/index.css +237 -144
  49. package/lib/esm/ColorPicker/index.tsx +53 -49
  50. package/lib/esm/DragDropList/index.scss +245 -0
  51. package/lib/esm/DragDropList/index.tsx +494 -0
  52. package/lib/esm/Input/index.tsx +17 -3
  53. package/lib/esm/MultipleSelect/index.scss +288 -183
  54. package/lib/esm/MultipleSelect/index.tsx +305 -166
  55. package/lib/esm/MultipleSelect/utils/func.ts +21 -1
  56. package/lib/esm/Tabs/Tabs.tsx +1 -1
  57. package/lib/esm/Textarea/index.tsx +18 -1
  58. package/lib/esm/Tree/TreeList.tsx +32 -0
  59. package/lib/esm/Tree/index.tsx +3 -0
  60. package/lib/esm/Utils/hooks/useBoundedDrag.tsx +301 -0
  61. package/lib/esm/Utils/hooks/useDragDropPosition.tsx +420 -0
  62. package/lib/esm/Utils/hooks/useIsMobile.tsx +56 -0
  63. package/lib/esm/index.js +1 -0
  64. package/package.json +1 -1
  65. package/lib/esm/MultipleSelect/ItemList.tsx +0 -323
@@ -1,14 +1,12 @@
1
1
  import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from 'react';
2
2
 
3
+ import DragDropList from 'funda-dragdrop-list';
4
+
3
5
 
4
6
  import useComId from 'funda-utils/dist/cjs/useComId';
5
7
  import {
6
8
  isJSON
7
9
  } from 'funda-utils/dist/cjs/initDefaultOptions';
8
- import {
9
- addTreeDepth,
10
- addTreeIndent,
11
- } from 'funda-utils/dist/cjs/tree';
12
10
  import {
13
11
  extractContentsOfBrackets
14
12
  } from 'funda-utils/dist/cjs/extract';
@@ -22,12 +20,21 @@ import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
22
20
 
23
21
 
24
22
 
25
- import { multiSelControlOptionExist, uniqueArr } from './utils/func';
26
- import ItemList from './ItemList';
23
+ import { multiSelControlOptionExist, uniqueArr, uniqueOpt } from './utils/func';
27
24
 
28
25
 
29
26
  export interface OptionConfig {
30
- [propName: string]: string | number | boolean | Function;
27
+ id: number;
28
+ parentId?: number;
29
+ label: string;
30
+ listItemLabel: string;
31
+ value: string;
32
+ queryString: string;
33
+ depth?: number;
34
+ children?: OptionConfig[];
35
+ disabled?: boolean;
36
+ extendedContent?: React.ReactNode;
37
+ [key: string]: any;
31
38
  }
32
39
 
33
40
 
@@ -46,11 +53,6 @@ export type MultipleSelectProps = {
46
53
  iconAdd?: React.ReactNode | string;
47
54
  iconRemove?: React.ReactNode | string;
48
55
  unattachedSelect?: boolean;
49
- hierarchical?: boolean;
50
- indentation?: string;
51
- doubleIndent?: boolean;
52
- alternateCollapse?: boolean;
53
- arrow?: React.ReactNode;
54
56
  defaultValue?: string;
55
57
  value?: string;
56
58
  label?: React.ReactNode | string;
@@ -58,7 +60,16 @@ export type MultipleSelectProps = {
58
60
  options?: OptionConfig[] | string;
59
61
  disabled?: any;
60
62
  required?: any;
61
- appendControl?: React.ReactNode;
63
+ /** DragDrop List */
64
+ draggable?: boolean;
65
+ handleHide?: boolean;
66
+ handleIcon?: string;
67
+ handlePos?: 'left' | 'right';
68
+ dragMode?: 'handle' | 'block';
69
+ indentation?: string;
70
+ doubleIndent?: boolean;
71
+ alternateCollapse?: boolean;
72
+ arrow?: React.ReactNode;
62
73
  /** Whether to use square brackets to save result and initialize default value */
63
74
  extractValueByBrackets?: boolean;
64
75
  /** Incoming data, you can set the third parameter of `onFetch` */
@@ -72,9 +83,9 @@ export type MultipleSelectProps = {
72
83
  fetchFuncMethodParams?: any[];
73
84
  fetchCallback?: (data: any) => void;
74
85
  onFetch?: (data: any) => void;
75
- onAddAll?: (e: any, data: any, dataStr: any) => void;
76
- onRemoveAll?: (e: any, data: any, dataStr: any) => void;
77
- onChange?: (e: any, data: any, dataStr: any, currentData: any, type: string) => void;
86
+ onAddAll?: (e: HTMLElement | null, data: any[], dataStr: string, res: any[]) => void;
87
+ onRemoveAll?: (e: HTMLElement | null, data: any[], dataStr: string, res: any[]) => void;
88
+ onChange?: (e: HTMLElement | null, data: any[], dataStr: string, currentData: any, type: string, res: any[]) => void;
78
89
 
79
90
  };
80
91
 
@@ -95,20 +106,23 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
95
106
  iconAdd,
96
107
  iconRemove,
97
108
  unattachedSelect,
98
- hierarchical,
99
- indentation,
100
- doubleIndent,
101
- alternateCollapse,
102
- arrow,
103
109
  options,
104
110
  disabled,
105
111
  required,
106
- appendControl,
107
112
  defaultValue,
108
113
  value,
109
114
  label,
110
115
  name,
111
116
  id,
117
+ draggable = true,
118
+ handleHide = false,
119
+ handleIcon = '☰',
120
+ handlePos = 'left',
121
+ dragMode = 'handle',
122
+ indentation,
123
+ doubleIndent,
124
+ alternateCollapse,
125
+ arrow = <><svg viewBox="0 0 22 22" width="8px"><path d="m345.44 248.29l-194.29 194.28c-12.359 12.365-32.397 12.365-44.75 0-12.354-12.354-12.354-32.391 0-44.744l171.91-171.91-171.91-171.9c-12.354-12.359-12.354-32.394 0-44.748 12.354-12.359 32.391-12.359 44.75 0l194.29 194.28c6.177 6.18 9.262 14.271 9.262 22.366 0 8.099-3.091 16.196-9.267 22.373" transform="matrix(.03541-.00013.00013.03541 2.98 3.02)" fill="#a5a5a5" /></svg></>,
112
126
  extractValueByBrackets,
113
127
  style,
114
128
  data,
@@ -124,58 +138,137 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
124
138
  } = props;
125
139
 
126
140
 
127
- const UN_ATTACHED_SELECT = typeof unattachedSelect === 'undefined' || unattachedSelect === false ? false : true;
141
+ const UNATTACHED_SELECT = typeof unattachedSelect === 'undefined' || unattachedSelect === false ? false : true;
128
142
  const WRAPPER_MIN_H = typeof wrapperMinHeight === 'undefined' ? '' : wrapperMinHeight;
129
143
  const WRAPPER_MIN_W = typeof wrapperMinWidth === 'undefined' ? '' : wrapperMinWidth;
130
- const INDENT_PLACEHOLDER = doubleIndent ? `&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;` : `&nbsp;&nbsp;&nbsp;&nbsp;`;
131
- const INDENT_LAST_PLACEHOLDER = `${typeof indentation !== 'undefined' && indentation !== '' ? `${indentation}&nbsp;&nbsp;` : ''}`;
132
144
  const VALUE_BY_BRACKETS = typeof extractValueByBrackets === 'undefined' ? true : extractValueByBrackets;
133
145
  const uniqueID = useComId();
134
146
  const idRes = id || uniqueID;
135
147
  const rootRef = useRef<any>(null);
136
148
  const inputRef = useRef<any>(null);
137
149
  const availableListRef = useRef<any>(null);
138
- const selectedListRef = useRef<any>(null);
139
150
  const optionsRes = options ? isJSON(options) ? JSON.parse(options as string) : options : [];
140
151
  const [valSelectedData, setValSelectedData] = useState<any[]>([]);
141
152
  const [valSelected, setValSelected] = useState<any[]>([]);
142
153
 
154
+ // temp default value
155
+ const [tempDefaultValue, setTempDefaultValue] = useState<string | undefined>(undefined);
143
156
 
144
157
  // return a array of options
145
158
  let optionsDataInit: OptionConfig[] = optionsRes;
146
159
 
147
-
148
160
  //
149
161
  const [changedSearchVal, setChangedSearchVal] = useState<string>('');
150
162
 
151
163
  //
152
164
  const [dataInit, setDataInit] = useState<OptionConfig[]>(optionsDataInit);
153
165
  const [hasErr, setHasErr] = useState<boolean>(false);
166
+
154
167
 
155
168
 
156
169
  // exposes the following methods
157
-
158
170
  useImperativeHandle(
159
171
  contentRef,
160
172
  () => ({
161
173
  clear: (cb?: any) => {
162
- initDefaultValue('', dataInit);
174
+
175
+ const _params: any[] = fetchFuncMethodParams || [];
176
+ fetchData((_params).join(','), '');
177
+
163
178
  cb?.();
164
179
  },
165
- /*
166
- set([{"label": "Option 1","listItemLabel":"Option 1 (No: 001)","value": "value-1","queryString": "option1"}], () => { console.log('callback') }])
167
- */
168
180
  set: (inputData: any[], cb?: any) => {
169
181
  if (! Array.isArray(inputData)) return;
170
-
171
- initDefaultValue(inputData.map((v: any) => `[${v.value}]`).join(''), dataInit);
182
+
183
+ const _params: any[] = fetchFuncMethodParams || [];
184
+ fetchData((_params).join(','), inputData.map((v: any) => `[${v.value}]`).join(''));
172
185
 
173
186
  cb?.();
174
187
  }
175
188
  }),
176
- [contentRef, dataInit],
189
+ [contentRef],
177
190
  );
178
191
 
192
+ const getExtControll = (index: number, id: number, value: number | string, extendedContent: React.ReactNode, defaultValue: any, forceItemSelected: boolean | undefined = undefined) => {
193
+
194
+
195
+ let itemSelected: boolean = false;
196
+ if (typeof defaultValue !== 'undefined' && defaultValue !== '') {
197
+ const _val = VALUE_BY_BRACKETS ? extractContentsOfBrackets(defaultValue) : defaultValue.trim().replace(/^\,|\,$/g, '').split(',');
198
+
199
+ if (Array.isArray(_val) && _val.includes(String(value))) {
200
+ itemSelected = true;
201
+ }
202
+ }
203
+
204
+ if (typeof forceItemSelected !== 'undefined') itemSelected = forceItemSelected;
205
+
206
+
207
+ return <>
208
+
209
+ <div style={{
210
+ paddingLeft: '1rem',
211
+ width: '100%',
212
+ display: 'flex',
213
+ alignItems: 'center',
214
+ justifyContent: 'end'
215
+ }}>
216
+
217
+ {extendedContent ? <>
218
+ <span className="m-select-v2__ext" id={`m-select-v2__ext-${id}${itemSelected ? '-selected' : ''}`}>
219
+ {extendedContent}
220
+ </span>
221
+ </> : null}
222
+
223
+
224
+ {itemSelected ? <>
225
+ <a href="#" onClick={(e: React.MouseEvent) => {
226
+ e.preventDefault();
227
+ e.stopPropagation();
228
+
229
+ // remove
230
+ removeItem(id);
231
+ }}>
232
+ {iconRemove ? <>{iconRemove}</> : <><svg width="15px" height="15px" viewBox="0 0 24 24" fill="none"><path fillRule="evenodd" clipRule="evenodd" d="M22 12c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2s10 4.477 10 10ZM8 11a1 1 0 1 0 0 2h8a1 1 0 1 0 0-2H8Z" fill="#000" /></svg></>}
233
+ </a>
234
+
235
+ </> : <>
236
+ <a href="#" onClick={(e: React.MouseEvent) => {
237
+ e.preventDefault();
238
+ e.stopPropagation();
239
+
240
+ // add
241
+ selectItem(id);
242
+ }}>
243
+ {iconAdd ? <>{iconAdd}</> : <><svg width="15px" height="15px" viewBox="0 0 24 24" fill="none"><path d="M12 2C6.49 2 2 6.49 2 12C2 17.51 6.49 22 12 22C17.51 22 22 17.51 22 12C22 6.49 17.51 2 12 2ZM16 12.75H12.75V16C12.75 16.41 12.41 16.75 12 16.75C11.59 16.75 11.25 16.41 11.25 16V12.75H8C7.59 12.75 7.25 12.41 7.25 12C7.25 11.59 7.59 11.25 8 11.25H11.25V8C11.25 7.59 11.59 7.25 12 7.25C12.41 7.25 12.75 7.59 12.75 8V11.25H16C16.41 11.25 16.75 11.59 16.75 12C16.75 12.41 16.41 12.75 16 12.75Z" fill="#000" /></svg></>}
244
+ </a>
245
+ </>}
246
+
247
+
248
+ </div>
249
+
250
+ </>
251
+ };
252
+
253
+ const dragdropListDataInit = (data: any[]) => {
254
+ // Add appendControl to list
255
+ data.forEach((item: any, index: number) => {
256
+ item.appendControl = getExtControll(index, item.id, item.value, item.extendedContent, tempDefaultValue);
257
+ });
258
+
259
+
260
+ return data;
261
+ };
262
+ const dragdropListDefaultDataInit = (data: any[]) => {
263
+ // Update appendControl to list
264
+ data.forEach((item: any, index: number) => {
265
+ item.appendControl = getExtControll(index, item.id, item.value, item.extendedContent, tempDefaultValue, false);
266
+ });
267
+
268
+
269
+ return data;
270
+ };
271
+
179
272
 
180
273
  async function fetchData(params: any, inputDefault: any) {
181
274
 
@@ -201,16 +294,12 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
201
294
  }
202
295
 
203
296
 
204
- // Set hierarchical categories ( with sub-categories )
205
- if (hierarchical) {
206
- _ORGIN_DATA = addTreeDepth(_ORGIN_DATA);
207
- addTreeIndent(_ORGIN_DATA, INDENT_PLACEHOLDER, INDENT_LAST_PLACEHOLDER, 'label');
208
- }
209
-
210
-
211
297
  // remove Duplicate objects from JSON Array
212
298
  _ORGIN_DATA = removeArrDuplicateItems(_ORGIN_DATA, 'value');
213
299
 
300
+ // save temporary default value
301
+ setTempDefaultValue(inputDefault);
302
+
214
303
  //
215
304
  setDataInit(_ORGIN_DATA); // data must be initialized
216
305
 
@@ -224,16 +313,12 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
224
313
  return _ORGIN_DATA;
225
314
  } else {
226
315
 
227
- // Set hierarchical categories ( with sub-categories )
228
- if (hierarchical) {
229
- optionsDataInit = addTreeDepth(optionsDataInit);
230
- addTreeIndent(optionsDataInit, INDENT_PLACEHOLDER, INDENT_LAST_PLACEHOLDER, 'label');
231
- }
232
-
233
-
316
+
234
317
  // remove Duplicate objects from JSON Array
235
318
  optionsDataInit = removeArrDuplicateItems(optionsDataInit, 'value');
236
319
 
320
+ // save temporary default value
321
+ setTempDefaultValue(inputDefault);
237
322
 
238
323
  //
239
324
  setDataInit(optionsDataInit); // data must be initialized
@@ -270,10 +355,12 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
270
355
  if (Array.isArray(_val)) {
271
356
 
272
357
  const _initVal = _val.filter((v: any) => v !== '');
358
+
273
359
  setValSelected(_initVal);
274
360
 
361
+
275
362
  // Initialize selected options
276
- if (UN_ATTACHED_SELECT) {
363
+ if (UNATTACHED_SELECT) {
277
364
  setValSelectedData((prevState: OptionConfig[]) => {
278
365
 
279
366
  let _data = [...prevState, ...options.filter((item: any) => {
@@ -282,12 +369,19 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
282
369
 
283
370
  return uniqueArr(_data);
284
371
  });
372
+
373
+
285
374
  } else {
286
375
  setValSelectedData(options.filter((item: any) => {
287
376
  return multiSelControlOptionExist(_initVal, item.value);
288
377
  }));
289
378
  }
290
379
 
380
+ // Initialize default options
381
+ setDataInit(options.filter((item: any) => {
382
+ return !multiSelControlOptionExist(_initVal, item.value);
383
+ }));
384
+
291
385
 
292
386
  } else {
293
387
  setValSelected([]);
@@ -299,127 +393,161 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
299
393
  }
300
394
 
301
395
 
302
- function selectItem(el: HTMLElement) {
303
- if (el === null) return;
396
+ function selectItem(curId: number) {
397
+
304
398
 
399
+ // update default options
400
+ setDataInit((prevState) => {
401
+ const newDefaultData = prevState.filter((item: any) => item.id != curId);
305
402
 
306
- const _li = el;
307
- const _val = _li.dataset.value;
308
- const _listItemLabel = _li.dataset.listItemLabel;
309
- const _label = _listItemLabel === '' ? _li.dataset.label : _listItemLabel;
310
- const _data = typeof _li.dataset.itemdata !== 'undefined' ? JSON.parse(_li.dataset.itemdata) : {};
311
403
 
404
+ const targetData = prevState.find((v: any) => v.id == curId); // !!!from old "dataInit"
405
+ const _data = typeof targetData !== 'undefined' ? targetData : {};
312
406
 
313
- // set selected items
314
- setValSelected((prevState) => {
315
- const newData = JSON.parse(JSON.stringify(prevState));
316
- const index = newData.findIndex((item: string | number) => item == _val);
317
- if (index !== -1) newData.splice(index, 1);
407
+ // update selected data
408
+ setValSelectedData((prevState2: any[]) => {
409
+ const newSelectedData = dragdropListDataInit([...prevState2, _data]);
318
410
 
319
- const _res = (_val) ? Array.from(new Set([...newData, _val])) : newData;
320
- onChange?.(_li, _res, VALUE_BY_BRACKETS ? convertArrToValByBrackets(_res) : _res.join(','), _data, 'add');
411
+ // update selected items
412
+ setValSelected((prevState3) => {
413
+ const newValueData = newSelectedData.map((v: any) => v.value);
414
+ const newValueStr = VALUE_BY_BRACKETS ? convertArrToValByBrackets(newValueData) : newValueData.join(',');
415
+
416
+ onChange?.(document.querySelector(`[data-id="${curId}"]`), newValueData, newValueStr, _data, 'add', newSelectedData);
321
417
 
322
- // hide current item
323
- _li.classList.add('hide');
418
+ // update temporary default value
419
+ setTempDefaultValue(newValueStr);
324
420
 
325
- return _res;
421
+ return newValueData;
422
+ });
423
+
424
+ return uniqueArr(newSelectedData);
425
+ });
426
+
427
+ return uniqueArr(newDefaultData);
326
428
  });
327
429
 
328
430
 
329
- // update selected data
330
- setValSelectedData((prevState) => {
331
- const newData = JSON.parse(JSON.stringify(prevState));
332
- const index = newData.findIndex((item: any) => item.value == _val);
333
- if (index !== -1) newData.splice(index, 1);
334
431
 
335
- const _res = (_val) ? Array.from(new Set([...newData, _data])) : newData;
336
432
 
337
433
 
338
- return _res;
339
- });
340
434
  }
341
435
 
342
- function removeItem(el: HTMLElement) {
343
- if (el === null) return;
436
+ function removeItem(curId: number) {
344
437
 
345
- const _li = el;
346
- const _val = _li.dataset.value;
347
- const _data = typeof _li.dataset.itemdata !== 'undefined' ? JSON.parse(_li.dataset.itemdata) : {};
438
+ // update selected data
439
+ setValSelectedData((prevState: any[]) => {
440
+ const newSelectedData = prevState.filter((item: any) => item.id != curId);
348
441
 
442
+ const targetData = prevState.find((v: any) => v.id == curId); // !!!from old "valSelectedData"
443
+ const _data = typeof targetData !== 'undefined' ? targetData : {};
349
444
 
350
- // set selected items
351
- setValSelected((prevState) => {
352
- const newData = JSON.parse(JSON.stringify(prevState));
353
- const index = newData.findIndex((item: string | number) => item == _val);
354
- if (index !== -1) newData.splice(index, 1);
445
+ // update default options
446
+ setDataInit((prevState2) => {
447
+ const newDefaultData = dragdropListDefaultDataInit([...prevState2, _data]);
448
+ return uniqueArr(newDefaultData);
449
+ });
355
450
 
356
- const _res = newData;
451
+ // update selected items
452
+ setValSelected((prevState3) => {
453
+ const newValueData = newSelectedData.map((v: any) => v.value);
454
+ const newValueStr = VALUE_BY_BRACKETS ? convertArrToValByBrackets(newValueData) : newValueData.join(',');
455
+
456
+ onChange?.(document.querySelector(`[data-id="${curId}"]`), newValueData, newValueStr, _data, 'remove', newSelectedData);
357
457
 
358
- onChange?.(_li, _res, VALUE_BY_BRACKETS ? convertArrToValByBrackets(_res) : _res.join(','), _data, 'remove');
458
+ // update temporary default value
459
+ setTempDefaultValue(newValueStr);
359
460
 
360
- // show current item
361
- if (availableListRef.current) {
362
- const removedItem = availableListRef.current.querySelector(`li[data-value="${_val}"]`);
363
- if (removedItem !== null) removedItem.classList.remove('hide');
364
- }
365
461
 
462
+ return newValueData;
463
+ });
366
464
 
367
- return _res;
465
+ return uniqueArr(newSelectedData);
368
466
  });
369
467
 
370
468
 
371
- // update selected data
372
- setValSelectedData((prevState) => {
373
- const newData = JSON.parse(JSON.stringify(prevState));
374
- const index = newData.findIndex((item: any) => item.value == _val);
375
- if (index !== -1) newData.splice(index, 1);
469
+ }
376
470
 
377
- const _res = newData;
378
471
 
379
- return _res;
380
- });
381
472
 
382
473
 
383
- }
474
+ function handleSelectAll(event: any) {
475
+ event.preventDefault();
476
+ event.stopPropagation();
477
+
478
+
479
+ // update default options
480
+ setDataInit((prevState) => {
481
+ const newDefaultData: any[] = [];
482
+
483
+ // filter the "disabled" option
484
+ const disabledData = prevState.filter((v: any) => v.disabled === true); // !!!from old "dataInit"
485
+ const targetData = prevState.filter((v: any) => typeof v.disabled === 'undefined' || v.disabled === false); // !!!from old "dataInit"
486
+
487
+
488
+ // update selected data
489
+ setValSelectedData((prevState2: any[]) => {
490
+ const newSelectedData = dragdropListDataInit([...prevState2, ...targetData]);
491
+
492
+ // update selected items
493
+ setValSelected((prevState3) => {
494
+ const newValueData = newSelectedData.map((v: any) => v.value);
495
+ const newValueStr = VALUE_BY_BRACKETS ? convertArrToValByBrackets(newValueData) : newValueData.join(',');
496
+
497
+ onChange?.(null, newValueData, newValueStr, null, 'add-all', newSelectedData);
498
+
499
+ // update temporary default value
500
+ setTempDefaultValue(newValueStr);
501
+
502
+ return newValueData;
503
+ });
504
+
505
+ return uniqueArr(newSelectedData);
506
+ });
507
+
508
+ return uniqueArr([...newDefaultData, ...disabledData]);
509
+ });
384
510
 
385
511
 
512
+ }
386
513
 
387
514
 
388
- function handleSelectAll(event: any) {
515
+ function handleRemoveAll(event: any) {
389
516
  event.preventDefault();
390
- if (availableListRef.current === null) return;
517
+ event.stopPropagation();
391
518
 
392
- const items = [].slice.call(availableListRef.current.querySelectorAll('li[data-value]'));
393
- items.forEach((item: any) => {
394
519
 
395
- if (!item.classList.contains('disabled')) {
396
- selectItem(item);
397
- }
520
+ // update selected data
521
+ setValSelectedData((prevState: any[]) => {
522
+ const newSelectedData: any[] = [];
398
523
 
399
- });
524
+ const targetData = prevState; // !!!from old "valSelectedData"
400
525
 
401
- //
402
- onAddAll?.(event, dataInit.map((v: any) => `${v.value}`), VALUE_BY_BRACKETS ? dataInit.map((v: any) => `[${v.value}]`).join('') : dataInit.map((v: any) => v.value).join(''));
526
+ // update default options
527
+ setDataInit((prevState2) => {
528
+ const newDefaultData = dragdropListDefaultDataInit([...prevState2, ...targetData]);
403
529
 
404
-
530
+ return uniqueArr(newDefaultData);
531
+ });
405
532
 
533
+ // update selected items
534
+ setValSelected((prevState3) => {
535
+ const newValueData = newSelectedData.map((v: any) => v.value);
536
+ const newValueStr = VALUE_BY_BRACKETS ? convertArrToValByBrackets(newValueData) : newValueData.join(',');
537
+
538
+ onChange?.(null, newValueData, newValueStr, null, 'remove-all', newSelectedData);
539
+ onRemoveAll?.(event, newValueData, newValueStr, newSelectedData);
406
540
 
407
- }
541
+ // update temporary default value
542
+ setTempDefaultValue(newValueStr);
408
543
 
409
544
 
410
- function handleRemoveAll(event: any) {
411
- event.preventDefault();
412
- if (selectedListRef.current === null) return;
545
+ return newValueData;
546
+ });
413
547
 
414
- const items = [].slice.call(selectedListRef.current.querySelectorAll('li[data-value]'));
415
- items.forEach((item: any) => {
416
- removeItem(item);
548
+ return uniqueArr(newSelectedData);
417
549
  });
418
550
 
419
- //
420
- onRemoveAll?.(event, [], '');
421
-
422
-
423
551
 
424
552
  }
425
553
 
@@ -465,7 +593,6 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
465
593
 
466
594
  useEffect(() => {
467
595
 
468
-
469
596
  // data init
470
597
  //--------------
471
598
  const _params: any[] = fetchFuncMethodParams || [];
@@ -490,18 +617,18 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
490
617
 
491
618
  <div
492
619
  className={combinedCls(
493
- 'm-select__wrapper',
620
+ 'm-select-v2__wrapper',
494
621
  clsWrite(wrapperClassName, 'mb-3')
495
622
  )}
496
623
  ref={rootRef}
497
624
  style={{
498
- minWidth: WRAPPER_MIN_W === '' ? 'var(--m-select-wrapper-min-w)' : WRAPPER_MIN_W,
499
- minHeight: WRAPPER_MIN_H === '' ? 'var(--m-select-wrapper-min-h)' : WRAPPER_MIN_H
625
+ minWidth: WRAPPER_MIN_W === '' ? 'var(--m-select-v2-wrapper-min-w)' : WRAPPER_MIN_W,
626
+ minHeight: WRAPPER_MIN_H === '' ? 'var(--m-select-v2-wrapper-min-h)' : WRAPPER_MIN_H
500
627
  }}
501
628
  >
502
629
 
503
630
  {/* DIVIDING LINE */}
504
- <div className="m-select-diving-line"></div>
631
+ <div className="m-select-v2-diving-line"></div>
505
632
  {/* /DIVIDING LINE */}
506
633
 
507
634
  {/* VALUE INPUT */}
@@ -526,22 +653,22 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
526
653
  {/* /VALUE INPUT */}
527
654
 
528
655
 
529
- <div className="m-select-inner">
656
+ <div className="m-select-v2-inner">
530
657
 
531
658
  {/*
532
659
  // ++++++++++++++++++++
533
660
  // Available Container
534
661
  // ++++++++++++++++++++
535
662
  */}
536
- <div className="m-select__available__container">
537
- <div className="m-select__m-select__item-actions m-select__header">
663
+ <div className="m-select-v2__available__container">
664
+ <div className="m-select-v2__m-select-v2__item-actions m-select-v2__header">
538
665
 
539
666
  {/* SEARCH */}
540
- <div className="m-select__search__container">
667
+ <div className="m-select-v2__search__container">
541
668
  <input
542
669
  type="text"
543
670
  value={changedSearchVal}
544
- className="m-select__search"
671
+ className="m-select-v2__search"
545
672
  onChange={handleChangeSearch}
546
673
  />
547
674
  <i><svg width="0.8em" height="0.8em" fill="#ddd" viewBox="0 0 16 16">
@@ -550,28 +677,28 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
550
677
  </div>
551
678
  {/* /SEARCH */}
552
679
 
553
- <span className="m-select__title" dangerouslySetInnerHTML={{ __html: `${availableHeaderTitle || ''}` }}></span>
680
+ <span className="m-select-v2__title" dangerouslySetInnerHTML={{ __html: `${availableHeaderTitle || ''}` }}></span>
554
681
 
555
- <a href="#" className="m-select__btn--add-all" onClick={handleSelectAll}>{addAllBtnLabel || 'Add all'}</a>
682
+ <a href="#" className="m-select-v2__btn--add-all" onClick={handleSelectAll}>{addAllBtnLabel || 'Add all'}</a>
556
683
  </div>
557
684
 
558
685
 
559
686
 
560
687
  {/* OPTIONS LIST */}
561
- <ItemList
562
- appendControl={appendControl}
563
- root={rootRef.current}
564
- listContainerClassName="m-select__available m-select__options-contentlist"
688
+ <DragDropList
689
+ data={dragdropListDefaultDataInit(dataInit as [])}
690
+ wrapperClassName=""
565
691
  ref={availableListRef}
566
- indentStr={INDENT_LAST_PLACEHOLDER}
567
- valSelected={valSelected}
568
- iconAdd={iconAdd}
569
- onSelect={selectItem}
692
+ prefix="m-select-v2"
693
+ draggable={false}
694
+ handleHide={handleHide}
695
+ handleIcon={handleIcon}
696
+ handlePos={handlePos}
697
+ dragMode={dragMode}
698
+ indentation={indentation}
699
+ doubleIndent={doubleIndent}
570
700
  alternateCollapse={alternateCollapse}
571
- first={true}
572
701
  arrow={arrow}
573
- data={dataInit}
574
- childClassName={childClassName || 'm-select__options-contentlist-custom'}
575
702
  />
576
703
  {/* /OPTIONS LIST */}
577
704
 
@@ -583,30 +710,42 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
583
710
  // Selected Container
584
711
  // ++++++++++++++++++++
585
712
  */}
586
- <div className="m-select__selected__container">
587
- <div className="m-select__m-select__item-actions m-select__header">
588
- <span className="m-select__count" dangerouslySetInnerHTML={{ __html: `${typeof selectedHeaderNote !== 'undefined' ? selectedHeaderNote.replace('{items_num}', valSelectedData.length as never) : ''}` }}></span>
589
- <span className="m-select__title" dangerouslySetInnerHTML={{ __html: `${selectedHeaderTitle || ''}` }}></span>
590
- <a href="#" className="m-select__btn--remove-all" onClick={handleRemoveAll}>{removeAllBtnLabel || 'Remove all'}</a>
713
+ <div className="m-select-v2__selected__container">
714
+ <div className="m-select-v2__m-select-v2__item-actions m-select-v2__header">
715
+ <span className="m-select-v2__count" dangerouslySetInnerHTML={{ __html: `${typeof selectedHeaderNote !== 'undefined' ? selectedHeaderNote.replace('{items_num}', valSelectedData.length as never) : ''}` }}></span>
716
+ <span className="m-select-v2__title" dangerouslySetInnerHTML={{ __html: `${selectedHeaderTitle || ''}` }}></span>
717
+ <a href="#" className="m-select-v2__btn--remove-all" onClick={handleRemoveAll}>{removeAllBtnLabel || 'Remove all'}</a>
591
718
  </div>
592
719
 
593
720
 
594
721
  {/* OPTIONS LIST */}
595
- <ItemList
596
- appendControl={appendControl}
597
- root={rootRef.current}
598
- listContainerClassName="m-select__selected m-select__options-contentlist--sortable m-select__options-contentlist"
599
- ref={selectedListRef}
600
- indentStr={INDENT_LAST_PLACEHOLDER}
601
- valSelected={selectedResultReverse ? valSelected.reverse() : valSelected}
602
- iconRemove={iconRemove}
603
- onSelect={removeItem}
604
- alternateCollapse={alternateCollapse}
605
- first={true}
722
+ <DragDropList
723
+ data={dragdropListDataInit(selectedResultReverse ? valSelectedData.reverse() : valSelectedData)}
724
+ onUpdate={(newData: any[], curId: number) => {
725
+ setValSelectedData(newData);
726
+
727
+ const newValueData = newData.map((v: any) => v.value);
728
+ const newValueStr = VALUE_BY_BRACKETS ? convertArrToValByBrackets(newValueData) : newValueData.join(',');
729
+ const targetData = newData.find((v: any) => v.id == curId); // !!!from old "dataInit"
730
+ const _data = typeof targetData !== 'undefined' ? targetData : {};
731
+
732
+ setValSelected(newData.map((v: any) => v.value));
733
+
734
+ onChange?.(document.querySelector(`[data-id="${curId}"]`), newValueData, newValueStr, _data, 'update', newData);
735
+
736
+ }}
737
+ wrapperClassName=""
738
+ prefix="m-select-v2"
739
+ draggable={draggable}
740
+ handleHide={handleHide}
741
+ handleIcon={handleIcon}
742
+ handlePos={handlePos}
743
+ dragMode={dragMode}
744
+ indentation={indentation}
745
+ doubleIndent={doubleIndent}
746
+ alternateCollapse={false}
606
747
  arrow={arrow}
607
- data={selectedResultReverse ? valSelectedData.reverse() : valSelectedData}
608
- childClassName={clsWrite(childClassName, 'm-select__options-contentlist--custom')}
609
- selected
748
+ hierarchical={false}
610
749
  />
611
750
  {/* /OPTIONS LIST */}
612
751