UNPKG

@crossed/ui

Version:

A universal & performant styling library for React Native, Next.js & React

152 lines (151 loc) 4.62 kB
import { Fragment, jsx, jsxs } from "react/jsx-runtime"; import { forwardRef, memo, useCallback, useEffect, useMemo, useRef, useState } from "react"; import { Floating } from "../../overlay/Floating"; import { SelectConfigProvider, SelectValueProvider, useSelectConfig, useSelectValue } from "./context"; import { composeStyles, createStyles, inlineStyle, useTheme } from "@crossed/styled"; import { FadeIn, FadeOut } from "react-native-reanimated"; import { MenuList } from "../../display"; import { form } from "../../styles/form"; import { Input } from "../Input"; import Fuse from "fuse.js"; import { useSelect } from "./styles"; import { Focus } from "./Focus"; import { useFloatingContext } from "../../overlay/Floating/context"; import { Sheet } from "../../overlay/Sheet"; import { Spinner } from "../../display/Spinner"; import { gapStyles } from "../../styles"; import { List } from "./List"; const duration = 100; const styles = createStyles(() => ({ dynamic: (e) => e })); const SelectContent = memo( forwardRef(({ floatingStyles, onSearch, loading }, ref) => { useTheme(); const { onClose, open } = useFloatingContext(); const selectValue = useSelectValue(); const { items } = selectValue; const configContext = useSelectConfig(); const { searchable, showSheet } = configContext; const [search, setSearch] = useState(""); const handleChangeSearch = useCallback( (value) => { setSearch(value); if (onSearch) onSearch(value); }, [onSearch, setSearch] ); const fuse = useMemo( () => new Fuse(items, { keys: ["search", "value"] }), [items] ); const data = useMemo(() => { return search && !onSearch ? fuse.search(search).map(({ item }) => item) : items; }, [fuse, search, items, onSearch]); useEffect(() => { var _a, _b; if (!open) { (_a = totoRef.current) == null ? void 0 : _a.hide(); setSearch(""); } else { (_b = totoRef.current) == null ? void 0 : _b.show(); } }, [open]); const renderSearch = searchable ? /* @__PURE__ */ jsx( Input, { formFieldStyle: inlineStyle(({ space }) => ({ base: { flexGrow: 0, marginTop: space.xxs, marginHorizontal: space.xs } })), value: search, onChangeText: handleChangeSearch, clearable: true, autoFocus: true } ) : null; const totoRef = useRef(); return /* @__PURE__ */ jsx(Fragment, { children: showSheet ? /* @__PURE__ */ jsx( Sheet.Content, { ref: totoRef, onClose, containerStyle: composeStyles( searchable && inlineStyle(() => ({ base: { height: "100%" } })) ), children: /* @__PURE__ */ jsxs(Sheet.Padded, { testID: "content-select", children: [ /* @__PURE__ */ jsx(MenuList.Item, { children: renderSearch }), loading ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx(List, { data }) ] }) } ) : /* @__PURE__ */ jsx(Floating.Portal, { children: /* @__PURE__ */ jsx( Focus, { onEscapeKey: onClose, onClickOutside: onClose, enabled: open, children: /* @__PURE__ */ jsx( Floating.Content, { exiting: FadeOut.duration(duration), entering: FadeIn.duration(duration), style: composeStyles( inlineStyle(({ boxShadow }) => ({ base: { zIndex: 100 }, web: { base: { boxShadow } } })) ), children: /* @__PURE__ */ jsx(SelectConfigProvider, { ...configContext, children: /* @__PURE__ */ jsx(SelectValueProvider, { ...selectValue, children: /* @__PURE__ */ jsxs( MenuList, { testID: "content-select", ref, style: composeStyles( form.input, useSelect.content, gapStyles.xs, inlineStyle(() => ({ web: { base: { overflowY: "auto" } } })), styles.dynamic(floatingStyles) ), children: [ renderSearch, loading ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx(List, { data }) ] } ) }) }) } ) } ) }) }); }) ); export { SelectContent }; //# sourceMappingURL=Content.js.map