hs-uix 1.6.4 → 1.7.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/dist/kanban.js CHANGED
@@ -35,12 +35,133 @@ __export(kanban_exports, {
35
35
  module.exports = __toCommonJS(kanban_exports);
36
36
 
37
37
  // packages/kanban/src/Kanban.jsx
38
- var import_react2 = __toESM(require("react"));
38
+ var import_react3 = __toESM(require("react"));
39
+
40
+ // src/utils/query.js
39
41
  var import_fuse = __toESM(require("fuse.js"));
42
+ var getEmptyFilterValue = (filter) => {
43
+ const type = filter.type || "select";
44
+ if (type === "multiselect") return [];
45
+ if (type === "dateRange") return { from: null, to: null };
46
+ return "";
47
+ };
48
+ var isFilterActive = (filter, value) => {
49
+ const type = filter.type || "select";
50
+ if (type === "multiselect") return Array.isArray(value) && value.length > 0;
51
+ if (type === "dateRange") return value && (value.from || value.to);
52
+ return !!value;
53
+ };
54
+ var formatDateChip = (dateObj) => {
55
+ if (!dateObj) return "";
56
+ const { year, month, date } = dateObj;
57
+ return new Intl.DateTimeFormat("en-US", {
58
+ month: "short",
59
+ day: "numeric",
60
+ year: "numeric"
61
+ }).format(new Date(year, month, date));
62
+ };
63
+ var dateToTimestamp = (dateObj) => {
64
+ if (!dateObj) return null;
65
+ return new Date(dateObj.year, dateObj.month, dateObj.date).getTime();
66
+ };
67
+ var toStableKey = (value) => {
68
+ try {
69
+ return JSON.stringify(value);
70
+ } catch (_error) {
71
+ return String(value);
72
+ }
73
+ };
74
+ var filterRows = (rows, filters, values) => {
75
+ let result = rows;
76
+ for (const filter of filters || []) {
77
+ const value = values[filter.name];
78
+ if (!isFilterActive(filter, value)) continue;
79
+ const type = filter.type || "select";
80
+ if (filter.filterFn) {
81
+ result = result.filter((row) => filter.filterFn(row, value));
82
+ } else if (type === "multiselect") {
83
+ result = result.filter((row) => value.includes(row[filter.name]));
84
+ } else if (type === "dateRange") {
85
+ const fromTs = dateToTimestamp(value.from);
86
+ const toTs = value.to ? dateToTimestamp(value.to) + 864e5 - 1 : null;
87
+ result = result.filter((row) => {
88
+ const rowTs = new Date(row[filter.name]).getTime();
89
+ if (Number.isNaN(rowTs)) return false;
90
+ if (fromTs && rowTs < fromTs) return false;
91
+ if (toTs && rowTs > toTs) return false;
92
+ return true;
93
+ });
94
+ } else {
95
+ result = result.filter((row) => row[filter.name] === value);
96
+ }
97
+ }
98
+ return result;
99
+ };
100
+ var searchRows = (rows, term, fields, opts = {}) => {
101
+ const { fuzzy = false, fuzzyOptions } = opts;
102
+ const t = String(term ?? "").toLowerCase();
103
+ if (!t || !fields || fields.length === 0) return rows;
104
+ if (fuzzy) {
105
+ const fuse = new import_fuse.default(rows, {
106
+ keys: fields,
107
+ threshold: 0.4,
108
+ distance: 100,
109
+ ignoreLocation: true,
110
+ ...fuzzyOptions
111
+ });
112
+ return fuse.search(t).map((r) => r.item);
113
+ }
114
+ return rows.filter(
115
+ (row) => fields.some((field) => {
116
+ const val = row[field];
117
+ return val && String(val).toLowerCase().includes(t);
118
+ })
119
+ );
120
+ };
40
121
 
41
- // src/common-components/StyledText.js
42
- var import_react = __toESM(require("react"));
122
+ // src/utils/interactionHooks.js
123
+ var import_react = require("react");
43
124
  var import_ui_extensions = require("@hubspot/ui-extensions");
125
+ var useDebouncedDispatch = (value, debounceMs, dispatch) => {
126
+ const debounced = (0, import_ui_extensions.useDebounce)(value, debounceMs > 0 ? debounceMs : 300);
127
+ const pendingRef = (0, import_react.useRef)(null);
128
+ (0, import_react.useEffect)(() => {
129
+ if (debounceMs <= 0) return;
130
+ if (pendingRef.current == null) return;
131
+ if (debounced !== pendingRef.current) return;
132
+ const next = pendingRef.current;
133
+ pendingRef.current = null;
134
+ dispatch(next);
135
+ }, [debounceMs, debounced, dispatch]);
136
+ return (0, import_react.useCallback)(
137
+ (next) => {
138
+ if (debounceMs > 0) {
139
+ pendingRef.current = next;
140
+ } else {
141
+ pendingRef.current = null;
142
+ dispatch(next);
143
+ }
144
+ },
145
+ [debounceMs, dispatch]
146
+ );
147
+ };
148
+ var useSelectionReset = ({ resetKey, enabled, isControlled, clearSelection }) => {
149
+ const ref = (0, import_react.useRef)("");
150
+ (0, import_react.useEffect)(() => {
151
+ if (!enabled || isControlled) {
152
+ ref.current = resetKey;
153
+ return;
154
+ }
155
+ if (ref.current && ref.current !== resetKey) {
156
+ clearSelection();
157
+ }
158
+ ref.current = resetKey;
159
+ }, [resetKey, enabled, isControlled, clearSelection]);
160
+ };
161
+
162
+ // src/common-components/StyledText.js
163
+ var import_react2 = __toESM(require("react"));
164
+ var import_ui_extensions2 = require("@hubspot/ui-extensions");
44
165
 
45
166
  // src/common-components/svgDefaults.js
46
167
  var HS_FONT_FAMILY = '"Lexend Deca", Helvetica, Arial, sans-serif';
@@ -231,7 +352,7 @@ var makeStyledTextDataUri = (text, opts = {}) => {
231
352
  };
232
353
 
233
354
  // packages/kanban/src/Kanban.jsx
234
- var import_ui_extensions2 = require("@hubspot/ui-extensions");
355
+ var import_ui_extensions3 = require("@hubspot/ui-extensions");
235
356
  var DEFAULT_DENSITY = "compact";
236
357
  var DEFAULT_MAX_CARDS = 10;
237
358
  var DEFAULT_MAX_EXPANDED = 50;
@@ -261,6 +382,7 @@ var DEFAULT_LABELS = {
261
382
  emptyTitle: "No cards",
262
383
  emptyMessage: "Nothing matches the current filters.",
263
384
  loading: "Loading board...",
385
+ loadingMessage: "This should only take a moment.",
264
386
  errorTitle: "Something went wrong.",
265
387
  errorMessage: "An error occurred while loading data.",
266
388
  cardCount: (n) => String(n),
@@ -288,38 +410,6 @@ var makeRotatedLabelDataUri = (label) => makeStyledTextDataUri(label, {
288
410
  format: { fontWeight: "demibold" },
289
411
  orientation: "vertical-down"
290
412
  });
291
- var getEmptyFilterValue = (filter) => {
292
- const type = filter.type || "select";
293
- if (type === "multiselect") return [];
294
- if (type === "dateRange") return { from: null, to: null };
295
- return "";
296
- };
297
- var isFilterActive = (filter, value) => {
298
- const type = filter.type || "select";
299
- if (type === "multiselect") return Array.isArray(value) && value.length > 0;
300
- if (type === "dateRange") return value && (value.from || value.to);
301
- return !!value;
302
- };
303
- var formatDateChip = (dateObj) => {
304
- if (!dateObj) return "";
305
- const { year, month, date } = dateObj;
306
- return new Intl.DateTimeFormat("en-US", {
307
- month: "short",
308
- day: "numeric",
309
- year: "numeric"
310
- }).format(new Date(year, month, date));
311
- };
312
- var dateToTimestamp = (dateObj) => {
313
- if (!dateObj) return null;
314
- return new Date(dateObj.year, dateObj.month, dateObj.date).getTime();
315
- };
316
- var toStableKey = (value) => {
317
- try {
318
- return JSON.stringify(value);
319
- } catch (_error) {
320
- return String(value);
321
- }
322
- };
323
413
  var canStageReceiveRow = (stage, row, canMove) => {
324
414
  if (!stage) return false;
325
415
  if (typeof canMove === "function" && !canMove(row, stage.value)) return false;
@@ -394,10 +484,10 @@ var KanbanCard = ({
394
484
  const titleHref = fields.title ? resolveHref(fields.title.href, row) : null;
395
485
  const rawTitleValue = fields.title ? fields.title.render ? fields.title.render(resolveFieldValue(fields.title, row), row) : resolveFieldValue(fields.title, row) : null;
396
486
  const titleValue = fields.title && typeof rawTitleValue === "string" ? applyTruncate(rawTitleValue, fields.title.truncate, DEFAULT_TITLE_TRUNCATE) : rawTitleValue;
397
- const titleNode = titleHref ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Link, { href: titleHref }, titleValue) : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { format: { fontWeight: "demibold" } }, titleValue);
487
+ const titleNode = titleHref ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Link, { href: titleHref }, titleValue) : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { format: { fontWeight: "demibold" } }, titleValue);
398
488
  const metaNodes = fields.meta.filter((f) => !f.visible || f.visible(row)).map((f) => {
399
489
  const val = resolveFieldValue(f, row);
400
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { key: f.field || f.label, variant: "microcopy" }, f.render ? f.render(val, row) : val);
490
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { key: f.field || f.label, variant: "microcopy" }, f.render ? f.render(val, row) : val);
401
491
  });
