@steroidsjs/core 3.1.3 → 3.1.5

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 (32) hide show
  1. package/components/StoreComponent.d.ts +1 -1
  2. package/components/UiComponent.js +2 -2
  3. package/docs-autogen-result.json +72 -4
  4. package/en.json +7 -5
  5. package/hooks/useApplication.d.ts +2 -1
  6. package/hooks/useFetch.d.ts +1 -1
  7. package/hooks/useFile.js +1 -1
  8. package/package.json +3 -3
  9. package/reducers/list.d.ts +1 -1
  10. package/ui/content/CalendarSystem/hooks/useCalendarSystem.d.ts +2 -2
  11. package/ui/content/CalendarSystem/hooks/useCalendarSystemEventGroupModals.d.ts +2 -1
  12. package/ui/content/CalendarSystem/hooks/useCalendarSystemEventGroupModals.js +4 -1
  13. package/ui/content/CalendarSystem/hooks/useDisplayDate.d.ts +1 -1
  14. package/ui/content/CalendarSystem/hooks/useMonthGrid.d.ts +1 -1
  15. package/ui/content/CalendarSystem/utils/utils.d.ts +3 -2
  16. package/ui/content/Detail/Detail.js +2 -2
  17. package/ui/content/Icon/Icon.js +1 -1
  18. package/ui/content/Kanban/enums/KanbanPrioritiesEnum.d.ts +2 -2
  19. package/ui/form/CheckboxField/CheckboxField.d.ts +5 -0
  20. package/ui/form/CheckboxField/CheckboxField.js +3 -2
  21. package/ui/form/CheckboxTreeField/CheckboxTreeField.d.ts +1 -0
  22. package/ui/form/CheckboxTreeField/CheckboxTreeField.js +13 -5
  23. package/ui/form/NumberField/NumberField.d.ts +11 -4
  24. package/ui/form/NumberField/NumberField.js +78 -24
  25. package/ui/format/EnumFormatter/EnumFormatter.js +1 -1
  26. package/ui/modal/ModalPortal/ModalPortal.js +5 -5
  27. package/ui/nav/Router/Router.js +2 -2
  28. package/ui/nav/Router/helpers.d.ts +1 -1
  29. package/utils/data.d.ts +1 -1
  30. package/utils/data.js +1 -1
  31. package/ui/form/NumberField/hooks/useInputTypeNumber.d.ts +0 -11
  32. package/ui/form/NumberField/hooks/useInputTypeNumber.js +0 -66
@@ -4,7 +4,7 @@ import { History, LocationState } from 'history';
4
4
  import { Store, Dispatch, Unsubscribe, Reducer, AnyAction } from 'redux';
5
5
  declare global {
6
6
  interface Window {
7
- APP_REDUX_PRELOAD_STATES?: any;
7
+ APP_REDUX_PRELOAD_STATES?: [any];
8
8
  __REDUX_DEVTOOLS_EXTENSION__?: any;
9
9
  }
10
10
  }
