UNPKG

ra-core

Version:

Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React

225 lines 10.1 kB
"use strict"; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSuggestionsFactory = exports.useSuggestions = void 0; var react_1 = require("react"); var set_1 = __importDefault(require("lodash/set")); var useChoices_1 = require("./choices/useChoices"); var i18n_1 = require("../i18n"); /* * Returns helper functions for suggestions handling. * * @param allowDuplicates A boolean indicating whether a suggestion can be added several times * @param choices An array of available choices * @param limitChoicesToValue A boolean indicating whether the initial suggestions should be limited to the currently selected one(s) * @param matchSuggestion Optional unless `optionText` is a React element. Function which check whether a choice matches a filter. Must return a boolean. * @param optionText Either a string defining the property to use to get the choice text, a function or a React element * @param optionValue The property to use to get the choice value * @param selectedItem The currently selected item. Maybe an array of selected items * @param suggestionLimit The maximum number of suggestions returned * @param translateChoice A boolean indicating whether to option text should be translated * * @returns An object with helper functions: * - getChoiceText: Returns the choice text or a React element * - getChoiceValue: Returns the choice value * - getSuggestions: A function taking a filter value (string) and returning the matching suggestions */ var useSuggestions = function (_a) { var allowCreate = _a.allowCreate, choices = _a.choices, _b = _a.createText, createText = _b === void 0 ? 'ra.action.create' : _b, _c = _a.createValue, createValue = _c === void 0 ? '@@create' : _c, _d = _a.createHintValue, createHintValue = _d === void 0 ? '@@ra-create-hint' : _d, limitChoicesToValue = _a.limitChoicesToValue, matchSuggestion = _a.matchSuggestion, optionText = _a.optionText, optionValue = _a.optionValue, selectedItem = _a.selectedItem, _e = _a.suggestionLimit, suggestionLimit = _e === void 0 ? 0 : _e, translateChoice = _a.translateChoice; var translate = (0, i18n_1.useTranslate)(); var _f = (0, useChoices_1.useChoices)({ optionText: optionText, optionValue: optionValue, translateChoice: translateChoice, createValue: createValue, createHintValue: createHintValue, }), getChoiceText = _f.getChoiceText, getChoiceValue = _f.getChoiceValue; // eslint-disable-next-line react-hooks/exhaustive-deps var getSuggestions = (0, react_1.useCallback)((0, exports.getSuggestionsFactory)({ allowCreate: allowCreate, choices: choices, createText: createText, createValue: createValue, getChoiceText: getChoiceText, getChoiceValue: getChoiceValue, limitChoicesToValue: limitChoicesToValue, matchSuggestion: matchSuggestion, optionText: optionText, optionValue: optionValue, selectedItem: selectedItem, suggestionLimit: suggestionLimit, }), [ allowCreate, choices, createText, createValue, getChoiceText, getChoiceValue, limitChoicesToValue, matchSuggestion, optionText, optionValue, selectedItem, suggestionLimit, translate, ]); return { getChoiceText: getChoiceText, getChoiceValue: getChoiceValue, getSuggestions: getSuggestions, }; }; exports.useSuggestions = useSuggestions; var escapeRegExp = function (value) { return value ? value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') : ''; }; // $& means the whole matched string /** * Default matcher implementation which check whether the suggestion text matches the filter. */ var defaultMatchSuggestion = function (getChoiceText) { return function (filter, suggestion, exact) { if (exact === void 0) { exact = false; } var suggestionText = getChoiceText(suggestion); var isReactElement = (0, react_1.isValidElement)(suggestionText); var regex = escapeRegExp(filter); return isReactElement ? false : suggestionText && !!suggestionText.match( // We must escape any RegExp reserved characters to avoid errors // For example, the filter might contain * which must be escaped as \* new RegExp(exact ? "^".concat(regex, "$") : regex, 'i')); }; }; /** * Get the suggestions to display after applying a fuzzy search on the available choices * * @example * * getSuggestions({ * choices: [{ id: 1, name: 'admin' }, { id: 2, name: 'publisher' }], * optionText: 'name', * optionValue: 'id', * getSuggestionText: choice => choice[optionText], * })('pub') * * // Will return [{ id: 2, name: 'publisher' }] * getSuggestions({ * choices: [{ id: 1, name: 'admin' }, { id: 2, name: 'publisher' }], * optionText: 'name', * optionValue: 'id', * getSuggestionText: choice => choice[optionText], * })('pub') * * // Will return [{ id: 2, name: 'publisher' }] */ var getSuggestionsFactory = function (_a) { var _b = _a.allowCreate, allowCreate = _b === void 0 ? false : _b, _c = _a.choices, choices = _c === void 0 ? [] : _c, _d = _a.createText, createText = _d === void 0 ? 'ra.action.create' : _d, _e = _a.createValue, createValue = _e === void 0 ? '@@create' : _e, _f = _a.optionText, optionText = _f === void 0 ? 'name' : _f, _g = _a.optionValue, optionValue = _g === void 0 ? 'id' : _g, getChoiceText = _a.getChoiceText, getChoiceValue = _a.getChoiceValue, _h = _a.limitChoicesToValue, limitChoicesToValue = _h === void 0 ? false : _h, _j = _a.matchSuggestion, matchSuggestion = _j === void 0 ? defaultMatchSuggestion(getChoiceText) : _j, selectedItem = _a.selectedItem, _k = _a.suggestionLimit, suggestionLimit = _k === void 0 ? 0 : _k; return function (filter) { var suggestions = []; // if an item is selected and matches the filter if (selectedItem && !Array.isArray(selectedItem) && matchSuggestion(filter, selectedItem)) { if (limitChoicesToValue) { // display only the selected item suggestions = choices.filter(function (choice) { return getChoiceValue(choice) === getChoiceValue(selectedItem); }); } else { suggestions = __spreadArray([], choices, true); } } else { suggestions = choices.filter(function (choice) { return matchSuggestion(filter, choice) || (selectedItem != null && (!Array.isArray(selectedItem) ? getChoiceValue(choice) === getChoiceValue(selectedItem) : selectedItem.some(function (selected) { return getChoiceValue(choice) === getChoiceValue(selected); }))); }); } suggestions = limitSuggestions(suggestions, suggestionLimit); var hasExactMatch = suggestions.some(function (suggestion) { return matchSuggestion(filter, suggestion, true); }); if (allowCreate) { var filterIsSelectedItem = // If the selectedItem is an array (for example AutocompleteArrayInput) // we shouldn't try to match !!selectedItem && !Array.isArray(selectedItem) ? matchSuggestion(filter, selectedItem, true) : false; if (!hasExactMatch && !filterIsSelectedItem) { suggestions.push(getSuggestion({ optionText: optionText, optionValue: optionValue, text: createText, value: createValue, })); } } // Only keep unique items. Necessary because we might have fetched // the currently selected choice in addition of the possible choices // that may also contain it var result = suggestions.filter(function (suggestion, index) { return suggestions.indexOf(suggestion) === index; }); return result; }; }; exports.getSuggestionsFactory = getSuggestionsFactory; /** * @example * * limitSuggestions( * [{ id: 1, name: 'foo'}, { id: 2, name: 'bar' }], * 1 * ); * * // Will return [{ id: 1, name: 'foo' }] * * @param suggestions List of suggestions * @param limit */ var limitSuggestions = function (suggestions, limit) { if (limit === void 0) { limit = 0; } return Number.isInteger(limit) && limit > 0 ? suggestions.slice(0, limit) : suggestions; }; /** * addSuggestion( * [{ id: 1, name: 'foo'}, { id: 2, name: 'bar' }], * ); * * // Will return [{ id: null, name: '' }, { id: 1, name: 'foo' }, { id: 2, name: 'bar' }] * * @param suggestions List of suggestions * @param options * @param options.optionText */ var getSuggestion = function (_a) { var _b = _a.optionText, optionText = _b === void 0 ? 'name' : _b, _c = _a.optionValue, optionValue = _c === void 0 ? 'id' : _c, _d = _a.text, text = _d === void 0 ? '' : _d, _e = _a.value, value = _e === void 0 ? null : _e; var suggestion = {}; (0, set_1.default)(suggestion, optionValue, value); if (typeof optionText === 'string') { (0, set_1.default)(suggestion, optionText, text); } return suggestion; }; //# sourceMappingURL=useSuggestions.js.map