402
492
  const showSubtitle = density === "comfortable" && fields.subtitle;
403
493
  const subtitleNode = showSubtitle ? fields.subtitle.render ? fields.subtitle.render(resolveFieldValue(fields.subtitle, row), row) : resolveFieldValue(fields.subtitle, row) : null;
@@ -409,9 +499,9 @@ var KanbanCard = ({
409
499
  const val = resolveFieldValue(f, row);
410
500
  const rendered = f.render ? f.render(val, row) : val;
411
501
  const key = f.key || f.field || f.label || `footer-${idx}`;
412
- return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, { key }, rendered);
502
+ return /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, { key }, rendered);
413
503
  };
414
- const stageControlNode = stageControl === "none" ? null : /* @__PURE__ */ import_react2.default.createElement(
504
+ const stageControlNode = stageControl === "none" ? null : /* @__PURE__ */ import_react3.default.createElement(
415
505
  StageControl,
416
506
  {
417
507
  row,
@@ -425,33 +515,33 @@ var KanbanCard = ({
425
515
  labels
426
516
  }
427
517
  );
428
- const titleRow = /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: "between", align: "center", gap: "sm" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { flex: 1 }, titleNode), selectable ? /* @__PURE__ */ import_react2.default.createElement(
429
- import_ui_extensions2.Checkbox,
518
+ const titleRow = /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", justify: "between", align: "center", gap: "sm" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Box, { flex: 1 }, titleNode), selectable ? /* @__PURE__ */ import_react3.default.createElement(
519
+ import_ui_extensions3.Checkbox,
430
520
  {
431
521
  name: `kanban-select-${rowId}`,
432
522
  checked: selected,
433
523
  onChange: () => onToggleSelect(rowId)
434
524
  }
435
525
  ) : null);
436
- const metaRow = metaNodes.length === 0 ? null : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: "end", align: "center", gap: "xs" }, metaNodes);
437
- const bodyRow = bodyFields.length === 0 ? null : bodyAs === "descriptionList" ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.DescriptionList, { direction: "row" }, bodyFields.map((f, idx) => {
526
+ const metaRow = metaNodes.length === 0 ? null : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", justify: "end", align: "center", gap: "xs" }, metaNodes);
527
+ const bodyRow = bodyFields.length === 0 ? null : bodyAs === "descriptionList" ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.DescriptionList, { direction: "row" }, bodyFields.map((f, idx) => {
438
528
  const val = resolveFieldValue(f, row);
439
529
  const rendered = f.render ? f.render(val, row) : val ?? "\u2014";
440
530
  const key = f.key || f.field || f.label || `body-${idx}`;
441
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.DescriptionListItem, { key, label: f.label || "" }, rendered);
442
- })) : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: "flush" }, bodyFields.map((f, idx) => {
531
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.DescriptionListItem, { key, label: f.label || "" }, rendered);
532
+ })) : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: "flush" }, bodyFields.map((f, idx) => {
443
533
  const val = resolveFieldValue(f, row);
444
534
  const rendered = f.render ? f.render(val, row) : val ?? "\u2014";
445
535
  const key = f.key || f.field || f.label || `body-${idx}`;
446
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { key, variant: "microcopy" }, f.label ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { inline: true, variant: "microcopy" }, `${f.label}: `) : null, rendered);
536
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { key, variant: "microcopy" }, f.label ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { inline: true, variant: "microcopy" }, `${f.label}: `) : null, rendered);
447
537
  }));
448
- const footerAlertsNode = footerAlerts.length === 0 ? null : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: "xs" }, footerAlerts.map((f, idx) => renderFooterField(f, idx)));
538
+ const footerAlertsNode = footerAlerts.length === 0 ? null : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: "xs" }, footerAlerts.map((f, idx) => renderFooterField(f, idx)));
449
539
  const footerActionsNode = footerActionsField ? renderFooterField(footerActionsField, footerFields.length - 1) : null;
450
540
  const inlineStageControl = stageControlPlacement === "inline" ? stageControlNode : null;
451
541
  const separateRowStageControl = stageControlPlacement === "separateRow" ? stageControlNode : null;
452
- const footerMainRow = inlineStageControl || footerActionsNode ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: "between", align: "start", gap: "sm" }, inlineStageControl ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { alignSelf: "center" }, inlineStageControl) : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, null), footerActionsNode ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { flex: 1 }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: "end", align: "start" }, footerActionsNode)) : null) : null;
453
- const footerRow = !footerAlertsNode && !footerMainRow ? null : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: "xs" }, footerAlertsNode, footerMainRow);
454
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Tile, { compact: density === "compact" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: density === "compact" ? "xs" : "sm" }, titleRow, dividers.afterTitle && (metaRow || bodyRow || footerRow || separateRowStageControl) ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Divider, null) : null, subtitleNode ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { variant: "microcopy" }, subtitleNode) : null, dividers.afterSubtitle && subtitleNode && (metaRow || bodyRow || footerRow || separateRowStageControl) ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Divider, null) : null, metaRow, bodyRow, dividers.afterBody && bodyRow && (footerRow || separateRowStageControl) ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Divider, null) : null, footerRow, dividers.afterFooter && footerRow && separateRowStageControl ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Divider, null) : null, separateRowStageControl));
542
+ const footerMainRow = inlineStageControl || footerActionsNode ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", justify: "between", align: "start", gap: "sm" }, inlineStageControl ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Box, { alignSelf: "center" }, inlineStageControl) : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Box, null), footerActionsNode ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Box, { flex: 1 }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", justify: "end", align: "start" }, footerActionsNode)) : null) : null;
543
+ const footerRow = !footerAlertsNode && !footerMainRow ? null : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: "xs" }, footerAlertsNode, footerMainRow);
544
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Tile, { compact: density === "compact" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: density === "compact" ? "xs" : "sm" }, titleRow, dividers.afterTitle && (metaRow || bodyRow || footerRow || separateRowStageControl) ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Divider, null) : null, subtitleNode ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { variant: "microcopy" }, subtitleNode) : null, dividers.afterSubtitle && subtitleNode && (metaRow || bodyRow || footerRow || separateRowStageControl) ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Divider, null) : null, metaRow, bodyRow, dividers.afterBody && bodyRow && (footerRow || separateRowStageControl) ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Divider, null) : null, footerRow, dividers.afterFooter && footerRow && separateRowStageControl ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Divider, null) : null, separateRowStageControl));
455
545
  };
