@flanksource/clicky-ui 0.2.3 → 0.2.5

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.
Files changed (178) hide show
  1. package/dist/components/Combobox.cjs +291 -0
  2. package/dist/components/Combobox.cjs.map +1 -0
  3. package/dist/components/Combobox.d.ts +59 -0
  4. package/dist/components/Combobox.d.ts.map +1 -0
  5. package/dist/components/Combobox.js +291 -0
  6. package/dist/components/Combobox.js.map +1 -0
  7. package/dist/components/FilterBar.cjs +153 -124
  8. package/dist/components/FilterBar.cjs.map +1 -1
  9. package/dist/components/FilterBar.d.ts +25 -1
  10. package/dist/components/FilterBar.d.ts.map +1 -1
  11. package/dist/components/FilterBar.js +153 -124
  12. package/dist/components/FilterBar.js.map +1 -1
  13. package/dist/components/FormatOptionsDropdown.cjs +62 -0
  14. package/dist/components/FormatOptionsDropdown.cjs.map +1 -0
  15. package/dist/components/FormatOptionsDropdown.d.ts +37 -0
  16. package/dist/components/FormatOptionsDropdown.d.ts.map +1 -0
  17. package/dist/components/FormatOptionsDropdown.js +62 -0
  18. package/dist/components/FormatOptionsDropdown.js.map +1 -0
  19. package/dist/components/SplitButton.cjs +87 -0
  20. package/dist/components/SplitButton.cjs.map +1 -0
  21. package/dist/components/SplitButton.d.ts +32 -0
  22. package/dist/components/SplitButton.d.ts.map +1 -0
  23. package/dist/components/SplitButton.js +87 -0
  24. package/dist/components/SplitButton.js.map +1 -0
  25. package/dist/components/icon-menu-picker.cjs +14 -3
  26. package/dist/components/icon-menu-picker.cjs.map +1 -1
  27. package/dist/components/icon-menu-picker.d.ts.map +1 -1
  28. package/dist/components/icon-menu-picker.js +15 -4
  29. package/dist/components/icon-menu-picker.js.map +1 -1
  30. package/dist/components.cjs +7 -0
  31. package/dist/components.cjs.map +1 -1
  32. package/dist/components.d.ts +3 -0
  33. package/dist/components.d.ts.map +1 -1
  34. package/dist/components.js +7 -0
  35. package/dist/components.js.map +1 -1
  36. package/dist/data/Badge.d.ts +1 -1
  37. package/dist/data/ProgressBar.cjs +4 -2
  38. package/dist/data/ProgressBar.cjs.map +1 -1
  39. package/dist/data/ProgressBar.d.ts +1 -1
  40. package/dist/data/ProgressBar.d.ts.map +1 -1
  41. package/dist/data/ProgressBar.js +4 -2
  42. package/dist/data/ProgressBar.js.map +1 -1
  43. package/dist/data/TaskManager.cjs +162 -0
  44. package/dist/data/TaskManager.cjs.map +1 -0
  45. package/dist/data/TaskManager.d.ts +21 -0
  46. package/dist/data/TaskManager.d.ts.map +1 -0
  47. package/dist/data/TaskManager.js +162 -0
  48. package/dist/data/TaskManager.js.map +1 -0
  49. package/dist/data/TaskProgress.cjs +125 -0
  50. package/dist/data/TaskProgress.cjs.map +1 -0
  51. package/dist/data/TaskProgress.d.ts +20 -0
  52. package/dist/data/TaskProgress.d.ts.map +1 -0
  53. package/dist/data/TaskProgress.js +125 -0
  54. package/dist/data/TaskProgress.js.map +1 -0
  55. package/dist/data/TaskSnapshot.cjs +23 -0
  56. package/dist/data/TaskSnapshot.cjs.map +1 -0
  57. package/dist/data/TaskSnapshot.d.ts +49 -0
  58. package/dist/data/TaskSnapshot.d.ts.map +1 -0
  59. package/dist/data/TaskSnapshot.js +23 -0
  60. package/dist/data/TaskSnapshot.js.map +1 -0
  61. package/dist/data/TimeseriesPanel.axes.cjs +39 -0
  62. package/dist/data/TimeseriesPanel.axes.cjs.map +1 -0
  63. package/dist/data/TimeseriesPanel.axes.d.ts +28 -0
  64. package/dist/data/TimeseriesPanel.axes.d.ts.map +1 -0
  65. package/dist/data/TimeseriesPanel.axes.js +39 -0
  66. package/dist/data/TimeseriesPanel.axes.js.map +1 -0
  67. package/dist/data/TimeseriesPanel.cjs +324 -0
  68. package/dist/data/TimeseriesPanel.cjs.map +1 -0
  69. package/dist/data/TimeseriesPanel.d.ts +141 -0
  70. package/dist/data/TimeseriesPanel.d.ts.map +1 -0
  71. package/dist/data/TimeseriesPanel.js +324 -0
  72. package/dist/data/TimeseriesPanel.js.map +1 -0
  73. package/dist/data/Tree.cjs.map +1 -1
  74. package/dist/data/Tree.d.ts.map +1 -1
  75. package/dist/data/Tree.js.map +1 -1
  76. package/dist/data/TreeNode.cjs +44 -7
  77. package/dist/data/TreeNode.cjs.map +1 -1
  78. package/dist/data/TreeNode.d.ts +19 -1
  79. package/dist/data/TreeNode.d.ts.map +1 -1
  80. package/dist/data/TreeNode.js +44 -7
  81. package/dist/data/TreeNode.js.map +1 -1
  82. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +66 -44
  83. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
  84. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts +21 -1
  85. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
  86. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +65 -43
  87. package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
  88. package/dist/data/diagnostics/DiagnosticsTree.cjs +2 -1
  89. package/dist/data/diagnostics/DiagnosticsTree.cjs.map +1 -1
  90. package/dist/data/diagnostics/DiagnosticsTree.js +2 -1
  91. package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -1
  92. package/dist/data/diagnostics/FrameSourceWindow.cjs +37 -0
  93. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -0
  94. package/dist/data/diagnostics/FrameSourceWindow.d.ts +15 -0
  95. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -0
  96. package/dist/data/diagnostics/FrameSourceWindow.js +37 -0
  97. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -0
  98. package/dist/data/diagnostics/JvmStackTrace.cjs +25 -12
  99. package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
  100. package/dist/data/diagnostics/JvmStackTrace.d.ts +8 -1
  101. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
  102. package/dist/data/diagnostics/JvmStackTrace.js +26 -13
  103. package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
  104. package/dist/data/diagnostics/ThreadCard.cjs +9 -2
  105. package/dist/data/diagnostics/ThreadCard.cjs.map +1 -1
  106. package/dist/data/diagnostics/ThreadCard.d.ts +3 -1
  107. package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
  108. package/dist/data/diagnostics/ThreadCard.js +9 -2
  109. package/dist/data/diagnostics/ThreadCard.js.map +1 -1
  110. package/dist/data/diagnostics/jvm-stacktrace.cjs +10 -1
  111. package/dist/data/diagnostics/jvm-stacktrace.cjs.map +1 -1
  112. package/dist/data/diagnostics/jvm-stacktrace.d.ts.map +1 -1
  113. package/dist/data/diagnostics/jvm-stacktrace.js +10 -1
  114. package/dist/data/diagnostics/jvm-stacktrace.js.map +1 -1
  115. package/dist/data/diagnostics/utils.cjs +0 -12
  116. package/dist/data/diagnostics/utils.cjs.map +1 -1
  117. package/dist/data/diagnostics/utils.d.ts +1 -1
  118. package/dist/data/diagnostics/utils.d.ts.map +1 -1
  119. package/dist/data/diagnostics/utils.js +0 -12
  120. package/dist/data/diagnostics/utils.js.map +1 -1
  121. package/dist/data/task-status.cjs +108 -0
  122. package/dist/data/task-status.cjs.map +1 -0
  123. package/dist/data/task-status.d.ts +21 -0
  124. package/dist/data/task-status.d.ts.map +1 -0
  125. package/dist/data/task-status.js +108 -0
  126. package/dist/data/task-status.js.map +1 -0
  127. package/dist/data.cjs +21 -0
  128. package/dist/data.cjs.map +1 -1
  129. package/dist/data.d.ts +7 -1
  130. package/dist/data.d.ts.map +1 -1
  131. package/dist/data.js +21 -0
  132. package/dist/data.js.map +1 -1
  133. package/dist/hooks/use-task-run.cjs +137 -0
  134. package/dist/hooks/use-task-run.cjs.map +1 -0
  135. package/dist/hooks/use-task-run.d.ts +35 -0
  136. package/dist/hooks/use-task-run.d.ts.map +1 -0
  137. package/dist/hooks/use-task-run.js +137 -0
  138. package/dist/hooks/use-task-run.js.map +1 -0
  139. package/dist/hooks.cjs +3 -0
  140. package/dist/hooks.cjs.map +1 -1
  141. package/dist/hooks.d.ts +1 -0
  142. package/dist/hooks.d.ts.map +1 -1
  143. package/dist/hooks.js +3 -0
  144. package/dist/hooks.js.map +1 -1
  145. package/dist/index.cjs +37 -0
  146. package/dist/index.cjs.map +1 -1
  147. package/dist/index.js +37 -0
  148. package/dist/index.js.map +1 -1
  149. package/dist/lib/color.cjs +33 -0
  150. package/dist/lib/color.cjs.map +1 -0
  151. package/dist/lib/color.d.ts +10 -0
  152. package/dist/lib/color.d.ts.map +1 -0
  153. package/dist/lib/color.js +33 -0
  154. package/dist/lib/color.js.map +1 -0
  155. package/dist/lib/format.cjs +77 -0
  156. package/dist/lib/format.cjs.map +1 -0
  157. package/dist/lib/format.d.ts +30 -0
  158. package/dist/lib/format.d.ts.map +1 -0
  159. package/dist/lib/format.js +77 -0
  160. package/dist/lib/format.js.map +1 -0
  161. package/dist/overlay/DropdownMenu.cjs +18 -2
  162. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  163. package/dist/overlay/DropdownMenu.d.ts +3 -1
  164. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  165. package/dist/overlay/DropdownMenu.js +18 -2
  166. package/dist/overlay/DropdownMenu.js.map +1 -1
  167. package/dist/rpc/types.cjs.map +1 -1
  168. package/dist/rpc/types.d.ts +4 -0
  169. package/dist/rpc/types.d.ts.map +1 -1
  170. package/dist/rpc/types.js.map +1 -1
  171. package/dist/styles.css +1 -1
  172. package/dist/utils.cjs +6 -0
  173. package/dist/utils.cjs.map +1 -1
  174. package/dist/utils.d.ts +1 -0
  175. package/dist/utils.d.ts.map +1 -1
  176. package/dist/utils.js +6 -0
  177. package/dist/utils.js.map +1 -1
  178. package/package.json +4 -1
