diff --git a/packages/core/src/components/badge-list.tsx b/packages/core/src/components/badge-list.tsx
index e9e0df53..4df72fd4 100644
--- a/packages/core/src/components/badge-list.tsx
+++ b/packages/core/src/components/badge-list.tsx
@@ -61,6 +61,17 @@ export function resolveBadgeLabel(
return options?.badgeLabelMap?.[value];
}
+/**
+ * Normalize a value into an array. If the value is already an array, return it
+ * as-is. If it is a non-null single value, wrap it in an array. Otherwise
+ * return an empty array.
+ */
+export function toValueArray(value: unknown): unknown[] {
+ if (Array.isArray(value)) return value;
+ if (value != null) return [value];
+ return [];
+}
+
// ============================================================================
// BADGE LIST COMPONENT
// ============================================================================
@@ -95,7 +106,7 @@ export function BadgeList({
resolveLabel: resolveLabelProp,
badgeClassName,
}: BadgeListProps): React.ReactNode {
- const values = Array.isArray(value) ? value : [value];
+ const values = toValueArray(value);
const nonEmpty = values.filter((v) => v != null && v !== "");
if (nonEmpty.length === 0) return null;
diff --git a/packages/core/src/components/data-table/cell-renderers.tsx b/packages/core/src/components/data-table/cell-renderers.tsx
index 38a923b7..83596e88 100644
--- a/packages/core/src/components/data-table/cell-renderers.tsx
+++ b/packages/core/src/components/data-table/cell-renderers.tsx
@@ -1,6 +1,6 @@
import type { ReactNode } from "react";
import { Link } from "react-router";
-import { BadgeList } from "@/components/badge-list";
+import { BadgeList, toValueArray } from "@/components/badge-list";
import type {
BadgeCellOptions,
Column,
@@ -132,7 +132,7 @@ function renderDate(value: unknown, options: DateCellOptions | undefined): React
}
function renderBadge(value: unknown, options: BadgeCellOptions | undefined): ReactNode {
- const items = Array.isArray(value) ? value : value != null ? [value] : [];
+ const items = toValueArray(value);
const nonEmpty = items.filter((v) => v != null && v !== "");
if (nonEmpty.length === 0) return PLACEHOLDER;
return ;
diff --git a/packages/core/src/components/description-card/field-renderers.tsx b/packages/core/src/components/description-card/field-renderers.tsx
index 84a9bdee..413b1ad4 100644
--- a/packages/core/src/components/description-card/field-renderers.tsx
+++ b/packages/core/src/components/description-card/field-renderers.tsx
@@ -2,11 +2,10 @@
import * as React from "react";
import { Link } from "react-router";
-import { BadgeList } from "../badge-list";
+import { BadgeList, resolveBadgeLabel, toValueArray } from "../badge-list";
import { Tooltip } from "../tooltip";
import { Copy, Check, ExternalLink } from "lucide-react";
import type { ResolvedField, DateFormat } from "./types";
-import { resolveBadgeLabel } from "../badge-list";
import { useDescriptionCardT } from "./i18n";
// ============================================================================
@@ -336,11 +335,7 @@ function TextFieldRenderer({ field }: { field: ResolvedField }) {
* Render a badge field
*/
function BadgeFieldRenderer({ field }: { field: ResolvedField }) {
- const values = Array.isArray(field.value)
- ? (field.value as unknown[])
- : field.value != null
- ? [field.value]
- : [];
+ const values = toValueArray(field.value);
if (values.every((v) => isEmpty(v))) {
return {EMPTY_DASH};