trotl-filter 1.0.39 → 1.0.41

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 CHANGED
@@ -9033,29 +9033,6 @@ function DateTimeInput({
9033
9033
  className = "",
9034
9034
  style = {},
9035
9035
  predefinedRanges = ["today", "yesterday"],
9036
- presets = [{
9037
- label: "Clear",
9038
- type: "clear"
9039
- }, {
9040
- label: "Today",
9041
- type: "today"
9042
- }, {
9043
- label: "+1 Week",
9044
- type: "days",
9045
- value: 7
9046
- }, {
9047
- label: "+10 Days",
9048
- type: "days",
9049
- value: 10
9050
- }, {
9051
- label: "+1 Month",
9052
- type: "months",
9053
- value: 1
9054
- }, {
9055
- label: "+1 Year",
9056
- type: "years",
9057
- value: 1
9058
- }],
9059
9036
  startWith = "sunday",
9060
9037
  ...rest
9061
9038
  }) {
@@ -9073,11 +9050,12 @@ function DateTimeInput({
9073
9050
  };
9074
9051
  }
9075
9052
  const paramKey = pushUrlParamObj || null;
9053
+
9054
+ // Refs to stabilize callbacks and prevent re-entrant URL updates
9076
9055
  const onChangeRef = React.useRef(onChange);
9077
9056
  const controlledValueRef = React.useRef(controlledValue);
9078
- const lastUrlValueRef = React.useRef(null);
9079
9057
  const isUpdatingFromComponentRef = React.useRef(false);
9080
- const historyPatchedRef = React.useRef(false);
9058
+ const lastUrlValueRef = React.useRef(null);
9081
9059
  React.useEffect(() => {
9082
9060
  onChangeRef.current = onChange;
9083
9061
  }, [onChange]);
@@ -9101,6 +9079,12 @@ function DateTimeInput({
9101
9079
  return `${yyyy}-${mm}-${dd}`;
9102
9080
  }, [time]);
9103
9081
 
9082
+ // Stable ref for toInputString to avoid effect re-runs
9083
+ const toInputStringRef = React.useRef(toInputString);
9084
+ React.useEffect(() => {
9085
+ toInputStringRef.current = toInputString;
9086
+ }, [toInputString]);
9087
+
9104
9088
  // Initial value
9105
9089
  const [value, setValue] = React.useState(() => {
9106
9090
  if (typeof controlledValue !== "undefined") return controlledValue;
@@ -9122,10 +9106,6 @@ function DateTimeInput({
9122
9106
  }
9123
9107
  return toInputString(d.getTime());
9124
9108
  });
9125
- const valueRef = React.useRef(value);
9126
- React.useEffect(() => {
9127
- valueRef.current = value;
9128
- }, [value]);
9129
9109
 
9130
9110
  // Dropdown state & positioning
9131
9111
  const [open, setOpen] = React.useState(false);
@@ -9312,10 +9292,9 @@ function DateTimeInput({
9312
9292
  const d = new Date(val);
9313
9293
  ts = d.getTime();
9314
9294
  }
9315
- const nextVal = ts && String(ts).length > 0 && !isNaN(Number(ts)) ? String(ts) : "";
9316
- lastUrlValueRef.current = nextVal;
9317
- if (nextVal) params.set(paramKey, nextVal);else params.delete(paramKey);
9295
+ if (ts && String(ts).length > 0 && !isNaN(Number(ts))) params.set(paramKey, String(ts));else params.delete(paramKey);
9318
9296
  const newUrl = window.location.pathname + (params.toString() ? `?${params.toString()}` : "");
9297
+ lastUrlValueRef.current = params.get(paramKey) || null;
9319
9298
  window.history.replaceState({}, "", newUrl);
9320
9299
  setTimeout(() => {
9321
9300
  isUpdatingFromComponentRef.current = false;
@@ -9329,33 +9308,32 @@ function DateTimeInput({
9329
9308
  if (isUpdatingFromComponentRef.current) return;
9330
9309
  const params = new URLSearchParams(window.location.search);
9331
9310
  const urlVal = params.get(paramKey);
9332
- if (urlVal) {
9333
- if (lastUrlValueRef.current === urlVal && valueRef.current === toInputString(urlVal)) return;
9334
- const str = toInputString(urlVal);
9335
- if (str !== valueRef.current) {
9336
- setValue(prev => prev !== str ? str : prev);
9337
- if (onChangeRef.current && str !== controlledValueRef.current) onChangeRef.current(urlVal);
9338
- }
9311
+ if (urlVal && urlVal !== lastUrlValueRef.current) {
9312
+ const str = toInputStringRef.current(urlVal);
9313
+ setValue(prev => prev !== str ? str : prev);
9314
+ if (onChangeRef.current && str !== controlledValueRef.current) onChangeRef.current(urlVal);
9315
+ lastUrlValueRef.current = urlVal;
9316
+ } else if (!urlVal && lastUrlValueRef.current !== null) {
9317
+ setValue("");
9318
+ if (onChangeRef.current) onChangeRef.current("");
9319
+ lastUrlValueRef.current = null;
9339
9320
  }
9340
9321
  };
9341
9322
  syncFromUrl();
9342
9323
  window.addEventListener('popstate', syncFromUrl);
9343
-
9344
- // Only patch history methods once globally
9345
- if (!historyPatchedRef.current) {
9346
- const origPushState = window.history.pushState;
9347
- const origReplaceState = window.history.replaceState;
9348
- window.history.pushState = function () {
9349
- const rv = origPushState.apply(this, arguments);
9350
- window.dispatchEvent(new Event('pushState'));
9351
- return rv;
9352
- };
9353
- window.history.replaceState = function () {
9354
- const rv = origReplaceState.apply(this, arguments);
9355
- window.dispatchEvent(new Event('replaceState'));
9356
- return rv;
9324
+ // Patch history methods only once globally
9325
+ if (!window.__historyPatched) {
9326
+ window.__historyPatched = true;
9327
+ const patchHistory = type => {
9328
+ const orig = window.history[type];
9329
+ window.history[type] = function () {
9330
+ const rv = orig.apply(this, arguments);
9331
+ window.dispatchEvent(new Event(type));
9332
+ return rv;
9333
+ };
9357
9334
  };
9358
- historyPatchedRef.current = true;
9335
+ patchHistory('pushState');
9336
+ patchHistory('replaceState');
9359
9337
  }
9360
9338
  window.addEventListener('pushState', syncFromUrl);
9361
9339
  window.addEventListener('replaceState', syncFromUrl);
@@ -9364,7 +9342,7 @@ function DateTimeInput({
9364
9342
  window.removeEventListener('pushState', syncFromUrl);
9365
9343
  window.removeEventListener('replaceState', syncFromUrl);
9366
9344
  };
9367
- }, [paramKey, toInputString]);
9345
+ }, [paramKey]);
9368
9346
 
9369
9347
  // Controlled value sync
9370
9348
  React.useEffect(() => {
@@ -9432,41 +9410,6 @@ function DateTimeInput({
9432
9410
  onChange?.("");
9433
9411
  };
9434
9412
 
9435
- // Presets (custom actions like clear, today, +N days/months/years)
9436
- const handlePresetClick = React.useCallback(p => {
9437
- if (!p || disabled) return;
9438
- const type = String(p.type || '').toLowerCase();
9439
- if (type === 'clear') {
9440
- handleClear();
9441
- return;
9442
- }
9443
- let d = new Date();
9444
- if (type === 'today') {
9445
- d = new Date();
9446
- d.setHours(0, 0, 0, 0);
9447
- } else if (type === 'days') {
9448
- const v = Number(p.value) || 0;
9449
- d.setHours(0, 0, 0, 0);
9450
- d.setDate(d.getDate() + v);
9451
- } else if (type === 'months') {
9452
- const v = Number(p.value) || 0;
9453
- d.setHours(0, 0, 0, 0);
9454
- d.setMonth(d.getMonth() + v);
9455
- } else if (type === 'years') {
9456
- const v = Number(p.value) || 0;
9457
- d.setHours(0, 0, 0, 0);
9458
- d.setFullYear(d.getFullYear() + v);
9459
- } else {
9460
- // unknown type: ignore
9461
- return;
9462
- }
9463
- if (time && timeStart) {
9464
- const [h, m] = (timeStart || '00:00').split(':');
9465
- d.setHours(Number(h), Number(m), 0, 0);
9466
- }
9467
- applySelection(d);
9468
- }, [disabled, time, timeStart, applySelection, handleClear]);
9469
-
9470
9413
  // Outside click close
9471
9414
  React.useEffect(() => {
9472
9415
  if (!open) return;
@@ -9553,28 +9496,7 @@ function DateTimeInput({
9553
9496
  cursor: disabled ? 'not-allowed' : 'pointer'
9554
9497
  }
9555
9498
  }, p.label);
9556
- })), Array.isArray(presets) && presets.length > 0 && /*#__PURE__*/React.createElement("div", {
9557
- style: {
9558
- display: 'flex',
9559
- flexWrap: 'wrap',
9560
- gap: 6,
9561
- marginBottom: 8
9562
- }
9563
- }, presets.map((ps, idx) => /*#__PURE__*/React.createElement("button", {
9564
- key: `preset_${idx}`,
9565
- type: "button",
9566
- onClick: () => handlePresetClick(ps),
9567
- disabled: disabled,
9568
- className: "basic-btn",
9569
- style: {
9570
- padding: '4px 8px',
9571
- fontSize: 12,
9572
- background: disabled ? '#f9fafb' : '#fff',
9573
- color: disabled ? '#9ca3af' : '#000',
9574
- border: disabled ? '1px solid #e5e7eb' : '1px solid #d9d9d9',
9575
- cursor: disabled ? 'not-allowed' : 'pointer'
9576
- }
9577
- }, ps.label))), /*#__PURE__*/React.createElement("div", {
9499
+ })), /*#__PURE__*/React.createElement("div", {
9578
9500
  style: {
9579
9501
  display: 'flex',
9580
9502
  justifyContent: 'space-between',
@@ -9735,8 +9657,7 @@ DateTimeInput.propTypes = {
9735
9657
  disabled: PropTypes.bool,
9736
9658
  className: PropTypes.string,
9737
9659
  style: PropTypes.object,
9738
- predefinedRanges: PropTypes.array,
9739
- presets: PropTypes.array
9660
+ predefinedRanges: PropTypes.array
9740
9661
  };
9741
9662
  const buttonStyle = {
9742
9663
  padding: '6px 16px',