@@ -6,6 +6,7 @@ const FilterPill = require("../data/FilterPill.cjs");
6
6
  const Icon = require("../data/Icon.cjs");
7
7
  const utils = require("../lib/utils.cjs");
8
8
  const button = require("./button.cjs");
9
+ const Combobox = require("./Combobox.cjs");
9
10
  const DateTimePicker = require("./DateTimePicker.cjs");
10
11
  const MultiSelect = require("./MultiSelect.cjs");
11
12
  const RangeSlider = require("./RangeSlider.cjs");
@@ -449,6 +450,13 @@ function FilterBarKeyValueControl({ filter }) {
449
450
  function filterInputId(filter) {
450
451
  return `filterbar-overflow-${filter.key}`;
451
452
  }
453
+ function lookupOptionsToCombobox(options) {
454
+ return options.map((option) => ({
455
+ value: option.value,
456
+ label: option.label ?? option.value,
457
+ ...option.disabled !== void 0 ? { disabled: option.disabled } : {}
458
+ }));
459
+ }
452
460
  function valueInputClassName(disabled) {
453
461
  return utils.cn(
454
462
  "h-8 w-full rounded-md border border-input bg-background px-2 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring",
@@ -473,7 +481,6 @@ function TextFilterValueControl({ filter }) {
473
481
  }
474
482
  function LookupFilterValueControl({ filter }) {
475
483
  const [draft, setDraft] = useDebouncedTextDraft(filter.value, filter.onChange);
476
- const listId = `${filter.key}-overflow-lookup-options`;
477
484
  if (filter.inputType === "date") {
478
485
  return /* @__PURE__ */ jsxRuntime.jsx(
479
486
  DateTimePicker.DateTimePicker,
@@ -483,56 +490,55 @@ function LookupFilterValueControl({ filter }) {
483
490
  className: "w-full",
484
491
  inputClassName: valueInputClassName(filter.disabled),
485
492
  buttonClassName: "right-1",
486
- placeholder: filter.placeholder ?? "Filter...",
493
+ placeholder: filter.placeholder,
487
494
  value: draft,
488
- list: listId,
489
495
  disabled: filter.disabled,
490
496
  onChange: setDraft
491
497
  }
492
498
  );
493
499
  }
494
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
495
- /* @__PURE__ */ jsxRuntime.jsx(
500
+ if (filter.inputType === "number") {
501
+ return /* @__PURE__ */ jsxRuntime.jsx(
496
502
  "input",
497
503
  {
498
504
  id: filterInputId(filter),
499
- type: filter.inputType === "number" ? "number" : "text",
505
+ type: "number",
500
506
  "aria-label": filter.label,
501
507
  className: valueInputClassName(filter.disabled),
502
- placeholder: filter.placeholder ?? "Filter...",
508
+ placeholder: filter.placeholder,
503
509
  value: draft,
504
- list: listId,
505
510
  disabled: filter.disabled,
506
511
  onChange: (event) => setDraft(event.target.value)
507
512
  }
508
- ),
509
- /* @__PURE__ */ jsxRuntime.jsx("datalist", { id: listId, children: filter.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
510
- "option",
511
- {
512
- value: option.value,
513
- label: option.label ?? option.value,
514
- disabled: option.disabled
515
- },
516
- option.value
517
- )) })
518
- ] });
513
+ );
514
+ }
515
+ return /* @__PURE__ */ jsxRuntime.jsx(
516
+ Combobox.Combobox,
517
+ {
518
+ id: filterInputId(filter),
519
+ options: lookupOptionsToCombobox(filter.options),
520
+ value: filter.value,
521
+ onChange: filter.onChange,
522
+ allowCustomValue: false,
523
+ className: "w-full",
524
+ ...filter.placeholder !== void 0 ? { placeholder: filter.placeholder } : {},
525
+ ...filter.disabled !== void 0 ? { disabled: filter.disabled } : {}
526
+ }
527
+ );
519
528
  }