456
546
  var StageControl = ({
457
547
  row,
@@ -465,7 +555,7 @@ var StageControl = ({
465
555
  labels
466
556
  }) => {
467
557
  if (isChanging) {
468
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.LoadingSpinner, { size: "xs" });
558
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.LoadingSpinner, { size: "xs" });
469
559
  }
470
560
  const availableStages = (stages || []).filter(
471
561
  (stage) => stage.value === currentStage.value || canStageReceiveRow(stage, row, canMove)
@@ -473,17 +563,17 @@ var StageControl = ({
473
563
  if (mode === "menu") {
474
564
  const targetStages = availableStages.filter((stage) => stage.value !== currentStage.value);
475
565
  if (targetStages.length === 0) {
476
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "transparent", size: "extra-small", disabled: true }, labels.moveTo);
566
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Button, { variant: "transparent", size: "extra-small", disabled: true }, labels.moveTo);
477
567
  }
478
- return /* @__PURE__ */ import_react2.default.createElement(
479
- import_ui_extensions2.Dropdown,
568
+ return /* @__PURE__ */ import_react3.default.createElement(
569
+ import_ui_extensions3.Dropdown,
480
570
  {
481
571
  variant: "transparent",
482
572
  buttonText: labels.moveTo,
483
573
  buttonSize: "xs"
484
574
  },
485
- targetStages.map((stage) => /* @__PURE__ */ import_react2.default.createElement(
486
- import_ui_extensions2.Dropdown.ButtonItem,
575
+ targetStages.map((stage) => /* @__PURE__ */ import_react3.default.createElement(
576
+ import_ui_extensions3.Dropdown.ButtonItem,
487
577
  {
488
578
  key: stage.value,
489
579
  onClick: () => onStageChangeRequest(row, stage.value, currentStage.value)
@@ -492,8 +582,8 @@ var StageControl = ({
492
582
  ))
493
583
  );
494
584
  }
495
- return /* @__PURE__ */ import_react2.default.createElement(
496
- import_ui_extensions2.Select,
585
+ return /* @__PURE__ */ import_react3.default.createElement(
586
+ import_ui_extensions3.Select,
497
587
  {
498
588
  name: `stage-${rowId}`,
499
589
  label: "",
@@ -527,12 +617,12 @@ var KanbanColumn = ({
527
617
  children
528
618
  }) => {
529
619
  const countLabel = labels.cardCount(totalCount != null ? totalCount : bucketCount);
530
- const countNode = countDisplay === "text" ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { format: { fontWeight: "demibold" } }, countLabel) : countDisplay === "none" ? null : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Tag, { variant: "subtle" }, countLabel);
620
+ const countNode = countDisplay === "text" ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { format: { fontWeight: "demibold" } }, countLabel) : countDisplay === "none" ? null : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Tag, { variant: "default" }, countLabel);
531
621
  if (collapsed) {
532
622
  const rotated = makeRotatedLabelDataUri(stage.label);
533
623
  const rotatedCount = countDisplay === "none" ? null : makeRotatedTagDataUri(countLabel);
534
- const stageIdentifier = stage.icon ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Icon, { name: stage.icon, size: "sm", screenReaderText: stage.label }) : /* @__PURE__ */ import_react2.default.createElement(
535
- import_ui_extensions2.Image,
624
+ const stageIdentifier = stage.icon ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: stage.icon, size: "sm", screenReaderText: stage.label }) : /* @__PURE__ */ import_react3.default.createElement(
625
+ import_ui_extensions3.Image,
536
626
  {
537
627
  src: rotated.src,
538
628
  width: rotated.width,
@@ -540,17 +630,17 @@ var KanbanColumn = ({
540
630
  alt: stage.label
541
631
  }
542
632
  );
543
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Tile, { compact: true }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: "xs", align: "center" }, /* @__PURE__ */ import_react2.default.createElement(
544
- import_ui_extensions2.Button,
633
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Tile, { compact: true }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: "xs", align: "center" }, /* @__PURE__ */ import_react3.default.createElement(
634
+ import_ui_extensions3.Button,
545
635
  {
546
636
  variant: "transparent",
547
637
  size: "sm",
548
638
  onClick: onToggleCollapsed,
549
639
  tooltip: `Expand ${stage.label}`
550
640
  },
551
- /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Icon, { name: "right", size: "sm", screenReaderText: `Expand ${stage.label}` })
552
- ), stageIdentifier, rotatedCount ? /* @__PURE__ */ import_react2.default.createElement(
553
- import_ui_extensions2.Image,
641
+ /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: "right", size: "sm", screenReaderText: `Expand ${stage.label}` })
642
+ ), stageIdentifier, rotatedCount ? /* @__PURE__ */ import_react3.default.createElement(
643
+ import_ui_extensions3.Image,
554
644
  {
555
645
  src: rotatedCount.src,
556
646
  width: rotatedCount.width,
@@ -560,13 +650,13 @@ var KanbanColumn = ({
560
650
  ) : null));
561
651
  }
562
652
  const footerContent = stage.footer ? stage.footer(rows) : columnFooter ? columnFooter(rows, stage) : null;
563
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Tile, { compact: true }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: "xs" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", align: "center", justify: "between", gap: "xs" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { format: { fontWeight: "demibold" } }, stage.shortLabel || stage.label), countNode, loading ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.LoadingSpinner, { size: "xs" }) : null), /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "transparent", size: "sm", onClick: onToggleCollapsed, tooltip: "Collapse" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Icon, { name: "left", size: "sm", screenReaderText: `Collapse ${stage.label}` }))), footerContent ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { variant: "microcopy" }, footerContent) : null, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Divider, null), children, error ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Alert, { variant: "danger", title: labels.errorTitle }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", gap: "xs", align: "center" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { variant: "microcopy" }, error), onLoadMore ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "transparent", size: "xs", onClick: () => onLoadMore(stage.value) }, labels.retryLoadMore) : null)) : null, !error && hasMore && onLoadMore && !loading && bucketCount > 0 ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: "center" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Link, { onClick: () => onLoadMore(stage.value) }, labels.loadMore(bucketCount, totalCount))) : null, !error && loading && hasMore ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.LoadingSpinner, { size: "sm", layout: "centered", label: labels.loadingMore }) : null, !error && !hasMore && bucketCount > rows.length ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", justify: "center" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Link, { onClick: onToggleExpanded }, expanded ? labels.showLess : labels.showMore(rows.length, bucketCount))) : null, rows.length === 0 && bucketCount === 0 && !loading ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { variant: "microcopy", format: { italic: true } }, labels.emptyColumn) : null));
653
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Tile, { compact: true }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: "xs" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", align: "center", justify: "between", gap: "xs" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { format: { fontWeight: "demibold" } }, stage.shortLabel || stage.label), countNode, loading ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.LoadingSpinner, { size: "xs" }) : null), /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Button, { variant: "transparent", size: "sm", onClick: onToggleCollapsed, tooltip: "Collapse" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: "left", size: "sm", screenReaderText: `Collapse ${stage.label}` }))), footerContent ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { variant: "microcopy" }, footerContent) : null, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Divider, null), children, error ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Alert, { variant: "danger", title: labels.errorTitle }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", gap: "xs", align: "center" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { variant: "microcopy" }, error), onLoadMore ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Button, { variant: "transparent", size: "xs", onClick: () => onLoadMore(stage.value) }, labels.retryLoadMore) : null)) : null, !error && hasMore && onLoadMore && !loading && bucketCount > 0 ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", justify: "center" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Link, { onClick: () => onLoadMore(stage.value) }, labels.loadMore(bucketCount, totalCount))) : null, !error && loading && hasMore ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.LoadingSpinner, { size: "sm", layout: "centered", label: labels.loadingMore }) : null, !error && !hasMore && bucketCount > rows.length ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", justify: "center" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Link, { onClick: onToggleExpanded }, expanded ? labels.showLess : labels.showMore(rows.length, bucketCount))) : null, rows.length === 0 && bucketCount === 0 && !loading ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { variant: "microcopy", format: { italic: true } }, labels.emptyColumn) : null));
564
654
  };
