@true-engineering/true-react-common-ui-kit 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Input/Input.styles.d.ts +1 -0
- package/dist/components/Select/Select.d.ts +12 -3
- package/dist/components/Select/Select.styles.d.ts +10 -0
- package/dist/components/Select/SelectList/SelectList.d.ts +6 -4
- package/dist/components/Select/SelectList/SelectList.styles.d.ts +5 -0
- package/dist/components/Select/SelectListItem/SelectListItem.d.ts +14 -0
- package/dist/components/Select/SelectListItem/SelectListItem.styles.d.ts +2 -0
- package/dist/components/Select/constants.d.ts +2 -0
- package/dist/components/Select/helpers.d.ts +4 -1
- package/dist/components/Select/index.d.ts +1 -0
- package/dist/components/Select/types.d.ts +1 -0
- package/dist/helpers/utils.d.ts +2 -0
- package/dist/true-react-common-ui-kit.js +340 -163
- package/dist/true-react-common-ui-kit.js.map +1 -1
- package/dist/true-react-common-ui-kit.umd.cjs +340 -163
- package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Input/Input.styles.ts +2 -0
- package/src/components/Input/Input.tsx +4 -1
- package/src/components/Select/MultiSelect.stories.tsx +262 -0
- package/src/components/Select/Select.styles.ts +13 -0
- package/src/components/Select/Select.tsx +215 -114
- package/src/components/Select/SelectList/SelectList.styles.ts +6 -2
- package/src/components/Select/SelectList/SelectList.tsx +64 -39
- package/src/components/Select/SelectListItem/SelectListItem.styles.ts +14 -0
- package/src/components/Select/SelectListItem/SelectListItem.tsx +73 -0
- package/src/components/Select/constants.ts +2 -0
- package/src/components/Select/helpers.ts +16 -8
- package/src/components/Select/index.ts +1 -0
- package/src/components/Select/types.ts +1 -0
- package/src/helpers/utils.ts +29 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CheckboxStyles } from '../../Checkbox';
|
|
2
|
+
import { CELL_PADDING } from '../SelectList/SelectList.styles';
|
|
3
|
+
|
|
4
|
+
export const checkboxStyles: CheckboxStyles = {
|
|
5
|
+
root: {
|
|
6
|
+
padding: CELL_PADDING,
|
|
7
|
+
width: '100%',
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
input: {
|
|
11
|
+
// иначе будет фокуситься и энтер будет вызывать изменение нескольких опций
|
|
12
|
+
display: 'none',
|
|
13
|
+
},
|
|
14
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ReactNode, MouseEvent, FC } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { ScrollIntoViewIfNeeded } from '../../ScrollIntoViewIfNeeded';
|
|
4
|
+
import { addDataAttributes, isNotEmpty } from '../../../helpers';
|
|
5
|
+
import { checkboxStyles } from './SelectListItem.styles';
|
|
6
|
+
import { Checkbox } from '../../Checkbox';
|
|
7
|
+
import { Classes } from 'jss';
|
|
8
|
+
|
|
9
|
+
export interface ISelectListItemProps {
|
|
10
|
+
index: number;
|
|
11
|
+
isSemiChecked?: boolean;
|
|
12
|
+
isDisabled?: boolean;
|
|
13
|
+
isActive?: boolean;
|
|
14
|
+
isFocused?: boolean;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
classes: Classes<
|
|
17
|
+
'cellWithCheckbox' | 'cell' | 'focused' | 'active' | 'disabled'
|
|
18
|
+
>;
|
|
19
|
+
onOptionSelect(index: number, event: MouseEvent<HTMLElement>): void;
|
|
20
|
+
onToggleCheckbox?(index: number, isSelected: boolean): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const SelectListItem: FC<ISelectListItemProps> = ({
|
|
24
|
+
classes,
|
|
25
|
+
index,
|
|
26
|
+
isSemiChecked,
|
|
27
|
+
isDisabled,
|
|
28
|
+
isActive,
|
|
29
|
+
children,
|
|
30
|
+
isFocused,
|
|
31
|
+
onOptionSelect,
|
|
32
|
+
onToggleCheckbox,
|
|
33
|
+
}) => {
|
|
34
|
+
const isMultiSelect = isNotEmpty(onToggleCheckbox);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<ScrollIntoViewIfNeeded
|
|
38
|
+
active={isFocused}
|
|
39
|
+
options={{ block: 'nearest' }}
|
|
40
|
+
className={clsx(classes.cell, {
|
|
41
|
+
[classes.cellWithCheckbox]: isMultiSelect,
|
|
42
|
+
[classes.focused]: isFocused,
|
|
43
|
+
[classes.active]: isActive && !isMultiSelect,
|
|
44
|
+
[classes.disabled]: isDisabled,
|
|
45
|
+
})}
|
|
46
|
+
{...addDataAttributes({
|
|
47
|
+
disabled: isDisabled,
|
|
48
|
+
active: isActive,
|
|
49
|
+
focused: isFocused,
|
|
50
|
+
})}
|
|
51
|
+
onClick={
|
|
52
|
+
!isDisabled && !isMultiSelect
|
|
53
|
+
? (event) => onOptionSelect(index, event)
|
|
54
|
+
: undefined
|
|
55
|
+
}
|
|
56
|
+
>
|
|
57
|
+
{isMultiSelect ? (
|
|
58
|
+
<Checkbox
|
|
59
|
+
value={index}
|
|
60
|
+
isChecked={isActive || isSemiChecked}
|
|
61
|
+
isSemiChecked={isSemiChecked}
|
|
62
|
+
isDisabled={isDisabled}
|
|
63
|
+
tweakStyles={checkboxStyles}
|
|
64
|
+
onSelect={(v) => onToggleCheckbox(index, v.isSelected)}
|
|
65
|
+
>
|
|
66
|
+
{children}
|
|
67
|
+
</Checkbox>
|
|
68
|
+
) : (
|
|
69
|
+
children
|
|
70
|
+
)}
|
|
71
|
+
</ScrollIntoViewIfNeeded>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { isNotEmpty } from '../../helpers';
|
|
2
|
+
import type { IMultipleSelectProps, ISelectProps } from './Select';
|
|
3
|
+
import { IMultipleSelectValue } from './types';
|
|
2
4
|
|
|
3
5
|
export const defaultIsOptionDisabled = <Value>(option: Value): boolean =>
|
|
4
6
|
typeof option === 'object' &&
|
|
@@ -11,11 +13,17 @@ export const defaultConvertFunction = (v: unknown) =>
|
|
|
11
13
|
export const defaultCompareFunction = <Value>(v1: Value, v2: Value) =>
|
|
12
14
|
v1 === v2;
|
|
13
15
|
|
|
14
|
-
export const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
export const getDefaultConvertToIdFunction =
|
|
17
|
+
<Value>(
|
|
18
|
+
convertValueToString: (value: Value) => string | undefined,
|
|
19
|
+
): ((value: Value) => string | undefined) =>
|
|
20
|
+
(value) =>
|
|
21
|
+
isNotEmpty((value as { id: unknown })?.id)
|
|
22
|
+
? String((value as { id: unknown }).id)
|
|
23
|
+
: convertValueToString(value);
|
|
24
|
+
|
|
25
|
+
export const isMultiSelectValue = <Value>(
|
|
26
|
+
props: ISelectProps<Value> | IMultipleSelectProps<Value>,
|
|
27
|
+
_value: Value | IMultipleSelectValue<Value> | undefined,
|
|
28
|
+
): _value is IMultipleSelectValue<Value> | undefined =>
|
|
29
|
+
props.isMultiSelect === true;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type IMultipleSelectValue<Value> = Array<NonNullable<Value>>;
|
package/src/helpers/utils.ts
CHANGED
|
@@ -169,6 +169,13 @@ export const isNotEmpty = <T>(val: T | null | undefined): val is T =>
|
|
|
169
169
|
? val.trim() !== ''
|
|
170
170
|
: val !== null && val !== undefined;
|
|
171
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Проверяет, что передана непустая строка
|
|
174
|
+
*/
|
|
175
|
+
export const isStringNotEmpty = <T extends string>(
|
|
176
|
+
value: T | undefined | null,
|
|
177
|
+
): value is T => (value ?? '').trim() !== '';
|
|
178
|
+
|
|
172
179
|
export const trimStringToMaxLength = (val: string, maxLength: number) =>
|
|
173
180
|
val.length > maxLength ? val.slice(0, maxLength) : val;
|
|
174
181
|
|
|
@@ -219,3 +226,25 @@ export const addClickHandler = (
|
|
|
219
226
|
: {
|
|
220
227
|
tabIndex: -1,
|
|
221
228
|
};
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Позволяет создать текстовый фильтр для набора items
|
|
232
|
+
* @param getter - функция возвращающая набор строковых значений из каждого item,
|
|
233
|
+
* по которым должен осуществляться поиск
|
|
234
|
+
*/
|
|
235
|
+
export const createFilter =
|
|
236
|
+
<T>(
|
|
237
|
+
getter: (item: T) => Array<string | undefined>,
|
|
238
|
+
): ((items: T[], query: string) => T[]) =>
|
|
239
|
+
(items, query) =>
|
|
240
|
+
items.filter((item) => {
|
|
241
|
+
const possibleValues = getter(item).reduce(
|
|
242
|
+
(acc, cur) => [
|
|
243
|
+
...acc,
|
|
244
|
+
...(isStringNotEmpty(cur) ? [cur?.toLowerCase()] : []),
|
|
245
|
+
],
|
|
246
|
+
[] as string[],
|
|
247
|
+
);
|
|
248
|
+
const queryString = query.toLowerCase().trim();
|
|
249
|
+
return possibleValues.some((v) => v?.includes(queryString));
|
|
250
|
+
});
|