@yamada-ui/autocomplete
Version:
Yamada UI autocomplete component
255 lines (252 loc) • 8.12 kB
JavaScript
"use client"
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/use-autocomplete-option.ts
var use_autocomplete_option_exports = {};
__export(use_autocomplete_option_exports, {
useAutocompleteCreate: () => useAutocompleteCreate,
useAutocompleteEmpty: () => useAutocompleteEmpty,
useAutocompleteOption: () => useAutocompleteOption
});
module.exports = __toCommonJS(use_autocomplete_option_exports);
var import_utils2 = require("@yamada-ui/utils");
var import_react = require("react");
// src/autocomplete-context.ts
var import_use_descendant = require("@yamada-ui/use-descendant");
var import_utils = require("@yamada-ui/utils");
var {
DescendantsContextProvider: AutocompleteDescendantsContextProvider,
useDescendant: useAutocompleteDescendant,
useDescendants: useAutocompleteDescendants,
useDescendantsContext: useAutocompleteDescendantsContext
} = (0, import_use_descendant.createDescendant)();
var [AutocompleteProvider, useAutocompleteContext] = (0, import_utils.createContext)({
name: "AutocompleteContext",
errorMessage: `useAutocompleteContext returned is 'undefined'. Seems you forgot to wrap the components in "<Autocomplete />" or "<MultiAutocomplete />"`
});
// src/use-autocomplete-option.ts
var isTargetOption = (target) => {
var _a;
return (0, import_utils2.isHTMLElement)(target) && !!((_a = target.getAttribute("role")) == null ? void 0 : _a.startsWith("option"));
};
var useAutocompleteOption = (props) => {
var _a, _b;
const {
closeOnSelect,
focusedIndex,
inputRef,
omitSelectedValues,
setFocusedIndex,
value: selectedValue,
optionProps,
onChange,
onClose,
onFocusNext
} = useAutocompleteContext();
const uuid = (0, import_react.useId)();
const itemRef = (0, import_react.useRef)(null);
const {
id = uuid,
children,
closeOnSelect: customCloseOnSelect,
isDisabled,
disabled = isDisabled,
isFocusable,
focusable = isFocusable,
icon: customIcon,
value: optionValue,
...computedProps
} = { ...optionProps, ...props };
const trulyDisabled = !!disabled && !focusable;
const { descendants, index, register } = useAutocompleteDescendant({
disabled: trulyDisabled
});
const values = descendants.values();
const frontValues = values.slice(0, index);
const multi = (0, import_utils2.isArray)(selectedValue);
const target = "target" in ((_b = (_a = itemRef.current) == null ? void 0 : _a.dataset) != null ? _b : {});
const focused = index === focusedIndex;
const value = (0, import_react.useMemo)(() => {
let value2 = optionValue;
if ((0, import_utils2.isUndefined)(optionValue)) {
if ((0, import_utils2.isString)(children) || (0, import_utils2.isNumber)(children)) {
value2 = children.toString();
} else {
console.warn(
`${!multi ? "Autocomplete" : "MultiAutocomplete"}: Cannot infer the option value of complex children. Pass a \`value\` prop or use a plain string as children to <Option>.`
);
}
}
return value2 != null ? value2 : "";
}, [children, multi, optionValue]);
const duplicated = frontValues.some(
({ node }) => node.dataset.value === value
);
const selected = !duplicated && (!multi ? value === selectedValue : selectedValue.includes(value));
const onClick = (0, import_react.useCallback)(
(ev) => {
ev.stopPropagation();
if (disabled || !isTargetOption(ev.currentTarget)) {
if (inputRef.current) inputRef.current.focus();
return;
}
if (!duplicated) setFocusedIndex(index);
onChange(value);
if (inputRef.current) inputRef.current.focus();
if (customCloseOnSelect != null ? customCloseOnSelect : closeOnSelect) onClose();
if (omitSelectedValues) onFocusNext(index);
},
[
duplicated,
onFocusNext,
omitSelectedValues,
disabled,
value,
setFocusedIndex,
index,
onChange,
customCloseOnSelect,
closeOnSelect,
onClose,
inputRef
]
);
const getOptionProps = (0, import_react.useCallback)(
(props2 = {}, ref = null) => {
const hidden = !target || omitSelectedValues && selected;
const style = {
border: "0px",
clip: "rect(0px, 0px, 0px, 0px)",
height: "1px",
margin: "-1px",
overflow: "hidden",
padding: "0px",
position: "absolute",
whiteSpace: "nowrap",
width: "1px"
};
return {
ref: (0, import_utils2.mergeRefs)(itemRef, ref, register),
role: "option",
...computedProps,
...props2,
id,
style: hidden ? style : void 0,
"aria-disabled": (0, import_utils2.ariaAttr)(disabled),
"aria-hidden": (0, import_utils2.ariaAttr)(hidden),
"aria-selected": selected,
"data-disabled": (0, import_utils2.dataAttr)(disabled),
"data-duplicated": (0, import_utils2.dataAttr)(duplicated),
"data-focus": (0, import_utils2.dataAttr)(focused),
"data-target": (0, import_utils2.dataAttr)(true),
"data-value": value,
tabIndex: -1,
onClick: (0, import_utils2.handlerAll)(computedProps.onClick, props2.onClick, onClick)
};
},
[
id,
duplicated,
value,
computedProps,
disabled,
focused,
selected,
target,
omitSelectedValues,
onClick,
register
]
);
return {
target,
children,
customIcon,
focused,
omitSelectedValues,
selected,
getOptionProps
};
};
var useAutocompleteCreate = () => {
const { hit, onCreate } = useAutocompleteContext();
const getCreateProps = (0, import_react.useCallback)(
(props = {}, ref = null) => {
const style = {
border: "0px",
clip: "rect(0px, 0px, 0px, 0px)",
height: "1px",
margin: "-1px",
overflow: "hidden",
padding: "0px",
position: "absolute",
whiteSpace: "nowrap",
width: "1px"
};
return {
ref,
role: "option",
...props,
style: hit ? style : void 0,
"aria-hidden": (0, import_utils2.ariaAttr)(hit),
"data-focus": (0, import_utils2.dataAttr)(!hit),
tabIndex: -1,
onClick: (0, import_utils2.handlerAll)(props.onClick, onCreate)
};
},
[hit, onCreate]
);
return { getCreateProps };
};
var useAutocompleteEmpty = () => {
const { empty, hit } = useAutocompleteContext();
const getEmptyProps = (0, import_react.useCallback)(
(props = {}, ref = null) => {
const hidden = hit && !empty;
const style = {
border: "0px",
clip: "rect(0px, 0px, 0px, 0px)",
height: "1px",
margin: "-1px",
overflow: "hidden",
padding: "0px",
position: "absolute",
whiteSpace: "nowrap",
width: "1px"
};
return {
ref,
role: "presentation",
...props,
style: hidden ? style : void 0,
"aria-hidden": (0, import_utils2.ariaAttr)(hidden),
tabIndex: -1
};
},
[hit, empty]
);
return { getEmptyProps };
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
useAutocompleteCreate,
useAutocompleteEmpty,
useAutocompleteOption
});
//# sourceMappingURL=use-autocomplete-option.js.map