@steroidsjs/core 3.0.5 → 3.0.7

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.
Files changed (39) hide show
  1. package/actions/auth.d.ts +2 -2
  2. package/actions/list.d.ts +2 -2
  3. package/actions/router.d.ts +1 -3
  4. package/components/HttpComponent.d.ts +1 -1
  5. package/docs-autogen-result.json +235 -108
  6. package/en.json +5 -1
  7. package/hooks/useDataProvider.d.ts +1 -1
  8. package/hooks/useDataSelect.d.ts +1 -1
  9. package/hooks/useFile.d.ts +5 -5
  10. package/hooks/useForm.d.ts +2 -1
  11. package/hooks/useTree.d.ts +10 -0
  12. package/hooks/useTree.js +26 -1
  13. package/index.d.ts +10 -0
  14. package/package.json +1 -1
  15. package/ui/form/Button/Button.d.ts +3 -3
  16. package/ui/form/CheckboxTreeField/CheckboxTreeField.d.ts +3 -3
  17. package/ui/form/CheckboxTreeField/CheckboxTreeField.js +11 -7
  18. package/ui/form/DateField/DateField.d.ts +1 -1
  19. package/ui/form/Field/Field.d.ts +1 -1
  20. package/ui/form/FieldList/FieldList.d.ts +3 -3
  21. package/ui/form/FieldSet/FieldSet.d.ts +2 -2
  22. package/ui/form/FileField/FileField.d.ts +1 -1
  23. package/ui/form/FileField/FileField.js +4 -5
  24. package/ui/form/Form/Form.d.ts +4 -3
  25. package/ui/form/NumberField/NumberField.d.ts +4 -0
  26. package/ui/form/NumberField/NumberField.js +14 -4
  27. package/ui/form/NumberField/hooks/useInputTypeNumber.d.ts +2 -1
  28. package/ui/form/NumberField/hooks/useInputTypeNumber.js +18 -11
  29. package/ui/form/TimeField/TimeField.d.ts +1 -1
  30. package/ui/form/TimeRangeField/TimeRangeField.d.ts +1 -1
  31. package/ui/layout/Tooltip/Tooltip.d.ts +2 -2
  32. package/ui/list/List/List.d.ts +3 -3
  33. package/ui/list/TreeTable/TreeTable.d.ts +2 -1
  34. package/ui/list/TreeTable/TreeTable.js +5 -2
  35. package/ui/nav/Breadcrumbs/Breadcrumbs.d.ts +2 -2
  36. package/ui/nav/Controls/Controls.d.ts +1 -1
  37. package/ui/nav/Nav/Nav.d.ts +3 -3
  38. package/ui/nav/Tree/Tree.d.ts +1 -1
  39. package/ui/nav/Tree/Tree.js +5 -2
package/en.json CHANGED
@@ -979,11 +979,15 @@
979
979
  "Скрыть иконку c лева от элемента": "",
980
980
  "\nКомпонент `Kanban` позволяет создать доску для управления задачами.\nКоличество столбцов задается с помощью пропа `columns`.\nЗадачи на доске можно создавать, редактировать и перемещать с визуальным отображением.\n\nДля работы этого компонента необходимо установить в проекте зависимости `react-beautiful-dnd`\nи передать в пропсы `droppableComponent`, `draggableComponent` и `dndContext`\nкомпоненты `Droppable`, `Draggable` и `DragDropContext` соответственно.\n\nДля корректной работы функционала создания задач,\nнеобходимо установить в проекте зависимости `@ckeditor/ckeditor5-react` и `@steroidsjs/ckeditor5`,\nзатем импортировать `CKEditor` из `@ckeditor/ckeditor5-react` и `ClassicEditor` из `@steroidsjs/ckeditor5/packages/ckeditor5-build-classic`.\nИмпортированные компоненты нужно передать в проп `createTaskEditorConfig`,\nв поле `htmlComponent` передать `CKEditor`, а в `editorConstructor` передать `ClassicEditor`.\n": "",
981
981
  "Компонент для создания HTML-разметки, использующий WYSIWYG редактор.\n\nДля использования WYSIWYG редактора, необходимо установить в проекте зависимости `@ckeditor/ckeditor5-react` и `@steroidsjs/ckeditor5`,\nзатем импортировать `CKEditor` из `@ckeditor/ckeditor5-react` и `ClassicEditor` из `@steroidsjs/ckeditor5/packages/ckeditor5-build-classic`.\nКомпонент `CKEditor` нужно передать в проп `htmlComponent`, а конструктор `ClassicEditor` в проп `editorConstructor`.\n\nПри передаче `HtmlField` с бэкенда, необходимо переопределить `view` компонента, указав локальный.\nВ локальном компоненте добавить вместо пропсов `htmlComponent` и `editorConstructor` импорты `CKEditor` и `ClassicEditor` соотвественно.\n": "",