@@ -42,7 +42,7 @@ var UiComponent = /** @class */ (function () {
42
42
  Component = this._getComponent('views', Component);
43
43
  }
44
44
  if (!forceNode && (0, isFunction_1["default"])(Component)) {
45
- if (Component.defaultProps) {
45
+ if ('defaultProps' in Component && (0, isObject_1["default"])(Component.defaultProps)) {
46
46
  return Component(__assign(__assign({}, Component.defaultProps), props));
47
47
  }
48
48
  return Component(props);
@@ -111,7 +111,7 @@ var UiComponent = /** @class */ (function () {
111
111
  var _this = this;
112
112
  if (defaultNamespace === void 0) { defaultNamespace = null; }
113
113
  // require.context()
114
- if ((0, isFunction_1["default"])(items) && (0, isFunction_1["default"])(items.keys)) {
114
+ if ((0, isFunction_1["default"])(items) && 'keys' in items && (0, isFunction_1["default"])(items.keys)) {
115
115
  items.keys().forEach(function (fileName) {
116
116
  var matches = fileName.match(/^\.\/(.*\/)?[^\\/]+\/([^\\/]+)\.(js|ts)x?$/);
117
117
  if (matches) {
@@ -2996,7 +2996,7 @@
2996
2996
  "decorators": [],
2997
2997
  "description": "",
2998
2998
  "required": false,
2999
- "type": "Record",
2999
+ "type": "{}",
3000
3000
  "example": null
3001
3001
  }
3002
3002
  ],
@@ -15416,6 +15416,15 @@
15416
15416
  "example": null,
15417
15417
  "defaultValue": null
15418
15418
  },
15419
+ {
15420
+ "name": "indeterminate",
15421
+ "decorators": [],
15422
+ "description": "Промежуточное состояние чекбокса — часть дочерних элементов выбрана",
15423
+ "required": false,
15424
+ "type": "boolean",
15425
+ "example": null,
15426
+ "defaultValue": null
15427
+ },
15419
15428
  {
15420
15429
  "name": "inputProps",
15421
15430
  "decorators": [],
@@ -15645,6 +15654,14 @@
15645
15654
  "type": "string",
15646
15655
  "example": null
15647
15656
  },
15657
+ {
15658
+ "name": "indeterminate",
15659
+ "decorators": [],
15660
+ "description": "Промежуточное состояние чекбокса — часть дочерних элементов выбрана",
15661
+ "required": false,
15662
+ "type": "boolean",
15663
+ "example": null
15664
+ },
15648
15665
  {
15649
15666
  "name": "input",
15650
15667
  "decorators": [],
@@ -16836,6 +16853,14 @@
16836
16853
  "type": "number",
16837
16854
  "example": "32"
16838
16855
  },
16856
+ {
16857
+ "name": "primaryKey",
16858
+ "decorators": [],
16859
+ "description": "",
16860
+ "required": false,
16861
+ "type": "string",
16862
+ "example": null
16863
+ },
16839
16864
  {
16840
16865
  "name": "selectedIds",
16841
16866
  "decorators": [],
@@ -27117,6 +27142,15 @@
27117
27142
  "example": "{width: '45%'}",
27118
27143
  "defaultValue": null
27119
27144
  },
27145
+ {
27146
+ "name": "thousandSeparator",
27147
+ "decorators": [],
27148
+ "description": "Разделитель тысяч (по умолчанию пустая строка — без разделителя, например 1000).\nДля отображения \"1 000\" передать пробел: thousandSeparator=\" \"",
27149
+ "required": false,
27150
+ "type": "string",
27151
+ "example": "','",
27152
+ "defaultValue": null
27153
+ },
27120
27154
  {
27121
27155
  "name": "value",
27122
27156
  "decorators": [],
@@ -27305,7 +27339,7 @@
27305
27339
  "decorators": [],
27306
27340
  "description": "Свойства для элемента input",
27307
27341
  "required": true,
27308
- "type": "{disabled: boolean, max: number, min: number, name: string, placeholder: string, required: boolean, step: string | number, type: string, value: number, onChange: null}",
27342
+ "type": "{disabled: boolean, max: number, min: number, name: string, placeholder: string, required: boolean, step: string | number, type: string, value: string | number, onInput: null}",
27309
27343
  "example": null
27310
27344
  },
27311
27345
  {
@@ -27444,6 +27478,14 @@
27444
27478
  "type": "CSSProperties",
27445
27479
  "example": "{width: '45%'}"
27446
27480
  },
27481
+ {
27482
+ "name": "thousandSeparator",
27483
+ "decorators": [],
27484
+ "description": "Разделитель тысяч (по умолчанию пустая строка — без разделителя, например 1000).\nДля отображения \"1 000\" передать пробел: thousandSeparator=\" \"",
27485
+ "required": false,
27486
+ "type": "string",
27487
+ "example": "','"
27488
+ },
27447
27489
  {
27448
27490
  "name": "value",
27449
27491
  "decorators": [],
@@ -28135,6 +28177,15 @@
28135
28177
  "example": null,
28136
28178
  "defaultValue": null
28137
28179
  },
28180
+ {
28181
+ "name": "indeterminate",
28182
+ "decorators": [],
28183
+ "description": "Промежуточное состояние чекбокса — часть дочерних элементов выбрана",
28184
+ "required": false,
28185
+ "type": "boolean",
28186
+ "example": null,
28187
+ "defaultValue": null
28188
+ },
28138
28189
  {
28139
28190
  "name": "inputProps",
28140
28191
  "decorators": [],
@@ -30465,6 +30516,15 @@
30465
30516
  "example": null,
30466
30517
  "defaultValue": null
30467
30518
  },
30519
+ {
30520
+ "name": "indeterminate",
30521
+ "decorators": [],
30522
+ "description": "Промежуточное состояние чекбокса — часть дочерних элементов выбрана",
30523
+ "required": false,
30524
+ "type": "boolean",
30525
+ "example": null,
30526
+ "defaultValue": null
30527
+ },
30468
30528
  {
30469
30529
  "name": "inputProps",
30470
30530
  "decorators": [],
@@ -41897,6 +41957,14 @@
41897
41957
  "type": "\"top\" | \"bottom\" | \"both\" | string",
41898
41958
  "example": null
41899
41959
  },
41960
+ "ComponentConstructor": {
41961
+ "name": "ComponentConstructor",
41962
+ "decorators": [],
41963
+ "description": "",
41964
+ "required": true,
41965
+ "type": "{}",
41966
+ "example": null
41967
+ },
41900
41968
  "DataProviderItems": {
41901
41969
  "name": "DataProviderItems",
41902
41970
  "decorators": [],
@@ -45447,7 +45515,7 @@
45447
45515
  "decorators": [],
45448
45516
  "description": "",
45449
45517
  "required": false,
45450
- "type": "any",
45518
+ "type": "number",
45451
45519
  "example": null,
45452
45520
  "parameters": []
45453
45521
  },
@@ -45510,7 +45578,7 @@
45510
45578
  "decorators": [],
45511
45579
  "description": "",
45512
45580
  "required": false,
45513
- "type": "any",
45581
+ "type": "ITaskPriority",
45514
45582
  "example": null,
45515
45583
  "parameters": [
45516
45584
  {
package/en.json CHANGED
@@ -1057,9 +1057,11 @@
1057
1057
  "Применяется для SSR. Если fetch критический — SSR вернет страницу со статус кодом ошибки.": "Used for SSR. If the fetch is critical, SSR will return the page with an error status code.",
1058
1058
  "Дополнительное содержание сообщения.": "Additional message content.",
1059
1059
  "Метки на ползунке. В объекте {key: 'value'} key определяет положение, а value определяет, что будет отображаться.\nЕсли вы хотите задать стиль определенной точки метки, значением должен быть объект,\nсодержащий свойства style и label.": "Labels on the slider. In the object {key: 'value'}, the key determines the position, and the value determines what will be displayed.\nIf you want to set a style for a specific label point, the value must be an object\ncontaining the style and label properties.",
1060
- "Применяется для ssr. Если fetch критический — ssr вернет страницу со статус кодом ошибки.": "",
1061
- "Название цвета для Alert и Notification": "",
1062
- "Название цвета для Badge": "",
1063
- "Название цвета для Button": "",
1064
- "Название цвета для Text, Title": ""
1060
+ "Применяется для ssr. Если fetch критический — ssr вернет страницу со статус кодом ошибки.": "Used for SSR. If the fetch is critical, the SSR will return the page with an error status code.",
1061
+ "Разделитель тысяч (по умолчанию пустая строка — без разделителя, например 1000).\nДля отображения \"1 000\" передать пробел: thousandSeparator=\" \"": "Thousands separator (default is an empty string — no separator, e.g., 1000).\nTo display \"1 000\", pass a space: thousandSeparator=\" \"",
1062
+ "Название цвета для Alert и Notification": "Color name for Alert and Notification",
1063
+ "Название цвета для Badge": "Color name for Badge",
1064
+ "Название цвета для Button": "Color name for Button",
1065
+ "Название цвета для Text, Title": "Color name for Text, Title",
1066
+ "Промежуточное состояние чекбокса — часть дочерних элементов выбрана": ""
1065
1067
  }
@@ -15,8 +15,9 @@ import { IComponents } from '../providers/ComponentsProvider';
15
15
  import { IScreenProviderProps } from '../providers/ScreenProvider';
16
16
  import { IThemeProviderProps } from '../providers/ThemeProvider';
17
17
  import { IRouteItem, IRouterProps } from '../ui/nav/Router/Router';
18
+ export type ComponentConstructor = new (components: IComponents, config?: Record<string, any>) => any;
18
19
  export interface IComponentConfig {
19
- className?: Record<string, any>;
20
+ className?: ComponentConstructor;
20
21
  [key: string]: any;
21
22
  }
22
23
  /**
@@ -25,7 +25,7 @@ export interface IFetchResult<T> {
25
25
  axiosError: AxiosError | null;
26
26
  }
27
27
  export declare const normalizeConfig: (config: any) => any;
28
- export declare const getConfigId: (config: any) => any;
28
+ export declare const getConfigId: (config: any) => string;
29
29
  export declare const defaultFetchHandler: (config: any, components: any, addCancelToken: any) => any;
30
30
  export declare const fetchData: (config: any, components: any, addCancelToken: any) => any;
31
31
  /**
package/hooks/useFile.js CHANGED
@@ -219,7 +219,7 @@ function useFile(props) {
219
219
  var prevInputValue = (0, react_use_1.usePrevious)(props.input.value);
220
220
  //todo refactoring
221
221
  (0, react_1.useEffect)(function () {
222
- if (prevInputValue && !(0, isEqual_1["default"])(prevInputValue !== props.input.value)) {
222
+ if (prevInputValue && !(0, isEqual_1["default"])(prevInputValue, props.input.value)) {
223
223
  var toRemove_1 = (0, difference_1["default"])([].concat(prevInputValue || []), [].concat(props.input.value || []));
224
224
  if (toRemove_1.length > 0) {
225
225
  uploader.queue.remove(uploader.queue.getFiles().filter(function (file) { return (toRemove_1.indexOf((0, get_1["default"])(file.getResultHttpMessage(), 'id')) !== -1); }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steroidsjs/core",
3
- "version": "3.1.3",
3
+ "version": "3.1.5",
4
4
  "description": "",
5
5
  "author": "Vladimir Kozhin <hello@kozhindev.com>",
6
6
  "repository": {
@@ -39,8 +39,7 @@
39
39
  "intl-messageformat": "^10.1.4",
40
40
  "js-cookie": "^2.2.1",
41
41
  "load-js": "^3.0.3",
42
- "lodash": "^4.17.21",
43
- "lodash-es": "^4.17.21",
42
+ "lodash-es": "^4.17.23",
44
43
  "path-to-regexp": "1.9.0",
45
44
  "qs": "^6.15.0",
46
45
  "react": "^18.2.0",
@@ -72,6 +71,7 @@
72
71
  "@types/enzyme": "^3.10.8",
73
72
  "@types/enzyme-adapter-react-16": "^1.0.6",
74
73
  "@types/jest": "^26.0.22",
74
+ "@types/lodash-es": "^4.17.12",
75
75
  "@types/markdown-to-jsx": "^7.0.1",
76
76
  "@types/reach__router": "^1.3.7",
77
77
  "@types/react": "^18.0.20",
@@ -9,4 +9,4 @@ export declare const getIds: (state: any, listId: any) => any;
9
9
  export declare const getListItems: (state: any, listId: any) => any;
10
10
  export declare const getSelectedIds: (state: any, listId: any) => any;
11
11
  export declare const isSelected: (state: any, listId: any, itemId: any) => any;
12
- export declare const isSelectedAll: (state: any, listId: any) => any;
12
+ export declare const isSelectedAll: (state: any, listId: any) => boolean;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  import { ICalendarSystemProps, ICalendarUser, IEventGroup } from '../CalendarSystem';
3
3
  export declare const useCalendarSystem: (props: ICalendarSystemProps) => {
4
- monthGridWeekDays: any;
4
+ monthGridWeekDays: string[];
5
5
  monthGridCalendarDays: import("../CalendarSystem").IDay[];
6
6
  weekGridTwentyFourHoursArray: string[];
7
7
  weekGridCurrentWeekDays: {
@@ -13,7 +13,7 @@ export declare const useCalendarSystem: (props: ICalendarSystemProps) => {
13
13
  }[];
14
14
  dayGridTwentyFourHoursArray: string[];
15
15
  dayGridCurrentDay: import("../CalendarSystem").IDay;
16
- dateToDisplay: any;
16
+ dateToDisplay: Capitalize<any>;
17
17
  innerEventGroups: IEventGroup[];
18
18
  calendarType: string;
19
19
  users: ICalendarUser[];
@@ -1,5 +1,6 @@
1
+ import { Dispatch, SetStateAction } from 'react';
1
2
  import { IModalProps } from '../../../modal/Modal/Modal';
2
3
  import { IEventGroup } from '../CalendarSystem';
3
- export declare const useCalendarSystemEventGroupModals: (innerEventGroups: IEventGroup[], setInnerEventGroups: React.Dispatch<React.SetStateAction<IEventGroup[]>>, eventGroupModalProps: IModalProps) => {
4
+ export declare const useCalendarSystemEventGroupModals: (innerEventGroups: IEventGroup[], setInnerEventGroups: Dispatch<SetStateAction<IEventGroup[]>>, eventGroupModalProps: IModalProps) => {
4
5
  openCreateEventGroupModal: () => void;
5
6
  };
@@ -30,8 +30,11 @@ var useCalendarSystemEventGroupModals = function (innerEventGroups, setInnerEven
30
30
  var defaultEventGroupColor = (0, react_1.useMemo)(function () { return theme === 'light' ? PRIMARY_LIGHT : PRIMARY_DARK; }, [theme]);
31
31
  var onSubmit = (0, react_1.useCallback)(function (fields) {
32
32
  var _a;
33
+ var maxGroup = (0, maxBy_1["default"])(innerEventGroups, function (group) { return group.id; });
34
+ var maxId = (_a = Number(maxGroup === null || maxGroup === void 0 ? void 0 : maxGroup.id)) !== null && _a !== void 0 ? _a : DEFAULT_ID;
35
+ var id = maxId + 1;
33
36
  var newEventGroup = {
34
- id: (((_a = (0, maxBy_1["default"])(innerEventGroups, function (eventsGroup) { return eventsGroup.id; })) === null || _a === void 0 ? void 0 : _a.id) || DEFAULT_ID) + 1,
37
+ id: id,
35
38
  label: fields.label,
36
39
  color: fields.color,
37
40
  events: []
@@ -1,6 +1,6 @@
1
1
  import { IDay } from '../CalendarSystem';
2
2
  declare const useDisplayDate: (generalCurrentDay: IDay) => {
3
- dateToDisplay: any;
3
+ dateToDisplay: Capitalize<any>;
4
4
  displayFormat: string;
5
5
  changeDisplayFormat: (newFormat: string) => void;
6
6
  };
@@ -1,6 +1,6 @@
1
1
  import { IDay } from '../CalendarSystem';
2
2
  declare const useMonthGrid: (generalCurrentDay: IDay) => {
3
- monthGridWeekDays: any;
3
+ monthGridWeekDays: string[];
4
4
  monthGridCalendarDays: IDay[];
5
5
  };
6
6
  export default useMonthGrid;
@@ -1,8 +1,9 @@
1
+ /// <reference types="lodash" />
1
2
  import { CSSProperties } from 'react';
2
3
  import { IDay, IEvent, IEventGroup } from '../CalendarSystem';
3
4
  export declare const getWeekDaysFromDate: (date: Date) => IDay[];
4
5
  export declare const isDateIsToday: (date: Date) => boolean;
5
- export declare const getOmittedEvent: (event: IEvent | Omit<IEvent, 'color'>) => any;
6
+ export declare const getOmittedEvent: (event: IEvent | Omit<IEvent, 'color'>) => import("lodash").Omit<IEvent | Omit<IEvent, "color">, "color" | "eventGroupId">;
6
7
  export declare const sortEventsInGroup: (group: IEventGroup) => Omit<IEvent, "color">[];
7
8
  export declare const getSourceCalendarControl: (control: string) => HTMLElement;
8
9
  export declare const getFormattedDay: (date?: Date) => IDay;
@@ -14,7 +15,7 @@ export declare const getFormattedWeekFromDate: (fromDate?: Date) => {
14
15
  formattedDisplay?: string;
15
16
  }[];
16
17
  export declare const getTwentyFourHoursArray: () => string[];
17
- export declare const getWeekDays: () => any;
18
+ export declare const getWeekDays: () => string[];
18
19
  export declare const getProportionFromEvent: (event: IEvent) => number;
19
20
  export declare const getTopMarginFromEvent: (event: IEvent) => CSSProperties;
20
21
  export declare const formatEventTime: (date: Date) => any;
@@ -15,8 +15,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
15
15
  };
16
16
  exports.__esModule = true;
17
17
  exports.constants = exports.DetailLayoutEnum = void 0;
18
- var isArray_1 = __importDefault(require("lodash/isArray"));
19
- var orderBy_1 = __importDefault(require("lodash/orderBy"));
18
+ var isArray_1 = __importDefault(require("lodash-es/isArray"));
19
+ var orderBy_1 = __importDefault(require("lodash-es/orderBy"));
20
20
  var react_1 = require("react");
21
21
  var DetailItem_1 = __importDefault(require("./DetailItem"));
22
22
  var hooks_1 = require("../../../hooks");
@@ -19,7 +19,7 @@ function Icon(props) {
19
19
  icon = name.indexOf('<svg') === 0 || name.indexOf('http') === 0
20
20
  ? name
21
21
  : components.ui.getIcon(name);
22
- if ((0, isObject_1["default"])(icon) && (0, isString_1["default"])(icon["default"])) {
22
+ if ((0, isObject_1["default"])(icon) && 'default' in icon && (0, isString_1["default"])(icon["default"])) {
23
23
  icon = icon["default"];
24
24
  }
25
25
  // Fix width attribute in icon
@@ -13,6 +13,6 @@ export default class KanbanPrioritiesEnum extends Enum {
13
13
  };
14
14
  static getColorByType(type: any): string;
15
15
  static getPrioritiesArray(): ITaskPriority[];
16
- static getPriorityById(id: any): any;
17
- static getDefaultSelectedPriorityId(): any;
16
+ static getPriorityById(id: any): ITaskPriority;
17
+ static getDefaultSelectedPriorityId(): number;
18
18
  }
@@ -20,6 +20,10 @@ export interface ICheckboxFieldProps extends IFieldWrapperInputProps, IUiCompone
20
20
  * Пользовательский цвет для чекбокса
21
21
  */
22
22
  color?: string;
23
+ /**
24
+ * Промежуточное состояние чекбокса — часть дочерних элементов выбрана
25
+ */
26
+ indeterminate?: boolean;
23
27
  [key: string]: any;
24
28
  }
25
29
  export interface ICheckboxFieldViewProps extends ICheckboxFieldProps, IFieldWrapperOutputProps {
@@ -31,6 +35,7 @@ export interface ICheckboxFieldViewProps extends ICheckboxFieldProps, IFieldWrap
31
35
  disabled?: boolean;
32
36
  required?: boolean;
33
37
  };
38
+ indeterminate?: boolean;
34
39
  }
35
40
  declare const _default: import("../Field/fieldWrapper").FieldWrapperComponent<ICheckboxFieldProps>;
36
41
  export default _default;
@@ -44,9 +44,10 @@ function CheckboxField(props) {
44
44
  id: props.id,
45
45
  label: props.label,
46
46
  onChange: props.onChange,
47
- required: props.required
47
+ required: props.required,
48
+ indeterminate: props.indeterminate
48
49
  }); }, [inputProps, props.checked, props.className, props.color, props.disabled,
49
- props.errors, props.id, props.label, props.onChange, props.required, props.size, props.style]);
50
+ props.errors, props.id, props.indeterminate, props.label, props.onChange, props.required, props.size, props.style]);
50
51
  return components.ui.renderView(props.view || 'form.CheckboxFieldView', viewProps);
51
52
  }
