@caratlogic/design-system 0.1.22 → 0.1.24

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.
@@ -1,3 +1,4 @@
1
+ import type { ReactElement } from 'react';
1
2
  import type { ApiComboBoxProps } from './ApiComboBox.types';
2
- export declare function ApiComboBox({ contactType, selectedItem, onSelect, fetchBusinessContacts, searchPlaceholder, className, disabled, align, displayAttribute, separator, customerCode, hideTriggerSearchIcon, }: ApiComboBoxProps): import("react/jsx-runtime").JSX.Element;
3
+ export declare function ApiComboBox({ contactType, selectedItem, onSelect, fetchBusinessContacts, searchPlaceholder, className, disabled, align, displayAttribute, separator, customerCode, hideTriggerSearchIcon, }: ApiComboBoxProps): ReactElement;
3
4
  //# sourceMappingURL=ApiComboBox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ApiComboBox.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/ApiComboBox/ApiComboBox.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,qBAAqB,CAAC;AAE1E,wBAAgB,WAAW,CAAC,EAC1B,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,qBAAqB,EACrB,iBAA+B,EAC/B,SAAS,EACT,QAAgB,EAChB,KAAK,EACL,gBAAgC,EAChC,SAAiB,EACjB,YAAY,EACZ,qBAA6B,GAC9B,EAAE,gBAAgB,2CAoDlB"}
