@ariakit/react-core
Version:
Ariakit React core
129 lines (127 loc) • 3.86 kB
JavaScript
"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
};