982
+ "Идентификатор (ключ) для сохранения в LocalStorage коллекции.": "",
983
+ "Сохранение в localStorage уровней вложенности.": "",
982
984
  "Компоненты для подключения wysiwyg редактора": "",
983
985
  "Отображать чекбоксы только на узлах, не имеющих вложенных элементов": "",
984
986
  "Размер компонента и вложенных полей": "",
985
987
  "Параметры для кнопки отправки формы": "",
986
988
  "Конструктор редактора 'ckeditor5-react' из библиотеки @steroidsjs/ckeditor5/packages/ckeditor5-build-classic\nПримечание: для использования встроенного отображения 'HtmlField', данный компонент должен быть передан": "",
987
989
  "Компонент редактора 'ckeditor5-react' из библиотеки @ckeditor\nПримечание: для использования встроенного отображения 'HtmlField', данный компонент должен быть передан": "",
988
- "CSS-класс для элемента навигации.": ""
990
+ "Допустимое количество символов после разделителя": "",
991
+ "CSS-класс для элемента навигации.": "",
992
+ "Тип данных для параметров маршрута.": ""
989
993
  }
@@ -20,7 +20,7 @@ export type DataProviderItems = string | ({
20
20
  new (): Enum;
21
21
  }) | (string | number | {
22
22
  id: string | number | boolean;
23
- label: string | any;
23
+ label: string | Record<string, any>;
24
24
  [key: string]: any;
25
25
  })[];
