@paubox/ui 1.19.1 → 2.0.0

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/index.esm.js CHANGED
@@ -31073,7 +31073,7 @@ var EMPTY_CANDIDATES = [];
31073
31073
  var SearchOmnibox = function(param) {
31074
31074
  var bar = param.bar, _param_placeholder = param.placeholder, placeholder = _param_placeholder === void 0 ? 'Search' : _param_placeholder, _param_pbSearchBaseUrl = param.pbSearchBaseUrl, pbSearchBaseUrl = _param_pbSearchBaseUrl === void 0 ? '' : _param_pbSearchBaseUrl, _param_getAuthToken = param.getAuthToken, getAuthToken = _param_getAuthToken === void 0 ? function() {
31075
31075
  return '';
31076
- } : _param_getAuthToken, _param_mode = param.mode, mode = _param_mode === void 0 ? 'remote' : _param_mode, _param_withHistory = param.withHistory, withHistory = _param_withHistory === void 0 ? true : _param_withHistory, onResultClick = param.onResultClick, onSubmitFullSearch = param.onSubmitFullSearch, _param_localCandidates = param.localCandidates, localCandidates = _param_localCandidates === void 0 ? EMPTY_CANDIDATES : _param_localCandidates, onLocalQueryChange = param.onLocalQueryChange, _param_testId = param.testId, testId = _param_testId === void 0 ? 'search-omnibox' : _param_testId, _param_initialQuery = param.initialQuery, initialQuery = _param_initialQuery === void 0 ? '' : _param_initialQuery;
31076
+ } : _param_getAuthToken, _param_mode = param.mode, mode = _param_mode === void 0 ? 'remote' : _param_mode, _param_withHistory = param.withHistory, withHistory = _param_withHistory === void 0 ? true : _param_withHistory, onResultClick = param.onResultClick, onCommit = param.onCommit, onLiveChange = param.onLiveChange, _param_localCandidates = param.localCandidates, localCandidates = _param_localCandidates === void 0 ? EMPTY_CANDIDATES : _param_localCandidates, _param_testId = param.testId, testId = _param_testId === void 0 ? 'search-omnibox' : _param_testId, _param_initialQuery = param.initialQuery, initialQuery = _param_initialQuery === void 0 ? '' : _param_initialQuery;
31077
31077
  var _useState = _sliced_to_array$4(useState(initialQuery), 2), query = _useState[0], setQuery = _useState[1];
31078
31078
  var _useState1 = _sliced_to_array$4(useState(initialQuery), 2), debouncedQuery = _useState1[0], setDebouncedQuery = _useState1[1];
31079
31079
  var _useState2 = _sliced_to_array$4(useState(false), 2), focused = _useState2[0], setFocused = _useState2[1];
@@ -31275,46 +31275,46 @@ var SearchOmnibox = function(param) {
31275
31275
  mode,
31276
31276
  apiFetch
31277
31277
  ]);
31278
- // Tracks the last query value we've notified the local-mode parent about,
31279
- // so synchronous notifications from clear / Enter / selectLocal aren't
31280
- // echoed ~200ms later by the debounced local-autocomplete effect.
31281
- var lastLocalNotifyRef = useRef(undefined);
31282
- // Hold the parent callbacks in refs so `notifyParent` is stable across
31283
- // renders. Otherwise any caller passing inline arrow functions for
31284
- // `onSubmitFullSearch` / `onLocalQueryChange` (the common case) would
31285
- // re-allocate `notifyParent` every render, triggering the local-
31286
- // autocomplete effect on every render, which in turn calls
31287
- // `setLocalMatches([])` a new empty-array reference every time — and
31288
- // re-renders forever. Refs decouple the parent's reference identity
31289
- // from the effect's dep array.
31290
- var onSubmitFullSearchRef = useRef(onSubmitFullSearch);
31291
- var onLocalQueryChangeRef = useRef(onLocalQueryChange);
31278
+ // Tracks the last query value we've notified the parent about via the
31279
+ // debounced live-change path, so a synchronous commit (Enter / footer /
31280
+ // recent / local) isn't echoed ~200ms later when the debounced effect
31281
+ // fires for the same query.
31282
+ var lastLiveChangeRef = useRef(undefined);
31283
+ // Hold the parent callbacks in refs so the firing functions stay stable
31284
+ // across renders. Otherwise any caller passing inline arrow functions
31285
+ // (the common case) would re-allocate the firing closures every render,
31286
+ // churning effect dependencies and triggering loops. Refs decouple the
31287
+ // parent's reference identity from our effect deps.
31288
+ var onCommitRef = useRef(onCommit);
31289
+ var onLiveChangeRef = useRef(onLiveChange);
31292
31290
  useEffect(function() {
31293
- onSubmitFullSearchRef.current = onSubmitFullSearch;
31291
+ onCommitRef.current = onCommit;
31294
31292
  }, [
31295
- onSubmitFullSearch
31293
+ onCommit
31296
31294
  ]);