520
529
  function LookupMultiFilterValueControl({ filter }) {
521
530
  return /* @__PURE__ */ jsxRuntime.jsx(
522
- MultiSelect.MultiSelect,
531
+ Combobox.Combobox,
523
532
  {
524
- options: filter.options.map((option) => ({
525
- value: option.value,
526
- label: option.label ?? option.value,
527
- ...option.disabled !== void 0 ? { disabled: option.disabled } : {},
528
- ...option.title !== void 0 ? { title: option.title } : {}
529
- })),
533
+ multiple: true,
534
+ id: filterInputId(filter),
535
+ options: lookupOptionsToCombobox(filter.options),
530
536
  value: filter.value,
531
537
  onChange: filter.onChange,
532
- placeholder: filter.placeholder ?? `Any ${filter.label.toLowerCase()}`,
533
- ...filter.disabled !== void 0 ? { disabled: filter.disabled } : {},
534
- triggerClassName: "h-8 w-full rounded-md border border-input bg-background px-2 text-sm shadow-none",
535
- menuClassName: "left-auto right-0"
538
+ allowCustomValue: false,
539
+ className: "w-full",
540
+ ...filter.placeholder !== void 0 ? { placeholder: filter.placeholder } : {},
541
+ ...filter.disabled !== void 0 ? { disabled: filter.disabled } : {}
536
542
  }
537
543
  );
538
544
  }