26
26
  export interface IDataProvider {
@@ -24,7 +24,7 @@ export interface IDataSelectConfig {
24
24
  * Сделать активным первый элемент в списке
25
25
  * @example true
26
26
  */
27
- selectFirst?: any;
27
+ selectFirst?: boolean;
28
28
  /**
29
29
  * Список с идентификаторами выбранных элементов
30
30
  * @example [1, 4]
@@ -15,20 +15,20 @@ export interface IFileInput {
15
15
  * Экшен для отправки на бэкенд
16
16
  * @example '/api/v1/user/avatar/crop'
17
17
  */
18
- backendUrl?: any;
18
+ backendUrl?: string;
19
19
  /**
20
20
  * Список mime-типов
21
21
  */
22
- mimeTypes?: any;
22
+ mimeTypes?: string[];
23
23
  /**
24
24
  * Использовать только изображения
25
25
  */
26
- imagesOnly?: any;
27
- imagesProcessor?: any;
26
+ imagesOnly?: boolean;
27
+ imagesProcessor?: string;
28
28
  /**
29
29
  * Точные размеры изображений
30
30
  */
31
- imagesExactSize?: any;
31
+ imagesExactSize?: string;
32
32
  /**
33
33
  * Начальные файлы
34
34
  */
@@ -1,8 +1,9 @@
1
+ /// <reference types="react" />
1
2
  export default function useForm(): {
2
3
  formId: string;
3
4
  model: any;
4
5
  prefix: string | boolean;
5
6
  size: string;
6
- formDispatch: any;
7
+ formDispatch: import("react").Dispatch<any>;
7
8
  formSelector: (selector: (state: any, setValue: any) => any) => any;
8
9
  };
@@ -100,5 +100,15 @@ export interface ITreeConfig {
100
100
  * @example true
101
101
  */
102
102
  useSameSelectedItemId?: boolean;
103
+ /**
104
+ * Сохранение в localStorage уровней вложенности.
105
+ * @example true
106
+ */
107
+ saveInClientStorage?: boolean;
108
+ /**
109
+ * Идентификатор (ключ) для сохранения в LocalStorage коллекции.
110
+ * @example 'exampleTree'
111
+ */
112
+ clientStorageId?: string;
103
113
  }
104
114
  export default function useTree(config: ITreeConfig): ITreeOutput;
package/hooks/useTree.js CHANGED
@@ -22,12 +22,15 @@ var isEqual_1 = __importDefault(require("lodash-es/isEqual"));
22
22
  var isEmpty_1 = __importDefault(require("lodash-es/isEmpty"));
23
23
  var isNil_1 = __importDefault(require("lodash-es/isNil"));
24
24
  var keys_1 = __importDefault(require("lodash-es/keys"));
25
+ var react_use_1 = require("react-use");
26
+ var useComponents_1 = __importDefault(require("./useComponents"));
25
27
  var useSelector_1 = __importDefault(require("./useSelector"));
26
28
  var router_1 = require("../reducers/router");
27
29
  var INITIAL_CURRENT_LEVEL = 0;
28
30
  var DOT_SEPARATOR = '.';
29
31
  var EMPTY_PARENT_ID = '';
30
32
  var FIRST_LEVEL_PARENT_ID = '0';
33
+ var CLIENT_STORAGE_KEY = '_tree';
31
34
  var defaultProps = {
32
35
  itemsKey: 'items',
33
36
  autoOpenLevels: 0
@@ -96,6 +99,7 @@ function useTree(config) {
96
99
  var primaryKey = config.itemsKey || defaultProps.itemsKey;
97
100
  var _a = (0, react_1.useState)(null), selectedUniqueId = _a[0], setSelectedUniqueId = _a[1];
98
101
  var _b = (0, react_1.useState)({}), expandedItems = _b[0], setExpandedItems = _b[1];
102
+ var clientStorage = (0, useComponents_1["default"])().clientStorage;
99
103
  //Redux connection
100
104
  var _c = (0, useSelector_1["default"])(function (state) { return ({
101
105
  routes: (0, isString_1["default"])(config.items) ? (0, router_1.getNavItems)(state, config.items) : null,
@@ -116,11 +120,32 @@ function useTree(config) {
116
120
  }, [config.items, config.routerParams, routes]);
117
121
  // Initial expanded items
118
122
  (0, react_1.useEffect)(function () {
119
- // TODO add clientStorage
120
123
  setExpandedItems(getAutoExpandedItems(items, selectedItemId, primaryKey, config.autoOpenLevels));
121
124
  var selectedItem = findChildById(items, selectedItemId, primaryKey);
122
125
  setSelectedUniqueId(selectedItem ? selectedItem.uniqueId : null);
123
126
  }, [items]);
127
+ var localTree = JSON.parse(clientStorage.get(CLIENT_STORAGE_KEY)) || {};
128
+ var saveInClientStorage = function () {
129
+ if (config.saveInClientStorage) {
130
+ localTree[config.clientStorageId] = expandedItems;
131
+ clientStorage.set(CLIENT_STORAGE_KEY, JSON.stringify(localTree));
132
+ }
133
+ };
134
+ (0, react_use_1.useMount)(function () {
135
+ if (config.saveInClientStorage) {
136
+ var treeData = localTree[config.clientStorageId];
137
+ if (treeData) {
138
+ setExpandedItems(treeData);
139
+ }
140
+ }
141
+ });
142
+ (0, react_use_1.useUnmount)(function () {
143
+ saveInClientStorage();
144
+ });
145
+ (0, react_use_1.useBeforeUnload)(function () {
146
+ saveInClientStorage();
147
+ return true;
148
+ });
124
149
  var onExpand = (0, react_1.useCallback)(function (e, uniqueId, item) {
125
150
  var _a;
126
151
  e.preventDefault();
package/index.d.ts CHANGED
@@ -79,6 +79,11 @@ declare type CustomStyle = React.CSSProperties;
79
79
  */
80
80
  declare type CustomView = React.ReactNode | ((props: React.ComponentProps<any>) => JSX.Element);
81
81
 
82
+ /**
83
+ * Свойства для view компонента
84
+ */
85
+ declare type CustomViewProps = React.ComponentProps<any>;
86
+
82
87
  /**
83
88
  * Кастомная иконка
84
89
  * @example custom-icon
@@ -108,3 +113,8 @@ declare interface IUiComponent {
108
113
  */
109
114
  style?: CustomStyle,
110
115
  }
116
+
117
+ /**
118
+ * Тип данных для параметров маршрута.
119
+ */
120
+ declare type RouteParams = Record<string, any> | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steroidsjs/core",
3
- "version": "3.0.5",
3
+ "version": "3.0.7",
4
4
  "description": "",
5
5
  "author": "Vladimir Kozhin <hello@kozhindev.com>",
6
6
  "repository": {
@@ -31,12 +31,12 @@ export interface IButtonProps extends IUiComponent {
31
31
  * Текст кнопки или ссылки
32
32
  * @example Save
33
33
  */
34
- label?: string | any;
34
+ label?: string;
35
35
  /**
36
36
  * Подсказка, отображается при наведении (через тег title)
37
37
  * @example Save
38
38
  */
39
- hint?: string | any;
39
+ hint?: string;
40
40
  /**
41
41
  * HTML Тип
42
42
  * @example submit
@@ -148,7 +148,7 @@ export interface IButtonProps extends IUiComponent {
148
148
  /**
149
149
  * Цвет текста кнопки или ссылки
150
150
  */
151
- textColor?: any;
151
+ textColor?: string;
152
152
  [key: string]: any;
153
153
  }
154
154
  export interface IButtonViewProps extends IButtonProps {
@@ -19,7 +19,7 @@ type CheckboxTreeItems = string | ({
19
19
  *
20
20
  * Список с вложенными чекбоксами. Используется в формах для создания иерархической структуры и выбора нескольких значений.
21
21
  */
22
- export interface ICheckboxTreeFieldProps extends IFieldWrapperInputProps, Omit<IDataProviderConfig, 'items'>, Omit<IDataSelectConfig, 'items'>, IUiComponent, Pick<ITreeProps, 'levelPadding' | 'alwaysOpened' | 'customIcon'> {
22
+ export interface ICheckboxTreeFieldProps extends IFieldWrapperInputProps, Omit<IDataProviderConfig, 'items'>, Omit<IDataSelectConfig, 'items'>, IUiComponent, Pick<ITreeProps, 'levelPadding' | 'alwaysOpened' | 'hasIconExpandOnly' | 'customIcon' | 'saveInClientStorage'> {
23
23
  /**
24
24
  * Свойства для элемента input
25
25
  * @example { onKeyDown: ... }
@@ -52,7 +52,7 @@ export interface ICheckboxTreeFieldProps extends IFieldWrapperInputProps, Omit<I
52
52
  hasOnlyLeafCheckboxes?: boolean;
53
53
  [key: string]: any;
54
54
  }
55
- export interface ICheckboxTreeFieldViewProps extends IFieldWrapperOutputProps, Pick<ITreeProps, 'levelPadding' | 'customIcon'> {
55
+ export interface ICheckboxTreeFieldViewProps extends IFieldWrapperOutputProps, Pick<ITreeProps, 'levelPadding' | 'hasIconExpandOnly' | 'customIcon'> {
56
56
  items: {
57
57
  id: number | string | boolean;
58
58
  label?: string;
@@ -67,6 +67,6 @@ export interface ICheckboxTreeFieldViewProps extends IFieldWrapperOutputProps, P
67
67
  size?: Size;
68
68
  hasOnlyLeafCheckboxes?: boolean;
69
69
  }
70
- export declare const getNestedItemsIds: (item: any, groupAttribute: any) => any[];
70
+ export declare const getNestedItemsIds: (item: any, groupAttribute: any, hasOnlyLeafCheckboxes?: boolean) => any[];
71
71
  declare const _default: import("../../../ui/form/Field/fieldWrapper").FieldWrapperComponent<ICheckboxTreeFieldProps>;
72
72
  export default _default;
@@ -44,12 +44,13 @@ var isArray_1 = __importDefault(require("lodash-es/isArray"));
44
44
  var isEqual_1 = __importDefault(require("lodash-es/isEqual"));
45
45
  var hooks_1 = require("../../../hooks");
46
46
  var fieldWrapper_1 = __importDefault(require("../../../ui/form/Field/fieldWrapper"));
47
- var getNestedItemsIds = function (item, groupAttribute) {
47
+ var getNestedItemsIds = function (item, groupAttribute, hasOnlyLeafCheckboxes) {
48
+ if (hasOnlyLeafCheckboxes === void 0) { hasOnlyLeafCheckboxes = false; }
48
49
  if (item.disabled) {
49
50
  return [];
50
51
  }
51
52
  var _a = item, _b = groupAttribute, _c = _a[_b], nestedItems = _c === void 0 ? [] : _c;
52
- var result = [item.id];
53
+ var result = hasOnlyLeafCheckboxes ? [] : [item.id];
53
54
  if (groupAttribute && (0, isArray_1["default"])(nestedItems)) {
54
55
  nestedItems.reduce(function (acc, nestedItem) {
55
56
  if ((0, isArray_1["default"])(nestedItem[groupAttribute])) {
@@ -88,8 +89,8 @@ function CheckboxTreeField(props) {
88
89
  inputValue: props.input.value
89
90
  }), selectedIds = _a.selectedIds, setSelectedIds = _a.setSelectedIds;
90
91
  var onItemSelect = (0, react_1.useCallback)(function (checkbox) {
91
- if (checkbox.hasItems && !props.hasOnlyLeafCheckboxes) {
92
- var selectedItemIds = (0, exports.getNestedItemsIds)(checkbox, props.primaryKey);
92
+ if (checkbox.hasItems) {
93
+ var selectedItemIds = (0, exports.getNestedItemsIds)(checkbox, props.primaryKey, props.hasOnlyLeafCheckboxes);
93
94
  setSelectedIds(selectedItemIds);
94
95
  }
95
96
  else if (checkbox.id && !checkbox.hasItems) {
@@ -126,8 +127,9 @@ function CheckboxTreeField(props) {
126
127
  renderCheckbox: renderCheckbox,
127
128
  size: props.size,
128
129
  levelPadding: props.levelPadding,
129
- hasOnlyLeafCheckboxes: props.hasOnlyLeafCheckboxes
130
- }); }, [onItemSelect, props.levelPadding, props.hasOnlyLeafCheckboxes, props.size, renderCheckbox, selectedIds, treeItems]);
130
+ hasOnlyLeafCheckboxes: props.hasOnlyLeafCheckboxes,
131
+ hasIconExpandOnly: props.hasIconExpandOnly
132
+ }); }, [treeItems, onItemSelect, selectedIds, renderCheckbox, props.size, props.levelPadding, props.hasOnlyLeafCheckboxes, props.hasIconExpandOnly]);
131
133
  return components.ui.renderView(props.view || 'form.CheckboxTreeFieldView', viewProps);
132
134
  }
133
135
  CheckboxTreeField.defaultProps = {
@@ -137,6 +139,8 @@ CheckboxTreeField.defaultProps = {
137
139
  levelPadding: 32,
138
140
  alwaysOpened: false,
139
141
  primaryKey: 'items',
140
- hasOnlyLeafCheckboxes: false
142
+ hasOnlyLeafCheckboxes: false,
143
+ hasIconExpandOnly: true,
144
+ saveInClientStorage: false
141
145
  };
142
146
  exports["default"] = (0, fieldWrapper_1["default"])('CheckboxTreeField', CheckboxTreeField);
@@ -16,7 +16,7 @@ export interface IDateFieldProps extends IDateInputStateInput, IUiComponent, Pic
16
16
  /**
17
17
  * Свойства для view компонента
18
18
  */
19
- viewProps?: Record<string, unknown>;
19
+ viewProps?: CustomViewProps;
20
20
  /**
21
21
  * Свойства для компонента Calendar
22
22
  */
@@ -13,7 +13,7 @@ export interface IFieldProps extends IFieldWrapperInputProps {
13
13
  * Аттрибут (название) поля в форме
14
14
  * @example isVisible
15
15
  */
16
- attribute?: any;
16
+ attribute?: string;
17
17
  /**
18
18
  * Модель с полями формы
19
19
  * @example
@@ -70,16 +70,16 @@ export interface IFieldListProps extends IFieldWrapperInputProps, IUiComponent {
70
70
  /**
71
71
  * Пропсы для компонента отображения списка с группами полей - FieldListView
72
72
  */
73
- viewProps?: any;
73
+ viewProps?: CustomViewProps;
74
74
  /**
75
75
  * Переопределение view React компонента для кастомизации отображения группы полей
76
76
  * @example MyCustomView
77
77
  */
78
- itemView?: any;
78
+ itemView?: CustomView;
79
79
  /**
80
80
  * Пропсы для компонента отображения группы полей - FieldListItemView
81
81
  */
82
- itemViewProps?: any;
82
+ itemViewProps?: CustomViewProps;
83
83
  /**
84
84
  * При фокусировке на одном из элементов формы и нажатию на клавиши стрелок вверх/вниз + Shift
85
85
  * происходит добавление группы полей сверху или снизу соответственно
@@ -14,7 +14,7 @@ export interface IFieldSetProps extends IFormContext {
14
14
  * Заголовок для группы полей в форме
15
15
  * @example Save
16
16
  */
17
- label?: any;
17
+ label?: string;
18
18
  /**
19
19
  * Переопределение view React компонента для кастомизации отображения
20
20
  * @example MyCustomView
@@ -29,7 +29,7 @@ export interface IFieldSetProps extends IFormContext {
29
29
  export interface IFieldSetViewProps {
30
30
  className?: CssClassName;
31
31
  children?: React.ReactNode;
32
- label?: string | any;
32
+ label?: string;
33
33
  }
34
34
  declare function FieldSet(props: IFieldSetProps): JSX.Element;
35
35
  export default FieldSet;
@@ -47,7 +47,7 @@ export interface IFileFieldProps extends IFieldWrapperInputProps, IFileFieldComm
47
47
  * View компонент для элемента списка файлов
48
48
  * @example true
49
49
  */
50
- itemView?: any;
50
+ itemView?: CustomView;
51
51
  /**
52
52
  * Пропсы для элемента файла
53
53
  * @example true
@@ -38,11 +38,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  };
39
39
  exports.__esModule = true;
40
40
  exports.FilesLayout = void 0;
41
- var React = __importStar(require("react"));
42
41
  var File_1 = __importDefault(require("fileup-core/lib/models/File"));
43
42
  var first_1 = __importDefault(require("lodash-es/first"));
44
43
  var values_1 = __importDefault(require("lodash-es/values"));
45
- var react_1 = require("react");
44
+ var react_1 = __importStar(require("react"));
46
45
  var useFile_1 = __importDefault(require("../../../hooks/useFile"));
47
46
  var hooks_1 = require("../../../hooks");
48
47
  var fieldWrapper_1 = __importDefault(require("../Field/fieldWrapper"));
@@ -55,7 +54,7 @@ var FILE_STATUS_END = 'end';
55
54
  function FileFieldComponent(props) {
56
55
  var components = (0, hooks_1.useComponents)();
57
56
  var _a = (0, useFile_1["default"])(props), files = _a.files, onBrowse = _a.onBrowse, onRemove = _a.onRemove;
58
- var _b = React.useState(false), isFilesLoaded = _b[0], setIsFilesLoaded = _b[1];
57
+ var _b = react_1["default"].useState(false), isFilesLoaded = _b[0], setIsFilesLoaded = _b[1];
59
58
  var FileFieldView = props.view || components.ui.getView('form.FileFieldView');
60
59
  var FileFieldItemView = props.itemView || components.ui.getView('form.FileFieldItemView');
61
60
  (0, react_1.useEffect)(function () {
@@ -125,13 +124,13 @@ function FileFieldComponent(props) {
125
124
  })
126
125
  }); }, [FileFieldItemView, files, onBrowse, onRemove, props.buttonProps, props.buttonView, props.className, props.disabled,
127
126
  props.filesLayout, props.imagesOnly, props.imagesProcessor, props.itemProps, props.showRemove, props.size]);
128
- return (React.createElement(FileFieldView, __assign({}, viewProps)));
127
+ return (react_1["default"].createElement(FileFieldView, __assign({}, viewProps)));
129
128
  }
130
129
  function FileField(props) {
131
130
  if (process.env.IS_SSR) {
132
131
  return null;
133
132
  }
134
- return (React.createElement(FileFieldComponent, __assign({}, props)));
133
+ return (react_1["default"].createElement(FileFieldComponent, __assign({}, props)));
135
134
  }
136
135
  FileField.defaultProps = {
137
136
  disabled: false,
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { IButtonProps } from '@steroidsjs/core/ui/form/Button/Button';
3
3
  import { IAddressBarConfig } from '../../../hooks/useAddressBar';
4
4
  import { IFieldProps } from '../Field/Field';
5
+ import { providers } from '../../../utils/form';
5
6
  /**
6
7
  * Form
7
8
  *
@@ -60,7 +61,7 @@ export interface IFormProps extends IUiComponent {
60
61
  * ['age', 'integer']
61
62
  * ]
62
63
  */
63
- validators?: any[];
64
+ validators?: string[] | Array<string[]> | Array<Record<string, any>>;
64
65
  /**
65
66
  * Обработчик события перед отправкой формы
66
67
  * @param args
@@ -207,7 +208,7 @@ export interface IFormContext {
207
208
  /**
208
209
  * Провайдер
209
210
  */
210
- provider?: any;
211
+ provider?: typeof providers.redux | typeof providers.reducer;
211
212
  /**
212
213
  * Редьюсер
213
214
  */
@@ -218,7 +219,7 @@ export interface IFormContext {
218
219
  /**
219
220
  * Диспатч
220
221
  */
221
- dispatch?: any;
222
+ dispatch?: React.Dispatch<any>;
222
223
  }
223
224
  export declare const FormContext: React.Context<IFormContext>;
224
225
  declare function Form(props: IFormProps): JSX.Element;
@@ -22,6 +22,10 @@ export interface INumberFieldProps extends IBaseFieldProps {
22
22
  * @example 5
23
23
  */
24
24
  step?: number;
25
+ /**
26
+ * Допустимое количество символов после разделителя
27
+ */
28
+ decimal?: number;
25
29
  }
26
30
  export interface INumberFieldViewProps extends INumberFieldProps, IFieldWrapperOutputProps {
27
31
  inputProps: {
@@ -50,12 +50,22 @@ function NumberField(props) {
50
50
  var onInputChange = (0, useInputTypeNumber_1["default"])(currentInputRef, {
51
51
  max: props.max,
52
52
  min: props.min,
53
- value: props.input.value
54
- }, onChange).onInputChange;
53
+ value: props.input.value,
54
+ required: props.required
55
+ }, onChange, props.decimal).onInputChange;
55
56
  var onStep = (0, react_1.useCallback)(function (isIncrement) {
56
57
  var _a;
57
- onChange(null, String(Number((_a = currentInputRef === null || currentInputRef === void 0 ? void 0 : currentInputRef.current) === null || _a === void 0 ? void 0 : _a.value) + (isIncrement ? step : -step)));
58
- }, [currentInputRef, onChange, step]);
58
+ var currentValue = Number((_a = currentInputRef === null || currentInputRef === void 0 ? void 0 : currentInputRef.current) === null || _a === void 0 ? void 0 : _a.value);
59
+ var newValue;
60
+ var fixToDecimal = function (value) { return props.decimal ? value.toFixed(props.decimal) : value; };
61
+ if (isIncrement) {
62
+ newValue = fixToDecimal(currentValue + step);
63
+ }
64
+ else {
65
+ newValue = fixToDecimal(currentValue - step);
66
+ }
67
+ onChange(null, String(newValue));
68
+ }, [currentInputRef, onChange, props.decimal, step]);
59
69
  var onStepUp = (0, react_1.useCallback)(function () {
60
70
  if (!(Number(currentInputRef.current.value) + step > props.max)) {
61
71
  onStep(true);
@@ -3,8 +3,9 @@ interface IInputTypeNumberProps {
3
3
  max: any;
4
4
  min: any;
5
5
  value: string | undefined | null;
6
+ required?: boolean;
6
7
  }
7
- declare const useInputTypeNumber: (currentInputRef: React.MutableRefObject<HTMLInputElement>, inputTypeNumberProps: IInputTypeNumberProps, onChange: (event: React.ChangeEvent<HTMLInputElement>, value?: any) => void) => {
8
+ declare const useInputTypeNumber: (currentInputRef: React.MutableRefObject<HTMLInputElement>, inputTypeNumberProps: IInputTypeNumberProps, onChange: (event: React.ChangeEvent<HTMLInputElement>, value?: any) => void, decimal: number) => {
8
9
  onInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
9
10
  };
10
11
  export default useInputTypeNumber;
@@ -4,28 +4,35 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  exports.__esModule = true;
6
6
  var react_1 = __importDefault(require("react"));
7
- var useInputTypeNumber = function (currentInputRef, inputTypeNumberProps, onChange) {
7
+ var useInputTypeNumber = function (currentInputRef, inputTypeNumberProps, onChange, decimal) {
8
8
  react_1["default"].useEffect(function () {
9
9
  var _a;
10
- var defaultValidity = 'The number is not valid.';
11
- var errorMessage = inputTypeNumberProps.value > inputTypeNumberProps.max
12
- || inputTypeNumberProps.value < inputTypeNumberProps.min
13
- || !inputTypeNumberProps.value
14
- ? __(defaultValidity)
10
+ var defaultValidity = __('The number is not valid.');
11
+ var errorMessage = inputTypeNumberProps.required
12
+ && (inputTypeNumberProps.value > inputTypeNumberProps.max
13
+ || inputTypeNumberProps.value < inputTypeNumberProps.min
14
+ || !inputTypeNumberProps.value)
15
+ ? defaultValidity
15
16
  : '';
16
17
  (_a = currentInputRef.current) === null || _a === void 0 ? void 0 : _a.setCustomValidity(errorMessage);
17
- }, [currentInputRef, inputTypeNumberProps.value, inputTypeNumberProps.max, inputTypeNumberProps.min]);
18
+ }, [currentInputRef, inputTypeNumberProps.value, inputTypeNumberProps.max, inputTypeNumberProps.min, inputTypeNumberProps.required]);
18
19
  var isValueNumeric = function (value) {
19
20
  if (!value) {
20
21
  return true;
21
22
  }
22
23
  /**
23
- * Подходят как отрицательные так и положительные числа
24
- * @example -1
24
+ * Подходят как отрицательные так и положительные числа с плавающей точкой
25
+ * @example -1.0
26
+ * @example 1.1
27
+ */
28
+ var numericFloatRegExp = new RegExp("^-?\\d*\\.?\\d{0,".concat(decimal, "}$"));
29
+ /**
30
+ * Подходят как отрицательные так и положительные целые числа
25
31
  * @example 1
32
+ * @example -2
26
33
  */
27
- var numericRegex = /^-?\d*\.?\d+$/;
28
- return numericRegex.test(value);
34
+ var numericRegExp = new RegExp('^-?\\d*$');
35
+ return decimal ? numericFloatRegExp.test(value) : numericRegExp.test(value);
29
36
  };
30
37
  var onInputChange = function (event) {
31
38
  var _a;
@@ -16,7 +16,7 @@ export interface ITimeFieldProps extends IDateInputStateInput, IUiComponent {
16
16
  /**
17
17
  * Свойства для view компонента
18
18
  */
19
- viewProps?: Record<string, unknown>;
19
+ viewProps?: CustomViewProps;
20
20
  /**
21
21
  * Свойства для компонента панели времени
22
22
  */
@@ -20,7 +20,7 @@ export interface ITimeRangeFieldProps extends IDateInputStateInput, Omit<IFieldW
20
20
  /**
21
21
  * Свойства для view компонента
22
22
  */
23
- viewProps?: Record<string, unknown>;
23
+ viewProps?: CustomViewProps;
24
24
  /**
25
25
  * Свойства для компонента панели времени
26
26
  */
@@ -42,7 +42,7 @@ export interface ITooltipProps {
42
42
  * Текст подсказки
43
43
  * @example 'Это всплывающая подсказка.'
44
44
  */
45
- content?: string | any;
45
+ content?: string;
46
46
  /**
47
47
  * Вложенные элементы
48
48
  */
@@ -90,7 +90,7 @@ export interface ITooltipProps {
90
90
  }
91
91
  export interface ITooltipViewProps extends ITooltipProps {
92
92
  isTooltipVisible: boolean;
93
- content: string | any;
93
+ content: string;
94
94
  position: PositionType;
95
95
  style: ITooltipStylePosition;
96
96
  className?: CssClassName;
@@ -13,7 +13,7 @@ export interface IListProps extends IListConfig {
13
13
  /**
14
14
  * Свойства для элемента коллекции
15
15
  */
16
- itemProps?: Record<string, unknown>;
16
+ itemProps?: CustomViewProps;
17
17
  /**
18
18
  * Переопределение view React компонента для кастомизации отображения
19
19
  * @example MyCustomView
@@ -37,8 +37,8 @@ export interface IListItemViewProps {
37
37
  primaryKey: PrimaryKey;
38
38
  item: {
39
39
  id?: PrimaryKey;
40
- title?: string | any;
41
- label?: string | any;
40
+ title?: string;
41
+ label?: string;
42
42
  [key: string]: any;
43
43
  };
44
44
  index: number;
@@ -10,7 +10,7 @@ export interface ITreeColumnViewProps extends IColumnViewProps, Pick<ITreeTableP
10
10
  *
11
11
  * Компонент для представления данных коллекции в виде иерархической структуры.
12
12
  */
13
- export interface ITreeTableProps extends Omit<IGridProps, 'items'>, Pick<ITreeProps, 'alwaysOpened' | 'levelPadding' | 'customIcon'> {
13
+ export interface ITreeTableProps extends Omit<IGridProps, 'items'>, Pick<ITreeProps, 'alwaysOpened' | 'levelPadding' | 'customIcon' | 'saveInClientStorage'> {
14
14
  /**
15
15
  * Элементы коллекции
16
16
  * @example
@@ -35,6 +35,7 @@ declare namespace TreeTable {
35
35
  var defaultProps: {
36
36
  levelPadding: number;
37
37
  alwaysOpened: boolean;
38
+ saveInClientStorage: boolean;
38
39
  };
39
40
  }
40
41
  export default TreeTable;
@@ -73,12 +73,15 @@ function TreeTable(props) {
73
73
  autoOpenLevels: 0,
74
74
  alwaysOpened: props.alwaysOpened,
75
75
  currentPage: list === null || list === void 0 ? void 0 : list.page,
76
- itemsOnPage: list === null || list === void 0 ? void 0 : list.pageSize
76
+ itemsOnPage: list === null || list === void 0 ? void 0 : list.pageSize,
77
+ saveInClientStorage: props.saveInClientStorage,
78
+ clientStorageId: props.listId
77
79
  }).treeItems;
78
80
  return (React.createElement(Grid_1["default"], __assign({}, props, { columns: columns, items: treeItems, itemsIndexing: false })));
79
81
  }
80
82
  exports["default"] = TreeTable;
81
83
  TreeTable.defaultProps = {
82
84
  levelPadding: 32,
83
- alwaysOpened: false
85
+ alwaysOpened: false,
86
+ saveInClientStorage: false
84
87
  };
@@ -1,4 +1,4 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  import { IRouteItem } from '../Router/Router';
3
3
  /**
4
4
  * Breadcrumbs
@@ -55,6 +55,6 @@ export interface IBreadcrumbsProps {
55
55
  [key: string]: any;
56
56
  }
57
57
  export type IBreadcrumbsViewProps = IBreadcrumbsProps & {
58
- routeParams?: any;
58
+ routeParams?: Record<string, unknown>;
59
59
  };
60
60
  export default function Breadcrumbs(props: IBreadcrumbsProps): JSX.Element;