-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
/
useChoices.ts
89 lines (76 loc) · 2.63 KB
/
useChoices.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { ReactElement, isValidElement, cloneElement, useCallback } from 'react';
import get from 'lodash/get';
import { useTranslate } from '../i18n';
import { Record } from '../types';
import { InputProps } from '.';
export type OptionTextElement = ReactElement<{
record: Record;
}>;
export type OptionText = (choice: object) => string | OptionTextElement;
export interface ChoicesInputProps<T = any>
extends Omit<InputProps<T>, 'source'> {
// Optional as choices inputs can be used inside Reference inputs which inject the source
source?: string;
// Optional as choices inputs can be used inside Reference inputs which inject the choices
choices?: object[];
}
export interface ChoicesProps {
choices: object[];
optionValue?: string;
optionText?: OptionTextElement | OptionText | string;
translateChoice?: boolean;
}
export interface UseChoicesOptions {
optionValue?: string;
optionText?: OptionTextElement | OptionText | string;
disableValue?: string;
translateChoice?: boolean;
}
/*
* Returns helper functions for choices handling.
*
* @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 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
*/
const useChoices = ({
optionText = 'name',
optionValue = 'id',
disableValue = 'disabled',
translateChoice = true,
}: UseChoicesOptions) => {
const translate = useTranslate();
const getChoiceText = useCallback(
choice => {
if (isValidElement<{ record: any }>(optionText)) {
return cloneElement<{ record: any }>(optionText, {
record: choice,
});
}
const choiceName =
typeof optionText === 'function'
? optionText(choice)
: get(choice, optionText);
return translateChoice
? translate(choiceName, { _: choiceName })
: choiceName;
},
[optionText, translate, translateChoice]
);
const getChoiceValue = useCallback(choice => get(choice, optionValue), [
optionValue,
]);
const getDisableValue = useCallback(choice => get(choice, disableValue), [
disableValue,
]);
return {
getChoiceText,
getChoiceValue,
getDisableValue,
};
};
export default useChoices;