565
655
  var SortModalBody = ({ sortOptions, sortValue, onSortChange, labels }) => {
566
656
  const hasFieldDirection = Array.isArray(sortOptions) && sortOptions.length > 0 && sortOptions.every(isFieldDirectionSortOption);
567
657
  if (!hasFieldDirection) {
568
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: "xs" }, sortOptions.map((opt) => /* @__PURE__ */ import_react2.default.createElement(
569
- import_ui_extensions2.Button,
658
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: "xs" }, sortOptions.map((opt) => /* @__PURE__ */ import_react3.default.createElement(
659
+ import_ui_extensions3.Button,
570
660
  {
571
661
  key: opt.value,
572
662
  variant: sortValue === opt.value ? "primary" : "secondary",
@@ -593,8 +683,8 @@ var SortModalBody = ({ sortOptions, sortValue, onSortChange, labels }) => {
593
683
  const next = sortOptions.find((o) => o.field === newField && o.direction === currentDirection) || sortOptions.find((o) => o.field === newField && o.direction === "desc") || sortOptions.find((o) => o.field === newField);
594
684
  if (next) onSortChange(next.value);
595
685
  };
596
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Inline, { align: "center", gap: "small" }, /* @__PURE__ */ import_react2.default.createElement(
597
- import_ui_extensions2.Select,
686
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Inline, { align: "center", gap: "small" }, /* @__PURE__ */ import_react3.default.createElement(
687
+ import_ui_extensions3.Select,
598
688
  {
599
689
  name: "kanban-sort-field",
600
690
  label: "",
@@ -602,15 +692,15 @@ var SortModalBody = ({ sortOptions, sortValue, onSortChange, labels }) => {
602
692
  onChange: handleFieldChange,
603
693
  options: uniqueFields
604
694
  }
605
- ), /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Inline, { align: "center", gap: "flush" }, descOption ? /* @__PURE__ */ import_react2.default.createElement(
606
- import_ui_extensions2.Button,
695
+ ), /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Inline, { align: "center", gap: "flush" }, descOption ? /* @__PURE__ */ import_react3.default.createElement(
696
+ import_ui_extensions3.Button,
607
697
  {
608
698
  variant: currentDirection === "desc" ? "primary" : "secondary",
609
699
  onClick: () => onSortChange(descOption.value)
610
700
  },
611
701
  labels.sortDescending
612
- ) : null, ascOption ? /* @__PURE__ */ import_react2.default.createElement(
613
- import_ui_extensions2.Button,
702
+ ) : null, ascOption ? /* @__PURE__ */ import_react3.default.createElement(
703
+ import_ui_extensions3.Button,
614
704
  {
615
705
  variant: currentDirection === "asc" ? "primary" : "secondary",
616
706
  onClick: () => onSortChange(ascOption.value)
@@ -621,8 +711,8 @@ var SortModalBody = ({ sortOptions, sortValue, onSortChange, labels }) => {
621
711
  var renderFilterControl = ({ filter, value, onChange, labels }) => {
622
712
  const type = filter.type || "select";
623
713
  if (type === "multiselect") {
624
- return /* @__PURE__ */ import_react2.default.createElement(
625
- import_ui_extensions2.MultiSelect,
714
+ return /* @__PURE__ */ import_react3.default.createElement(
715
+ import_ui_extensions3.MultiSelect,
626
716
  {
627
717
  key: filter.name,
628
718
  name: `kanban-filter-${filter.name}`,
@@ -636,8 +726,8 @@ var renderFilterControl = ({ filter, value, onChange, labels }) => {
636
726
  }
637
727
  if (type === "dateRange") {
638
728
  const rangeVal = value || { from: null, to: null };
639
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { key: filter.name, direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ import_react2.default.createElement(
640
- import_ui_extensions2.DateInput,
729
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { key: filter.name, direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ import_react3.default.createElement(
730
+ import_ui_extensions3.DateInput,
641
731
  {
642
732
  size: "sm",
643
733
  name: `kanban-filter-${filter.name}-from`,
@@ -647,8 +737,8 @@ var renderFilterControl = ({ filter, value, onChange, labels }) => {
647
737
  value: rangeVal.from,
648
738
  onChange: (val) => onChange(filter.name, { ...rangeVal, from: val })
649
739
  }
650
- ), /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Icon, { name: "dataSync", size: "sm" }), /* @__PURE__ */ import_react2.default.createElement(
651
- import_ui_extensions2.DateInput,
740
+ ), /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: "dataSync", size: "sm" }), /* @__PURE__ */ import_react3.default.createElement(
741
+ import_ui_extensions3.DateInput,
652
742
  {
653
743
  size: "sm",
654
744
  name: `kanban-filter-${filter.name}-to`,
@@ -660,8 +750,8 @@ var renderFilterControl = ({ filter, value, onChange, labels }) => {
660
750
  }
661
751
  ));
662
752
  }
663
- return /* @__PURE__ */ import_react2.default.createElement(
664
- import_ui_extensions2.Select,
753
+ return /* @__PURE__ */ import_react3.default.createElement(
754
+ import_ui_extensions3.Select,
665
755
  {
666
756
  key: filter.name,
667
757
  name: `kanban-filter-${filter.name}`,
@@ -680,15 +770,15 @@ var renderMetricsPanel = (metrics) => {
680
770
  if (!metrics) return null;
681
771
  if (!Array.isArray(metrics)) return metrics;
682
772
  if (metrics.length === 0) return null;
683
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Statistics, null, metrics.map((m, i) => /* @__PURE__ */ import_react2.default.createElement(
684
- import_ui_extensions2.StatisticsItem,
773
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Statistics, null, metrics.map((m, i) => /* @__PURE__ */ import_react3.default.createElement(
774
+ import_ui_extensions3.StatisticsItem,
685
775
  {
686
776
  key: m.id || m.label || i,
687
777
  label: m.label,
688
778
  number: m.number != null ? String(m.number) : ""
689
779
  },
690
- m.trend ? /* @__PURE__ */ import_react2.default.createElement(
691
- import_ui_extensions2.StatisticsTrend,
780
+ m.trend ? /* @__PURE__ */ import_react3.default.createElement(
781
+ import_ui_extensions3.StatisticsTrend,
692
782
  {
693
783
  direction: m.trend.direction || "increase",
694
784
  value: m.trend.value,
@@ -718,11 +808,11 @@ var KanbanToolbar = ({
718
808
  onToggleMetrics,
719
809
  labels
720
810
  }) => {
721
- const [showMoreFilters, setShowMoreFilters] = (0, import_react2.useState)(false);
811
+ const [showMoreFilters, setShowMoreFilters] = (0, import_react3.useState)(false);
722
812
  const inlineFilters = (filters || []).slice(0, filterInlineLimit);
723
813
  const overflowFilters = (filters || []).slice(filterInlineLimit);
724
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: "xs" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", gap: "sm" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { flex: 3 }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: "sm" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", align: "center", gap: "sm", wrap: "wrap" }, showSearch ? /* @__PURE__ */ import_react2.default.createElement(
725
- import_ui_extensions2.SearchInput,
814
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: "xs" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", gap: "sm" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Box, { flex: 3 }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: "sm" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", align: "center", gap: "sm", wrap: "wrap" }, showSearch ? /* @__PURE__ */ import_react3.default.createElement(
815
+ import_ui_extensions3.SearchInput,
726
816
  {
727
817
  name: "kanban-search",
728
818
  placeholder: searchPlaceholder,
@@ -736,45 +826,45 @@ var KanbanToolbar = ({
736
826
  onChange: onFilterChange,
737
827
  labels
738
828
  })
739
- ), overflowFilters.length > 0 ? /* @__PURE__ */ import_react2.default.createElement(
740
- import_ui_extensions2.Button,
829
+ ), overflowFilters.length > 0 ? /* @__PURE__ */ import_react3.default.createElement(
830
+ import_ui_extensions3.Button,
741
831
  {
742
832
  variant: "transparent",
743
833
  size: "small",
744
834
  onClick: () => setShowMoreFilters((prev) => !prev)
745
835
  },
746
- /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Icon, { name: "filter", size: "sm" }),
836
+ /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: "filter", size: "sm" }),
747
837
  " ",
748
838
  labels.filtersButton
749
- ) : null), showMoreFilters && overflowFilters.length > 0 ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", align: "center", gap: "sm", wrap: "wrap" }, overflowFilters.map(
839
+ ) : null), showMoreFilters && overflowFilters.length > 0 ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", align: "center", gap: "sm", wrap: "wrap" }, overflowFilters.map(
750
840
  (filter) => renderFilterControl({
751
841
  filter,
752
842
  value: filterValues[filter.name],
753
843
  onChange: onFilterChange,
754
844
  labels
755
845
  })
756
- )) : null, activeChips.length > 0 && (showFilterBadges || showClearFiltersButton) ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", align: "center", gap: "sm", wrap: "wrap" }, showFilterBadges ? activeChips.map((chip) => /* @__PURE__ */ import_react2.default.createElement(
757
- import_ui_extensions2.Tag,
846
+ )) : null, activeChips.length > 0 && (showFilterBadges || showClearFiltersButton) ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", align: "center", gap: "sm", wrap: "wrap" }, showFilterBadges ? activeChips.map((chip) => /* @__PURE__ */ import_react3.default.createElement(
847
+ import_ui_extensions3.Tag,
758
848
  {
759
849
  key: chip.key,
760
850
  variant: "default",
761
851
  onDelete: () => onFilterRemove(chip.key)
762
852
  },
763
853
  chip.label
764
- )) : null, showClearFiltersButton ? /* @__PURE__ */ import_react2.default.createElement(
765
- import_ui_extensions2.Button,
854
+ )) : null, showClearFiltersButton ? /* @__PURE__ */ import_react3.default.createElement(
855
+ import_ui_extensions3.Button,
766
856
  {
767
857
  variant: "transparent",
768
858
  size: "extra-small",
769
859
  onClick: () => onFilterRemove("all")
770
860
  },
771
861
  labels.clearAll
772
- ) : null) : null)), (sortOptions == null ? void 0 : sortOptions.length) > 0 || metrics ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Box, { flex: 1, alignSelf: "start" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", align: "center", gap: "sm", justify: "end" }, sortOptions && sortOptions.length > 0 ? /* @__PURE__ */ import_react2.default.createElement(
773
- import_ui_extensions2.Button,
862
+ ) : null) : null)), (sortOptions == null ? void 0 : sortOptions.length) > 0 || metrics ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Box, { flex: 1, alignSelf: "start" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", align: "center", gap: "sm", justify: "end" }, sortOptions && sortOptions.length > 0 ? /* @__PURE__ */ import_react3.default.createElement(
863
+ import_ui_extensions3.Button,
774
864
  {
775
865
  variant: "secondary",
776
866
  size: "small",
777
- overlay: /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Modal, { id: "kanban-sort-modal", title: labels.sortButton }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.ModalBody, null, /* @__PURE__ */ import_react2.default.createElement(
867
+ overlay: /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Modal, { id: "kanban-sort-modal", title: labels.sortButton }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.ModalBody, null, /* @__PURE__ */ import_react3.default.createElement(
778
868
  SortModalBody,
779
869
  {
780
870
  sortOptions,
@@ -784,10 +874,10 @@ var KanbanToolbar = ({
784
874
  }
785
875
  )))
786
876
  },
787
- /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Icon, { name: "sortAmtDesc", size: "sm" }),
877
+ /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: "sortAmtDesc", size: "sm" }),
788
878
  " ",
789
879
  labels.sortButton
790
- ) : null, metrics ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "secondary", size: "small", onClick: onToggleMetrics }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Icon, { name: "reports", size: "sm" }), " ", labels.metricsButton) : null)) : null), showMetrics && metrics ? renderMetricsPanel(metrics) : null);
880
+ ) : null, metrics ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Button, { variant: "secondary", size: "small", onClick: onToggleMetrics }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: "reports", size: "sm" }), " ", labels.metricsButton) : null)) : null), showMetrics && metrics ? renderMetricsPanel(metrics) : null);
791
881
  };