31297
31295
  useEffect(function() {
31298
- onLocalQueryChangeRef.current = onLocalQueryChange;
31296
+ onLiveChangeRef.current = onLiveChange;
31299
31297
  }, [
31300
- onLocalQueryChange
31301
- ]);
31302
- // Route parent notifications to the mode-appropriate callback. In local
31303
- // mode we dedupe so non-idempotent consumers don't see the same query
31304
- // twice (once synchronously, once via debounce).
31305
- var notifyParent = useCallback(function(q) {
31306
- if (mode === 'local') {
31307
- var _onLocalQueryChangeRef_current;
31308
- if (lastLocalNotifyRef.current === q) return;
31309
- lastLocalNotifyRef.current = q;
31310
- (_onLocalQueryChangeRef_current = onLocalQueryChangeRef.current) === null || _onLocalQueryChangeRef_current === void 0 ? void 0 : _onLocalQueryChangeRef_current.call(onLocalQueryChangeRef, q);
31311
- } else {
31312
- var _onSubmitFullSearchRef_current;
31313
- (_onSubmitFullSearchRef_current = onSubmitFullSearchRef.current) === null || _onSubmitFullSearchRef_current === void 0 ? void 0 : _onSubmitFullSearchRef_current.call(onSubmitFullSearchRef, q);
31314
- }
31315
- }, [
31316
- mode
31317
- ]);
31298
+ onLiveChange
31299
+ ]);
31300
+ // Fire when the user has explicitly committed (Enter, footer click,
31301
+ // recent-row select, local-row select). Always invokes onCommit, in both
31302
+ // modes. Also seeds `lastLiveChangeRef` so the imminent debounced
31303
+ // `notifyLiveChange` doesn't re-fire for the same query.
31304
+ var fireCommit = useCallback(function(q) {
31305
+ var _onCommitRef_current;
31306
+ lastLiveChangeRef.current = q;
31307
+ (_onCommitRef_current = onCommitRef.current) === null || _onCommitRef_current === void 0 ? void 0 : _onCommitRef_current.call(onCommitRef, q);
31308
+ }, []);
31309
+ // Fire when the debounced query changes — every keystroke (200ms after
31310
+ // the last). Deduped so repeated identical values don't fire twice.
31311
+ // Invokes onLiveChange in both modes.
31312
+ var notifyLiveChange = useCallback(function(q) {
31313
+ var _onLiveChangeRef_current;
31314
+ if (lastLiveChangeRef.current === q) return;
31315
+ lastLiveChangeRef.current = q;
31316
+ (_onLiveChangeRef_current = onLiveChangeRef.current) === null || _onLiveChangeRef_current === void 0 ? void 0 : _onLiveChangeRef_current.call(onLiveChangeRef, q);
31317
+ }, []);
31318
31318
  // Local autocomplete: filter candidates client-side.
31319
31319
  // The `setLocalMatches` calls are guarded against no-op writes — calling
31320
31320
  // setState with a fresh `[]` literal every render is enough to cause a
@@ -31337,12 +31337,20 @@ var SearchOmnibox = function(param) {
31337
31337
  }) ? prev : next;
31338
31338
  });
31339
31339
  }
31340
- notifyParent(debouncedQuery);
31341
31340
  }, [
31342
31341
  debouncedQuery,
31343
31342
  mode,
31344
- localCandidates,
31345
- notifyParent
31343
+ localCandidates
31344
+ ]);
31345
+ // Live-change notification: fires on debounced typing in both modes.
31346
+ // Pages that want to live-filter their table (or fetch as the user
31347
+ // types) pass `onLiveChange`; pages that only care about explicit
31348
+ // commits leave it out. Independent of `mode`.
31349
+ useEffect(function() {
31350
+ notifyLiveChange(debouncedQuery);
31351
+ }, [
31352
+ debouncedQuery,
31353
+ notifyLiveChange
31346
31354
  ]);
31347
31355
  // Note: click-outside dismissal is handled by Popper's built-in useClickOutside
31348
31356
  // (it watches the anchorRef + its own container ref) via the onClose callback.
@@ -31541,7 +31549,7 @@ var SearchOmnibox = function(param) {
31541
31549
  // empty input is a legitimate "clear filter, show everything" action.
31542
31550
  // recordSearch itself guards against recording empty strings, so we
31543
31551
  // don't pollute history.
31544
- notifyParent(q);
31552
+ fireCommit(q);
31545
31553
  void recordSearch(q);
31546
31554
  setFocused(false);
31547
31555
  return [
@@ -31553,14 +31561,14 @@ var SearchOmnibox = function(param) {
31553
31561
  return _ref.apply(this, arguments);
31554
31562
  };
31555
31563
  }(), [
31556
- notifyParent,
31564
+ fireCommit,
31557
31565
  recordSearch
31558
31566
  ]);