52
53
  CheckboxField.defaultProps = {
@@ -66,6 +66,7 @@ export interface ICheckboxTreeFieldViewProps extends IFieldWrapperOutputProps, P
66
66
  required?: boolean;
67
67
  } & IPreparedTreeItem[];
68
68
  selectedIds: (PrimaryKey | any)[];
69
+ primaryKey?: string;
69
70
  onItemSelect: (checkbox: IPreparedTreeItem) => void;
70
71
  renderCheckbox: (checkboxProps: ICheckboxFieldViewProps) => JSX.Element;
71
72
  size?: Size;
@@ -17,6 +17,7 @@ exports.__esModule = true;
17
17
  exports.getNestedItemsIds = void 0;
18
18
  var jsx_runtime_1 = require("react/jsx-runtime");
19
19
  var isArray_1 = __importDefault(require("lodash-es/isArray"));
20
+ var isEmpty_1 = __importDefault(require("lodash-es/isEmpty"));
20
21
  var isEqual_1 = __importDefault(require("lodash-es/isEqual"));
21
22
  var react_1 = require("react");
22
23
  var react_use_1 = require("react-use");
@@ -71,13 +72,19 @@ function CheckboxTreeField(props) {
71
72
  }), selectedIds = _a.selectedIds, setSelectedIds = _a.setSelectedIds;