792
882
  var DefaultSelectionBar = ({
793
883
  selectedIds,
@@ -801,15 +891,15 @@ var DefaultSelectionBar = ({
801
891
  labels
802
892
  }) => {
803
893
  const pluralForCount = (n) => countLabel(n);
804
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Tile, { compact: true }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Inline, { align: "center", justify: "between", gap: "small" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Inline, { align: "center", gap: "small" }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, { inline: true, format: { fontWeight: "demibold" } }, typeof labels.selected === "function" ? labels.selected(selectedCount, pluralForCount(selectedCount)) : `${selectedCount} selected`), !allSelected ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "transparent", size: "extra-small", onClick: onSelectAll }, typeof labels.selectAll === "function" ? labels.selectAll(displayCount, pluralForCount(displayCount)) : labels.selectAll) : null, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Button, { variant: "transparent", size: "extra-small", onClick: onDeselectAll }, labels.deselectAll)), (selectionActions || []).length > 0 ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Inline, { align: "center", gap: "extra-small" }, selectionActions.map((action, i) => /* @__PURE__ */ import_react2.default.createElement(
805
- import_ui_extensions2.Button,
894
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Tile, { compact: true }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Inline, { align: "center", justify: "between", gap: "small" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Inline, { align: "center", gap: "small" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { inline: true, format: { fontWeight: "demibold" } }, typeof labels.selected === "function" ? labels.selected(selectedCount, pluralForCount(selectedCount)) : `${selectedCount} selected`), !allSelected ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Button, { variant: "transparent", size: "extra-small", onClick: onSelectAll }, typeof labels.selectAll === "function" ? labels.selectAll(displayCount, pluralForCount(displayCount)) : labels.selectAll) : null, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Button, { variant: "transparent", size: "extra-small", onClick: onDeselectAll }, labels.deselectAll)), (selectionActions || []).length > 0 ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Inline, { align: "center", gap: "extra-small" }, selectionActions.map((action, i) => /* @__PURE__ */ import_react3.default.createElement(
895
+ import_ui_extensions3.Button,
806
896
  {
807
897
  key: action.key || action.label || i,
808
898
  variant: action.variant || "transparent",
809
899
  size: "extra-small",
810
900
  onClick: () => action.onClick([...selectedIds])
811
901
  },
812
- action.icon ? /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Icon, { name: action.icon, size: "sm" }) : null,
902
+ action.icon ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: action.icon, size: "sm" }) : null,
813
903
  " ",
814
904
  action.label
815
905
  ))) : null));