@@ -731,57 +737,63 @@ function TextFilterField({ filter, grow }) {
731
737
  }
732
738
  );
733
739
  }
740
+ function lookupFieldWidthClass(grow) {
741
+ return grow ? "min-w-[12rem] max-w-[18rem] flex-1" : "min-w-[11rem] max-w-[15rem] shrink-0";
742
+ }
734
743
  function LookupFilterField({ filter, grow }) {
735
744
  const [draft, setDraft] = useDebouncedTextDraft(filter.value, filter.onChange);
736
- const listId = `${filter.key}-lookup-options`;
737
- return /* @__PURE__ */ jsxRuntime.jsxs(
738
- "label",
739
- {
740
- title: filter.description,
741
- className: utils.cn(
742
- "flex h-8 items-center gap-2 rounded-md border border-input bg-muted/30 pl-2 pr-2 text-xs",
743
- grow ? "min-w-[12rem] max-w-[18rem] flex-1" : "min-w-[11rem] max-w-[15rem] shrink-0",
744
- filter.disabled && "opacity-60",
745
- filter.className
746
- ),
747
- children: [
748
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap font-medium uppercase tracking-wide text-muted-foreground", children: filter.label }),
749
- filter.inputType === "date" ? /* @__PURE__ */ jsxRuntime.jsx(
750
- DateTimePicker.DateTimePicker,
751
- {
752
- "aria-label": filter.label,
753
- className: "w-full",
754
- inputClassName: "w-full min-w-0 border-0 bg-transparent px-0 pr-6 text-sm text-foreground shadow-none focus-visible:ring-0",
755
- buttonClassName: "right-0",
756
- placeholder: filter.placeholder ?? "Filter…",
757
- value: draft,
758
- list: listId,
759
- disabled: filter.disabled,
760
- onChange: setDraft
761
- }
762
- ) : /* @__PURE__ */ jsxRuntime.jsx(
763
- "input",
764
- {
765
- type: filter.inputType === "number" ? "number" : "text",
766
- "aria-label": filter.label,
767
- className: "w-full min-w-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed",
768
- placeholder: filter.placeholder ?? "Filter…",
769
- value: draft,
770
- list: listId,
771
- disabled: filter.disabled,
772
- onChange: (event) => setDraft(event.target.value)
773
- }
745
+ if (filter.inputType === "date" || filter.inputType === "number") {
746
+ return /* @__PURE__ */ jsxRuntime.jsxs(
747
+ "label",
748
+ {
749
+ title: filter.description,
750
+ className: utils.cn(
751
+ "flex h-8 items-center gap-2 rounded-md border border-input bg-muted/30 pl-2 pr-2 text-xs",
752
+ lookupFieldWidthClass(grow),
753
+ filter.disabled && "opacity-60",
754
+ filter.className
774
755
  ),
775
- /* @__PURE__ */ jsxRuntime.jsx("datalist", { id: listId, children: filter.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
776
- "option",
777
- {
778
- value: option.value,
779
- label: option.label ?? option.value,
780
- disabled: option.disabled
781
- },
782
- option.value
783
- )) })
784
- ]
756
+ children: [
757
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap font-medium uppercase tracking-wide text-muted-foreground", children: filter.label }),
758
+ filter.inputType === "date" ? /* @__PURE__ */ jsxRuntime.jsx(
759
+ DateTimePicker.DateTimePicker,
760
+ {
761
+ "aria-label": filter.label,
762
+ className: "w-full",
763
+ inputClassName: "w-full min-w-0 border-0 bg-transparent px-0 pr-6 text-sm text-foreground shadow-none focus-visible:ring-0",
764
+ buttonClassName: "right-0",
765
+ placeholder: filter.placeholder,
766
+ value: draft,
767
+ disabled: filter.disabled,
768
+ onChange: setDraft
769
+ }
770
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
771
+ "input",
772
+ {
773
+ type: "number",
774
+ "aria-label": filter.label,
775
+ className: "w-full min-w-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed",
776
+ placeholder: filter.placeholder,
777
+ value: draft,
778
+ disabled: filter.disabled,
779
+ onChange: (event) => setDraft(event.target.value)
780
+ }
781
+ )
782
+ ]
783
+ }
784
+ );
785
+ }
786
+ return /* @__PURE__ */ jsxRuntime.jsx(
787
+ Combobox.Combobox,
788
+ {
789
+ label: filter.label,
790
+ options: lookupOptionsToCombobox(filter.options),
791
+ value: filter.value,
792
+ onChange: filter.onChange,
793
+ allowCustomValue: false,
794
+ className: utils.cn(lookupFieldWidthClass(grow), filter.className),
795
+ ...filter.placeholder !== void 0 ? { placeholder: filter.placeholder } : {},
796
+ ...filter.disabled !== void 0 ? { disabled: filter.disabled } : {}
785
797
  }
786
798
  );
787
799
  }
@@ -789,46 +801,20 @@ function LookupMultiFilterField({
789
801
  filter,
790
802
  grow
791
803
  }) {
792
- const [draft, setDraft] = useDebouncedTextDraft(
793
- filter.value.join(", "),
794
- (next) => filter.onChange(parseLookupMultiValue(next))
795
- );
796
- const listId = `${filter.key}-lookup-options`;
797
- return /* @__PURE__ */ jsxRuntime.jsxs(
798
- "label",
804
+ return /* @__PURE__ */ jsxRuntime.jsx(
805
+ Combobox.Combobox,
799
806
  {
800
- title: filter.description,
801
- className: utils.cn(
802
- "flex h-8 items-center gap-2 rounded-md border border-input bg-muted/30 pl-2 pr-2 text-xs",
803
- grow ? "min-w-[12rem] max-w-[18rem] flex-1" : "min-w-[11rem] max-w-[15rem] shrink-0",
804
- filter.disabled && "opacity-60",
805
- filter.className
806
- ),
807
- children: [
808
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap font-medium uppercase tracking-wide text-muted-foreground", children: filter.label }),
809
- /* @__PURE__ */ jsxRuntime.jsx(
810
- "input",
811
- {
812
- type: "text",
813
- "aria-label": filter.label,
814
- className: "w-full min-w-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed",
815
- placeholder: filter.placeholder ?? "value-1, value-2",
816
- value: draft,
817
- list: listId,
818
- disabled: filter.disabled,
819
- onChange: (event) => setDraft(event.target.value)
820
- }
821
- ),
822
- /* @__PURE__ */ jsxRuntime.jsx("datalist", { id: listId, children: filter.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
823
- "option",
824
- {
825
- value: option.value,
826
- label: option.label ?? option.value,
827
- disabled: option.disabled
828
- },
829
- option.value
830
- )) })
831
- ]
807
+ multiple: true,
808
+ label: filter.label,
809
+ options: lookupOptionsToCombobox(filter.options),
810
+ value: filter.value,
811
+ onChange: filter.onChange,
812
+ allowCustomValue: false,
813
+ className: utils.cn(lookupFieldWidthClass(grow), filter.className),
814
+ ...filter.placeholder !== void 0 ? { placeholder: filter.placeholder } : {},
815
+ ...filter.onSearch !== void 0 ? { onSearch: filter.onSearch } : {},
816
+ ...filter.loading !== void 0 ? { loading: filter.loading } : {},
817
+ ...filter.disabled !== void 0 ? { disabled: filter.disabled } : {}
832
818
  }
833
819
  );
834
820
  }