72
73
  var onItemSelect = (0, react_1.useCallback)(function (checkbox) {
73
74
  if (checkbox.hasItems) {
74
- var selectedItemIds = (0, exports.getNestedItemsIds)(checkbox, props.primaryKey, props.hasOnlyLeafCheckboxes);
75
- setSelectedIds(selectedItemIds);
75
+ var nestedIds = (0, exports.getNestedItemsIds)(checkbox, props.primaryKey, props.hasOnlyLeafCheckboxes);
76
+ var childIds = nestedIds.filter(function (id) { return id !== checkbox.id; });
77
+ var allChildrenSelected = !(0, isEmpty_1["default"])(childIds) && childIds.every(function (id) { return selectedIds.includes(id); });
78
+ // Передаём только те ID, что уже в selectedIds — useDataSelect сбросит эту ветку через isEqual,
79
+ // не затронув остальные выбранные элементы.
80
+ setSelectedIds(allChildrenSelected
81
+ ? nestedIds.filter(function (id) { return selectedIds.includes(id); })
82
+ : nestedIds);
76
83
  }
77
- else if (checkbox.id && !checkbox.hasItems) {
84
+ else if (checkbox.id && !checkbox.hasItems && typeof checkbox.id !== 'boolean') {
78
85
  setSelectedIds(checkbox.id);
79
86
  }
80
- }, [props.hasOnlyLeafCheckboxes, props.primaryKey, setSelectedIds]);
87
+ }, [props.hasOnlyLeafCheckboxes, props.primaryKey, selectedIds, setSelectedIds]);
81
88
  var onReset = (0, react_1.useCallback)(function () {
82
89
  setSelectedIds([]);
83
90
  }, [setSelectedIds]);
