ra-core
Version:
Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React
132 lines • 7.69 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useCreateSuggestionContext = exports.useSupportCreateSuggestion = void 0;
const React = __importStar(require("react"));
const react_1 = require("react");
const useTranslate_1 = require("../../i18n/useTranslate.cjs");
const set_js_1 = __importDefault(require("lodash/set.js"));
/**
* This hook provides support for suggestion creation in inputs which have choices.
*
* @param options The hook option
* @param {ReactElement} options.create A react element which will be rendered when users choose to create a new choice. This component must call the `useCreateSuggestionContext` hook which provides `onCancel`, `onCreate` and `filter`. See the examples.
* @param {React.ReactNode|string} options.createLabel Optional. The label for the choice item allowing users to create a new choice. Can be a translation key. Defaults to `ra.action.create`.
* @param {React.ReactNode|string} options.createItemLabel Optional. The label for the choice item allowing users to create a new choice when they already entered a filter. Can be a translation key. The function and ttranslation will receive an `item` parameter. Providing this option will turn the create label when there is no filter to be a hint (i.e. a disabled item).
* @param {any} options.createValue Optional. The value for the choice item allowing users to create a new choice. Defaults to `@@ra-create`.
* @param {any} options.createHintValue Optional. The value for the (disabled) item hinting users on how to create a new choice. Defaults to `@@ra-create-hint`.
* @param {String} options.filter Optional. The filter users may have already entered. Useful for autocomplete inputs for example.
* @param {OnCreateHandler} options.onCreate Optional. A function which will be called when users choose to create a new choice, if the `create` option wasn't provided.
* @param {Function} options.handleChange A function to pass to the input. Receives the same parameter as the original event handler and an additional newItem parameter if a new item was create.
*
* @returns {UseSupportCreateValue} An object with the following properties:
* - getCreateItem: a function which will return the label of the choice for create a new choice.
* - handleChange: a function which should be called when the input value changes. It will call the `onCreate` function if the value is the createValue.
* - createElement: a React element to render after the input. It will be rendered when users choose to create a new choice. It renders null otherwise.
* - getOptionDisabled: a function which should be passed to the input to disable the create choice when the filter is empty (to make it a hint).
*/
const useSupportCreateSuggestion = (options) => {
const { create, createLabel = 'ra.action.create', createItemLabel, createValue = '@@ra-create', createHintValue = '@@ra-create-hint', optionText = 'name', filter, handleChange, onCreate, } = options;
const translate = (0, useTranslate_1.useTranslate)();
const [renderOnCreate, setRenderOnCreate] = (0, react_1.useState)(false);
const filterRef = (0, react_1.useRef)(filter);
return {
createId: createValue,
createHintId: createHintValue,
getCreateItem: (filter) => {
filterRef.current = filter;
return (0, set_js_1.default)({
id: createItemLabel && !filter
? createHintValue
: createValue,
}, typeof optionText === 'string' ? optionText : 'name', filter && createItemLabel
? typeof createItemLabel === 'string'
? translate(createItemLabel, {
item: filter,
_: createItemLabel,
})
: createItemLabel(filter)
: typeof createLabel === 'string'
? translate(createLabel, { _: createLabel })
: createLabel);
},
handleChange: async (eventOrValue) => {
const value = eventOrValue?.target?.value || eventOrValue;
const finalValue = Array.isArray(value) ? [...value].pop() : value;
if (finalValue?.id === createValue || finalValue === createValue) {
if (!(0, react_1.isValidElement)(create)) {
if (!onCreate) {
// this should never happen because the createValue is only added if a create function is provided
// @see AutocompleteInput:filterOptions
throw new Error('To create a new option, you must pass an onCreate function or a create element.');
}
const newSuggestion = await onCreate(filter);
if (newSuggestion) {
handleChange(newSuggestion);
return;
}
}
else {
setRenderOnCreate(true);
return;
}
}
handleChange(eventOrValue);
},
createElement: renderOnCreate && (0, react_1.isValidElement)(create) ? (React.createElement(CreateSuggestionContext.Provider, { value: {
filter: filterRef.current,
onCancel: () => setRenderOnCreate(false),
onCreate: item => {
setRenderOnCreate(false);
handleChange(item);
},
} }, create)) : null,
getOptionDisabled: option => option?.id === createHintValue || option === createHintValue,
};
};
exports.useSupportCreateSuggestion = useSupportCreateSuggestion;
const CreateSuggestionContext = (0, react_1.createContext)(undefined);
const useCreateSuggestionContext = () => {
const context = (0, react_1.useContext)(CreateSuggestionContext);
if (!context) {
throw new Error('useCreateSuggestionContext must be used inside a CreateSuggestionContext.Provider');
}
return context;
};
exports.useCreateSuggestionContext = useCreateSuggestionContext;
//# sourceMappingURL=useSupportCreateSuggestion.js.map