@@ -1074,17 +1060,45 @@ function MultiFilterField({ filter, grow }) {
1074
1060
  const triggerRef = react.useRef(null);
1075
1061
  const [open, setOpen] = react.useState(false);
1076
1062
  const [optionQuery, setOptionQuery] = react.useState("");
1063
+ const [searchOptions, setSearchOptions] = react.useState([]);
1077
1064
  const [draft, setDraft] = useDebouncedMultiDraft(filter.value, filter.onChange);
1078
1065
  useDismissablePopup(open, rootRef, triggerRef, () => setOpen(false));
1066
+ const onSearch = filter.onSearch;
1067
+ react.useEffect(() => {
1068
+ if (!onSearch) return;
1069
+ const query = optionQuery.trim();
1070
+ if (!query) {
1071
+ setSearchOptions([]);
1072
+ return;
1073
+ }
1074
+ let cancelled = false;
1075
+ const handle = setTimeout(() => {
1076
+ Promise.resolve(onSearch(query)).then((opts) => {
1077
+ if (!cancelled && Array.isArray(opts)) setSearchOptions(opts);
1078
+ }).catch(() => {
1079
+ if (!cancelled) setSearchOptions([]);
1080
+ });
1081
+ }, 250);
1082
+ return () => {
1083
+ cancelled = true;
1084
+ clearTimeout(handle);
1085
+ };
1086
+ }, [onSearch, optionQuery]);
1079
1087
  const summary = summarizeMultiFilter(filter.label, draft);
1080
- const showOptionFilter = filter.options.length > 7;
1088
+ const showOptionFilter = filter.truncated || Boolean(onSearch) || filter.options.length > 7;
1081
1089
  const visibleOptions = react.useMemo(() => {
1082
- const query = optionQuery.trim().toLowerCase();
1090
+ const query = optionQuery.trim();
1083
1091
  if (!query) return filter.options;
1092
+ if (onSearch) {
1093
+ const selectedHead = filter.options.filter((o) => draft[o.value] !== void 0);
1094
+ return mergeMultiSelectOptions(selectedHead, searchOptions);
1095
+ }
1096
+ const lowered = query.toLowerCase();
1084
1097
  return filter.options.filter(
1085
- (option) => multiSelectOptionText(option).toLowerCase().includes(query)
1098
+ (option) => multiSelectOptionText(option).toLowerCase().includes(lowered)
1086
1099
  );
1087
- }, [filter.options, optionQuery]);
1100
+ }, [filter.options, searchOptions, optionQuery, onSearch, draft]);
1101
+ const moreCount = filter.truncated && filter.total ? Math.max(filter.total - filter.options.length, 0) : 0;
1088
1102
  return /* @__PURE__ */ jsxRuntime.jsxs(
1089
1103
  "div",
1090
1104
  {
@@ -1182,12 +1196,30 @@ function MultiFilterField({ filter, grow }) {
1182
1196
  );
1183
1197
  }),