@@ -105,6 +112,7 @@ function CheckboxTreeField(props) {
105
112
  items: treeItems,
106
113
  onItemSelect: onItemSelect,
107
114
  selectedIds: selectedIds,
115
+ primaryKey: props.primaryKey,
108
116
  renderCheckbox: renderCheckbox,
109
117
  size: props.size,
110
118
  levelPadding: props.levelPadding,
@@ -112,7 +120,7 @@ function CheckboxTreeField(props) {
112
120
  hasIconExpandOnly: props.hasIconExpandOnly,
113
121
  itemView: TreeItemView,
114
122
  itemProps: props.itemProps
115
- }); }, [treeItems, onItemSelect, selectedIds, renderCheckbox, props.size, props.levelPadding,
123
+ }); }, [treeItems, onItemSelect, selectedIds, props.primaryKey, renderCheckbox, props.size, props.levelPadding,
116
124
  props.hasOnlyLeafCheckboxes, props.hasIconExpandOnly, props.itemProps, TreeItemView]);
117
125
  return components.ui.renderView(props.view || 'form.CheckboxTreeFieldView', viewProps);
118
126
  }
@@ -1,5 +1,5 @@
1
1
  import { ISaveCursorPositionDebounceConfig } from '@steroidsjs/core/hooks/useSaveCursorPosition';
2
- import { ChangeEvent } from 'react';
2
+ import { ChangeEvent, MutableRefObject } from 'react';
3
3
  import { IFieldWrapperInputProps, IFieldWrapperOutputProps } from '../Field/fieldWrapper';
4
4
  import { IBaseFieldProps } from '../InputField/InputField';
5
5
  /**
@@ -35,13 +35,20 @@ export interface INumberFieldProps extends IFieldWrapperInputProps, IBaseFieldPr
35
35
  * Задержка применения введённого значения
36
36
  */
37
37
  debounce?: boolean | ISaveCursorPositionDebounceConfig;
38
+ /**
39
+ * Разделитель тысяч (по умолчанию пустая строка — без разделителя, например 1000).
40
+ * Для отображения "1 000" передать пробел: thousandSeparator=" "
41
+ * @example ' '
42
+ * @example ','
43
+ */
44
+ thousandSeparator?: string;
38
45
  }