31559
31567
  var selectRecent = useCallback(function() {
31560
31568
  var _ref = _async_to_generator(function(q) {
31561
31569
  return _ts_generator(this, function(_state) {
31562
31570
  setQuery(q);
31563
- notifyParent(q);
31571
+ fireCommit(q);
31564
31572
  void recordSearch(q);
31565
31573
  setFocused(false);
31566
31574
  return [
@@ -31572,7 +31580,7 @@ var SearchOmnibox = function(param) {
31572
31580
  return _ref.apply(this, arguments);
31573
31581
  };
31574
31582
  }(), [
31575
- notifyParent,
31583
+ fireCommit,
31576
31584
  recordSearch
31577
31585
  ]);
31578
31586
  var selectResult = useCallback(function(result) {
@@ -31586,11 +31594,11 @@ var SearchOmnibox = function(param) {
31586
31594
  ]);
31587
31595
  var selectLocal = useCallback(function(s) {
31588
31596
  setQuery(s);
31589
- notifyParent(s);
31597
+ fireCommit(s);
31590
31598
  void recordSearch(s);
31591
31599
  setFocused(false);
31592
31600
  }, [
31593
- notifyParent,
31601
+ fireCommit,
31594
31602
  recordSearch
31595
31603
  ]);
31596
31604
  var handleKeyDown = function(e) {
@@ -31725,10 +31733,10 @@ var SearchOmnibox = function(param) {
31725
31733
  onClick: function() {
31726
31734
  var _inputRef_current;
31727
31735
  setQuery('');
31728
- // Clearing the input is a "remove the filter" action: notify
31729
- // the parent so the page-level data resets to its unfiltered
31736
+ // Clearing the input is a "remove the filter" action — fire
31737
+ // commit so the page-level data resets to its unfiltered
31730
31738
  // state, the same way pressing Enter on an empty input would.
31731
- notifyParent('');
31739
+ fireCommit('');
31732
31740
  // After a prior commit the dropdown is closed (`focused=false`)
31733
31741
  // even though the input has DOM focus. Re-engage explicitly so
31734
31742
  // the recent-searches view reappears for the now-empty input.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@paubox/ui",
3
3
  "author": "Paubox, Inc.",
4
4
  "description": "Paubox Component Library",
5
- "version": "1.19.1",
5
+ "version": "2.0.0",
6
6
  "type": "module",
7
7
  "private": false,
8
8
  "publishConfig": {
@@ -51,17 +51,25 @@ export interface SearchOmniboxProps {
51
51
  * from pb_search.
52
52
  */
53
53
  withHistory?: boolean;
54
- /** Remote mode: called when user clicks a result row in the dropdown. */
54
+ /** Called when the user clicks a result row in the live-results dropdown
55
+ * (remote mode only; the dropdown is a pb_search-fed top-5 list). */
55
56
  onResultClick?: (result: SearchOmniboxResult) => void;
56
- /** Called when user presses Enter (or clicks the "All results" footer) to commit a full search. */
57
- onSubmitFullSearch?: (query: string) => void;
57
+ /** Called when the user **commits** a search explicit action.
58
+ * Triggers: Enter on the input (no row highlighted), click on the
59
+ * "All search results for X" footer row, Enter or click on a
60
+ * recent-search row, Enter or click on a local-match row.
61
+ * Fires in both `local` and `remote` modes. */
62
+ onCommit?: (query: string) => void;
63
+ /** Called when the user's typed query changes, debounced (~200ms).
64
+ * Lets pages live-filter their table or fetch as the user types.
65
+ * Fires in both `local` and `remote` modes. Optional — pages that
66
+ * only care about explicit commits should just not pass this. */
67
+ onLiveChange?: (query: string) => void;
58
68
  /** Local mode only: candidate strings to filter against (e.g. ruleset names, usernames). */
59
69
  localCandidates?: string[];
60
- /** Local mode: fires when the (debounced) query changes; let the page filter its own table. */
61
- onLocalQueryChange?: (query: string) => void;
62
70
  /** Test id prefix; defaults to `search-omnibox`. */
63
71
  testId?: string;
64
72
  /** Optional initial query (e.g. when restoring from URL state). */
65
73
  initialQuery?: string;
66
74
  }
67
- export declare const SearchOmnibox: ({ bar, placeholder, pbSearchBaseUrl, getAuthToken, mode, withHistory, onResultClick, onSubmitFullSearch, localCandidates, onLocalQueryChange, testId, initialQuery, }: SearchOmniboxProps) => import("@emotion/react/jsx-runtime").JSX.Element;
75
+ export declare const SearchOmnibox: ({ bar, placeholder, pbSearchBaseUrl, getAuthToken, mode, withHistory, onResultClick, onCommit, onLiveChange, localCandidates, testId, initialQuery, }: SearchOmniboxProps) => import("@emotion/react/jsx-runtime").JSX.Element;