UNPKG

@ariakit/react-core

Version:

Ariakit React core

129 lines (127 loc) 3.86 kB
"use client"; import { ComboboxItemValueContext, useComboboxScopedContext } from "../__chunks/OLVWQA7U.js"; import "../__chunks/Y67KZUMI.js"; import "../__chunks/T2AZQXQU.js"; import "../__chunks/ABN76PSX.js"; import "../__chunks/APTFW6PT.js"; import { useStoreState } from "../__chunks/RTNCFSKZ.js"; import "../__chunks/5CPL3B7G.js"; import { createElement, createHook, forwardRef } from "../__chunks/VOQWLFSQ.js"; import "../__chunks/5GGHRIN3.js"; import "../__chunks/SK3NAZA3.js"; import { __objRest, __spreadValues } from "../__chunks/3YLGPPWQ.js"; // src/combobox/combobox-item-value.tsx import { toArray } from "@ariakit/core/utils/array"; import { normalizeString, removeUndefinedValues } from "@ariakit/core/utils/misc"; import { useContext, useMemo } from "react"; import { jsx } from "react/jsx-runtime"; var TagName = "span"; function normalizeValue(value) { return normalizeString(value).toLowerCase(); } function getOffsets(string, values) { const offsets = []; for (const value of values) { let pos = 0; const length = value.length; while (string.indexOf(value, pos) !== -1) { const index = string.indexOf(value, pos); if (index !== -1) { offsets.push([index, length]); } pos = index + 1; } } return offsets; } function filterOverlappingOffsets(offsets) { return offsets.filter(([offset, length], i, arr) => { return !arr.some( ([o, l], j) => j !== i && o <= offset && o + l >= offset + length ); }); } function sortOffsets(offsets) { return offsets.sort(([a], [b]) => a - b); } function splitValue(itemValue, userValue) { if (!itemValue) return itemValue; if (!userValue) return itemValue; const userValues = toArray(userValue).filter(Boolean).map(normalizeValue); const parts = []; const span = (value, autocomplete = false) => /* @__PURE__ */ jsx( "span", { "data-autocomplete-value": autocomplete ? "" : void 0, "data-user-value": autocomplete ? void 0 : "", children: value }, parts.length ); const offsets = sortOffsets( filterOverlappingOffsets( // Convert userValues into a set to avoid duplicates getOffsets(normalizeValue(itemValue), new Set(userValues)) ) ); if (!offsets.length) { parts.push(span(itemValue, true)); return parts; } const [firstOffset] = offsets[0]; const values = [ itemValue.slice(0, firstOffset), ...offsets.flatMap(([offset, length], i) => { var _a; const value = itemValue.slice(offset, offset + length); const nextOffset = (_a = offsets[i + 1]) == null ? void 0 : _a[0]; const nextValue = itemValue.slice(offset + length, nextOffset); return [value, nextValue]; }) ]; values.forEach((value, i) => { if (!value) return; parts.push(span(value, i % 2 === 0)); }); return parts; } var useComboboxItemValue = createHook(function useComboboxItemValue2(_a) { var _b = _a, { store, value, userValue } = _b, props = __objRest(_b, ["store", "value", "userValue"]); const context = useComboboxScopedContext(); store = store || context; const itemContext = useContext(ComboboxItemValueContext); const itemValue = value != null ? value : itemContext; const inputValue = useStoreState(store, (state) => userValue != null ? userValue : state == null ? void 0 : state.value); const children = useMemo(() => { if (!itemValue) return; if (!inputValue) return itemValue; return splitValue(itemValue, inputValue); }, [itemValue, inputValue]); props = __spreadValues({ children }, props); return removeUndefinedValues(props); }); var ComboboxItemValue = forwardRef(function ComboboxItemValue2(props) { const htmlProps = useComboboxItemValue(props); return createElement(TagName, htmlProps); }); export { ComboboxItemValue, useComboboxItemValue };