funda-ui 4.2.375 → 4.2.445

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.
@@ -87,8 +87,7 @@
87
87
  cursor: default;
88
88
  position: relative;
89
89
  font-size: var(--m-select-body-font-size);
90
- display: flex;
91
- justify-content: space-between;
90
+ display: block;
92
91
  background: var(--m-select-options-item-bg);
93
92
  border-bottom: 1px solid var(--m-select-options-item-dividingline-color);
94
93
 
@@ -119,47 +118,51 @@
119
118
  &:last-child {
120
119
  border-bottom: none;
121
120
  }
122
- > span {
121
+ > div {
123
122
  padding: .35rem .75rem;
124
- display: inline-block;
125
- max-width: 100%;
123
+ display: flex;
124
+ justify-content: space-between;
125
+ width: 100%;
126
126
  overflow: hidden;
127
127
  text-overflow: ellipsis;
128
128
  word-wrap: break-word;
129
129
  word-break: break-word;
130
- }
131
130
 
132
- > strong {
133
- font-weight: normal;
134
- }
135
-
136
- > i {
137
- display: inline-block;
138
- padding: .35rem .75rem;
139
- cursor: pointer;
140
131
 
141
- svg {
142
- path {
143
- fill: var(--m-select-options-item-icon-color);
132
+ > strong {
133
+ font-weight: normal;
134
+ display: flex;
135
+ align-items: center;
136
+
137
+ .arrow {
138
+ display: inline-block;
139
+ margin-left: .2rem;
140
+ }
141
+
142
+ }
143
+
144
+ &.active {
145
+ .arrow {
146
+ transform: rotate(90deg);
144
147
  }
145
148
  }
146
- }
147
149
 
148
150
 
151
+ > i {
152
+ display: inline-block;
153
+ cursor: pointer;
149
154
 
150
- a {
151
- color: #999;
152
- text-decoration: none;
153
- padding: 0;
154
- display: block;
155
- cursor: pointer;
156
- &.m-select__item-action {
157
- position: absolute;
158
- right: 0.5rem;
159
- top: 0.5rem;
155
+ svg {
156
+ path {
157
+ fill: var(--m-select-options-item-icon-color);
158
+ }
159
+ }
160
160
  }
161
+
161
162
  }
163
+
162
164
  }
165
+
163
166
  div {
164
167
  &.m-select__selected__container {
165
168
  .m-select__header {
@@ -232,8 +235,36 @@
232
235
  }
233
236
 
234
237
 
238
+ /*-------- Multilevel --------*/
239
+ ul.m-select__options-contentlist {
240
+
241
+ > li {
242
+
243
+ ul {
244
+ transition: max-height 0.25s ease;
245
+ overflow: hidden;
246
+ position: relative;
247
+ padding-left: 1rem;
248
+ }
249
+ }
250
+
251
+ > li:not(.active) {
252
+
253
+ ul {
254
+ max-height: 0;
255
+ }
256
+ }
257
+
258
+
259
+ > li ul ul {
260
+ margin-top: auto;
261
+ }
262
+
263
+ }
264
+
265
+
235
266
  /*-------- List --------*/
236
- .m-select__options-contentlist {
267
+ ul.m-select__options-contentlist {
237
268
  position: relative;
238
269
  width: 100%;
239
270
  overflow: hidden;
@@ -252,7 +283,7 @@
252
283
  cursor: grab;
253
284
  }
254
285
  }
255
- .m-select__options-contentlist--hide {
286
+ ul.m-select__options-contentlist--hide {
256
287
  overflow: hidden;
257
288
  height: auto;
258
289
  }
@@ -13,6 +13,10 @@ import {
13
13
 
14
14
 
15
15
 
16
+ import { multiSelControlOptionExist } from './multiple-select-utils/func';
17
+ import ItemList from './ItemList';
18
+
19
+
16
20
  export interface OptionConfig {
17
21
  [propName: string]: string | number | boolean;
18
22
  }
@@ -20,6 +24,7 @@ export interface OptionConfig {
20
24
 
21
25
  type MultipleSelectProps = {
22
26
  wrapperClassName?: string;
27
+ childClassName?: string;
23
28
  wrapperMinHeight?: string;
24
29
  wrapperMinWidth?: string;
25
30
  availableHeaderTitle?: string;
@@ -32,6 +37,8 @@ type MultipleSelectProps = {
32
37
  hierarchical?: boolean;
33
38
  indentation?: string;
34
39
  doubleIndent?: boolean;
40
+ alternateCollapse?: boolean;
41
+ arrow?: React.ReactNode;
35
42
  value?: string;
36
43
  label?: React.ReactNode | string;
37
44
  name?: string;
@@ -59,6 +66,7 @@ type MultipleSelectProps = {
59
66
  const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any) => {
60
67
  const {
61
68
  wrapperClassName,
69
+ childClassName,
62
70
  wrapperMinHeight,
63
71
  wrapperMinWidth,
64
72
  availableHeaderTitle,
@@ -71,6 +79,8 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
71
79
  hierarchical,
72
80
  indentation,
73
81
  doubleIndent,
82
+ alternateCollapse,
83
+ arrow,
74
84
  options,
75
85
  disabled,
76
86
  required,
@@ -117,12 +127,6 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
117
127
  const [hasErr, setHasErr] = useState<boolean>(false);
118
128
 
119
129
 
120
- const multiSelControlOptionExist = (arr: any[], val: any) => {
121
- const _data = arr.filter(Boolean);
122
- return _data.map((v: any) => v.toString()).includes(val.toString());
123
- };
124
-
125
-
126
130
  async function fetchData(params: any) {
127
131
 
128
132
  // set default value
@@ -170,6 +174,12 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
170
174
  return _ORGIN_DATA;
171
175
  } else {
172
176
 
177
+ // Set hierarchical categories ( with sub-categories )
178
+ if ( hierarchical ) {
179
+ optionsDataInit = addTreeDepth(optionsDataInit);
180
+ addTreeIndent(optionsDataInit, INDENT_PLACEHOLDER, INDENT_LAST_PLACEHOLDER, 'label');
181
+ }
182
+
173
183
 
174
184
  // remove Duplicate objects from JSON Array
175
185
  optionsDataInit = removeArrDuplicateItems(optionsDataInit, 'value');
@@ -460,49 +470,26 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
460
470
 
461
471
  <a href="#" className="m-select__btn--add-all" onClick={handleSelectAll}>{addAllBtnLabel || 'Add all'}</a>
462
472
  </div>
463
- <ul className="m-select__available m-select__options-contentlist" ref={availableListRef}>
464
-
465
- {/* OPTIONS LIST */}
466
- {dataInit ? dataInit.map((item: any, i: number) => {
467
-
468
-
469
- return <li
470
- key={'item' + i}
471
- className={`${item.disabled ? 'disabled' : ''} ${multiSelControlOptionExist(valSelected, item.value) ? 'hide' : ''}`}
472
- data-index={i}
473
- data-value={`${item.value}`}
474
- data-label={`${item.label}`}
475
- data-list-item-label={`${typeof item.listItemLabel === 'undefined' ? '' : item.listItemLabel}`}
476
- data-disabled={item.disabled || 'false'}
477
- data-querystring={`${typeof item.queryString === 'undefined' ? '' : item.queryString}`}
478
- data-itemdata={JSON.stringify(item)}
479
- >
480
-
481
- <span>
482
- <strong dangerouslySetInnerHTML={{
483
- __html: typeof item.listItemLabel === 'undefined' ? item.label : item.listItemLabel
484
- }}></strong>
485
- <a
486
- href="#"
487
- className="m-select__item-action"
488
- ></a>
489
- </span>
490
- <i
491
- onClick={(e: React.MouseEvent) => {
492
- selectItem((e.target as any).closest('li'));
493
- }}>
494
- {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></>}
495
-
496
-
497
- </i>
498
-
499
- </li>;
500
- }) : null}
501
-
502
- {/* /OPTIONS LIST */}
503
-
504
-
505
- </ul>
473
+
474
+
475
+
476
+ {/* OPTIONS LIST */}
477
+ <ItemList
478
+ root={rootRef.current}
479
+ listContainerClassName="m-select__available m-select__options-contentlist"
480
+ ref={availableListRef}
481
+ indentStr={INDENT_LAST_PLACEHOLDER}
482
+ valSelected={valSelected}
483
+ iconAdd={iconAdd}
484
+ onSelect={selectItem}
485
+ alternateCollapse={alternateCollapse}
486
+ first={true}
487
+ arrow={arrow}
488
+ data={dataInit}
489
+ childClassName={childClassName || 'm-select__options-contentlist-custom'}
490
+ />
491
+ {/* /OPTIONS LIST */}
492
+
506
493
  </div>
507
494
 
508
495
 
@@ -517,44 +504,26 @@ const MultipleSelect = forwardRef((props: MultipleSelectProps, externalRef: any)
517
504
  <span className="m-select__title" dangerouslySetInnerHTML={{__html: `${selectedHeaderTitle || ''}`}}></span>
518
505
  <a href="#" className="m-select__btn--remove-all" onClick={handleRemoveAll}>{removeAllBtnLabel || 'Remove all'}</a>
519
506
  </div>
520
- <ul className="m-select__selected m-select__options-contentlist--sortable m-select__options-contentlist" ref={selectedListRef}>
521
-
522
- {/* OPTIONS LIST */}
523
- {valSelectedData ? valSelectedData.map((item: any, i: number) => {
524
- return <li
525
- key={'item-selected' + i}
526
- className="selected"
527
- data-index={i}
528
- data-value={`${item.value}`}
529
- data-label={`${item.label}`}
530
- data-list-item-label={`${typeof item.listItemLabel === 'undefined' ? '' : item.listItemLabel}`}
531
- data-disabled={item.disabled || 'false'}
532
- data-querystring={`${typeof item.queryString === 'undefined' ? '' : item.queryString}`}
533
- data-itemdata={JSON.stringify(item)}
534
- >
535
-
536
- <span>
537
- <strong dangerouslySetInnerHTML={{
538
- __html: typeof item.listItemLabel === 'undefined' ? item.label : item.listItemLabel
539
- }}></strong>
540
- <a
541
- href="#"
542
- className="m-select__item-action"
543
- ></a>
544
- </span>
545
- <i
546
- onClick={(e: React.MouseEvent) => {
547
- removeItem((e.target as any).closest('li'));
548
- }}>
549
- {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></>}
550
-
551
- </i>
552
-
553
- </li>;
554
- }) : null}
555
- {/* /OPTIONS LIST */}
556
-
557
- </ul>
507
+
508
+
509
+ {/* OPTIONS LIST */}
510
+ <ItemList
511
+ root={rootRef.current}
512
+ listContainerClassName="m-select__selected m-select__options-contentlist--sortable m-select__options-contentlist"
513
+ ref={selectedListRef}
514
+ indentStr={INDENT_LAST_PLACEHOLDER}
515
+ valSelected={valSelected}
516
+ iconRemove={iconRemove}
517
+ onSelect={removeItem}
518
+ alternateCollapse={alternateCollapse}
519
+ first={true}
520
+ arrow={arrow}
521
+ data={valSelectedData}
522
+ childClassName={childClassName || 'm-select__options-contentlist--custom'}
523
+ selected
524
+ />
525
+ {/* /OPTIONS LIST */}
526
+
558
527
  </div>
559
528
 
560
529
 
@@ -0,0 +1,29 @@
1
+
2
+ /**
3
+ * Format indent value
4
+ * @param {String|Array} inputData
5
+ * @param {String} placeholder
6
+ * @returns {String|Array}
7
+ */
8
+ export function formatIndentVal(inputData: any, placeholder: string) {
9
+ const reVar = new RegExp(placeholder, 'g');
10
+ if (Array.isArray(inputData)) {
11
+ return inputData.map((s: any) => String(s).replace(reVar, '').replace(/\&nbsp;/ig, ''));
12
+ } else {
13
+ const _txt: any = typeof inputData === 'string' ? inputData : inputData.toString();
14
+ return _txt.replace(reVar, '').replace(/\&nbsp;/ig, '');
15
+ }
16
+
17
+ }
18
+
19
+
20
+ /**
21
+ * Determine whether the option exists
22
+ * @param val
23
+ * @returns
24
+ */
25
+ export function multiSelControlOptionExist(arr: any[], val: any) {
26
+ const _data = arr.filter(Boolean);
27
+ return _data.map((v: any) => v.toString()).includes(val.toString());
28
+
29
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "author": "UIUX Lab",
3
3
  "email": "uiuxlab@gmail.com",
4
4
  "name": "funda-ui",
5
- "version": "4.2.375",
5
+ "version": "4.2.445",
6
6
  "description": "React components using pure Bootstrap 5+ which does not contain any external style and script libraries.",
7
7
  "repository": {
8
8
  "type": "git",