39
46
  export interface INumberFieldViewProps extends INumberFieldProps, IFieldWrapperOutputProps {
40
47
  inputProps: {
41
48
  type: string;
42
49
  name: string;
43
- onChange: (value: ChangeEvent<HTMLInputElement> | string) => void;
44
- value: number;
50
+ onInput: (event: ChangeEvent<HTMLInputElement>, value?: string) => void;
51
+ value: number | string;
45
52
  placeholder: string;
46
53
  disabled: boolean;
47
54
  min: number;
@@ -49,7 +56,7 @@ export interface INumberFieldViewProps extends INumberFieldProps, IFieldWrapperO
49
56
  step: string | number;
50
57
  required: boolean;
51
58
  };
52
- inputRef: React.MutableRefObject<any>;
59
+ inputRef: MutableRefObject<HTMLInputElement | null>;
53
60
  onStepUp: VoidFunction;
54
61
  onStepDown: VoidFunction;
55
62
  onKeyDown: VoidFunction;
@@ -14,12 +14,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
16
  exports.__esModule = true;
17
- var react_1 = require("react");
18
- var useInputTypeNumber_1 = __importDefault(require("./hooks/useInputTypeNumber"));
17
+ /* eslint-disable max-len */
18
+ var core_1 = require("@maskito/core");
19
+ var kit_1 = require("@maskito/kit");
20
+ var react_1 = require("@maskito/react");
21
+ var isNil_1 = __importDefault(require("lodash-es/isNil"));
22
+ var react_2 = require("react");
19
23
  var enums_1 = require("../../../enums");
20
24
  var hooks_1 = require("../../../hooks");
21
25
  var fieldWrapper_1 = __importDefault(require("../Field/fieldWrapper"));
22
26
  var DEFAULT_STEP = 1;
27
+ var DECIMAL_SEPARATOR = '.';
28
+ var MINUS_SIGN = '-';
29
+ var isNotEmptyValue = function (rawValue) { return !(0, isNil_1["default"])(rawValue) && rawValue !== ''; };
23
30
  function NumberField(props) {
24
31
  var _a;
25
32
  var components = (0, hooks_1.useComponents)();
@@ -30,27 +37,59 @@ function NumberField(props) {
30
37
  enabled: props.debounce
31
38
  } : ((_a = props.debounce) !== null && _a !== void 0 ? _a : {})))
32
39
  }), currentInputRef = _b.inputRef, onChange = _b.onChange, value = _b.value;
