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};