@steroidsjs/core 3.0.0-beta.80 → 3.0.0-beta.82
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/docs-autogen-result.json +398 -43
- package/en.json +23 -1
- package/hooks/useAbsolutePositioning.d.ts +56 -7
- package/hooks/useAbsolutePositioning.js +39 -131
- package/hooks/useApplication.js +2 -0
- package/hooks/useDataSelect.js +3 -0
- package/package.json +1 -1
- package/ui/content/Chart/Chart.d.ts +37 -0
- package/ui/content/Chart/Chart.js +19 -0
- package/ui/content/Chart/index.d.ts +2 -0
- package/ui/content/Chart/index.js +7 -0
- package/ui/content/DropDown/DropDown.d.ts +1 -1
- package/ui/content/DropDown/DropDown.js +1 -1
- package/ui/content/index.d.ts +2 -1
- package/ui/content/index.js +3 -1
- package/ui/form/CheckboxListField/CheckboxListField.d.ts +1 -1
- package/ui/form/CheckboxListField/CheckboxListField.js +1 -1
- package/ui/form/DateField/useDateRange.d.ts +2 -1
- package/ui/form/DateField/useDateRange.js +23 -0
- package/ui/form/DateRangeField/DateRangeField.js +3 -1
- package/ui/form/DateTimeRangeField/DateTimeRangeField.js +3 -1
- package/ui/form/FileField/FileField.d.ts +5 -0
- package/ui/form/FileField/FileField.js +11 -0
- package/ui/form/RadioListField/RadioListField.js +1 -1
- package/ui/layout/Sidebar/Sidebar.d.ts +0 -5
- package/ui/layout/Sidebar/Sidebar.js +1 -4
- package/ui/layout/Tooltip/Tooltip.d.ts +3 -7
- package/ui/layout/Tooltip/Tooltip.js +17 -49
- package/utils/calculateComponentAbsolutePosition.d.ts +6 -0
- package/{ui/layout/Tooltip/calculate.js → utils/calculateComponentAbsolutePosition.js} +64 -58
- package/utils/calendar.js +2 -0
- package/ui/layout/Tooltip/calculate.d.ts +0 -6
package/en.json
CHANGED
|
@@ -782,5 +782,27 @@
|
|
|
782
782
|
" Элементы меню": " Menu Items",
|
|
783
783
|
"При указании данного свойства, после нажатия на кнопку и до выполнения действия будет отображено нативное\nокно с текстом подтверждения - `window.confirm('Ваш текст')`.": "When this property is specified, after clicking the button and before performing the action, a native \nwindow with the confirmation text will be displayed - `window.confirm('Your text')`.",
|
|
784
784
|
"Контент, который отобразиться, если элемент навигации будет активен": "The content that will be displayed if the navigation element is active",
|
|
785
|
-
" Используется для управления раскрытием всех элементов в дереве": " Used to control the expansion of all items in the tree"
|
|
785
|
+
" Используется для управления раскрытием всех элементов в дереве": " Used to control the expansion of all items in the tree",
|
|
786
|
+
"\nСписок с чекбоксами. Используется в формах для выбора нескольких значений.\n": "",
|
|
787
|
+
"Разница времени с бекендом (в микросекундах)": "",
|
|
788
|
+
"Временная зона бекенда": "",
|
|
789
|
+
"Исходный язык": "",
|
|
790
|
+
"Переводы сообщений": "",
|
|
791
|
+
"Показывать ли компонент сразу после рендера страницы": "",
|
|
792
|
+
"Объект стилей для позиционирования стрелки": "",
|
|
793
|
+
"Позиция компонента слева": "",
|
|
794
|
+
"Позиция компонента справа": "",
|
|
795
|
+
"Позиция компонента сверху": "",
|
|
796
|
+
"Обработчик события загрузки файлов": "",
|
|
797
|
+
"Если в форме есть элементы \\<input\\>, то произойдет автоматическая фокусировка на первом из них": "",
|
|
798
|
+
"Варианты абсолютного позиционирования": "",
|
|
799
|
+
"Получение экземпляра `dayjs` с учетом временной зоны бекенда": "",
|
|
800
|
+
"Алиас для метода `translate`": "",
|
|
801
|
+
"Перевод сообщения": "",
|
|
802
|
+
"Компонент графика из библиотеки nivo": "",
|
|
803
|
+
"Конфигурация, настройки отображения графика": "",
|
|
804
|
+
"Данные для графика": "",
|
|
805
|
+
"Фиксированная высота графика в пикселях": "",
|
|
806
|
+
"Использовать ли дефолтную конфигурацию для графика типа line": "",
|
|
807
|
+
"Этот компонент позволяет создавать в проекте графики разных типов. Под капотом для графиков используется библиотека nivo.\nДля работы этого компонента необходимо установить в проекте зависимости @nivo/core и пакет конкретного графика nivo, например @nivo/line.\nКомпонент графика nivo нужно передать в пропс chartComponent": ""
|
|
786
808
|
}
|
|
@@ -1,14 +1,55 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
interface
|
|
2
|
+
export interface IComponentStylePosition {
|
|
3
|
+
/**
|
|
4
|
+
* Позиция компонента слева
|
|
5
|
+
*/
|
|
3
6
|
left: 'unset' | number;
|
|
7
|
+
/**
|
|
8
|
+
* Позиция компонента справа
|
|
9
|
+
*/
|
|
4
10
|
right: 'unset' | number;
|
|
11
|
+
/**
|
|
12
|
+
* Позиция компонента сверху
|
|
13
|
+
*/
|
|
5
14
|
top: 'unset' | number;
|
|
6
15
|
}
|
|
16
|
+
export interface IComponentArrowPosition {
|
|
17
|
+
/**
|
|
18
|
+
* Позиция стрелки слева
|
|
19
|
+
*/
|
|
20
|
+
left?: number | string;
|
|
21
|
+
/**
|
|
22
|
+
* Позиция стрелки справа
|
|
23
|
+
*/
|
|
24
|
+
right?: number | string;
|
|
25
|
+
/**
|
|
26
|
+
* Позиция стрелки сверху
|
|
27
|
+
*/
|
|
28
|
+
top?: number | string;
|
|
29
|
+
/**
|
|
30
|
+
* Позиция стрелки снизу
|
|
31
|
+
*/
|
|
32
|
+
bottom?: number | string;
|
|
33
|
+
}
|
|
34
|
+
export declare const enum Position {
|
|
35
|
+
TOP = "top",
|
|
36
|
+
TOP_LEFT = "topLeft",
|
|
37
|
+
TOP_RIGHT = "topRight",
|
|
38
|
+
BOTTOM = "bottom",
|
|
39
|
+
BOTTOM_LEFT = "bottomLeft",
|
|
40
|
+
BOTTOM_RIGHT = "bottomRight",
|
|
41
|
+
LEFT = "left",
|
|
42
|
+
LEFT_TOP = "leftTop",
|
|
43
|
+
LEFT_BOTTOM = "leftBottom",
|
|
44
|
+
RIGHT = "right",
|
|
45
|
+
RIGHT_TOP = "rightTop",
|
|
46
|
+
RIGHT_BOTTOM = "rightBottom"
|
|
47
|
+
}
|
|
7
48
|
/**
|
|
8
49
|
* Варианты абсолютного позиционирования
|
|
9
50
|
* @example 'top'
|
|
10
51
|
*/
|
|
11
|
-
type
|
|
52
|
+
export type PositionType = keyof typeof Position | string;
|
|
12
53
|
export interface IAbsolutePositioningInputProps {
|
|
13
54
|
/**
|
|
14
55
|
* Включает "умное" позиционирование - если компонент не может быть помещен в промежуток между целевым компонентом
|
|
@@ -32,13 +73,17 @@ export interface IAbsolutePositioningInputProps {
|
|
|
32
73
|
/**
|
|
33
74
|
* Позиционирование компонента, относительно целевого элемента
|
|
34
75
|
*/
|
|
35
|
-
position:
|
|
76
|
+
position: PositionType;
|
|
36
77
|
/**
|
|
37
78
|
* Отобразить или скрыть компонент.
|
|
38
79
|
* Включает "ручной режим", при котором можно задать логику отображения компонента извне,
|
|
39
80
|
* через измененение данного свойства.
|
|
40
81
|
*/
|
|
41
82
|
visible?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Показывать ли компонент сразу после рендера страницы
|
|
85
|
+
*/
|
|
86
|
+
defaultVisible?: boolean;
|
|
42
87
|
/**
|
|
43
88
|
* Обработчик изменения свойства isComponentVisible (отображение на странице).
|
|
44
89
|
* Возвращает значение isComponentVisible.
|
|
@@ -62,15 +107,19 @@ export interface IAbsolutePositioningOutputProps {
|
|
|
62
107
|
/**
|
|
63
108
|
* Объект стилей для абсолютного позиционирования
|
|
64
109
|
*/
|
|
65
|
-
style:
|
|
110
|
+
style: IComponentStylePosition;
|
|
111
|
+
/**
|
|
112
|
+
* Объект стилей для позиционирования стрелки
|
|
113
|
+
*/
|
|
114
|
+
arrowPosition?: IComponentArrowPosition;
|
|
66
115
|
}
|
|
67
116
|
export default function useAbsolutePositioning(props: IAbsolutePositioningInputProps): {
|
|
68
117
|
isComponentExist: boolean;
|
|
69
118
|
isComponentVisible: boolean;
|
|
70
|
-
style:
|
|
119
|
+
style: IComponentStylePosition;
|
|
71
120
|
position: string;
|
|
72
|
-
|
|
121
|
+
arrowPosition: IComponentArrowPosition;
|
|
122
|
+
calculateAbsolutePosition: (newPosition: PositionType, parentRef: any, componentSize: any, arrowSize?: any) => void;
|
|
73
123
|
onShow: () => void;
|
|
74
124
|
onHide: () => void;
|
|
75
125
|
};
|
|
76
|
-
export {};
|
|
@@ -1,146 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
exports.__esModule = true;
|
|
6
|
+
exports.Position = void 0;
|
|
3
7
|
var react_1 = require("react");
|
|
8
|
+
var calculateComponentAbsolutePosition_1 = __importDefault(require("../utils/calculateComponentAbsolutePosition"));
|
|
9
|
+
var Position;
|
|
10
|
+
(function (Position) {
|
|
11
|
+
Position["TOP"] = "top";
|
|
12
|
+
Position["TOP_LEFT"] = "topLeft";
|
|
13
|
+
Position["TOP_RIGHT"] = "topRight";
|
|
14
|
+
Position["BOTTOM"] = "bottom";
|
|
15
|
+
Position["BOTTOM_LEFT"] = "bottomLeft";
|
|
16
|
+
Position["BOTTOM_RIGHT"] = "bottomRight";
|
|
17
|
+
Position["LEFT"] = "left";
|
|
18
|
+
Position["LEFT_TOP"] = "leftTop";
|
|
19
|
+
Position["LEFT_BOTTOM"] = "leftBottom";
|
|
20
|
+
Position["RIGHT"] = "right";
|
|
21
|
+
Position["RIGHT_TOP"] = "rightTop";
|
|
22
|
+
Position["RIGHT_BOTTOM"] = "rightBottom";
|
|
23
|
+
})(Position = exports.Position || (exports.Position = {}));
|
|
24
|
+
var DEFAULT_AUTO_POSITIONING_VALUE = true;
|
|
4
25
|
function useAbsolutePositioning(props) {
|
|
5
26
|
var _a = (0, react_1.useState)(props.visible), isComponentExist = _a[0], setIsComponentExist = _a[1];
|
|
6
|
-
var _b = (0, react_1.useState)(props.visible), isComponentVisible = _b[0], setIsComponentVisible = _b[1];
|
|
27
|
+
var _b = (0, react_1.useState)(props.visible || props.defaultVisible), isComponentVisible = _b[0], setIsComponentVisible = _b[1];
|
|
7
28
|
var _c = (0, react_1.useState)(props.position), position = _c[0], setPosition = _c[1];
|
|
8
29
|
var _d = (0, react_1.useState)({
|
|
30
|
+
left: null,
|
|
31
|
+
right: null,
|
|
32
|
+
top: null,
|
|
33
|
+
bottom: null
|
|
34
|
+
}), arrowPosition = _d[0], setArrowPosition = _d[1];
|
|
35
|
+
var _e = (0, react_1.useState)({
|
|
9
36
|
left: null,
|
|
10
37
|
right: null,
|
|
11
38
|
top: null
|
|
12
|
-
}), style =
|
|
39
|
+
}), style = _e[0], setStyle = _e[1];
|
|
40
|
+
var hasAutoPositioning = (0, react_1.useMemo)(function () { var _a; return (_a = props.autoPositioning) !== null && _a !== void 0 ? _a : DEFAULT_AUTO_POSITIONING_VALUE; }, [props.autoPositioning]);
|
|
13
41
|
var timerRef = (0, react_1.useRef)(null);
|
|
14
|
-
var calculateAbsolutePosition = (0, react_1.useCallback)(function (newPosition,
|
|
15
|
-
|
|
16
|
-
var _a =
|
|
17
|
-
var parentDimensions = { top: top, right: right, left: left, width: width, height: height };
|
|
18
|
-
parentDimensions.top += window.scrollY;
|
|
19
|
-
var useAutoPositioning = props.autoPositioning;
|
|
20
|
-
// eslint-disable-next-line default-case
|
|
21
|
-
switch (newPosition) {
|
|
22
|
-
case 'top':
|
|
23
|
-
case 'topLeft':
|
|
24
|
-
case 'topRight':
|
|
25
|
-
// Проверка - выходит ли tooltip за верхний край страницы?
|
|
26
|
-
// Если да - меняем позицию на bottom
|
|
27
|
-
if (useAutoPositioning
|
|
28
|
-
&& ((parentDimensions.top - window.scrollY) <= Math.round(componentSize.height + props.gap))) {
|
|
29
|
-
newStyle.top = parentDimensions.top + parentDimensions.height;
|
|
30
|
-
newPosition = newPosition.replace('top', 'bottom');
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
newStyle.top = parentDimensions.top - componentSize.height;
|
|
34
|
-
}
|
|
35
|
-
break;
|
|
36
|
-
case 'bottom':
|
|
37
|
-
case 'bottomLeft':
|
|
38
|
-
case 'bottomRight':
|
|
39
|
-
// Проверка - выходит ли tooltip за нижний край страницы?
|
|
40
|
-
// Если да - меняем позицию на top
|
|
41
|
-
if (useAutoPositioning
|
|
42
|
-
&& ((window.innerHeight - (parentDimensions.top + parentDimensions.height - window.scrollY))) <= Math.round(componentSize.height + props.gap)) {
|
|
43
|
-
newStyle.top = parentDimensions.top - componentSize.height;
|
|
44
|
-
newPosition = newPosition.replace('bottom', 'top');
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
newStyle.top = parentDimensions.top + parentDimensions.height;
|
|
48
|
-
}
|
|
49
|
-
break;
|
|
50
|
-
case 'left':
|
|
51
|
-
case 'leftTop':
|
|
52
|
-
case 'leftBottom':
|
|
53
|
-
// Проверка - выходит ли tooltip за левый край страницы?
|
|
54
|
-
// Если да - меняем позицию на right
|
|
55
|
-
if (useAutoPositioning && (parentDimensions.left <= Math.round(componentSize.width + props.gap))) {
|
|
56
|
-
newStyle.left = parentDimensions.right;
|
|
57
|
-
newPosition = newPosition.replace('left', 'right');
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
newStyle.left = parentDimensions.left - componentSize.width;
|
|
61
|
-
}
|
|
62
|
-
break;
|
|
63
|
-
case 'right':
|
|
64
|
-
case 'rightTop':
|
|
65
|
-
case 'rightBottom':
|
|
66
|
-
// Проверка - выходит ли tooltip за правый край страницы?
|
|
67
|
-
// Если да - меняем позицию на left
|
|
68
|
-
if (useAutoPositioning
|
|
69
|
-
&& (document.body.clientWidth - parentDimensions.right <= Math.round(componentSize.width + props.gap))) {
|
|
70
|
-
newStyle.left = parentDimensions.left - componentSize.width;
|
|
71
|
-
newPosition = newPosition.replace('right', 'left');
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
newStyle.left = parentDimensions.right;
|
|
75
|
-
}
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
// eslint-disable-next-line default-case
|
|
79
|
-
switch (newPosition) {
|
|
80
|
-
case 'top':
|
|
81
|
-
case 'bottom':
|
|
82
|
-
// Выравнивание по середине
|
|
83
|
-
newStyle.left = (parentDimensions.left + (parentDimensions.width / 2)) - (componentSize.width / 2);
|
|
84
|
-
break;
|
|
85
|
-
case 'topLeft':
|
|
86
|
-
case 'bottomLeft':
|
|
87
|
-
// Ширина tooltip больше родителя - стрелка на середину родителя
|
|
88
|
-
newStyle.left = parentDimensions.left;
|
|
89
|
-
break;
|
|
90
|
-
case 'topRight':
|
|
91
|
-
case 'bottomRight':
|
|
92
|
-
// Ширина tooltip больше родителя - стрелка на середину родителя
|
|
93
|
-
newStyle.right = document.body.clientWidth - parentDimensions.right;
|
|
94
|
-
break;
|
|
95
|
-
case 'left':
|
|
96
|
-
case 'right':
|
|
97
|
-
newStyle.top = (parentDimensions.top + (parentDimensions.height / 2)) - (componentSize.height / 2);
|
|
98
|
-
break;
|
|
99
|
-
case 'leftTop':
|
|
100
|
-
case 'rightTop':
|
|
101
|
-
newStyle.top = parentDimensions.top;
|
|
102
|
-
break;
|
|
103
|
-
case 'leftBottom':
|
|
104
|
-
case 'rightBottom':
|
|
105
|
-
newStyle.top = parentDimensions.top + parentDimensions.height - componentSize.height;
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
// Проверка - при позиционировании top/bottom tooltip не выходит за пределы страницы по горизонтали
|
|
109
|
-
if (newPosition.includes('top') || newPosition.includes('bottom')) {
|
|
110
|
-
if (!newPosition.includes('Left')
|
|
111
|
-
&& (newStyle.left < 0 || parentDimensions.left
|
|
112
|
-
<= Math.round((componentSize.width - parentDimensions.width) + props.gap))) {
|
|
113
|
-
newStyle.right = null;
|
|
114
|
-
newPosition = newPosition.replace('Right', 'Left');
|
|
115
|
-
newStyle.left = parentDimensions.left;
|
|
116
|
-
}
|
|
117
|
-
if (!newPosition.includes('Right')
|
|
118
|
-
&& (document.body.clientWidth - parentDimensions.right
|
|
119
|
-
<= Math.round((componentSize.width - parentDimensions.width) + props.gap))) {
|
|
120
|
-
newPosition = newPosition.replace('Left', 'Right');
|
|
121
|
-
newStyle.left = null;
|
|
122
|
-
newStyle.right = document.body.clientWidth - parentDimensions.right;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
// Проверка - при позиционировании left/right tooltip не выходит за пределы страницы по вертикали
|
|
126
|
-
if (newPosition.includes('left') || newPosition.includes('right')) {
|
|
127
|
-
if (!newPosition.includes('Top')
|
|
128
|
-
&& parentDimensions.top - window.scrollY
|
|
129
|
-
<= Math.round((componentSize.height - parentDimensions.height) + props.gap)) {
|
|
130
|
-
newPosition = newPosition.replace('Bottom', 'Top');
|
|
131
|
-
newStyle.top = parentDimensions.top;
|
|
132
|
-
}
|
|
133
|
-
if (!newPosition.includes('Bottom')
|
|
134
|
-
&& (window.innerHeight - (parentDimensions.top + parentDimensions.height - window.scrollY)
|
|
135
|
-
<= Math.round((componentSize.height - parentDimensions.height) + props.gap))) {
|
|
136
|
-
newPosition = newPosition.replace('Top', 'Bottom');
|
|
137
|
-
newStyle.top = parentDimensions.top + parentDimensions.height - componentSize.height;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
42
|
+
var calculateAbsolutePosition = (0, react_1.useCallback)(function (newPosition, parentRef, componentSize, arrowSize) {
|
|
43
|
+
if (arrowSize === void 0) { arrowSize = null; }
|
|
44
|
+
var _a = (0, calculateComponentAbsolutePosition_1["default"])(props.gap, newPosition, parentRef, componentSize, arrowSize, hasAutoPositioning), newStyle = _a.style, calculatedPosition = _a.position, calculatedArrowPosition = _a.arrowPosition;
|
|
140
45
|
setStyle(newStyle);
|
|
141
|
-
setPosition(
|
|
142
|
-
|
|
143
|
-
|
|
46
|
+
setPosition(calculatedPosition);
|
|
47
|
+
if (calculatedArrowPosition) {
|
|
48
|
+
setArrowPosition(calculatedArrowPosition);
|
|
49
|
+
}
|
|
50
|
+
}, [hasAutoPositioning, props.gap]);
|
|
144
51
|
var onShow = (0, react_1.useCallback)(function () {
|
|
145
52
|
if (timerRef.current) {
|
|
146
53
|
clearTimeout(timerRef.current);
|
|
@@ -180,6 +87,7 @@ function useAbsolutePositioning(props) {
|
|
|
180
87
|
isComponentVisible: isComponentVisible,
|
|
181
88
|
style: style,
|
|
182
89
|
position: position,
|
|
90
|
+
arrowPosition: arrowPosition,
|
|
183
91
|
calculateAbsolutePosition: calculateAbsolutePosition,
|
|
184
92
|
onShow: onShow,
|
|
185
93
|
onHide: onHide
|
package/hooks/useApplication.js
CHANGED
|
@@ -55,6 +55,7 @@ var merge_1 = __importDefault(require("lodash-es/merge"));
|
|
|
55
55
|
var react_1 = require("react");
|
|
56
56
|
var relativeTime_1 = __importDefault(require("dayjs/plugin/relativeTime"));
|
|
57
57
|
var localizedFormat_1 = __importDefault(require("dayjs/plugin/localizedFormat"));
|
|
58
|
+
var customParseFormat_1 = __importDefault(require("dayjs/plugin/customParseFormat"));
|
|
58
59
|
var dayjs_1 = __importDefault(require("dayjs"));
|
|
59
60
|
var utc_1 = __importDefault(require("dayjs/plugin/utc"));
|
|
60
61
|
var ThemeProvider_1 = __importDefault(require("../providers/ThemeProvider"));
|
|
@@ -99,6 +100,7 @@ function useApplication(config) {
|
|
|
99
100
|
var useGlobal = config.useGlobal !== false;
|
|
100
101
|
//Extending dayjs / day.js with modules that used in steroids
|
|
101
102
|
dayjs_1["default"].extend(relativeTime_1["default"]);
|
|
103
|
+
dayjs_1["default"].extend(customParseFormat_1["default"]);
|
|
102
104
|
dayjs_1["default"].extend(localizedFormat_1["default"]);
|
|
103
105
|
dayjs_1["default"].extend(utc_1["default"]);
|
|
104
106
|
var components = (0, useComponents_1["default"])();
|
package/hooks/useDataSelect.js
CHANGED
|
@@ -102,6 +102,9 @@ function useDataSelect(config) {
|
|
|
102
102
|
if (selectedIds.length !== 1 || selectedIds[0] !== id_1) {
|
|
103
103
|
setSelectedIdsInternal([id_1]);
|
|
104
104
|
}
|
|
105
|
+
else if (selectedIds.length === 1 && selectedIds[0] === id_1) {
|
|
106
|
+
setSelectedIdsInternal([]);
|
|
107
|
+
}
|
|
105
108
|
setIsOpened(false);
|
|
106
109
|
}
|
|
107
110
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
/**
|
|
3
|
+
* Chart
|
|
4
|
+
* Этот компонент позволяет создавать в проекте графики разных типов. Под капотом для графиков используется библиотека nivo.
|
|
5
|
+
* Для работы этого компонента необходимо установить в проекте зависимости @nivo/core и пакет конкретного графика nivo, например @nivo/line.
|
|
6
|
+
* Компонент графика nivo нужно передать в пропс chartComponent
|
|
7
|
+
*/
|
|
8
|
+
export interface IChartProps extends IUiComponent {
|
|
9
|
+
/**
|
|
10
|
+
* Компонент графика из библиотеки nivo
|
|
11
|
+
* @example ResponsiveLine
|
|
12
|
+
*/
|
|
13
|
+
chartComponent: any;
|
|
14
|
+
/**
|
|
15
|
+
* Данные для графика
|
|
16
|
+
* @example [{id: 1, value: 15}, {id: 2, value: 30}]
|
|
17
|
+
*/
|
|
18
|
+
data: Record<string, any>[];
|
|
19
|
+
/**
|
|
20
|
+
* Конфигурация, настройки отображения графика
|
|
21
|
+
* @example {lineWidth: 3, pointSize: 10}
|
|
22
|
+
*/
|
|
23
|
+
config?: Record<string, any>;
|
|
24
|
+
/**
|
|
25
|
+
* Фиксированная высота графика в пикселях
|
|
26
|
+
* @example 500
|
|
27
|
+
*/
|
|
28
|
+
height?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Использовать ли дефолтную конфигурацию для графика типа line
|
|
31
|
+
* @example ResponsiveLine
|
|
32
|
+
*/
|
|
33
|
+
useDefaultLineChartConfig?: boolean;
|
|
34
|
+
[key: string]: any;
|
|
35
|
+
}
|
|
36
|
+
export type IChartViewProps = IChartProps;
|
|
37
|
+
export default function Chart(props: IChartProps): JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
exports.__esModule = true;
|
|
14
|
+
var hooks_1 = require("../../../hooks");
|
|
15
|
+
function Chart(props) {
|
|
16
|
+
var components = (0, hooks_1.useComponents)();
|
|
17
|
+
return components.ui.renderView(props.view || 'content.ChartView', __assign({}, props));
|
|
18
|
+
}
|
|
19
|
+
exports["default"] = Chart;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
exports.__esModule = true;
|
|
6
|
+
var Chart_1 = __importDefault(require("./Chart"));
|
|
7
|
+
exports["default"] = Chart_1["default"];
|
|
@@ -16,7 +16,7 @@ export interface IDropDownProps extends IAbsolutePositioningInputProps {
|
|
|
16
16
|
* В каком случае закрывать DropDown. По-умолчанию - `click-away`
|
|
17
17
|
* @example click-any
|
|
18
18
|
*/
|
|
19
|
-
closeMode?: 'click-away' | 'click-any';
|
|
19
|
+
closeMode?: 'click-away' | 'click-any' | string;
|
|
20
20
|
/**
|
|
21
21
|
* Позволяет управлять отображением указателя
|
|
22
22
|
* @example true
|
|
@@ -96,7 +96,7 @@ function DropDown(props) {
|
|
|
96
96
|
React.createElement(DropDownView, __assign({}, props, { className: props.className, forwardedRef: forwardedRef, content: props.content, position: position, style: style, calculatePosition: calculatePosition, isComponentVisible: isComponentVisible, onClose: onHide }))))));
|
|
97
97
|
}
|
|
98
98
|
DropDown.defaultProps = {
|
|
99
|
-
autoPositioning:
|
|
99
|
+
autoPositioning: true,
|
|
100
100
|
componentDestroyDelay: 300,
|
|
101
101
|
defaultVisible: false,
|
|
102
102
|
gap: 15,
|
package/ui/content/index.d.ts
CHANGED
|
@@ -8,5 +8,6 @@ import { Detail, DetailItem } from './Detail';
|
|
|
8
8
|
import Icon from './Icon';
|
|
9
9
|
import Menu from './Menu';
|
|
10
10
|
import CopyToClipboard from './CopyToClipboard';
|
|
11
|
+
import Chart from './Chart';
|
|
11
12
|
import Slider from './Slider';
|
|
12
|
-
export { Avatar, AvatarGroup, Accordion, AccordionItem, Alert, Card, DropDown, Badge, Detail, DetailItem, Icon, Menu, CopyToClipboard, Slider, };
|
|
13
|
+
export { Avatar, AvatarGroup, Accordion, AccordionItem, Alert, Card, DropDown, Badge, Detail, DetailItem, Icon, Menu, CopyToClipboard, Chart, Slider, };
|
package/ui/content/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
exports.__esModule = true;
|
|
6
|
-
exports.Slider = exports.CopyToClipboard = exports.Menu = exports.Icon = exports.DetailItem = exports.Detail = exports.Badge = exports.DropDown = exports.Card = exports.Alert = exports.AccordionItem = exports.Accordion = exports.AvatarGroup = exports.Avatar = void 0;
|
|
6
|
+
exports.Slider = exports.Chart = exports.CopyToClipboard = exports.Menu = exports.Icon = exports.DetailItem = exports.Detail = exports.Badge = exports.DropDown = exports.Card = exports.Alert = exports.AccordionItem = exports.Accordion = exports.AvatarGroup = exports.Avatar = void 0;
|
|
7
7
|
var Avatar_1 = require("./Avatar");
|
|
8
8
|
exports.Avatar = Avatar_1.Avatar;
|
|
9
9
|
exports.AvatarGroup = Avatar_1.AvatarGroup;
|
|
@@ -27,5 +27,7 @@ var Menu_1 = __importDefault(require("./Menu"));
|
|
|
27
27
|
exports.Menu = Menu_1["default"];
|
|
28
28
|
var CopyToClipboard_1 = __importDefault(require("./CopyToClipboard"));
|
|
29
29
|
exports.CopyToClipboard = CopyToClipboard_1["default"];
|
|
30
|
+
var Chart_1 = __importDefault(require("./Chart"));
|
|
31
|
+
exports.Chart = Chart_1["default"];
|
|
30
32
|
var Slider_1 = __importDefault(require("./Slider"));
|
|
31
33
|
exports.Slider = Slider_1["default"];
|
|
@@ -7,7 +7,6 @@ import { ICheckboxFieldViewProps } from '../CheckboxField/CheckboxField';
|
|
|
7
7
|
* CheckboxListField
|
|
8
8
|
*
|
|
9
9
|
* Список с чекбоксами. Используется в формах для выбора нескольких значений.
|
|
10
|
-
*
|
|
11
10
|
*/
|
|
12
11
|
export interface ICheckboxListFieldProps extends IFieldWrapperInputProps, IDataProviderConfig, Omit<IDataSelectConfig, 'items'>, IUiComponent {
|
|
13
12
|
/**
|
|
@@ -39,6 +38,7 @@ export interface ICheckboxListFieldViewProps extends IFieldWrapperOutputProps {
|
|
|
39
38
|
orientation?: Orientation;
|
|
40
39
|
disabled?: boolean;
|
|
41
40
|
renderCheckbox: (checkboxProps: ICheckboxFieldViewProps) => JSX.Element;
|
|
41
|
+
size?: Size;
|
|
42
42
|
}
|
|
43
43
|
declare const _default: import("../../../ui/form/Field/fieldWrapper").FieldWrapperComponent<ICheckboxListFieldProps>;
|
|
44
44
|
export default _default;
|
|
@@ -77,7 +77,7 @@ function CheckboxListField(props) {
|
|
|
77
77
|
}
|
|
78
78
|
}, [onReset, prevInputValue, props.input.value, selectedIds.length]);
|
|
79
79
|
var CheckboxFieldView = components.ui.getView('form.CheckboxFieldView');
|
|
80
|
-
var renderCheckbox = function (checkboxProps) { return React.createElement(CheckboxFieldView, __assign({}, checkboxProps)); };
|
|
80
|
+
var renderCheckbox = function (checkboxProps) { return (React.createElement(CheckboxFieldView, __assign({}, checkboxProps))); };
|
|
81
81
|
return components.ui.renderView(props.view || 'form.CheckboxListFieldView', __assign(__assign({}, props), { items: items, inputProps: inputProps, onItemSelect: onItemSelect, selectedIds: selectedIds, renderCheckbox: renderCheckbox }));
|
|
82
82
|
}
|
|
83
83
|
CheckboxListField.defaultProps = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { IDateInputStateInput } from '@steroidsjs/core/ui/form/DateField/useDateInputState';
|
|
2
|
+
interface IUseDateRangeProps extends Pick<IDateInputStateInput, 'displayFormat' | 'valueFormat' | 'useUTC' | 'dateInUTC'> {
|
|
2
3
|
onCloseFrom: any;
|
|
3
4
|
onCloseTo: any;
|
|
4
5
|
onClearFrom: any;
|
|
@@ -10,9 +10,14 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
};
|
|
11
11
|
return __assign.apply(this, arguments);
|
|
12
12
|
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
13
16
|
exports.__esModule = true;
|
|
14
17
|
var react_1 = require("react");
|
|
15
18
|
var react_use_1 = require("react-use");
|
|
19
|
+
var dayjs_1 = __importDefault(require("dayjs"));
|
|
20
|
+
var calendar_1 = require("@steroidsjs/core/utils/calendar");
|
|
16
21
|
function useDateRange(props) {
|
|
17
22
|
// Tracking focus for input being edited
|
|
18
23
|
var _a = (0, react_1.useState)('from'), focus = _a[0], setFocus = _a[1];
|
|
@@ -64,6 +69,24 @@ function useDateRange(props) {
|
|
|
64
69
|
}
|
|
65
70
|
// eslint-disable-next-line max-len
|
|
66
71
|
}, [focus, onClose, prevValueFrom, prevValueTo, props, props.inputFrom.onChange, props.inputFrom.value, props.inputTo.onChange, props.inputTo.value]);
|
|
72
|
+
// Swap start and end dates if start date is later than end date
|
|
73
|
+
(0, react_1.useEffect)(function () {
|
|
74
|
+
if (props.inputFrom.value
|
|
75
|
+
&& props.inputTo.value
|
|
76
|
+
&& ((0, dayjs_1["default"])(props.inputTo.value).isBefore((0, dayjs_1["default"])(props.inputFrom.value)))) {
|
|
77
|
+
var convertedDateFrom = (0, calendar_1.convertDate)(props.inputFrom.value, props.valueFormat, props.valueFormat, props.useUTC, props.dateInUTC);
|
|
78
|
+
var convertedDateTo = (0, calendar_1.convertDate)(props.inputTo.value, props.valueFormat, props.valueFormat, props.useUTC, props.dateInUTC);
|
|
79
|
+
props.inputFrom.onChange.call(null, convertedDateTo);
|
|
80
|
+
props.inputTo.onChange.call(null, convertedDateFrom);
|
|
81
|
+
}
|
|
82
|
+
}, [props.dateInUTC,
|
|
83
|
+
props.inputFrom.onChange,
|
|
84
|
+
props.inputFrom.value,
|
|
85
|
+
props.inputTo.onChange,
|
|
86
|
+
props.inputTo.value,
|
|
87
|
+
props.useUTC,
|
|
88
|
+
props.valueFormat,
|
|
89
|
+
]);
|
|
67
90
|
return {
|
|
68
91
|
focus: focus,
|
|
69
92
|
onClose: onClose,
|
|
@@ -62,7 +62,9 @@ function DateRangeField(props) {
|
|
|
62
62
|
inputPropsTo: inputPropsTo,
|
|
63
63
|
inputFrom: props.inputFrom,
|
|
64
64
|
inputTo: props.inputTo,
|
|
65
|
-
useSmartFocus: true
|
|
65
|
+
useSmartFocus: true,
|
|
66
|
+
displayFormat: props.displayFormat,
|
|
67
|
+
valueFormat: props.valueFormat
|
|
66
68
|
}), focus = _c.focus, onClose = _c.onClose, onClear = _c.onClear, extendedInputPropsFrom = _c.extendedInputPropsFrom, extendedInputPropsTo = _c.extendedInputPropsTo;
|
|
67
69
|
// Calendar props
|
|
68
70
|
var calendarProps = (0, react_1.useMemo)(function () { return ({
|
|
@@ -76,7 +76,9 @@ function DateTimeRangeField(props) {
|
|
|
76
76
|
inputPropsTo: inputPropsTo,
|
|
77
77
|
inputFrom: props.inputFrom,
|
|
78
78
|
inputTo: props.inputTo,
|
|
79
|
-
useSmartFocus: false
|
|
79
|
+
useSmartFocus: false,
|
|
80
|
+
displayFormat: props.displayFormat,
|
|
81
|
+
valueFormat: props.valueFormat
|
|
80
82
|
}), focus = _e.focus, onClose = _e.onClose, onClear = _e.onClear, extendedInputPropsFrom = _e.extendedInputPropsFrom, extendedInputPropsTo = _e.extendedInputPropsTo;
|
|
81
83
|
// Calendar props
|
|
82
84
|
var calendarProps = (0, react_1.useMemo)(function () { return (__assign({ value: [dateValueFrom, dateValueTo], onChange: focus === 'from' ? onDateFromSelect : onDateToSelect, valueFormat: dateValueFormat }, props.calendarProps)); }, [dateValueFormat, dateValueFrom, dateValueTo, focus, onDateFromSelect, onDateToSelect, props.calendarProps]);
|
|
@@ -94,6 +94,11 @@ export interface IFileFieldItemViewProps extends IFileFieldCommonProps {
|
|
|
94
94
|
*/
|
|
95
95
|
height: string;
|
|
96
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* Обработчик события загрузки файлов
|
|
99
|
+
* @param e
|
|
100
|
+
*/
|
|
101
|
+
onLoad?: () => void;
|
|
97
102
|
progress?: {
|
|
98
103
|
bytesUploaded: number;
|
|
99
104
|
percent: number;
|
|
@@ -42,6 +42,7 @@ var React = __importStar(require("react"));
|
|
|
42
42
|
var File_1 = __importDefault(require("fileup-core/lib/models/File"));
|
|
43
43
|
var first_1 = __importDefault(require("lodash-es/first"));
|
|
44
44
|
var values_1 = __importDefault(require("lodash-es/values"));
|
|
45
|
+
var react_1 = require("react");
|
|
45
46
|
var useFile_1 = __importDefault(require("../../../hooks/useFile"));
|
|
46
47
|
var hooks_1 = require("../../../hooks");
|
|
47
48
|
var fieldWrapper_1 = __importDefault(require("../Field/fieldWrapper"));
|
|
@@ -50,11 +51,21 @@ var FilesLayout;
|
|
|
50
51
|
FilesLayout["list"] = "list";
|
|
51
52
|
FilesLayout["wall"] = "wall";
|
|
52
53
|
})(FilesLayout = exports.FilesLayout || (exports.FilesLayout = {}));
|
|
54
|
+
var FILE_STATUS_END = 'end';
|
|
53
55
|
function FileFieldComponent(props) {
|
|
54
56
|
var components = (0, hooks_1.useComponents)();
|
|
55
57
|
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];
|
|
56
59
|
var FileFieldView = props.view || components.ui.getView('form.FileFieldView');
|
|
57
60
|
var FileFieldItemView = props.itemView || components.ui.getView('form.FileFieldItemView');
|
|
61
|
+
(0, react_1.useEffect)(function () {
|
|
62
|
+
setIsFilesLoaded(files.filter(function (file) { return file._status === FILE_STATUS_END; }).length === files.length);
|
|
63
|
+
}, [files]);
|
|
64
|
+
(0, react_1.useEffect)(function () {
|
|
65
|
+
if (isFilesLoaded && props.onLoad) {
|
|
66
|
+
props.onLoad();
|
|
67
|
+
}
|
|
68
|
+
}, [isFilesLoaded, props]);
|
|
58
69
|
return (React.createElement(FileFieldView, __assign({}, props, { buttonView: props.buttonView, buttonProps: __assign({ label: props.filesLayout === FilesLayout.wall
|
|
59
70
|
? __('Upload')
|
|
60
71
|
: __('Click to Upload'), size: props.size, disabled: props.disabled, onClick: onBrowse }, props.buttonProps), itemView: FileFieldItemView, items: files.map(function (file) {
|