@ariakit/react-core
Version:
Ariakit React core
166 lines (163 loc) • 4.85 kB
JavaScript
"use client";
import {
SelectItemCheckedContext,
useSelectScopedContext
} from "./QI6TYHPV.js";
import {
useCompositeHover
} from "./RIJYZEV5.js";
import {
useCompositeItem
} from "./FIT2LC3L.js";
import {
useStoreStateObject
} from "./Q3KUZPD7.js";
import {
createElement,
createHook,
forwardRef,
memo
} from "./ILRXHV7V.js";
import {
useBooleanEvent,
useEvent,
useId,
useWrapElement
} from "./K2XTQB3X.js";
// src/select/select-item.tsx
import { getPopupItemRole } from "@ariakit/core/utils/dom";
import { isDownloading, isOpeningInNewTab } from "@ariakit/core/utils/events";
import { disabledFromProps, invariant } from "@ariakit/core/utils/misc";
import { useCallback } from "react";
import { jsx } from "react/jsx-runtime";
var TagName = "div";
function isSelected(storeValue, itemValue) {
if (itemValue == null) return;
if (storeValue == null) return false;
if (Array.isArray(storeValue)) {
return storeValue.includes(itemValue);
}
return storeValue === itemValue;
}
var useSelectItem = createHook(
function useSelectItem2({
store,
value,
getItem: getItemProp,
hideOnClick,
setValueOnClick = value != null,
preventScrollOnKeyDown = true,
focusOnHover = true,
...props
}) {
var _a;
const context = useSelectScopedContext();
store = store || context;
invariant(
store,
process.env.NODE_ENV !== "production" && "SelectItem must be wrapped in a SelectList or SelectPopover component."
);
const id = useId(props.id);
const disabled = disabledFromProps(props);
const { listElement, multiSelectable, selected, autoFocus } = useStoreStateObject(store, {
listElement: "listElement",
multiSelectable(state) {
return Array.isArray(state.value);
},
selected(state) {
return isSelected(state.value, value);
},
autoFocus(state) {
if (value == null) return false;
if (state.value == null) return false;
if (state.activeId !== id && (store == null ? void 0 : store.item(state.activeId))) {
return false;
}
if (Array.isArray(state.value)) {
return state.value[state.value.length - 1] === value;
}
return state.value === value;
}
});
const getItem = useCallback(
(item) => {
const nextItem = {
...item,
value: disabled ? void 0 : value,
children: value
};
if (getItemProp) {
return getItemProp(nextItem);
}
return nextItem;
},
[disabled, value, getItemProp]
);
hideOnClick = hideOnClick != null ? hideOnClick : value != null && !multiSelectable;
const onClickProp = props.onClick;
const setValueOnClickProp = useBooleanEvent(setValueOnClick);
const hideOnClickProp = useBooleanEvent(hideOnClick);
const onClick = useEvent((event) => {
onClickProp == null ? void 0 : onClickProp(event);
if (event.defaultPrevented) return;
if (isDownloading(event)) return;
if (isOpeningInNewTab(event)) return;
if (setValueOnClickProp(event) && value != null) {
store == null ? void 0 : store.setValue((prevValue) => {
if (!Array.isArray(prevValue)) return value;
if (prevValue.includes(value)) {
return prevValue.filter((v) => v !== value);
}
return [...prevValue, value];
});
}
if (hideOnClickProp(event)) {
store == null ? void 0 : store.hide();
}
});
props = useWrapElement(
props,
(element) => /* @__PURE__ */ jsx(SelectItemCheckedContext.Provider, { value: selected != null ? selected : false, children: element }),
[selected]
);
props = {
id,
role: getPopupItemRole(listElement),
"aria-selected": selected,
children: value,
...props,
autoFocus: (_a = props.autoFocus) != null ? _a : autoFocus,
onClick
};
props = useCompositeItem({
store,
getItem,
preventScrollOnKeyDown,
...props
});
const focusOnHoverProp = useBooleanEvent(focusOnHover);
props = useCompositeHover({
store,
...props,
// We have to disable focusOnHover when the popup is closed, otherwise
// the active item will change to null (the container) when the popup is
// closed by clicking on an item.
focusOnHover(event) {
if (!focusOnHoverProp(event)) return false;
const state = store == null ? void 0 : store.getState();
return !!(state == null ? void 0 : state.open);
}
});
return props;
}
);
var SelectItem = memo(
forwardRef(function SelectItem2(props) {
const htmlProps = useSelectItem(props);
return createElement(TagName, htmlProps);
})
);
export {
useSelectItem,
SelectItem
};