UNPKG

@base-ui/react

Version:

Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.

108 lines (102 loc) 3.24 kB
'use client'; import * as React from 'react'; import { serializeValue } from "./serializeValue.js"; import { jsx as _jsx } from "react/jsx-runtime"; export function isGroupedItems(items) { return items != null && items.length > 0 && typeof items[0] === 'object' && items[0] != null && 'items' in items[0]; } /** * Checks if the items array contains an item with a null value that has a non-null label. */ export function hasNullItemLabel(items) { if (!Array.isArray(items)) { return items != null && 'null' in items; } const arrayItems = items; if (isGroupedItems(arrayItems)) { for (const group of arrayItems) { for (const item of group.items) { if (item && item.value == null && item.label != null) { return true; } } } return false; } for (const item of arrayItems) { if (item && item.value == null && item.label != null) { return true; } } return false; } export function stringifyAsLabel(item, itemToStringLabel) { if (itemToStringLabel && item != null) { return itemToStringLabel(item) ?? ''; } if (item && typeof item === 'object') { if ('label' in item && item.label != null) { return String(item.label); } if ('value' in item) { return String(item.value); } } return serializeValue(item); } export function stringifyAsValue(item, itemToStringValue) { if (itemToStringValue && item != null) { return itemToStringValue(item) ?? ''; } if (item && typeof item === 'object' && 'value' in item && 'label' in item) { return serializeValue(item.value); } return serializeValue(item); } export function resolveSelectedLabel(value, items, itemToStringLabel) { function fallback() { return stringifyAsLabel(value, itemToStringLabel); } if (itemToStringLabel && value != null) { return itemToStringLabel(value); } // Custom object with explicit label takes precedence if (value && typeof value === 'object' && 'label' in value && value.label != null) { return value.label; } // Items provided as plain record map if (items && !Array.isArray(items)) { return items[value] ?? fallback(); } // Items provided as array (flat or grouped) if (Array.isArray(items)) { const arrayItems = items; const flatItems = isGroupedItems(arrayItems) ? arrayItems.flatMap(group => group.items) : arrayItems; if (value == null || typeof value !== 'object') { const match = flatItems.find(item => item.value === value); if (match && match.label != null) { return match.label; } return fallback(); } // Object without explicit label: try matching by its `value` property if ('value' in value) { const match = flatItems.find(item => item && item.value === value.value); if (match && match.label != null) { return match.label; } } } return fallback(); } export function resolveMultipleLabels(values, items, itemToStringLabel) { return values.reduce((acc, value, index) => { if (index > 0) { acc.push(', '); } acc.push(/*#__PURE__*/_jsx(React.Fragment, { children: resolveSelectedLabel(value, items, itemToStringLabel) }, index)); return acc; }, []); }