1
+ {"version":3,"file":"ApiComboBox.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/ApiComboBox/ApiComboBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,qBAAqB,CAAC;AAE1E,wBAAgB,WAAW,CAAC,EAC1B,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,qBAAqB,EACrB,iBAA+B,EAC/B,SAAS,EACT,QAAgB,EAChB,KAAK,EACL,gBAAgC,EAChC,SAAiB,EACjB,YAAY,EACZ,qBAA6B,GAC9B,EAAE,gBAAgB,GAAG,YAAY,CAiDjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SearchableSelect.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/SearchableSelect/SearchableSelect.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEtE,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,eAAe,GAChB,MAAM,0BAA0B,CAAC;AAElC;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAM7C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,EAClC,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,qBAA6B,EAC7B,SAAS,EACT,OAAO,EAAE,aAAa,EACtB,QAAQ,EACR,aAAoB,EACpB,WAAW,EACX,iBAA6B,EAC7B,YAAkC,EAClC,QAA4B,EAC5B,UAA6B,EAC7B,QAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,KAAK,EACL,KAAY,EACZ,SAAS,EACT,UAAU,EACV,UAAU,GACX,EAAE,qBAAqB,CAAC,CAAC,CAAC,2CA2M1B"}
1
+ {"version":3,"file":"SearchableSelect.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/SearchableSelect/SearchableSelect.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEtE,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,eAAe,GAChB,MAAM,0BAA0B,CAAC;AAElC;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAM7C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,EAClC,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,qBAA6B,EAC7B,SAAS,EACT,OAAO,EAAE,aAAa,EACtB,QAAQ,EACR,aAAoB,EACpB,WAAW,EACX,iBAA6B,EAC7B,YAAkC,EAClC,QAA4B,EAC5B,UAA6B,EAC7B,QAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,KAAK,EACL,KAAY,EACZ,SAAS,EACT,UAAU,EACV,UAAU,GACX,EAAE,qBAAqB,CAAC,CAAC,CAAC,2CAoN1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"SearchableSelect.hooks.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/SearchableSelect/SearchableSelect.hooks.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EACvB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAIlC,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,EACrC,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,QAAQ,EACR,aAAa,EACb,WAAW,EACX,QAAQ,EACR,UAAU,GACX,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,yBAAyB,CAAC,CAAC,CAAC,CAuM3D"}
1
+ {"version":3,"file":"SearchableSelect.hooks.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/SearchableSelect/SearchableSelect.hooks.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EACvB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAIlC,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,EACrC,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,aAAa,EACb,QAAQ,EACR,aAAa,EACb,WAAW,EACX,QAAQ,EACR,UAAU,GACX,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,yBAAyB,CAAC,CAAC,CAAC,CAkN3D"}
package/dist/index.cjs.js CHANGED
@@ -14920,9 +14920,15 @@ function useSearchableSelect({ selectedItem, onChange, getOptionKey, getOptionLa
14920
14920
  // ===== ASYNC MODE =====
14921
14921
  const fetchPageRef = React.useRef(fetchPage);
14922
14922
  fetchPageRef.current = fetchPage;
14923
+ // Bumped by every fresh (non-append) fetch. A response from an older search,
14924
+ // or a "load more" started before the search changed, is discarded so it
14925
+ // can't overwrite or pad the current results.
14926
+ const requestSeq = React.useRef(0);
14923
14927
  const runFetch = React.useCallback(async (p, searchTerm, append) => {
14924
14928
  if (!fetchPageRef.current)
14925
14929
  return;
14930
+ const seq = append ? requestSeq.current : ++requestSeq.current;
14931
+ const isStale = () => seq !== requestSeq.current;
14926
14932
  if (append)
14927
14933
  setLoadingMore(true);
14928
14934
  else
@@ -14933,6 +14939,8 @@ function useSearchableSelect({ selectedItem, onChange, getOptionKey, getOptionLa
14933
14939
  limit: pageSize,
14934
14940
  search: searchTerm,
14935
14941
  });
14942
+ if (isStale())
14943
+ return;
14936
14944
  setHasMore(res.hasMore);
14937
14945
  setPage(p);
14938
14946
  setItems((prev) => {
@@ -14963,12 +14971,16 @@ function useSearchableSelect({ selectedItem, onChange, getOptionKey, getOptionLa
14963
14971
  });
14964
14972
  }
14965
14973
  catch {
14974
+ if (isStale())
14975
+ return;
14966
14976
  setItems(selectedItem ? [selectedItem] : []);
14967
14977
  setHasMore(false);
14968
14978
  }
14969
14979
  finally {
14970
- setLoading(false);
14971
- setLoadingMore(false);
14980
+ if (!isStale()) {
14981
+ setLoading(false);
14982
+ setLoadingMore(false);
14983
+ }
14972
14984
  }
14973
14985
  }, [pageSize, selectedItem, getOptionKey]);
14974
14986
  // Debounced search effect (async mode).
@@ -15128,10 +15140,14 @@ function SearchableSelect({ selectedItem, onChange, getOptionKey, getOptionLabel
15128
15140
  ? String(getOptionLabel(selectedItem))
15129
15141
  : undefined, children: getOptionLabel(selectedItem) }));
15130
15142
  }, [renderTrigger, selectedItem, searchPlaceholder, getOptionLabel]);
15143
+ const [activeValue, setActiveValue] = React.useState('');
15131
15144
  return (jsxRuntime.jsxs(Popover, { open: open, onOpenChange: handleOpenChange, modal: modal, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button$1, { type: "button", variant: "outline", role: "combobox", "aria-expanded": open, "aria-label": ariaLabel, disabled: disabled, className: cn('w-full justify-start min-w-40 px-3 py-1.5',
15132
15145
  // This trigger is a form control, not an action, so it takes the
15133
15146
  // input disabled treatment instead of the Button's opacity fade.
15134
- 'disabled:bg-muted/50 disabled:text-label disabled:opacity-100', className), children: [jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2 text-left", children: [!selectedItem && !hideTriggerSearchIcon && (jsxRuntime.jsx(Search, { "aria-hidden": "true", className: "h-4 w-4 shrink-0 text-muted-foreground" })), triggerNode] }), jsxRuntime.jsx(ChevronDown, { "aria-hidden": "true", className: "h-4 w-4 shrink-0 text-muted-foreground opacity-60" })] }) }), jsxRuntime.jsx(PopoverContent, { style: { width: 'var(--radix-popover-trigger-width)' }, className: cn('p-0', popoverClassName), align: align, children: jsxRuntime.jsxs(Command, { shouldFilter: false, children: [jsxRuntime.jsx(CommandInput, { placeholder: searchPlaceholder, value: search, onValueChange: setSearch }), headerSlot, jsxRuntime.jsx(CommandList, { ref: listRef, onScroll: handleScroll, className: LIST_MAX_HEIGHT_CLASS, children: loading ? (jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 p-3 text-sm text-muted-foreground", children: [jsxRuntime.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }), "Loading\u2026"] })) : visibleItems.length === 0 ? (jsxRuntime.jsx(CommandEmpty, { children: emptyMessage })) : (jsxRuntime.jsxs(CommandGroup, { className: "p-1", children: [visibleItems.map((item) => {
15147
+ 'disabled:bg-muted/50 disabled:text-label disabled:opacity-100', className), children: [jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2 text-left", children: [!selectedItem && !hideTriggerSearchIcon && (jsxRuntime.jsx(Search, { "aria-hidden": "true", className: "h-4 w-4 shrink-0 text-muted-foreground" })), triggerNode] }), jsxRuntime.jsx(ChevronDown, { "aria-hidden": "true", className: "h-4 w-4 shrink-0 text-muted-foreground opacity-60" })] }) }), jsxRuntime.jsx(PopoverContent, { style: { width: 'var(--radix-popover-trigger-width)' }, className: cn('p-0', popoverClassName), align: align, children: jsxRuntime.jsxs(Command, { shouldFilter: false, value: activeValue, onValueChange: setActiveValue, children: [jsxRuntime.jsx(CommandInput, { placeholder: searchPlaceholder, value: search, onValueChange: setSearch }), headerSlot, jsxRuntime.jsx(CommandList, { ref: listRef, onScroll: handleScroll,
15148
+ // cmdk keeps the last hovered row active for keyboard navigation;
15149
+ // clear it so the highlight doesn't linger once the pointer leaves.
15150
+ onMouseLeave: () => setActiveValue(''), className: LIST_MAX_HEIGHT_CLASS, children: loading ? (jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 p-3 text-sm text-muted-foreground", children: [jsxRuntime.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }), "Loading\u2026"] })) : visibleItems.length === 0 ? (jsxRuntime.jsx(CommandEmpty, { children: emptyMessage })) : (jsxRuntime.jsxs(CommandGroup, { className: "p-1", children: [visibleItems.map((item) => {
15135
15151
  const key = getOptionKey(item);
15136
15152
  const isSelected = selectedKey === key;
15137
15153
  if (renderOption) {
@@ -15232,10 +15248,12 @@ function ApiComboBox({ contactType, selectedItem, onSelect, fetchBusinessContact
15232
15248
  const selected = selectedItem?.value ? selectedItem : null;
15233
15249
  return (jsxRuntime.jsx(SearchableSelect, { selectedItem: selected, onChange: onSelect, getOptionKey: (i) => i.value, getOptionLabel: (i) => {
15234
15250
  const c = i.contactData;
15251
+ // A pre-selected item carries only { value, label }; its label is already formatted.
15252
+ if (!c)
15253
+ return i.label;
15235
15254
  const cid = i.contactId || i.code || '';
15236
- const contactName = c?.contactName || i.label || '';
15237
- const company = c?.companyName || '';
15238
- return (`${company}${company ? ' ' : ''}${cid ? `(${cid})` : ''}${contactName ? ` · ${contactName}` : ''}`.trim() || i.label);
15255
+ const companyPart = [c.companyName, cid && `(${cid})`].filter(Boolean).join(' ');
15256
+ return [companyPart, c.contactName].filter(Boolean).join(' · ') || i.label;
15239
15257
  }, getOptionSubLabel: (i) => {
15240
15258
  const c = i.contactData;
15241
15259
  const email = c?.email?.primary || '';