33
- var step = (0, react_1.useMemo)(function () { var _a; return (_a = props.step) !== null && _a !== void 0 ? _a : DEFAULT_STEP; }, [props.step]);
34
- var onInputChange = (0, useInputTypeNumber_1["default"])(currentInputRef, {
35
- max: props.max,
36
- min: props.min,
37
- value: props.input.value,
38
- required: props.required
39
- }, onChange, props.decimal, props.isCanBeNegative).onInputChange;
40
- var onStep = (0, react_1.useCallback)(function (isIncrement) {
41
- var _a;
42
- var currentValue = Number((_a = currentInputRef === null || currentInputRef === void 0 ? void 0 : currentInputRef.current) === null || _a === void 0 ? void 0 : _a.value);
43
- var newValue;
44
- var fixToDecimal = function (rawValue) { return props.decimal ? rawValue.toFixed(props.decimal) : rawValue; };
45
- if (isIncrement) {
46
- newValue = fixToDecimal(currentValue + step);
40
+ var step = (0, react_2.useMemo)(function () { var _a; return (_a = props.step) !== null && _a !== void 0 ? _a : DEFAULT_STEP; }, [props.step]);
41
+ var numberMaskOptions = (0, react_2.useMemo)(function () {
42
+ var _a, _b, _c, _d;
43
+ var min = (_a = props.min) !== null && _a !== void 0 ? _a : (props.isCanBeNegative ? -Infinity : 0);
44
+ var max = (_b = props.max) !== null && _b !== void 0 ? _b : Infinity;
45
+ return (0, kit_1.maskitoNumberOptionsGenerator)({
46
+ min: min,
47
+ max: max,
48
+ precision: (_c = props.decimal) !== null && _c !== void 0 ? _c : 0,
49
+ decimalSeparator: DECIMAL_SEPARATOR,
50
+ minusSign: MINUS_SIGN,
51
+ thousandSeparator: (_d = props.thousandSeparator) !== null && _d !== void 0 ? _d : ''
52
+ });
53
+ }, [props.min, props.max, props.isCanBeNegative, props.decimal, props.thousandSeparator]);
54
+ var maskedInputRef = (0, react_1.useMaskito)({
55
+ options: numberMaskOptions
56
+ });
57
+ (0, react_2.useEffect)(function () {
58
+ if (currentInputRef.current) {
59
+ maskedInputRef(currentInputRef.current);
60
+ }
61
+ }, [currentInputRef, maskedInputRef]);
62
+ (0, react_2.useEffect)(function () {
63
+ var input = currentInputRef.current;
64
+ var currentValue = props.input.value;
65
+ var hasValue = isNotEmptyValue(currentValue);
66
+ var numberValue = Number(currentValue);
67
+ var isValid = !props.required
68
+ || (hasValue && numberValue >= props.min && numberValue <= props.max);
69
+ input.setCustomValidity(isValid ? '' : __('The number is not valid.'));
70
+ }, [currentInputRef, props.required, props.min, props.max, props.input.value, props]);
71
+ var clampToMinMax = (0, react_2.useCallback)(function (rawValue) {
72
+ var val = rawValue;
73
+ if (val < props.min) {
74
+ val = props.min;
47
75
  }
48
- else {
49
- newValue = fixToDecimal(currentValue - step);
76
+ if (val > props.max) {
77
+ val = props.max;
50
78
  }
51
- onInputChange(null, String(newValue));
52
- }, [currentInputRef, onInputChange, props.decimal, step]);
53
- var onKeyDown = (0, react_1.useCallback)(function (event) {
79
+ return val;
80
+ }, [props.min, props.max]);
81
+ var onStep = (0, react_2.useCallback)(function (isIncrement) {
82
+ var _a;
83
+ var currentValue = Number((_a = currentInputRef === null || currentInputRef === void 0 ? void 0 : currentInputRef.current) === null || _a === void 0 ? void 0 : _a.value) || 0;
84
+ var fixToDecimal = function (raw) { return props.decimal
85
+ ? raw.toFixed(props.decimal)
86
+ : String(raw); };
87
+ var newValue = isIncrement
88
+ ? currentValue + step
89
+ : currentValue - step;
90
+ onChange(null, fixToDecimal(clampToMinMax(newValue)));
91
+ }, [currentInputRef, onChange, props.decimal, step, clampToMinMax]);
92
+ var onKeyDown = (0, react_2.useCallback)(function (event) {
54
93
  if (event.key === 'ArrowUp') {
55
94
  onStep(true);
56
95
  }
@@ -58,12 +97,27 @@ function NumberField(props) {
58
97
  onStep(false);
59
98
  }
60
99
  }, [onStep]);
61
- var inputProps = (0, react_1.useMemo)(function () { return (__assign(__assign({}, props.inputProps), { name: props.input.name, value: value, onChange: onInputChange, type: 'text', min: props.min, max: props.max, step: props.step, placeholder: props.placeholder, disabled: props.disabled, required: props.required, autoComplete: 'off', onKeyDown: onKeyDown })); }, [props.inputProps, props.input.name, props.min, props.max, props.step, props.placeholder, props.disabled, props.required, value, onInputChange, onKeyDown]);
62
- var viewProps = (0, react_1.useMemo)(function () { return ({
100
+ var onBlur = (0, react_2.useCallback)(function (event) {
101
+ var rawValue = event.target.value;
102
+ if (rawValue === '') {
103
+ return;
104
+ }
105
+ var numberValue = Number(rawValue);
106
+ var shouldApplyMin = !(0, isNil_1["default"])(props.min) && !Number.isNaN(numberValue) && numberValue < props.min;
107
+ if (shouldApplyMin) {
108
+ onChange(event, String(props.min));
109
+ }
110
+ }, [onChange, props]);
111
+ var displayValue = (0, react_2.useMemo)(function () { return isNotEmptyValue(value)
112
+ ? (0, core_1.maskitoTransform)(String(value), numberMaskOptions)
113
+ : value; }, [value, numberMaskOptions]);
114
+ var inputProps = (0, react_2.useMemo)(function () { return (__assign({ type: 'text', name: props.input.name, value: displayValue, onInput: onChange, placeholder: props.placeholder, min: props.min, max: props.max, step: props.step, disabled: props.disabled, required: props.required, autoComplete: 'off', onKeyDown: onKeyDown }, props.inputProps)); }, [props.inputProps, props.input.name, props.min, props.max, props.step, props.placeholder, props.disabled, props.required, displayValue, onChange, onKeyDown]);
115
+ var viewProps = (0, react_2.useMemo)(function () { return ({
63
116
  viewProps: props.viewProps,
64
117
  inputProps: inputProps,
65
118
  onStepUp: function () { return onStep(true); },
66
119
  onStepDown: function () { return onStep(false); },
120
+ onBlur: onBlur,
67
121
  input: props.input,
68
122
  inputRef: currentInputRef,
69
123
  size: props.size,
@@ -71,7 +125,7 @@ function NumberField(props) {
71
125
  className: props.className,
72
126
  disabled: props.disabled,
73
127
  id: props.id
74
- }); }, [currentInputRef, inputProps, onStep, props.className, props.disabled, props.errors, props.id, props.input, props.size, props.viewProps]);
128
+ }); }, [currentInputRef, inputProps, onBlur, onStep, props.className, props.disabled, props.errors, props.id, props.input, props.size, props.viewProps]);
75
129
  return components.ui.renderView(props.view || 'form.NumberFieldView', viewProps);
76
130
  }
77
131
  NumberField.defaultProps = {
@@ -20,7 +20,7 @@ var getLabel = function (items, id) {
20
20
  return foundItem ? foundItem.label : null;
21
21
  }
22
22
  // Enum
23
- if ((0, isObject_1["default"])(items) && (0, isFunction_1["default"])(items.getLabel)) {
23
+ if ((0, isObject_1["default"])(items) && 'getLabel' in items && (0, isFunction_1["default"])(items.getLabel)) {
24
24
  return items.getLabel(id);
25
25
  }
26
26
  return null;
@@ -42,11 +42,11 @@ function ModalPortal(props) {
42
42
  closeInternal(item);
43
43
  }
44
44
  }, [closeInternal, dispatch, props.animationDelayMc, props.group]);
45
- return (0, orderBy_1["default"])(opened, 'id').map(function (item, index) {
46
- var ModalComponent = item.modal;
47
- var modalProps = __assign(__assign({}, item.props), { index: index, group: group, isClosing: item.isClosing, onClose: function () { return onClose(item); }, closeTimeoutMs: item.props.closeTimeoutMs || props.animationDelayMc });
48
- return ((0, jsx_runtime_1.jsx)(ModalComponent, __assign({}, modalProps), item.id));
49
- });
45
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, orderBy_1["default"])(opened, 'id').map(function (item, index) {
46
+ var ModalComponent = item.modal;
47
+ var modalProps = __assign(__assign({}, item.props), { index: index, group: group, isClosing: item.isClosing, onClose: function () { return onClose(item); }, closeTimeoutMs: item.props.closeTimeoutMs || props.animationDelayMc });
48
+ return ((0, jsx_runtime_1.jsx)(ModalComponent, __assign({}, modalProps), item.id));
49
+ }) }));
50
50
  }