@@ -860,7 +950,7 @@ var Kanban = ({
860
950
  filters,
861
951
  filterInlineLimit = DEFAULT_FILTER_INLINE_LIMIT,
862
952
  showFilterBadges = true,
863
- showClearFiltersButton = true,
953
+ showClearFiltersButton,
864
954
  sortOptions,
865
955
  defaultSort,
866
956
  sort,
@@ -891,44 +981,44 @@ var Kanban = ({
891
981
  renderErrorState
892
982
  }) => {
893
983
  var _a;
894
- const labels = (0, import_react2.useMemo)(() => ({ ...DEFAULT_LABELS, ...labelsProp || {} }), [labelsProp]);
895
- const [internalSearch, setInternalSearch] = (0, import_react2.useState)(searchValue != null ? searchValue : "");
896
- const [internalFilters, setInternalFilters] = (0, import_react2.useState)(() => {
984
+ const labels = (0, import_react3.useMemo)(() => ({ ...DEFAULT_LABELS, ...labelsProp || {} }), [labelsProp]);
985
+ const [internalSearch, setInternalSearch] = (0, import_react3.useState)(searchValue != null ? searchValue : "");
986
+ const [internalFilters, setInternalFilters] = (0, import_react3.useState)(() => {
897
987
  const init = {};
898
988
  (filters || []).forEach((f) => {
899
989
  init[f.name] = getEmptyFilterValue(f);
900
990
  });
901
991
  return init;
902
992
  });
903
- const [internalSort, setInternalSort] = (0, import_react2.useState)(defaultSort || (((_a = sortOptions == null ? void 0 : sortOptions[0]) == null ? void 0 : _a.value) ?? ""));
904
- const [internalCollapsed, setInternalCollapsed] = (0, import_react2.useState)([]);
905
- const [internalExpanded, setInternalExpanded] = (0, import_react2.useState)([]);
906
- const [internalSelection, setInternalSelection] = (0, import_react2.useState)([]);
907
- const [internalShowMetrics, setInternalShowMetrics] = (0, import_react2.useState)(false);
908
- const [transitionPrompts, setTransitionPrompts] = (0, import_react2.useState)({});
909
- const selectionResetRef = (0, import_react2.useRef)("");
993
+ const [internalSort, setInternalSort] = (0, import_react3.useState)(defaultSort || (((_a = sortOptions == null ? void 0 : sortOptions[0]) == null ? void 0 : _a.value) ?? ""));
994
+ const [internalCollapsed, setInternalCollapsed] = (0, import_react3.useState)([]);
995
+ const [internalExpanded, setInternalExpanded] = (0, import_react3.useState)([]);
996
+ const [internalSelection, setInternalSelection] = (0, import_react3.useState)([]);
997
+ const [internalShowMetrics, setInternalShowMetrics] = (0, import_react3.useState)(false);
998
+ const [transitionPrompts, setTransitionPrompts] = (0, import_react3.useState)({});
910
999
  const resolvedShowMetrics = controlledShowMetrics != null ? controlledShowMetrics : internalShowMetrics;
911
- const toggleMetrics = (0, import_react2.useCallback)(() => {
1000
+ const toggleMetrics = (0, import_react3.useCallback)(() => {
912
1001
  const next = !resolvedShowMetrics;
913
1002
  if (onMetricsToggle) onMetricsToggle(next);
914
1003
  if (controlledShowMetrics == null) setInternalShowMetrics(next);
915
1004
  }, [resolvedShowMetrics, onMetricsToggle, controlledShowMetrics]);
916
1005
  const effectiveColumnWidth = Math.max(MIN_COLUMN_WIDTH, columnWidth || DEFAULT_COLUMN_WIDTH);
917
1006
  const resolvedSearch = searchValue != null ? searchValue : internalSearch;
1007
+ const searchInputValue = searchDebounce > 0 ? internalSearch : resolvedSearch;
918
1008
  const resolvedFilters = filterValues != null ? filterValues : internalFilters;
919
1009
  const resolvedSort = sort != null ? sort : internalSort;
920
1010
  const resolvedCollapsed = collapsedStages != null ? collapsedStages : internalCollapsed;
921
1011
  const resolvedExpanded = expandedStages != null ? expandedStages : internalExpanded;
922
1012
  const resolvedSelection = selectedIds != null ? selectedIds : internalSelection;
923
1013
  const searchEnabled = showSearch && Array.isArray(searchFields) && searchFields.length > 0;
924
- const stagesByValue = (0, import_react2.useMemo)(() => {
1014
+ const stagesByValue = (0, import_react3.useMemo)(() => {
925
1015
  const map = {};
926
1016
  for (const stage of stages || []) {
927
1017
  map[stage.value] = stage;
928
1018
  }
929
1019
  return map;
930
1020
  }, [stages]);
931
- const fireParamsChange = (0, import_react2.useCallback)((overrides = {}) => {
1021
+ const fireParamsChange = (0, import_react3.useCallback)((overrides = {}) => {
932
1022
  if (!onParamsChange) return;
933
1023
  onParamsChange({
934
1024
  search: overrides.search != null ? overrides.search : resolvedSearch,
@@ -937,27 +1027,30 @@ var Kanban = ({
937
1027
  collapsedStages: overrides.collapsedStages != null ? overrides.collapsedStages : resolvedCollapsed
938
1028
  });
939
1029
  }, [onParamsChange, resolvedCollapsed, resolvedFilters, resolvedSearch, resolvedSort]);
940
- const debounceRef = (0, import_react2.useRef)(null);
941
- (0, import_react2.useEffect)(() => () => {
942
- if (debounceRef.current) clearTimeout(debounceRef.current);
943
- }, []);
944
- const handleSearch = (0, import_react2.useCallback)(
1030
+ const lastAppliedSearchRef = (0, import_react3.useRef)(searchValue != null ? searchValue : "");
1031
+ (0, import_react3.useEffect)(() => {
1032
+ if (searchValue == null) return;
1033
+ if (searchValue === lastAppliedSearchRef.current) return;
1034
+ lastAppliedSearchRef.current = searchValue;
1035
+ setInternalSearch(searchValue);
1036
+ }, [searchValue]);
1037
+ const dispatchSearch = (0, import_react3.useCallback)(
945
1038
  (val) => {
946
- if (searchValue == null) setInternalSearch(val);
947
- const dispatch = () => {
948
- if (onSearchChange) onSearchChange(val);
949
- fireParamsChange({ search: val });
950
- };
951
- if (searchDebounce > 0) {
952
- if (debounceRef.current) clearTimeout(debounceRef.current);
953
- debounceRef.current = setTimeout(dispatch, searchDebounce);
954
- } else {
955
- dispatch();
956
- }
1039
+ lastAppliedSearchRef.current = val;
1040
+ if (onSearchChange) onSearchChange(val);
1041
+ fireParamsChange({ search: val });
957
1042
  },
958
- [fireParamsChange, onSearchChange, searchValue, searchDebounce]
1043
+ [fireParamsChange, onSearchChange]
959
1044
  );
960
- const handleFilter = (0, import_react2.useCallback)(
1045
+ const dispatchSearchDebounced = useDebouncedDispatch(internalSearch, searchDebounce, dispatchSearch);
1046
+ const handleSearch = (0, import_react3.useCallback)(
1047
+ (val) => {
1048
+ setInternalSearch(val);
1049
+ dispatchSearchDebounced(val);
1050
+ },
1051
+ [dispatchSearchDebounced]
1052
+ );
1053
+ const handleFilter = (0, import_react3.useCallback)(
961
1054
  (name, val) => {
962
1055
  const next = { ...resolvedFilters, [name]: val };
963
1056
  if (filterValues == null) setInternalFilters(next);
@@ -966,7 +1059,7 @@ var Kanban = ({
966
1059
  },
967
1060
  [fireParamsChange, onFilterChange, filterValues, resolvedFilters]
968
1061
  );
969
- const handleFilterRemove = (0, import_react2.useCallback)(
1062
+ const handleFilterRemove = (0, import_react3.useCallback)(
970
1063
  (key) => {
971
1064
  if (key === "all") {
972
1065
  const cleared = {};
@@ -987,7 +1080,7 @@ var Kanban = ({
987
1080
  },
988
1081
  [filters, filterValues, fireParamsChange, onFilterChange, resolvedFilters]
989
1082
  );
990
- const handleSort = (0, import_react2.useCallback)(
1083
+ const handleSort = (0, import_react3.useCallback)(
991
1084
  (val) => {
992
1085
  if (onSortChange) onSortChange(val);
993
1086
  if (sort == null) setInternalSort(val);
@@ -995,7 +1088,7 @@ var Kanban = ({
995
1088
  },
996
1089
  [fireParamsChange, onSortChange, sort]
997
1090
  );
998
- const handleCollapsed = (0, import_react2.useCallback)(
1091
+ const handleCollapsed = (0, import_react3.useCallback)(
999
1092
  (stageValue) => {
1000
1093
  const next = resolvedCollapsed.includes(stageValue) ? resolvedCollapsed.filter((v) => v !== stageValue) : [...resolvedCollapsed, stageValue];
1001
1094
  if (onCollapsedStagesChange) onCollapsedStagesChange(next);
@@ -1004,7 +1097,7 @@ var Kanban = ({
1004
1097
  },
1005
1098
  [fireParamsChange, resolvedCollapsed, collapsedStages, onCollapsedStagesChange]
1006
1099
  );
1007
- const handleExpanded = (0, import_react2.useCallback)(
1100
+ const handleExpanded = (0, import_react3.useCallback)(
1008
1101
  (stageValue) => {
1009
1102
  const next = resolvedExpanded.includes(stageValue) ? resolvedExpanded.filter((v) => v !== stageValue) : [...resolvedExpanded, stageValue];
1010
1103
  if (onExpandedStagesChange) onExpandedStagesChange(next);
@@ -1012,7 +1105,7 @@ var Kanban = ({
1012
1105
  },
1013
1106
  [resolvedExpanded, expandedStages, onExpandedStagesChange]
1014
1107
  );
1015
- const handleToggleSelect = (0, import_react2.useCallback)(
1108
+ const handleToggleSelect = (0, import_react3.useCallback)(
1016
1109
  (rowId) => {
1017
1110
  const next = resolvedSelection.includes(rowId) ? resolvedSelection.filter((id) => id !== rowId) : [...resolvedSelection, rowId];
1018
1111
  if (onSelectionChange) onSelectionChange(next);
@@ -1020,7 +1113,7 @@ var Kanban = ({
1020
1113
  },
1021
1114
  [resolvedSelection, selectedIds, onSelectionChange]
1022
1115
  );
1023
- const clearTransitionPrompt = (0, import_react2.useCallback)((rowId) => {
1116
+ const clearTransitionPrompt = (0, import_react3.useCallback)((rowId) => {
1024
1117
  setTransitionPrompts((prev) => {
1025
1118
  if (!Object.prototype.hasOwnProperty.call(prev, rowId)) return prev;
1026
1119
  const next = { ...prev };
@@ -1028,14 +1121,14 @@ var Kanban = ({
1028
1121
  return next;
1029
1122
  });
1030
1123
  }, []);
1031
- const commitStageChange = (0, import_react2.useCallback)(
1124
+ const commitStageChange = (0, import_react3.useCallback)(
1032
1125
  (row, newStage, oldStage, result) => {
1033
1126
  clearTransitionPrompt(row[rowIdField]);
1034
1127
  if (onStageChange) onStageChange(row, newStage, oldStage, result);
1035
1128
  },
1036
1129
  [clearTransitionPrompt, onStageChange, rowIdField]
1037
1130
  );
1038
- const selectionQueryKey = (0, import_react2.useMemo)(() => {
1131
+ const selectionQueryKey = (0, import_react3.useMemo)(() => {
1039
1132
  if (!resetSelectionOnQueryChange) return "";
1040
1133
  return toStableKey({
1041
1134
  search: resolvedSearch,
@@ -1043,73 +1136,36 @@ var Kanban = ({
1043
1136
  sort: resolvedSort || null
1044
1137
  });
1045
1138
  }, [resetSelectionOnQueryChange, resolvedFilters, resolvedSearch, resolvedSort]);
1046
- const combinedSelectionResetKey = (0, import_react2.useMemo)(
1139
+ const combinedSelectionResetKey = (0, import_react3.useMemo)(
1047
1140
  () => `${selectionQueryKey}::${selectionResetKey == null ? "" : toStableKey(selectionResetKey)}`,
1048
1141
  [selectionQueryKey, selectionResetKey]
1049
1142
  );
1050
- (0, import_react2.useEffect)(() => {
1051
- if (!selectable || selectedIds != null) {
1052
- selectionResetRef.current = combinedSelectionResetKey;
1053
- return;
1054
- }
1055
- if (selectionResetRef.current && selectionResetRef.current !== combinedSelectionResetKey) {
1056
- setInternalSelection([]);
1057
- }
1058
- selectionResetRef.current = combinedSelectionResetKey;
1059
- }, [combinedSelectionResetKey, selectable, selectedIds]);
1060
- const getStageFor = (0, import_react2.useCallback)(
1143
+ const clearSelection = (0, import_react3.useCallback)(() => setInternalSelection([]), []);
1144
+ useSelectionReset({
1145
+ resetKey: combinedSelectionResetKey,
1146
+ enabled: selectable,
1147
+ isControlled: selectedIds != null,
1148
+ clearSelection
1149
+ });
1150
+ const getStageFor = (0, import_react3.useCallback)(
1061
1151
  (row) => {
1062
1152
  if (typeof groupBy === "function") return groupBy(row);
1063
1153
  return row[groupBy];
1064
1154
  },
1065
1155
  [groupBy]
1066
1156
  );
1067
- const filteredData = (0, import_react2.useMemo)(() => {
1068
- let result = data;
1069
- for (const filter of filters || []) {
1070
- const val = resolvedFilters[filter.name];
1071
- if (!isFilterActive(filter, val)) continue;
1072
- const type = filter.type || "select";
1073
- if (filter.filterFn) {
1074
- result = result.filter((row) => filter.filterFn(row, val));
1075
- } else if (type === "multiselect") {
1076
- result = result.filter((row) => val.includes(row[filter.name]));
1077
- } else if (type === "dateRange") {
1078
- const fromTs = dateToTimestamp(val.from);
1079
- const toTs = val.to ? dateToTimestamp(val.to) + 864e5 - 1 : null;
1080
- result = result.filter((row) => {
1081
- const rowTs = new Date(row[filter.name]).getTime();
1082
- if (Number.isNaN(rowTs)) return false;
1083
- if (fromTs && rowTs < fromTs) return false;
1084
- if (toTs && rowTs > toTs) return false;
1085
- return true;
1086
- });
1087
- } else {
1088
- result = result.filter((row) => row[filter.name] === val);
1089
- }
1090
- }
1157
+ const filteredData = (0, import_react3.useMemo)(() => {
1158
+ let result = filterRows(data, filters, resolvedFilters);
1091
1159
  const searchLower = (resolvedSearch || "").toLowerCase().trim();
1092
1160
  if (searchEnabled && searchLower) {
1093
- if (fuzzySearch) {
1094
- const fuse = new import_fuse.default(result, {
1095
- keys: searchFields,
1096
- threshold: 0.4,
1097
- distance: 100,
1098
- ignoreLocation: true,
1099
- ...fuzzyOptions
1100
- });
1101
- result = fuse.search(searchLower).map((r) => r.item);
1102
- } else {
1103
- result = result.filter(
1104
- (row) => searchFields.some(
1105
- (f) => String(row[f] || "").toLowerCase().includes(searchLower)
1106
- )
1107
- );
1108
- }
1161
+ result = searchRows(result, searchLower, searchFields, {
1162
+ fuzzy: fuzzySearch,
1163
+ fuzzyOptions
1164
+ });
1109
1165
  }
1110
1166
  return result;
1111
1167
  }, [data, resolvedSearch, resolvedFilters, filters, searchEnabled, searchFields, fuzzySearch, fuzzyOptions]);
1112
- const buckets = (0, import_react2.useMemo)(() => {
1168
+ const buckets = (0, import_react3.useMemo)(() => {
1113
1169
  const map = {};
1114
1170
  for (const stage of stages) map[stage.value] = [];
1115
1171
  for (const row of filteredData) {
@@ -1123,12 +1179,12 @@ var Kanban = ({
1123
1179
  }
1124
1180
  return map;
1125
1181
  }, [filteredData, stages, getStageFor]);
1126
- const sortComparator = (0, import_react2.useMemo)(() => {
1182
+ const sortComparator = (0, import_react3.useMemo)(() => {
1127
1183
  if (!sortOptions || !resolvedSort) return null;
1128
1184
  const opt = sortOptions.find((s) => s.value === resolvedSort);
1129
1185
  return (opt == null ? void 0 : opt.comparator) || null;
1130
1186
  }, [sortOptions, resolvedSort]);
1131
- const sortedBuckets = (0, import_react2.useMemo)(() => {
1187
+ const sortedBuckets = (0, import_react3.useMemo)(() => {
1132
1188
  if (!sortComparator) return buckets;
1133
1189
  const out = {};
1134
1190
  for (const key of Object.keys(buckets)) {
@@ -1136,7 +1192,7 @@ var Kanban = ({
1136
1192
  }
1137
1193
  return out;
1138
1194
  }, [buckets, sortComparator]);
1139
- const activeChips = (0, import_react2.useMemo)(() => {
1195
+ const activeChips = (0, import_react3.useMemo)(() => {
1140
1196
  const chips = [];
1141
1197
  for (const filter of filters || []) {
1142
1198
  const val = resolvedFilters[filter.name];
@@ -1161,12 +1217,12 @@ var Kanban = ({
1161
1217
  }
1162
1218
  return chips;
1163
1219
  }, [filters, resolvedFilters]);
1164
- const partitioned = (0, import_react2.useMemo)(() => partitionFields(cardFields || []), [cardFields]);
1165
- const dividers = (0, import_react2.useMemo)(() => resolveDividers(cardDividers, cardDensity), [cardDividers, cardDensity]);
1220
+ const partitioned = (0, import_react3.useMemo)(() => partitionFields(cardFields || []), [cardFields]);
1221
+ const dividers = (0, import_react3.useMemo)(() => resolveDividers(cardDividers, cardDensity), [cardDividers, cardDensity]);
1166
1222
  const resolvedMaxBody = maxBodyLines || (cardDensity === "comfortable" ? 5 : 3);
1167
1223
  const resolvedStageControl = stageControl || (cardDensity === "comfortable" ? "select" : "menu");
1168
1224
  const resolvedStageControlPlacement = stageControlPlacement || (resolvedStageControl === "menu" ? "inline" : "separateRow");
1169
- const handleStageChangeRequest = (0, import_react2.useCallback)(
1225
+ const handleStageChangeRequest = (0, import_react3.useCallback)(
1170
1226
  (row, newStage, oldStage) => {
1171
1227
  var _a2;
1172
1228
  if (!newStage || newStage === oldStage) return;
@@ -1188,14 +1244,14 @@ var Kanban = ({
1188
1244
  },
1189
1245
  [canMove, commitStageChange, rowIdField, stagesByValue]
1190
1246
  );
1191
- const renderCardNode = (0, import_react2.useCallback)(
1247
+ const renderCardNode = (0, import_react3.useCallback)(
1192
1248
  (row, stage) => {
1193
1249
  var _a2;
1194
1250
  const rowId = row[rowIdField];
1195
1251
  const activePrompt = transitionPrompts[rowId];
1196
1252
  const promptStage = activePrompt ? stagesByValue[activePrompt.toStage] : null;
1197
1253
  if ((_a2 = promptStage == null ? void 0 : promptStage.onEnterRequired) == null ? void 0 : _a2.render) {
1198
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Tile, { key: rowId, compact: cardDensity === "compact" }, promptStage.onEnterRequired.render({
1254
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Tile, { key: rowId, compact: cardDensity === "compact" }, promptStage.onEnterRequired.render({
1199
1255
  row: activePrompt.row,
1200
1256
  fromStage: activePrompt.fromStage,
1201
1257
  toStage: activePrompt.toStage,
@@ -1211,7 +1267,7 @@ var Kanban = ({
1211
1267
  onStageChange: (newStage) => handleStageChangeRequest(row, newStage, stage.value)
1212
1268
  });
1213
1269
  }
1214
- return /* @__PURE__ */ import_react2.default.createElement(
1270
+ return /* @__PURE__ */ import_react3.default.createElement(
1215
1271
  KanbanCard,
1216
1272
  {
1217
1273
  key: rowId,
@@ -1287,17 +1343,21 @@ var Kanban = ({
1287
1343
  error,
1288
1344
  title: labels.errorTitle,
1289
1345
  message: typeof error === "string" ? error : labels.errorMessage
1290
- }) : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Alert, { variant: "danger", title: labels.errorTitle }, typeof error === "string" ? error : labels.errorMessage) : loading && data.length === 0 ? renderLoadingState ? renderLoadingState({ label: labels.loading }) : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.LoadingSpinner, { size: "md", layout: "centered", label: labels.loading }) : filteredData.length === 0 ? renderEmptyState ? renderEmptyState({
1346
+ }) : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Alert, { variant: "danger", title: labels.errorTitle }, typeof error === "string" ? error : labels.errorMessage) : loading && data.length === 0 ? renderLoadingState ? renderLoadingState({ label: labels.loading }) : (
1347
+ // Same EmptyState layout as the empty state (just the "building" image +
1348
+ // a loading message) so loading and empty match with no layout shift.
1349
+ /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Tile, null, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", align: "center", justify: "center" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.EmptyState, { title: labels.loading, imageName: "building", layout: "vertical" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, null, labels.loadingMessage))))
1350
+ ) : filteredData.length === 0 ? renderEmptyState ? renderEmptyState({
1291
1351
  title: labels.emptyTitle,
1292
1352
  message: labels.emptyMessage
1293
- }) : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Tile, null, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.EmptyState, { title: labels.emptyTitle, layout: "vertical", reverseOrder: true }, /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Text, null, labels.emptyMessage))) : /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "row", gap: "sm", wrap: "nowrap" }, stages.map((stage) => {
1353
+ }) : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Tile, null, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", align: "center", justify: "center" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.EmptyState, { title: labels.emptyTitle, layout: "vertical" }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, null, labels.emptyMessage)))) : /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", gap: "sm", wrap: "nowrap" }, stages.map((stage) => {
1294
1354
  const stageRows = sortedBuckets[stage.value] || [];
1295
1355
  const meta = stageMeta == null ? void 0 : stageMeta[stage.value];
1296
1356
  const isExpanded = resolvedExpanded.includes(stage.value);
1297
1357
  const clamp = isExpanded ? maxCardsExpanded : maxCardsPerColumn;
1298
1358
  const visibleRows = stageRows.slice(0, clamp);
1299
1359
  const isCollapsed = resolvedCollapsed.includes(stage.value);
1300
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.AutoGrid, { key: stage.value, columnWidth: isCollapsed ? 72 : effectiveColumnWidth }, /* @__PURE__ */ import_react2.default.createElement(
1360
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.AutoGrid, { key: stage.value, columnWidth: isCollapsed ? 72 : effectiveColumnWidth }, /* @__PURE__ */ import_react3.default.createElement(
1301
1361
  KanbanColumn,
1302
1362
  {
1303
1363
  stage,
@@ -1319,11 +1379,12 @@ var Kanban = ({
1319
1379
  visibleRows.map((row) => renderCardNode(row, stage))
1320
1380
  ));
1321
1381
  }));
1322
- return /* @__PURE__ */ import_react2.default.createElement(import_ui_extensions2.Flex, { direction: "column", gap: "sm" }, /* @__PURE__ */ import_react2.default.createElement(
1382
+ const resolvedShowClearFiltersButton = showClearFiltersButton ?? showFilterBadges;
1383
+ return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "column", gap: "sm" }, /* @__PURE__ */ import_react3.default.createElement(
1323
1384
  KanbanToolbar,
1324
1385
  {
1325
1386
  showSearch: searchEnabled,
1326
- searchValue: resolvedSearch,
1387
+ searchValue: searchInputValue,
1327
1388
  searchPlaceholder: resolvedSearchPlaceholder,
1328
1389
  onSearchChange: handleSearch,
1329
1390
  filters,
@@ -1331,7 +1392,7 @@ var Kanban = ({
1331
1392
  onFilterChange: handleFilter,
1332
1393
  filterInlineLimit,
1333
1394
  showFilterBadges,
1334
- showClearFiltersButton,
1395
+ showClearFiltersButton: resolvedShowClearFiltersButton,
1335
1396
  activeChips,
1336
1397
  onFilterRemove: handleFilterRemove,
1337
1398
  sortOptions,
@@ -1342,12 +1403,12 @@ var Kanban = ({
1342
1403
  onToggleMetrics: toggleMetrics,
1343
1404
  labels
1344
1405
  }
1345
- ), showSelectionBar && selectable && selectedCount > 0 ? renderSelectionBar ? renderSelectionBar(selectionBarProps) : /* @__PURE__ */ import_react2.default.createElement(DefaultSelectionBar, { ...selectionBarProps }) : null, mainContent);
1406
+ ), showSelectionBar && selectable && selectedCount > 0 ? renderSelectionBar ? renderSelectionBar(selectionBarProps) : /* @__PURE__ */ import_react3.default.createElement(DefaultSelectionBar, { ...selectionBarProps }) : null, mainContent);
1346
1407
  };
1347
1408
 
1348
1409
  // packages/kanban/src/KanbanCardActions.jsx
1349
- var import_react3 = __toESM(require("react"));
1350
- var import_ui_extensions3 = require("@hubspot/ui-extensions");
1410
+ var import_react4 = __toESM(require("react"));
1411
+ var import_ui_extensions4 = require("@hubspot/ui-extensions");
1351
1412
  var renderButton = (action, display, size) => {
1352
1413
  const { key, label, icon, tooltip, variant = "transparent", disabled, onClick, href } = action;
1353
1414
  const buttonProps = {
@@ -1360,12 +1421,12 @@ var renderButton = (action, display, size) => {
1360
1421
  if (href) buttonProps.href = typeof href === "string" ? href : href;
1361
1422
  if (onClick) buttonProps.onClick = onClick;
1362
1423
  if (display === "icon") {
1363
- return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Button, { ...buttonProps }, icon ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: icon, size: "sm", screenReaderText: label }) : label);
1424
+ return /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Button, { ...buttonProps }, icon ? /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Icon, { name: icon, size: "sm", screenReaderText: label }) : label);
1364
1425
  }
1365
1426
  if (display === "label") {
1366
- return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Button, { ...buttonProps }, label);
1427
+ return /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Button, { ...buttonProps }, label);
1367
1428
  }
1368
- return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Button, { ...buttonProps }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", align: "center", gap: "xs" }, icon ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Icon, { name: icon, size: "sm", screenReaderText: label }) : null, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { variant: "microcopy" }, label)));
1429
+ return /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Button, { ...buttonProps }, /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Flex, { direction: "row", align: "center", gap: "xs" }, icon ? /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Icon, { name: icon, size: "sm", screenReaderText: label }) : null, /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Text, { variant: "microcopy" }, label)));
1369
1430
  };
1370
1431
  var KanbanCardActions = ({
1371
1432
  actions = [],
@@ -1388,12 +1449,12 @@ var KanbanCardActions = ({
1388
1449
  const renderedPrimary = primary.map((action, idx) => {
1389
1450
  const button = renderButton(action, display, size);
1390
1451
  if (separator === "pipe" && idx > 0) {
1391
- return /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, { key: `${action.key || action.label}-sep` }, /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Text, { variant: "microcopy" }, "|"), button);
1452
+ return /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, { key: `${action.key || action.label}-sep` }, /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Text, { variant: "microcopy" }, "|"), button);
1392
1453
  }
1393
1454
  return button;
1394
1455
  });
1395
- const renderedOverflow = overflow.length > 0 ? /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Dropdown, { variant: "transparent", buttonText: overflowLabel, buttonSize: size, key: "overflow" }, overflow.map((action) => /* @__PURE__ */ import_react3.default.createElement(
1396
- import_ui_extensions3.Dropdown.ButtonItem,
1456
+ const renderedOverflow = overflow.length > 0 ? /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Dropdown, { variant: "transparent", buttonText: overflowLabel, buttonSize: size, key: "overflow" }, overflow.map((action) => /* @__PURE__ */ import_react4.default.createElement(
1457
+ import_ui_extensions4.Dropdown.ButtonItem,
1397
1458
  {
1398
1459
  key: action.key || action.label,
1399
1460
  onClick: action.onClick
@@ -1401,7 +1462,7 @@ var KanbanCardActions = ({
1401
1462
  action.label
1402
1463
  ))) : null;
1403
1464
  const justify = align === "end" ? "end" : align === "between" ? "between" : "start";
1404
- return /* @__PURE__ */ import_react3.default.createElement(import_ui_extensions3.Flex, { direction: "row", align: "end", justify, gap }, renderedPrimary, renderedOverflow);
1465
+ return /* @__PURE__ */ import_react4.default.createElement(import_ui_extensions4.Flex, { direction: "row", align: "end", justify, gap }, renderedPrimary, renderedOverflow);
1405
1466
  };
1406
1467
  // Annotate the CommonJS export names for ESM import in node:
1407
1468
  0 && (module.exports = {