trotl-filter 1.0.43 → 1.0.44
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/dist/index.cjs.js +326 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +326 -4
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -7224,12 +7224,12 @@ const MultiSelectDropdown = ({
|
|
|
7224
7224
|
maxHeight: 34,
|
|
7225
7225
|
minHeight: 34,
|
|
7226
7226
|
height: "auto",
|
|
7227
|
-
|
|
7227
|
+
background: disabled ? '#f5f5f5' : theme === "dark" ? "#1e1e1e" : "#fff",
|
|
7228
7228
|
borderColor: theme === "dark" ? "#555" : "#ccc",
|
|
7229
7229
|
color: theme === "dark" ? "#eee" : "#333",
|
|
7230
7230
|
boxShadow: "none",
|
|
7231
7231
|
borderRadius: 2,
|
|
7232
|
-
cursor: "pointer",
|
|
7232
|
+
cursor: disabled ? 'not-allowed' : "pointer",
|
|
7233
7233
|
paddingRight: showSpinner ? 36 : base.paddingRight
|
|
7234
7234
|
}),
|
|
7235
7235
|
menu: base => ({
|
|
@@ -7293,7 +7293,8 @@ const MultiSelectDropdown = ({
|
|
|
7293
7293
|
position: 'relative',
|
|
7294
7294
|
...style,
|
|
7295
7295
|
...(disabled ? {
|
|
7296
|
-
opacity: 0.6
|
|
7296
|
+
opacity: 0.6,
|
|
7297
|
+
background: '#f5f5f5'
|
|
7297
7298
|
} : {})
|
|
7298
7299
|
},
|
|
7299
7300
|
ref: containerRef,
|
|
@@ -8329,6 +8330,327 @@ function requirePropTypes () {
|
|
|
8329
8330
|
var propTypesExports = /*@__PURE__*/ requirePropTypes();
|
|
8330
8331
|
var PropTypes = /*@__PURE__*/getDefaultExportFromCjs(propTypesExports);
|
|
8331
8332
|
|
|
8333
|
+
function MultiSelect({
|
|
8334
|
+
isMulti = false,
|
|
8335
|
+
options = [],
|
|
8336
|
+
selected = [],
|
|
8337
|
+
onChange,
|
|
8338
|
+
placeholder = 'Select...',
|
|
8339
|
+
allowClear = false,
|
|
8340
|
+
disabled = false,
|
|
8341
|
+
addItem,
|
|
8342
|
+
pushUrlParamObj = false,
|
|
8343
|
+
loading = false,
|
|
8344
|
+
controlStyle = {},
|
|
8345
|
+
className = ''
|
|
8346
|
+
}) {
|
|
8347
|
+
const containerRef = React.useRef(null);
|
|
8348
|
+
const [open, setOpen] = React.useState(false);
|
|
8349
|
+
const [inputValue, setInputValue] = React.useState('');
|
|
8350
|
+
const [maxVisible, setMaxVisible] = React.useState(3);
|
|
8351
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
8352
|
+
React.useEffect(() => {
|
|
8353
|
+
if (!containerRef.current) return;
|
|
8354
|
+
const calc = () => {
|
|
8355
|
+
const w = containerRef.current.offsetWidth || 200;
|
|
8356
|
+
const avg = 90;
|
|
8357
|
+
setMaxVisible(Math.max(1, Math.floor((w - 40) / avg)));
|
|
8358
|
+
};
|
|
8359
|
+
calc();
|
|
8360
|
+
window.addEventListener('resize', calc);
|
|
8361
|
+
return () => window.removeEventListener('resize', calc);
|
|
8362
|
+
}, []);
|
|
8363
|
+
|
|
8364
|
+
// URL sync helpers
|
|
8365
|
+
const setUrlParam = value => {
|
|
8366
|
+
if (!pushUrlParamObj) return;
|
|
8367
|
+
const url = new URL(window.location);
|
|
8368
|
+
if (!value || Array.isArray(value) && value.length === 0) url.searchParams.delete(pushUrlParamObj);else url.searchParams.set(pushUrlParamObj, Array.isArray(value) ? value.join(',') : value);
|
|
8369
|
+
window.history.replaceState({}, '', url);
|
|
8370
|
+
};
|
|
8371
|
+
React.useEffect(() => {
|
|
8372
|
+
if (!pushUrlParamObj || !options || options.length === 0) return;
|
|
8373
|
+
const read = () => {
|
|
8374
|
+
const params = new URLSearchParams(window.location.search);
|
|
8375
|
+
const val = params.get(pushUrlParamObj);
|
|
8376
|
+
if (!val) return;
|
|
8377
|
+
if (isMulti) {
|
|
8378
|
+
const arr = val.split(',').filter(Boolean);
|
|
8379
|
+
if (JSON.stringify(arr) !== JSON.stringify(selected)) onChange?.(arr);
|
|
8380
|
+
} else {
|
|
8381
|
+
if (!selected || selected[0] !== val) onChange?.([val]);
|
|
8382
|
+
}
|
|
8383
|
+
};
|
|
8384
|
+
read();
|
|
8385
|
+
window.addEventListener('popstate', read);
|
|
8386
|
+
return () => window.removeEventListener('popstate', read);
|
|
8387
|
+
}, [pushUrlParamObj, options, isMulti, selected, onChange]);
|
|
8388
|
+
const selectedOptions = React.useMemo(() => {
|
|
8389
|
+
if (isMulti) return options.filter(o => (selected || []).includes(o.value));
|
|
8390
|
+
return options.find(o => o.value === (selected && selected[0])) || null;
|
|
8391
|
+
}, [options, selected, isMulti]);
|
|
8392
|
+
const inputExists = React.useMemo(() => {
|
|
8393
|
+
return options.some(opt => String(opt.label).toLowerCase() === inputValue.trim().toLowerCase());
|
|
8394
|
+
}, [inputValue, options]);
|
|
8395
|
+
const menuOptions = React.useMemo(() => {
|
|
8396
|
+
if (inputValue && !inputExists && typeof addItem === 'function') {
|
|
8397
|
+
return [...options, {
|
|
8398
|
+
label: `+ Add "${inputValue.trim()}"`,
|
|
8399
|
+
value: '__add_new__',
|
|
8400
|
+
__isAddNew: true
|
|
8401
|
+
}];
|
|
8402
|
+
}
|
|
8403
|
+
return options;
|
|
8404
|
+
}, [options, inputValue, inputExists, addItem]);
|
|
8405
|
+
|
|
8406
|
+
// Labels for items hidden behind the "overflow" indicator
|
|
8407
|
+
const hiddenLabels = React.useMemo(() => {
|
|
8408
|
+
if (!isMulti) return "";
|
|
8409
|
+
const arr = (selectedOptions || []).slice(maxVisible).map(s => s.label);
|
|
8410
|
+
return arr.join(', ');
|
|
8411
|
+
}, [isMulti, selectedOptions, maxVisible]);
|
|
8412
|
+
const toggleValue = val => {
|
|
8413
|
+
if (disabled) return;
|
|
8414
|
+
if (isMulti) {
|
|
8415
|
+
const prev = Array.isArray(selected) ? [...selected] : [];
|
|
8416
|
+
const idx = prev.findIndex(x => String(x) === String(val));
|
|
8417
|
+
if (idx === -1) prev.push(val);else prev.splice(idx, 1);
|
|
8418
|
+
onChange?.(prev);
|
|
8419
|
+
if (pushUrlParamObj) setUrlParam(prev);
|
|
8420
|
+
} else {
|
|
8421
|
+
const out = [val];
|
|
8422
|
+
onChange?.(out);
|
|
8423
|
+
if (pushUrlParamObj) setUrlParam(val);
|
|
8424
|
+
setOpen(false);
|
|
8425
|
+
}
|
|
8426
|
+
};
|
|
8427
|
+
const handleAddNew = () => {
|
|
8428
|
+
if (disabled) return;
|
|
8429
|
+
const label = inputValue.trim();
|
|
8430
|
+
if (!label) return;
|
|
8431
|
+
const exists = options.some(opt => String(opt.value).toLowerCase() === label.toLowerCase() || String(opt.label).toLowerCase() === label.toLowerCase());
|
|
8432
|
+
if (exists) {
|
|
8433
|
+
setInputValue('');
|
|
8434
|
+
return;
|
|
8435
|
+
}
|
|
8436
|
+
const newOpt = {
|
|
8437
|
+
label,
|
|
8438
|
+
value: label
|
|
8439
|
+
};
|
|
8440
|
+
if (typeof addItem === 'function') addItem(newOpt);
|
|
8441
|
+
if (isMulti) {
|
|
8442
|
+
const next = [...(selected || []), newOpt.value];
|
|
8443
|
+
onChange?.(next);
|
|
8444
|
+
if (pushUrlParamObj) setUrlParam(next);
|
|
8445
|
+
} else {
|
|
8446
|
+
onChange?.([newOpt.value]);
|
|
8447
|
+
if (pushUrlParamObj) setUrlParam(newOpt.value);
|
|
8448
|
+
setOpen(false);
|
|
8449
|
+
}
|
|
8450
|
+
setInputValue('');
|
|
8451
|
+
};
|
|
8452
|
+
const clearSelection = () => {
|
|
8453
|
+
if (disabled) return;
|
|
8454
|
+
onChange?.([]);
|
|
8455
|
+
if (pushUrlParamObj) setUrlParam([]);
|
|
8456
|
+
};
|
|
8457
|
+
React.useEffect(() => {
|
|
8458
|
+
const onDocClick = e => {
|
|
8459
|
+
if (!containerRef.current) return;
|
|
8460
|
+
if (!containerRef.current.contains(e.target)) setOpen(false);
|
|
8461
|
+
};
|
|
8462
|
+
document.addEventListener('mousedown', onDocClick);
|
|
8463
|
+
return () => document.removeEventListener('mousedown', onDocClick);
|
|
8464
|
+
}, []);
|
|
8465
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
8466
|
+
ref: containerRef,
|
|
8467
|
+
className: className,
|
|
8468
|
+
style: {
|
|
8469
|
+
position: 'relative',
|
|
8470
|
+
width: '100%',
|
|
8471
|
+
...controlStyle,
|
|
8472
|
+
...(disabled ? {
|
|
8473
|
+
background: '#f5f5f5',
|
|
8474
|
+
opacity: 0.9
|
|
8475
|
+
} : {})
|
|
8476
|
+
}
|
|
8477
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
8478
|
+
role: "button",
|
|
8479
|
+
tabIndex: 0,
|
|
8480
|
+
onClick: () => !disabled && setOpen(s => !s),
|
|
8481
|
+
onKeyDown: e => {
|
|
8482
|
+
if (e.key === 'Enter' && !disabled) setOpen(s => !s);
|
|
8483
|
+
},
|
|
8484
|
+
onFocus: () => setIsFocused(true),
|
|
8485
|
+
onBlur: () => setIsFocused(false),
|
|
8486
|
+
style: {
|
|
8487
|
+
minHeight: 36,
|
|
8488
|
+
display: 'flex',
|
|
8489
|
+
alignItems: 'center',
|
|
8490
|
+
gap: 8,
|
|
8491
|
+
padding: '6px 8px',
|
|
8492
|
+
border: disabled ? '1px solid #eee' : isFocused && (isMulti ? (selected || []).length > 0 : selected && selected[0] != null) ? '1px solid transparent' : '1px solid #ccc',
|
|
8493
|
+
borderRadius: 2,
|
|
8494
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
8495
|
+
background: disabled ? '#f5f5f5' : '#fff',
|
|
8496
|
+
outline: 'none',
|
|
8497
|
+
...controlStyle
|
|
8498
|
+
}
|
|
8499
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
8500
|
+
style: {
|
|
8501
|
+
display: 'flex',
|
|
8502
|
+
gap: 6,
|
|
8503
|
+
alignItems: 'center',
|
|
8504
|
+
flexWrap: 'nowrap',
|
|
8505
|
+
flex: 1,
|
|
8506
|
+
overflow: 'hidden',
|
|
8507
|
+
minWidth: 0
|
|
8508
|
+
}
|
|
8509
|
+
}, isMulti ? (selectedOptions || []).slice(0, maxVisible).map(s => /*#__PURE__*/React.createElement("div", {
|
|
8510
|
+
key: s.value,
|
|
8511
|
+
onClick: e => e.stopPropagation(),
|
|
8512
|
+
style: {
|
|
8513
|
+
display: 'inline-flex',
|
|
8514
|
+
alignItems: 'center',
|
|
8515
|
+
gap: 6,
|
|
8516
|
+
padding: '4px 8px',
|
|
8517
|
+
background: '#e6f4ff',
|
|
8518
|
+
borderRadius: 2,
|
|
8519
|
+
fontSize: 13,
|
|
8520
|
+
whiteSpace: 'nowrap',
|
|
8521
|
+
overflow: 'hidden',
|
|
8522
|
+
textOverflow: 'ellipsis',
|
|
8523
|
+
maxWidth: 200,
|
|
8524
|
+
minWidth: 0
|
|
8525
|
+
}
|
|
8526
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
8527
|
+
style: {
|
|
8528
|
+
overflow: 'hidden',
|
|
8529
|
+
textOverflow: 'ellipsis',
|
|
8530
|
+
whiteSpace: 'nowrap',
|
|
8531
|
+
display: 'inline-block'
|
|
8532
|
+
}
|
|
8533
|
+
}, s.label), /*#__PURE__*/React.createElement("button", {
|
|
8534
|
+
"aria-label": `Remove ${s.label}`,
|
|
8535
|
+
onClick: e => {
|
|
8536
|
+
e.stopPropagation();
|
|
8537
|
+
if (!disabled) toggleValue(s.value);
|
|
8538
|
+
},
|
|
8539
|
+
style: {
|
|
8540
|
+
border: 'none',
|
|
8541
|
+
background: 'transparent',
|
|
8542
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
8543
|
+
padding: 0,
|
|
8544
|
+
margin: 0,
|
|
8545
|
+
fontSize: 12
|
|
8546
|
+
}
|
|
8547
|
+
}, "\u2716"))) : /*#__PURE__*/React.createElement("div", {
|
|
8548
|
+
style: {
|
|
8549
|
+
fontSize: 14,
|
|
8550
|
+
color: selectedOptions ? '#000' : '#666',
|
|
8551
|
+
overflow: 'hidden',
|
|
8552
|
+
textOverflow: 'ellipsis',
|
|
8553
|
+
whiteSpace: 'nowrap'
|
|
8554
|
+
}
|
|
8555
|
+
}, selectedOptions ? selectedOptions.label : placeholder), isMulti && (selectedOptions || []).length > maxVisible && /*#__PURE__*/React.createElement("div", {
|
|
8556
|
+
title: hiddenLabels,
|
|
8557
|
+
style: {
|
|
8558
|
+
fontSize: 13,
|
|
8559
|
+
color: '#666',
|
|
8560
|
+
cursor: 'default',
|
|
8561
|
+
flex: '0 0 auto',
|
|
8562
|
+
paddingLeft: 4
|
|
8563
|
+
}
|
|
8564
|
+
}, "\u2026")), /*#__PURE__*/React.createElement("div", {
|
|
8565
|
+
style: {
|
|
8566
|
+
display: 'flex',
|
|
8567
|
+
alignItems: 'center',
|
|
8568
|
+
gap: 8
|
|
8569
|
+
}
|
|
8570
|
+
}, allowClear && selected && selected.length > 0 && /*#__PURE__*/React.createElement("span", {
|
|
8571
|
+
onClick: e => {
|
|
8572
|
+
e.stopPropagation();
|
|
8573
|
+
clearSelection();
|
|
8574
|
+
},
|
|
8575
|
+
disabled: disabled,
|
|
8576
|
+
style: {
|
|
8577
|
+
cursor: disabled ? 'not-allowed' : 'pointer'
|
|
8578
|
+
}
|
|
8579
|
+
}, "\u2716"), loading && !disabled && /*#__PURE__*/React.createElement("div", {
|
|
8580
|
+
style: {
|
|
8581
|
+
width: 16,
|
|
8582
|
+
height: 16,
|
|
8583
|
+
borderRadius: 2,
|
|
8584
|
+
border: '2px solid #ccc',
|
|
8585
|
+
borderTopColor: '#444',
|
|
8586
|
+
animation: 'spin 0.9s linear infinite'
|
|
8587
|
+
}
|
|
8588
|
+
}))), open && /*#__PURE__*/React.createElement("div", {
|
|
8589
|
+
style: {
|
|
8590
|
+
position: 'absolute',
|
|
8591
|
+
zIndex: 50,
|
|
8592
|
+
marginTop: 6,
|
|
8593
|
+
width: '100%',
|
|
8594
|
+
background: '#fff',
|
|
8595
|
+
border: '1px solid #ddd',
|
|
8596
|
+
borderRadius: 2,
|
|
8597
|
+
boxShadow: '0 4px 12px rgba(0,0,0,0.08)',
|
|
8598
|
+
maxHeight: 260,
|
|
8599
|
+
overflow: 'auto'
|
|
8600
|
+
}
|
|
8601
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
8602
|
+
style: {
|
|
8603
|
+
padding: 8,
|
|
8604
|
+
borderBottom: '1px solid #f1f1f1'
|
|
8605
|
+
}
|
|
8606
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
8607
|
+
autoFocus: true,
|
|
8608
|
+
value: inputValue,
|
|
8609
|
+
onChange: e => setInputValue(e.target.value),
|
|
8610
|
+
onKeyDown: e => {
|
|
8611
|
+
if (e.key === 'Enter' && inputValue && typeof addItem === 'function') {
|
|
8612
|
+
handleAddNew();
|
|
8613
|
+
}
|
|
8614
|
+
},
|
|
8615
|
+
placeholder: "Type to search...",
|
|
8616
|
+
disabled: disabled,
|
|
8617
|
+
style: {
|
|
8618
|
+
padding: '6px 8px',
|
|
8619
|
+
borderRadius: 2,
|
|
8620
|
+
border: '1px solid #ffffff'
|
|
8621
|
+
}
|
|
8622
|
+
})), /*#__PURE__*/React.createElement("div", null, menuOptions.filter(opt => String(opt.label).toLowerCase().includes(inputValue.trim().toLowerCase())).map(opt => /*#__PURE__*/React.createElement("div", {
|
|
8623
|
+
key: opt.value,
|
|
8624
|
+
onClick: e => {
|
|
8625
|
+
e.stopPropagation();
|
|
8626
|
+
if (opt.__isAddNew) {
|
|
8627
|
+
handleAddNew();
|
|
8628
|
+
} else {
|
|
8629
|
+
toggleValue(opt.value);
|
|
8630
|
+
}
|
|
8631
|
+
},
|
|
8632
|
+
style: {
|
|
8633
|
+
padding: '8px 12px',
|
|
8634
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
8635
|
+
background: (isMulti ? (selected || []).includes(opt.value) : selected && selected[0] === opt.value) ? '#eef6ff' : '#fff'
|
|
8636
|
+
}
|
|
8637
|
+
}, opt.label)))), /*#__PURE__*/React.createElement("style", null, `@keyframes spin { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }`));
|
|
8638
|
+
}
|
|
8639
|
+
MultiSelect.propTypes = {
|
|
8640
|
+
isMulti: PropTypes.bool,
|
|
8641
|
+
options: PropTypes.array,
|
|
8642
|
+
selected: PropTypes.array,
|
|
8643
|
+
onChange: PropTypes.func,
|
|
8644
|
+
placeholder: PropTypes.string,
|
|
8645
|
+
allowClear: PropTypes.bool,
|
|
8646
|
+
disabled: PropTypes.bool,
|
|
8647
|
+
addItem: PropTypes.func,
|
|
8648
|
+
pushUrlParamObj: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
|
8649
|
+
loading: PropTypes.bool,
|
|
8650
|
+
controlStyle: PropTypes.object,
|
|
8651
|
+
className: PropTypes.string
|
|
8652
|
+
};
|
|
8653
|
+
|
|
8332
8654
|
// import "src/style/DebounceSelect.css";
|
|
8333
8655
|
|
|
8334
8656
|
const DebounceSelect = ({
|
|
@@ -11126,6 +11448,7 @@ exports.DateTimeInput = DateTimeInput;
|
|
|
11126
11448
|
exports.DebounceSelect = DebounceSelect;
|
|
11127
11449
|
exports.IconInput = IconInput;
|
|
11128
11450
|
exports.LineDivider = LineDivider;
|
|
11451
|
+
exports.MultiSelect = MultiSelect;
|
|
11129
11452
|
exports.MultiSelectDropdown = MultiSelectDropdown;
|
|
11130
11453
|
exports.RangePicker = RangePicker;
|
|
11131
11454
|
exports.SearchInput = SearchInput;
|