1184
1198
  visibleOptions.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-3 text-sm text-muted-foreground", children: "No options found" })
1199
+ ] }),
1200
+ moreCount > 0 && !optionQuery.trim() && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 px-1.5 text-[11px] text-muted-foreground", children: [
1201
+ "… and ",
1202
+ moreCount.toLocaleString(),
1203
+ " more",
1204
+ onSearch ? " — type to search all" : ""
1185
1205
  ] })
1186
1206
  ] })
1187
1207
  ]
1188
1208
  }
1189
1209
  );
1190
1210
  }
1211
+ function mergeMultiSelectOptions(head, extra) {
1212
+ if (extra.length === 0) return head;
1213
+ const seen = new Set(head.map((o) => o.value));
1214
+ const merged = [...head];
1215
+ for (const option of extra) {
1216
+ if (!seen.has(option.value)) {
1217
+ seen.add(option.value);
1218
+ merged.push(option);
1219
+ }
1220
+ }
1221
+ return merged;
1222
+ }
1191
1223
  function MultiFilterPanel({
1192
1224
  filter,
1193
1225
  chrome = "full"
@@ -1781,9 +1813,6 @@ function summarizeMultiFilter(label, value) {
1781
1813
  ].filter(Boolean);
1782
1814
  return `${label} ${counts.join(" ")}`;
1783
1815
  }
1784
- function parseLookupMultiValue(value) {
1785
- return value.split(",").map((item) => item.trim()).filter(Boolean);
1786
- }
1787
1816
  function useDebouncedMultiDraft(value, onChange) {
1788
1817
  const { autoSubmit } = react.useContext(FilterBarContext);
1789
1818
  const [draft, setDraft] = react.useState(value);