51
51
  ModalPortal.defaultProps = {
52
52
  group: modal_2.MODAL_DEFAULT_GROUP,
@@ -94,8 +94,8 @@ function Router(props) {
94
94
  // Routes state
95
95
  var _c = (0, react_1.useState)((0, helpers_1.treeToList)(props.routes, true, null, props.alwaysAppendParentRoutePath)), routes = _c[0], setRoutes = _c[1];
96
96
  (0, react_use_1.useUpdateEffect)(function () {
97
- setRoutes(props.routes);
98
- }, [props.routes]);
97
+ setRoutes((0, helpers_1.treeToList)(props.routes, true, null, props.alwaysAppendParentRoutePath));
98
+ }, [props.alwaysAppendParentRoutePath, props.routes]);
99
99
  // Fix end slash on switch to base route
100
100
  (0, react_use_1.useUpdateEffect)(function () {
101
101
  if (window.history && pathname === '/' && window.location.pathname.match(/\/$/)) {
@@ -1,4 +1,4 @@
1
1
  import { IRouteItem } from './Router';
2
2
  export declare const findRedirectPathRecursive: (route: IRouteItem, parentPath?: string) => any;
3
3
  export declare const walkRoutesRecursive: (item: IRouteItem | Record<string, any>, defaultItem?: any, parentItem?: any, alwaysAppendParentRoutePath?: boolean) => any;
4
- export declare const treeToList: (item: IRouteItem | Record<string, any>, isRoot?: boolean, parentItem?: any, alwaysAppendParentRoutePath?: boolean) => Record<string, any>;
4
+ export declare const treeToList: (item: IRouteItem | Record<string, any>, isRoot?: boolean, parentItem?: any, alwaysAppendParentRoutePath?: boolean) => any[];
package/utils/data.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * @param {array|object} items
4
4
  * @returns {*}
5
5
  */
6
- export declare const normalizeItems: (items: any) => any;
6
+ export declare const normalizeItems: (items: any) => any[];
7
7
  export declare const checkCondition: (item: any, condition: any) => any;
8
8
  export declare const filterItems: (items: Array<any>, condition: any) => any[];
9
9
  export declare const shouldUpdateSingle: (a: any, b: any) => boolean;
package/utils/data.js CHANGED
@@ -51,7 +51,7 @@ var normalizeItems = function (items) {
51
51
  return items;
52
52
  }
53
53
  // Enum
54
- if ((0, isObject_1["default"])(items) && (0, isFunction_1["default"])(items.getLabels)) {
54
+ if ((0, isObject_1["default"])(items) && 'getLabels' in items && (0, isFunction_1["default"])(items.getLabels)) {
55
55
  var labels_1 = items.getLabels();
56
56
  return Object.keys(labels_1).map(function (id) { return ({
57
57
  id: id,
@@ -1,11 +0,0 @@
1
- import { ChangeEvent, MutableRefObject } from 'react';
2
- interface IInputTypeNumberProps {
3
- max: any;
4
- min: any;
5
- value: string | undefined | null;
6
- required?: boolean;
7
- }
8
- declare const useInputTypeNumber: (currentInputRef: MutableRefObject<HTMLInputElement>, inputTypeNumberProps: IInputTypeNumberProps, onChange: (event: ChangeEvent<HTMLInputElement>, value?: any) => void, decimal: number, isCanBeNegative?: boolean) => {
9
- onInputChange: (event: ChangeEvent<HTMLInputElement>, newValue?: string) => void;
10
- };
11
- export default useInputTypeNumber;
@@ -1,66 +0,0 @@
1
- "use strict";
2
- exports.__esModule = true;
3
- var react_1 = require("react");
4
- var useInputTypeNumber = function (currentInputRef, inputTypeNumberProps, onChange, decimal, isCanBeNegative) {
5
- (0, react_1.useEffect)(function () {
6
- var _a;
7
- var defaultValidity = __('The number is not valid.');
8
- var errorMessage = inputTypeNumberProps.required
9
- && (inputTypeNumberProps.value > inputTypeNumberProps.max
10
- || inputTypeNumberProps.value < inputTypeNumberProps.min
11
- || !inputTypeNumberProps.value)
12
- ? defaultValidity
13
- : '';
14
- (_a = currentInputRef.current) === null || _a === void 0 ? void 0 : _a.setCustomValidity(errorMessage);
15
- }, [currentInputRef, inputTypeNumberProps.value, inputTypeNumberProps.max, inputTypeNumberProps.min, inputTypeNumberProps.required]);
16
- var isValueNumeric = function (value) {
17
- if (!value) {
18
- return true;
19
- }
20
- var numericFloatRegExp = isCanBeNegative
21
- /**
22
- * Подходят отрицательные и положительные числа с плавающей точкой
23
- * @example -1.0
24
- * @example 1.1
25
- */
26
- ? new RegExp("^-?\\d*\\.?\\d{0,".concat(decimal, "}$"))
27
- /**
28
- * Подходят положительные числа с плавающей точкой
29
- * @example 1.1
30
- */
31
- : new RegExp("^\\d*\\.?\\d{0,".concat(decimal, "}$"));
32
- var numericRegExp = isCanBeNegative
33
- /**
34
- * Подходят отрицательные и положительные целые числа
35
- * @example 1
36
- * @example -2
37
- */
38
- ? /^-?\d*$/
39
- /**
40
- * Подходят положительные целые числа
41
- * @example 1
42
- */
43
- : /^\d+$/;
44
- return decimal ? numericFloatRegExp.test(value) : numericRegExp.test(value);
45
- };
46
- var onInputChange = function (event, newValue) {
47
- var _a;
48
- var value = newValue || ((_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.value);
49
- if (isValueNumeric(value)) {
50
- if (value !== '') {
51
- var numericValue = Number(value);
52
- if (numericValue > inputTypeNumberProps.max) {
53
- value = inputTypeNumberProps.max;
54
- }
55
- else if (numericValue < inputTypeNumberProps.min) {
56
- value = inputTypeNumberProps.min;
57
- }
58
- }
59
- onChange(event, value);
60
- }
61
- };
62
- return {
63
- onInputChange: onInputChange
64
- };
65
- };
66
- exports["default"] = useInputTypeNumber;