funda-ui 4.7.133 → 4.7.152
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.
- package/CascadingSelect/index.css +15 -4
- package/CascadingSelect/index.d.ts +2 -0
- package/CascadingSelect/index.js +294 -22
- package/CascadingSelectE2E/index.css +15 -4
- package/CascadingSelectE2E/index.d.ts +2 -0
- package/CascadingSelectE2E/index.js +300 -28
- package/Chatbox/index.d.ts +7 -0
- package/Chatbox/index.js +247 -163
- package/Checkbox/index.js +4 -2
- package/LiveSearch/index.js +2 -1
- package/Refresher/index.js +3 -3
- package/Select/index.css +33 -0
- package/Select/index.d.ts +1 -0
- package/Select/index.js +350 -39
- package/SplitterPanel/index.js +3 -3
- package/Switch/index.js +4 -2
- package/Utils/format-string.d.ts +2 -1
- package/Utils/format-string.js +22 -12
- package/Utils/time.d.ts +3 -3
- package/Utils/useIsMobile.js +3 -3
- package/lib/cjs/CascadingSelect/index.d.ts +2 -0
- package/lib/cjs/CascadingSelect/index.js +294 -22
- package/lib/cjs/CascadingSelectE2E/index.d.ts +2 -0
- package/lib/cjs/CascadingSelectE2E/index.js +300 -28
- package/lib/cjs/Chatbox/index.d.ts +7 -0
- package/lib/cjs/Chatbox/index.js +247 -163
- package/lib/cjs/Checkbox/index.js +4 -2
- package/lib/cjs/LiveSearch/index.js +2 -1
- package/lib/cjs/Refresher/index.js +3 -3
- package/lib/cjs/Select/index.d.ts +1 -0
- package/lib/cjs/Select/index.js +350 -39
- package/lib/cjs/SplitterPanel/index.js +3 -3
- package/lib/cjs/Switch/index.js +4 -2
- package/lib/cjs/Utils/format-string.d.ts +2 -1
- package/lib/cjs/Utils/format-string.js +22 -12
- package/lib/cjs/Utils/time.d.ts +3 -3
- package/lib/cjs/Utils/useIsMobile.js +3 -3
- package/lib/css/CascadingSelect/index.css +15 -4
- package/lib/css/CascadingSelectE2E/index.css +15 -4
- package/lib/css/Select/index.css +33 -0
- package/lib/esm/CascadingSelect/index.scss +22 -7
- package/lib/esm/CascadingSelect/index.tsx +49 -1
- package/lib/esm/CascadingSelectE2E/Group.tsx +1 -0
- package/lib/esm/CascadingSelectE2E/index.scss +23 -6
- package/lib/esm/CascadingSelectE2E/index.tsx +53 -1
- package/lib/esm/Chatbox/index.tsx +96 -11
- package/lib/esm/Checkbox/index.tsx +5 -3
- package/lib/esm/LiveSearch/index.tsx +2 -1
- package/lib/esm/Select/index.scss +43 -2
- package/lib/esm/Select/index.tsx +81 -24
- package/lib/esm/Select/utils/func.ts +0 -10
- package/lib/esm/Switch/index.tsx +4 -2
- package/lib/esm/Textarea/index.tsx +0 -1
- package/lib/esm/Utils/hooks/useIsMobile.tsx +9 -12
- package/lib/esm/Utils/libs/format-string.ts +22 -12
- package/lib/esm/Utils/libs/time.ts +6 -6
- package/package.json +1 -1
|
@@ -20,9 +20,13 @@ import {
|
|
|
20
20
|
addTreeDepth,
|
|
21
21
|
addTreeIndent
|
|
22
22
|
} from 'funda-utils/dist/cjs/tree';
|
|
23
|
+
import {
|
|
24
|
+
htmlToPlain
|
|
25
|
+
} from 'funda-utils/dist/cjs/format-string';
|
|
23
26
|
import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
|
|
24
27
|
|
|
25
28
|
|
|
29
|
+
|
|
26
30
|
import Group from './Group';
|
|
27
31
|
|
|
28
32
|
|
|
@@ -45,6 +49,8 @@ export type CascadingSelectE2EProps = {
|
|
|
45
49
|
wrapperClassName?: string;
|
|
46
50
|
controlClassName?: string;
|
|
47
51
|
controlExClassName?: string;
|
|
52
|
+
searchable?: boolean;
|
|
53
|
+
searchPlaceholder?: string;
|
|
48
54
|
perColumnHeadersShow?: boolean;
|
|
49
55
|
exceededSidePosOffset?: number;
|
|
50
56
|
value?: string;
|
|
@@ -107,6 +113,8 @@ const CascadingSelectE2E = (props: CascadingSelectE2EProps) => {
|
|
|
107
113
|
wrapperClassName,
|
|
108
114
|
controlClassName,
|
|
109
115
|
controlExClassName,
|
|
116
|
+
searchable = false,
|
|
117
|
+
searchPlaceholder = '',
|
|
110
118
|
perColumnHeadersShow = true,
|
|
111
119
|
exceededSidePosOffset,
|
|
112
120
|
disabled,
|
|
@@ -151,6 +159,9 @@ const CascadingSelectE2E = (props: CascadingSelectE2EProps) => {
|
|
|
151
159
|
const valRef = useRef<any>(null);
|
|
152
160
|
const listRef = useRef<any>(null);
|
|
153
161
|
|
|
162
|
+
// searchable
|
|
163
|
+
const [columnSearchKeywords, setColumnSearchKeywords] = useState<string[]>([]);
|
|
164
|
+
|
|
154
165
|
|
|
155
166
|
// exposes the following methods
|
|
156
167
|
useImperativeHandle(
|
|
@@ -1337,6 +1348,17 @@ const CascadingSelectE2E = (props: CascadingSelectE2EProps) => {
|
|
|
1337
1348
|
|
|
1338
1349
|
}, [value]);
|
|
1339
1350
|
|
|
1351
|
+
|
|
1352
|
+
// Automatically complete and truncate column Search Keywords each time the number of columns changes
|
|
1353
|
+
useEffect(() => {
|
|
1354
|
+
if (listData.current.length !== columnSearchKeywords.length) {
|
|
1355
|
+
setColumnSearchKeywords(
|
|
1356
|
+
Array(listData.current.length).fill('').map((v, i) => columnSearchKeywords[i] || '')
|
|
1357
|
+
);
|
|
1358
|
+
}
|
|
1359
|
+
}, [listData.current.length]);
|
|
1360
|
+
|
|
1361
|
+
|
|
1340
1362
|
return (
|
|
1341
1363
|
<>
|
|
1342
1364
|
|
|
@@ -1372,13 +1394,43 @@ const CascadingSelectE2E = (props: CascadingSelectE2EProps) => {
|
|
|
1372
1394
|
{listData.current.map((item: any, level: number) => {
|
|
1373
1395
|
|
|
1374
1396
|
if (item.length > 0) {
|
|
1397
|
+
|
|
1398
|
+
// filter data
|
|
1399
|
+
let filteredItem = item;
|
|
1400
|
+
if (searchable && columnSearchKeywords[level]) {
|
|
1401
|
+
const keyword = columnSearchKeywords[level].toLowerCase();
|
|
1402
|
+
filteredItem = item.filter((opt: any) =>
|
|
1403
|
+
(htmlToPlain(opt.name) || '').toLowerCase().includes(keyword)
|
|
1404
|
+
);
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
|
|
1375
1408
|
return (
|
|
1376
1409
|
<li key={level} data-col={level} className="cas-select-e2e__items-col">
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
{/* SEARCH BOX */}
|
|
1413
|
+
{searchable && (
|
|
1414
|
+
<div className="cas-select-e2e__items-col-searchbox">
|
|
1415
|
+
<input
|
|
1416
|
+
type="text"
|
|
1417
|
+
placeholder={searchPlaceholder}
|
|
1418
|
+
value={columnSearchKeywords[level] || ''}
|
|
1419
|
+
onChange={e => {
|
|
1420
|
+
const newKeywords = [...columnSearchKeywords];
|
|
1421
|
+
newKeywords[level] = e.target.value;
|
|
1422
|
+
setColumnSearchKeywords(newKeywords);
|
|
1423
|
+
}}
|
|
1424
|
+
/>
|
|
1425
|
+
</div>
|
|
1426
|
+
)}
|
|
1427
|
+
{/* /SEARCH BOX */}
|
|
1428
|
+
|
|
1377
1429
|
<Group
|
|
1378
1430
|
perColumnHeadersShow={perColumnHeadersShow}
|
|
1379
1431
|
level={level}
|
|
1380
1432
|
columnTitle={columnTitleData}
|
|
1381
|
-
data={
|
|
1433
|
+
data={filteredItem} // filter result
|
|
1382
1434
|
cleanNodeBtnClassName={cleanNodeBtnClassName}
|
|
1383
1435
|
cleanNodeBtnContent={cleanNodeBtnContent}
|
|
1384
1436
|
selectEv={(e, value, index) => handleClickItem(e, value, index, level, listData.current)}
|
|
@@ -13,7 +13,6 @@ import { htmlEncode } from 'funda-utils/dist/cjs/sanitize';
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
// loader
|
|
18
17
|
import PureLoader from './PureLoader';
|
|
19
18
|
import TypingEffect from "./TypingEffect";
|
|
@@ -46,16 +45,24 @@ export type QuestionData = {
|
|
|
46
45
|
list: Array<string>;
|
|
47
46
|
};
|
|
48
47
|
|
|
48
|
+
export type SelectedOption = {
|
|
49
|
+
[key: string]: string | number;
|
|
50
|
+
curIndex: number;
|
|
51
|
+
curValue: string;
|
|
52
|
+
};
|
|
49
53
|
|
|
50
54
|
export interface FloatingButton {
|
|
51
55
|
label: string; // HTML string
|
|
52
56
|
value: string;
|
|
53
57
|
onClick: string;
|
|
58
|
+
active?: boolean; // Specify if the button should be active by default
|
|
54
59
|
isSelect?: boolean; // Mark whether it is a drop-down selection button
|
|
55
60
|
dynamicOptions?: boolean; // Mark whether to use dynamic options
|
|
61
|
+
defaultSelected?: number; // Specify default selected option index
|
|
56
62
|
[key: string]: any; // Allows dynamic `onSelect__<number>` attributes, such as `onSelect__1`, `onSelect__2`, ...
|
|
57
63
|
}
|
|
58
64
|
|
|
65
|
+
|
|
59
66
|
export interface FloatingButtonSelectOption {
|
|
60
67
|
label: string;
|
|
61
68
|
value: string;
|
|
@@ -178,6 +185,11 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
178
185
|
const [enableStreamMode, setEnableStreamMode] = useState<boolean>(true);
|
|
179
186
|
const animatedMessagesRef = useRef<Set<number>>(new Set()); // Add a ref to keep track of messages that have already been animated
|
|
180
187
|
|
|
188
|
+
// Keep track of whether the default values have been initialized
|
|
189
|
+
const [initializedDefaults, setInitializedDefaults] = useState<Record<string, boolean>>({});
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
181
193
|
//
|
|
182
194
|
const timer = useRef<any>(null);
|
|
183
195
|
|
|
@@ -508,6 +520,19 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
508
520
|
return newState;
|
|
509
521
|
});
|
|
510
522
|
};
|
|
523
|
+
|
|
524
|
+
// The onClick action specifically used to perform the default options
|
|
525
|
+
const executeDefaultOptionAction = async (actionStr: string, buttonId: string) => {
|
|
526
|
+
try {
|
|
527
|
+
const actionFn = new Function('method', 'isActive', 'button', actionStr);
|
|
528
|
+
// To perform the action, pass false as the "isActive" parameter, as this is the default option
|
|
529
|
+
await actionFn(exposedMethods(), false, document.getElementById(buttonId));
|
|
530
|
+
} catch (error) {
|
|
531
|
+
console.error('Error executing default option action:', error);
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
|
|
511
536
|
const executeButtonAction = async (actionStr: string, buttonId: string, buttonElement: HTMLButtonElement) => {
|
|
512
537
|
try {
|
|
513
538
|
const actionFn = new Function('method', 'isActive', 'button', actionStr);
|
|
@@ -547,7 +572,11 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
547
572
|
|
|
548
573
|
|
|
549
574
|
// options
|
|
550
|
-
const [selectedOpt, setSelectedOpt] = useState<
|
|
575
|
+
const [selectedOpt, setSelectedOpt] = useState<SelectedOption>({
|
|
576
|
+
curIndex: -1,
|
|
577
|
+
curValue: ''
|
|
578
|
+
});
|
|
579
|
+
|
|
551
580
|
// Store dynamic options
|
|
552
581
|
const [dynamicOptions, setDynamicOptions] = useState<Record<string, FloatingButtonSelectOption[]>>({});
|
|
553
582
|
|
|
@@ -575,7 +604,7 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
575
604
|
return options;
|
|
576
605
|
};
|
|
577
606
|
|
|
578
|
-
const handleExecuteButtonSelect = (buttonId: string, option: FloatingButtonSelectOption, index: number, value: string) => {
|
|
607
|
+
const handleExecuteButtonSelect = (buttonId: string, option: FloatingButtonSelectOption, index: number, value: string, isDefaultSelection: boolean = false) => {
|
|
579
608
|
|
|
580
609
|
if (option.value === "cancel") {
|
|
581
610
|
setSelectedOpt(prev => {
|
|
@@ -597,11 +626,15 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
597
626
|
}));
|
|
598
627
|
}
|
|
599
628
|
|
|
629
|
+
|
|
630
|
+
// The button action is performed and the drop-down menu is closed only when it is not the default selection
|
|
631
|
+
if (!isDefaultSelection) {
|
|
632
|
+
executeButtonAction(option.onClick, buttonId, document.getElementById(buttonId) as HTMLButtonElement);
|
|
633
|
+
|
|
634
|
+
// Close the drop-down
|
|
635
|
+
closeDropdowns();
|
|
636
|
+
}
|
|
600
637
|
|
|
601
|
-
executeButtonAction(option.onClick, buttonId, document.getElementById(buttonId) as HTMLButtonElement);
|
|
602
|
-
|
|
603
|
-
// Close the drop-down
|
|
604
|
-
closeDropdowns();
|
|
605
638
|
};
|
|
606
639
|
|
|
607
640
|
// click outside
|
|
@@ -1054,10 +1087,11 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
1054
1087
|
customMethodsRef.current,
|
|
1055
1088
|
conversationHistory.current
|
|
1056
1089
|
);
|
|
1057
|
-
|
|
1058
1090
|
const { content, isStream } = customResponse;
|
|
1059
1091
|
let contentRes: any = content;
|
|
1060
1092
|
|
|
1093
|
+
|
|
1094
|
+
|
|
1061
1095
|
// Update stream mode
|
|
1062
1096
|
setEnableStreamMode(isStream);
|
|
1063
1097
|
|
|
@@ -1164,6 +1198,7 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
1164
1198
|
// hide loader
|
|
1165
1199
|
setLoaderDisplay(false);
|
|
1166
1200
|
|
|
1201
|
+
|
|
1167
1202
|
let result: any = jsonResponse;
|
|
1168
1203
|
if (extractPath) {
|
|
1169
1204
|
for (const path of extractPath) {
|
|
@@ -1176,6 +1211,7 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
1176
1211
|
// Replace with a valid label
|
|
1177
1212
|
content = fixHtmlTags(content, args().withReasoning, args().reasoningSwitchLabel);
|
|
1178
1213
|
|
|
1214
|
+
|
|
1179
1215
|
return {
|
|
1180
1216
|
reply: formatLatestDisplayContent(content),
|
|
1181
1217
|
useStreamRender: false
|
|
@@ -1244,6 +1280,53 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
1244
1280
|
(window as any).chatboxCopyToClipboard = chatboxCopyToClipboard;
|
|
1245
1281
|
}, []);
|
|
1246
1282
|
|
|
1283
|
+
|
|
1284
|
+
|
|
1285
|
+
// Initialize the default value of toolkit buttons
|
|
1286
|
+
useEffect(() => {
|
|
1287
|
+
if (args().toolkitButtons) {
|
|
1288
|
+
args().toolkitButtons.forEach((btn: FloatingButton, index: number) => {
|
|
1289
|
+
const _id = `${args().prefix || 'custom-'}chatbox-btn-tools-${chatId}${index}`;
|
|
1290
|
+
|
|
1291
|
+
if (btn.isSelect) {
|
|
1292
|
+
|
|
1293
|
+
if (!initializedDefaults[_id] && typeof btn.defaultSelected === 'number') {
|
|
1294
|
+
const options = getButtonOptions(btn, _id);
|
|
1295
|
+
|
|
1296
|
+
// If there is a default selected item, initialize the selected state
|
|
1297
|
+
if (btn.defaultSelected >= 0 && btn.defaultSelected < options.length) {
|
|
1298
|
+
const defaultOption = options[btn.defaultSelected];
|
|
1299
|
+
if (defaultOption) {
|
|
1300
|
+
// Update the selected status
|
|
1301
|
+
// console.log('--> defaultOption: ', defaultOption);
|
|
1302
|
+
|
|
1303
|
+
// Pass the "isDefaultSelection" parameter as true
|
|
1304
|
+
handleExecuteButtonSelect(_id, defaultOption, btn.defaultSelected, defaultOption.value, true);
|
|
1305
|
+
|
|
1306
|
+
// Perform the onClick action alone
|
|
1307
|
+
executeDefaultOptionAction(defaultOption.onClick, _id);
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
// Mark this button with the default value initialized
|
|
1311
|
+
setInitializedDefaults(prev => ({
|
|
1312
|
+
...prev,
|
|
1313
|
+
[_id]: true
|
|
1314
|
+
}));
|
|
1315
|
+
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
} else if (btn.active) {
|
|
1320
|
+
// For non-select buttons, if defaultActive is true, execute the onClick action
|
|
1321
|
+
executeButtonAction(btn.onClick, _id, document.getElementById(_id) as HTMLButtonElement);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
})
|
|
1326
|
+
}
|
|
1327
|
+
}, [chatId, args().toolkitButtons]); // It is only executed when the component is first rendered and when toolkitButtons changes
|
|
1328
|
+
|
|
1329
|
+
|
|
1247
1330
|
return (
|
|
1248
1331
|
<>
|
|
1249
1332
|
|
|
@@ -1570,12 +1653,13 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
1570
1653
|
|
|
1571
1654
|
if (btn.isSelect) {
|
|
1572
1655
|
const options = getButtonOptions(btn, _id);
|
|
1573
|
-
|
|
1656
|
+
|
|
1574
1657
|
return (
|
|
1575
1658
|
<div key={index} className="toolkit-select-wrapper">
|
|
1576
1659
|
<button
|
|
1577
1660
|
id={_id}
|
|
1578
|
-
|
|
1661
|
+
data-value={btn.value || ''}
|
|
1662
|
+
className={`toolkit-select-btn ${isActive ? 'active' : ''} ${selectedOpt.curValue !== 'cancel' && typeof selectedOpt.curValue !== 'undefined' && selectedOpt.curValue !== '' ? 'opt-active' : ''}`}
|
|
1579
1663
|
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
1580
1664
|
e.preventDefault();
|
|
1581
1665
|
setActiveButtons(prev => ({
|
|
@@ -1610,7 +1694,8 @@ const Chatbox = (props: ChatboxProps) => {
|
|
|
1610
1694
|
{options.map((option: FloatingButtonSelectOption, optIndex: number) => (
|
|
1611
1695
|
<div
|
|
1612
1696
|
key={optIndex}
|
|
1613
|
-
|
|
1697
|
+
data-value={option.value || ''}
|
|
1698
|
+
className={`toolkit-select-option ${selectedOpt.curIndex === optIndex ? 'selected' : ''}`}
|
|
1614
1699
|
onClick={() => handleExecuteButtonSelect(_id, option, optIndex, option.value)}
|
|
1615
1700
|
>
|
|
1616
1701
|
<span dangerouslySetInnerHTML={{ __html: option.label }}></span>
|
|
@@ -58,7 +58,7 @@ const Checkbox = forwardRef((props: CheckboxProps, externalRef: any) => {
|
|
|
58
58
|
const idRes = id || uniqueID;
|
|
59
59
|
const rootRef = useRef<any>(null);
|
|
60
60
|
const valRef = useRef<any>(null);
|
|
61
|
-
const [val, setVal] = useState<
|
|
61
|
+
const [val, setVal] = useState<boolean>(false); // Avoid the error "react checkbox changing an uncontrolled input to be controlled"
|
|
62
62
|
|
|
63
63
|
// exposes the following methods
|
|
64
64
|
useImperativeHandle(
|
|
@@ -78,7 +78,7 @@ const Checkbox = forwardRef((props: CheckboxProps, externalRef: any) => {
|
|
|
78
78
|
onChange(null, false);
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
-
set: (value:
|
|
81
|
+
set: (value: boolean, cb?: any) => {
|
|
82
82
|
setVal(value);
|
|
83
83
|
cb?.();
|
|
84
84
|
|
|
@@ -133,7 +133,9 @@ const Checkbox = forwardRef((props: CheckboxProps, externalRef: any) => {
|
|
|
133
133
|
useEffect(() => {
|
|
134
134
|
|
|
135
135
|
// default value
|
|
136
|
-
|
|
136
|
+
if (typeof checked === 'boolean') {
|
|
137
|
+
setVal(checked);
|
|
138
|
+
}
|
|
137
139
|
|
|
138
140
|
// Set a checkbox to indeterminate state
|
|
139
141
|
if (typeof indeterminate !== 'undefined') {
|
|
@@ -144,6 +144,7 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
|
|
|
144
144
|
} = props;
|
|
145
145
|
|
|
146
146
|
|
|
147
|
+
const QUERY_STRING_PLACEHOLDER = '------'; // Invalid parameters for the first automatic request
|
|
147
148
|
const DEPTH = depth || 1055; // the default value same as bootstrap
|
|
148
149
|
const POS_OFFSET = 0;
|
|
149
150
|
const EXCEEDED_SIDE_POS_OFFSET = Number(exceededSidePosOffset) || 15;
|
|
@@ -773,7 +774,7 @@ const LiveSearch = forwardRef((props: LiveSearchProps, externalRef: any) => {
|
|
|
773
774
|
// data init
|
|
774
775
|
//--------------
|
|
775
776
|
const _oparams: any[] = fetchFuncMethodParams || [];
|
|
776
|
-
const _params: any[] = _oparams.map((item: any) => item !== '$QUERY_STRING' ? item : (fetchTrigger && !fetchUpdate) ? '' : (fetchUpdate ?
|
|
777
|
+
const _params: any[] = _oparams.map((item: any) => item !== '$QUERY_STRING' ? item : (fetchTrigger && !fetchUpdate) ? '' : (fetchUpdate ? QUERY_STRING_PLACEHOLDER : (fetchTrigger ? QUERY_STRING_PLACEHOLDER : '')));
|
|
777
778
|
if (!firstFetch) {
|
|
778
779
|
fetchData((_params).join(','));
|
|
779
780
|
setFirstFetch(true); // avoid triggering two data requests if the input value has not changed
|
|
@@ -17,9 +17,11 @@
|
|
|
17
17
|
--cus-sel-removebtn-fill: #000;
|
|
18
18
|
--cus-sel-removebtn-hover-fill: #f00;
|
|
19
19
|
|
|
20
|
+
|
|
20
21
|
position: relative; /* Required */
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
|
|
23
25
|
|
|
24
26
|
/*------ Placeholder for input ------*/
|
|
25
27
|
input::placeholder {
|
|
@@ -33,7 +35,6 @@
|
|
|
33
35
|
fill: var(--cus-sel-arrow-fill);
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
|
-
|
|
37
38
|
/*------ Clean ------*/
|
|
38
39
|
.clean {
|
|
39
40
|
svg .clean-fill-g {
|
|
@@ -71,6 +72,7 @@
|
|
|
71
72
|
.custom-select-multi__control-blinking-cursor {
|
|
72
73
|
display: inline-block;
|
|
73
74
|
color: var(--cus-sel-placeholder-color);
|
|
75
|
+
width: 100%;
|
|
74
76
|
|
|
75
77
|
&.animated {
|
|
76
78
|
animation: 1s mf-sel-blink step-end infinite;
|
|
@@ -80,6 +82,15 @@
|
|
|
80
82
|
color: var(--cus-sel-input-placeholder-color);
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
/* Text preview */
|
|
86
|
+
> span {
|
|
87
|
+
display: inline-block;
|
|
88
|
+
text-overflow: ellipsis;
|
|
89
|
+
white-space: nowrap;
|
|
90
|
+
overflow: hidden;
|
|
91
|
+
max-width: 100%;
|
|
92
|
+
}
|
|
93
|
+
|
|
83
94
|
|
|
84
95
|
}
|
|
85
96
|
.custom-select-multi__control-blinking-following-cursor {
|
|
@@ -383,7 +394,7 @@
|
|
|
383
394
|
--cus-sel-listgroup-content-scrollbar-w: 10px;
|
|
384
395
|
--cus-sel-listgroup-grouptitle-color: #a2a2a2;
|
|
385
396
|
--cus-sel-listgroup-groupborder-color: #d8d8d8;
|
|
386
|
-
|
|
397
|
+
--cus-sel-loader-color: #000000;
|
|
387
398
|
|
|
388
399
|
|
|
389
400
|
|
|
@@ -391,11 +402,41 @@
|
|
|
391
402
|
min-width: var(--cus-sel-listgroup-popwin-min-width);
|
|
392
403
|
z-index: 1055; /* --bs-modal-zindex */
|
|
393
404
|
|
|
405
|
+
|
|
394
406
|
&.active {
|
|
395
407
|
display: block !important;
|
|
396
408
|
}
|
|
397
409
|
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
/*------ Loader ------*/
|
|
413
|
+
.cus-select-loader {
|
|
414
|
+
pointer-events: none;
|
|
415
|
+
z-index: 1;
|
|
416
|
+
width: 12px;
|
|
417
|
+
height: 12px;
|
|
418
|
+
text-align: center;
|
|
419
|
+
transform-origin: center;
|
|
420
|
+
transform: translate(-5px, 0) rotate(0);
|
|
421
|
+
animation: 1s linear infinite cus-select__spinner;
|
|
422
|
+
|
|
423
|
+
svg {
|
|
424
|
+
vertical-align: top;
|
|
425
|
+
|
|
426
|
+
path {
|
|
427
|
+
fill: var(--cus-sel-loader-color);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
@keyframes cus-select__spinner {
|
|
433
|
+
to {
|
|
434
|
+
transform: translate(-5px, 0) rotate(-360deg);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
398
437
|
|
|
438
|
+
|
|
439
|
+
/*------ Options ------*/
|
|
399
440
|
.custom-select__options-contentlist {
|
|
400
441
|
overflow: hidden;
|
|
401
442
|
overflow-y: auto;
|