@steroidsjs/core 2.1.0-beta.10 → 2.1.0-beta.14
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/components/StoreComponent.js +1 -1
- package/hoc/file.d.ts +1 -0
- package/hooks/useAbsolutePositioning.d.ts +5 -0
- package/hooks/useAbsolutePositioning.js +6 -6
- package/hooks/useFile.js +14 -2
- package/package.json +83 -82
- package/reducers/index.js +1 -1
- package/ui/content/Detail/Detail.d.ts +102 -0
- package/ui/content/Detail/Detail.js +155 -0
- package/ui/content/Detail/DetailItem.d.ts +43 -0
- package/ui/content/Detail/DetailItem.js +10 -0
- package/ui/content/Detail/demo/basic.d.ts +8 -0
- package/ui/content/Detail/demo/basic.js +56 -0
- package/ui/content/Detail/demo/controls.d.ts +8 -0
- package/ui/content/Detail/demo/controls.js +56 -0
- package/ui/content/Detail/demo/layout.d.ts +8 -0
- package/ui/content/Detail/demo/layout.js +56 -0
- package/ui/content/Detail/demo/responsive.d.ts +8 -0
- package/ui/content/Detail/demo/responsive.js +71 -0
- package/ui/content/Detail/demo/sizes.d.ts +8 -0
- package/ui/content/Detail/demo/sizes.js +61 -0
- package/ui/content/Detail/index.d.ts +3 -0
- package/ui/content/Detail/index.js +10 -0
- package/ui/content/DropDown/DropDown.d.ts +1 -0
- package/ui/content/DropDown/DropDown.js +1 -0
- package/ui/form/DateField/useDateInputState.d.ts +0 -1
- package/ui/form/DropDownField/DropDownField.js +3 -1
- package/ui/form/ImageField/ImageField.d.ts +87 -0
- package/ui/form/ImageField/ImageField.js +145 -0
- package/ui/form/ImageField/index.d.ts +2 -0
- package/ui/form/ImageField/index.js +7 -0
|
@@ -59,7 +59,7 @@ var StoreComponent = /** @class */ (function () {
|
|
|
59
59
|
: history_1.createBrowserHistory;
|
|
60
60
|
this.history = createHistory(__assign(__assign({}, get_1["default"](initialState, 'config.store.history', {})), config.history));
|
|
61
61
|
// Add '?' for fix connected-react-router
|
|
62
|
-
if (process.env.IS_SSR && !this.history.location.search
|
|
62
|
+
if (process.env.IS_SSR && !this.history.location.search) {
|
|
63
63
|
this.history.location.search = '?';
|
|
64
64
|
}
|
|
65
65
|
this._routerReducer = connected_react_router_1.connectRouter(this.history);
|
package/hoc/file.d.ts
CHANGED
|
@@ -10,6 +10,11 @@ interface IStyleObj {
|
|
|
10
10
|
*/
|
|
11
11
|
declare type Position = 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight' | 'left' | 'leftTop' | 'leftBottom' | 'right' | 'rightTop' | 'rightBottom' | string;
|
|
12
12
|
export interface IAbsolutePositioningInputProps {
|
|
13
|
+
/**
|
|
14
|
+
* Включает "умное" позиционирование - если компонент не может быть помещен в промежуток между целевым компонентом
|
|
15
|
+
* и краем viewport, тогда он будет показан в противоположном направлении от заданного в свойстве position.
|
|
16
|
+
*/
|
|
17
|
+
autoPositioning?: boolean;
|
|
13
18
|
/**
|
|
14
19
|
* Дочерние элементы
|
|
15
20
|
*/
|
|
@@ -12,11 +12,11 @@ function useAbsolutePositioning(props) {
|
|
|
12
12
|
}), style = _d[0], setStyle = _d[1];
|
|
13
13
|
var timerRef = react_1.useRef(null);
|
|
14
14
|
var calculateAbsolutePosition = react_1.useCallback(function (newPosition, childRef, componentSize) {
|
|
15
|
-
if (newPosition === void 0) { newPosition = 'pos'; }
|
|
16
15
|
var newStyle = { left: null, right: null, top: null };
|
|
17
16
|
var _a = childRef.getBoundingClientRect(), top = _a.top, right = _a.right, left = _a.left, width = _a.width, height = _a.height;
|
|
18
17
|
var parentDimensions = { top: top, right: right, left: left, width: width, height: height };
|
|
19
18
|
parentDimensions.top += window.scrollY;
|
|
19
|
+
var useAutoPositioning = props.autoPositioning;
|
|
20
20
|
// eslint-disable-next-line default-case
|
|
21
21
|
switch (newPosition) {
|
|
22
22
|
case 'top':
|
|
@@ -24,7 +24,7 @@ function useAbsolutePositioning(props) {
|
|
|
24
24
|
case 'topRight':
|
|
25
25
|
// Проверка - выходит ли tooltip за верхний край страницы?
|
|
26
26
|
// Если да - меняем позицию на bottom
|
|
27
|
-
if ((parentDimensions.top - window.scrollY) <= Math.round(componentSize.height + props.gap)) {
|
|
27
|
+
if (useAutoPositioning && ((parentDimensions.top - window.scrollY) <= Math.round(componentSize.height + props.gap))) {
|
|
28
28
|
newStyle.top = parentDimensions.top + parentDimensions.height;
|
|
29
29
|
newPosition = newPosition.replace('top', 'bottom');
|
|
30
30
|
}
|
|
@@ -35,9 +35,9 @@ function useAbsolutePositioning(props) {
|
|
|
35
35
|
case 'bottom':
|
|
36
36
|
case 'bottomLeft':
|
|
37
37
|
case 'bottomRight':
|
|
38
|
-
|
|
38
|
+
// Проверка - выходит ли tooltip за нижний край страницы?
|
|
39
39
|
// Если да - меняем позицию на top
|
|
40
|
-
if ((window.innerHeight - (parentDimensions.top + parentDimensions.height - window.scrollY))
|
|
40
|
+
if (useAutoPositioning && ((window.innerHeight - (parentDimensions.top + parentDimensions.height - window.scrollY)))
|
|
41
41
|
<= Math.round(componentSize.height + props.gap)) {
|
|
42
42
|
newStyle.top = parentDimensions.top - componentSize.height;
|
|
43
43
|
newPosition = newPosition.replace('bottom', 'top');
|
|
@@ -51,7 +51,7 @@ function useAbsolutePositioning(props) {
|
|
|
51
51
|
case 'leftBottom':
|
|
52
52
|
// Проверка - выходит ли tooltip за левый край страницы?
|
|
53
53
|
// Если да - меняем позицию на right
|
|
54
|
-
if (parentDimensions.left <= Math.round(componentSize.width + props.gap)) {
|
|
54
|
+
if (useAutoPositioning && (parentDimensions.left <= Math.round(componentSize.width + props.gap))) {
|
|
55
55
|
newStyle.left = parentDimensions.right;
|
|
56
56
|
newPosition = newPosition.replace('left', 'right');
|
|
57
57
|
}
|
|
@@ -64,7 +64,7 @@ function useAbsolutePositioning(props) {
|
|
|
64
64
|
case 'rightBottom':
|
|
65
65
|
// Проверка - выходит ли tooltip за правый край страницы?
|
|
66
66
|
// Если да - меняем позицию на left
|
|
67
|
-
if (document.body.clientWidth - parentDimensions.right <= Math.round(componentSize.width + props.gap)) {
|
|
67
|
+
if (useAutoPositioning && (document.body.clientWidth - parentDimensions.right <= Math.round(componentSize.width + props.gap))) {
|
|
68
68
|
newStyle.left = parentDimensions.left - componentSize.width;
|
|
69
69
|
newPosition = newPosition.replace('right', 'left');
|
|
70
70
|
}
|
package/hooks/useFile.js
CHANGED
|
@@ -39,6 +39,7 @@ function generateBackendUrl(props) {
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
function useFile(props) {
|
|
42
|
+
console.log(props.imagesOnly);
|
|
42
43
|
var uploader = useInitial_1["default"](function () { return new fileup_core_1["default"](__assign(__assign({ dropArea: {}, backendUrl: generateBackendUrl(props) }, props.uploader), { form: __assign(__assign({}, (props.uploader && props.uploader.form)), { multiple: props.multiple }) })); });
|
|
43
44
|
/**
|
|
44
45
|
* Force component update when file status or progress changes
|
|
@@ -178,18 +179,29 @@ function useFile(props) {
|
|
|
178
179
|
/**
|
|
179
180
|
* Remove selected file from uploader
|
|
180
181
|
* @param {File} fileToRemove
|
|
181
|
-
* @private
|
|
182
182
|
*/
|
|
183
183
|
var onRemove = function (fileToRemove) {
|
|
184
184
|
uploader.queue.remove([fileToRemove]);
|
|
185
185
|
forceUpdate();
|
|
186
186
|
};
|
|
187
187
|
var files = [].concat(uploader.queue.getFiles());
|
|
188
|
+
/**
|
|
189
|
+
* Add file to uploader
|
|
190
|
+
* @param {File} newFile
|
|
191
|
+
*/
|
|
192
|
+
var onAdd = function (newFile) {
|
|
193
|
+
if (!props.multiple) {
|
|
194
|
+
uploader.queue.remove(files);
|
|
195
|
+
}
|
|
196
|
+
uploader.queue.add([newFile]);
|
|
197
|
+
forceUpdate();
|
|
198
|
+
};
|
|
188
199
|
return {
|
|
189
200
|
uploader: uploader,
|
|
190
201
|
files: files,
|
|
191
202
|
onBrowse: onBrowse,
|
|
192
|
-
onRemove: onRemove
|
|
203
|
+
onRemove: onRemove,
|
|
204
|
+
onAdd: onAdd
|
|
193
205
|
};
|
|
194
206
|
}
|
|
195
207
|
exports["default"] = useFile;
|
package/package.json
CHANGED
|
@@ -1,84 +1,85 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
2
|
+
"name": "@steroidsjs/core",
|
|
3
|
+
"version": "2.1.0-beta.14",
|
|
4
|
+
"description": "",
|
|
5
|
+
"author": "Vladimir Kozhin <hello@kozhindev.com>",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/steroids/react"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/index.ts",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
"./": "./dist"
|
|
14
|
+
},
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"homepage": "https://github.com/steroids/react",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/steroids/react/issues"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"docs": "typedoc --ignoreCompilerErrors --json typedoc.json .",
|
|
22
|
+
"test": "jest",
|
|
23
|
+
"build": "tsc && cp ./{package.json,LICENSE,README.md} dist/ && cp src/index.d.ts dist/"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"axios": "^0.21.1",
|
|
27
|
+
"connected-react-router": "^6.9.1",
|
|
28
|
+
"domready": "^1.0.8",
|
|
29
|
+
"dot-prop-immutable": "^2.1.0",
|
|
30
|
+
"fileup-core": "^1.2.0",
|
|
31
|
+
"history": "^4.10.1",
|
|
32
|
+
"intl-messageformat": "^2.2.0",
|
|
33
|
+
"js-cookie": "^2.2.1",
|
|
34
|
+
"load-js": "^3.0.3",
|
|
35
|
+
"lodash": "^4.17.21",
|
|
36
|
+
"lodash-es": "^4.17.21",
|
|
37
|
+
"moment": "^2.29.1",
|
|
38
|
+
"path-to-regexp": "^1.7.0",
|
|
39
|
+
"qs": "^6.9.4",
|
|
40
|
+
"query-string": "^6.14.0",
|
|
41
|
+
"react": "^17.0.2",
|
|
42
|
+
"react-click-outside": "^3.0.1",
|
|
43
|
+
"react-day-picker": "^7.4.8",
|
|
44
|
+
"react-dom": "^17.0.2",
|
|
45
|
+
"react-grid-gallery": "^0.4.8",
|
|
46
|
+
"react-image-crop": "^9.0.2",
|
|
47
|
+
"react-input-mask": "^3.0.0-alpha.2",
|
|
48
|
+
"react-redux": "^7.1.1",
|
|
49
|
+
"react-router": "^5.2.0",
|
|
50
|
+
"react-router-dom": "^5.2.0",
|
|
51
|
+
"react-use": "^17.1.0",
|
|
52
|
+
"redux": "^4.0.4",
|
|
53
|
+
"redux-mock-store": "^1.5.4"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@babel/cli": "^7.13.14",
|
|
57
|
+
"@babel/core": "^7.13.15",
|
|
58
|
+
"@babel/preset-env": "^7.13.15",
|
|
59
|
+
"@babel/preset-react": "^7.13.13",
|
|
60
|
+
"@babel/preset-typescript": "^7.13.0",
|
|
61
|
+
"@types/enzyme": "^3.10.8",
|
|
62
|
+
"@types/enzyme-adapter-react-16": "^1.0.6",
|
|
63
|
+
"@types/jest": "^26.0.22",
|
|
64
|
+
"@types/markdown-to-jsx": "^6.11.3",
|
|
65
|
+
"@types/reach__router": "^1.3.7",
|
|
66
|
+
"@types/react": "=17.0.3",
|
|
67
|
+
"@types/react-color": "^3.0.4",
|
|
68
|
+
"@types/react-syntax-highlighter": "^13.5.0",
|
|
69
|
+
"@types/webpack-env": "^1.16.0",
|
|
70
|
+
"@typescript-eslint/eslint-plugin": "^4.15.0",
|
|
71
|
+
"@typescript-eslint/parser": "^4.15.0",
|
|
72
|
+
"@wojtekmaj/enzyme-adapter-react-17": "^0.4.1",
|
|
73
|
+
"enzyme": "^3.11.0",
|
|
74
|
+
"eslint": "^7.20.0",
|
|
75
|
+
"eslint-config-airbnb": "18.2.1",
|
|
76
|
+
"eslint-plugin-import": "^2.22.1",
|
|
77
|
+
"eslint-plugin-jsx-a11y": "^6.4.1",
|
|
78
|
+
"eslint-plugin-react": "^7.21.5",
|
|
79
|
+
"eslint-plugin-react-hooks": "^1.7.0",
|
|
80
|
+
"jest": "^26.6.3",
|
|
81
|
+
"jest-enzyme": "^7.1.2",
|
|
82
|
+
"ts-jest": "^26.5.1",
|
|
83
|
+
"typescript": "^4.1.3"
|
|
84
|
+
}
|
|
84
85
|
}
|
package/reducers/index.js
CHANGED
|
@@ -38,4 +38,4 @@ exports["default"] = (function (asyncReducers) { return redux_1.combineReducers(
|
|
|
38
38
|
list: list_1["default"],
|
|
39
39
|
notifications: notifications_1["default"],
|
|
40
40
|
modal: modal_1["default"],
|
|
41
|
-
screen: screen_1["default"] }, asyncReducers), { router: function (state, action) { return router_1["default"](asyncReducers.router(state, action), action); } })); });
|
|
41
|
+
screen: screen_1["default"] }, asyncReducers), { router: function (state, action) { return router_1["default"](asyncReducers.router ? asyncReducers.router(state, action) : {}, action); } })); });
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { IDetailItemProps } from './DetailItem';
|
|
3
|
+
import { IControlItem } from '../../nav/Controls/Controls';
|
|
4
|
+
/**
|
|
5
|
+
* Detail
|
|
6
|
+
* Представление данных в виде таблицы, в которой поля группируются по принципу "ключ-значение".
|
|
7
|
+
*/
|
|
8
|
+
export declare enum DetailLayoutEnum {
|
|
9
|
+
Horizontal = "horizontal",
|
|
10
|
+
Vertical = "vertical"
|
|
11
|
+
}
|
|
12
|
+
export interface IDetailMedia {
|
|
13
|
+
/**
|
|
14
|
+
* Максимальная ширина таблицы в px
|
|
15
|
+
* @example 600
|
|
16
|
+
*/
|
|
17
|
+
breakpoint: number;
|
|
18
|
+
/**
|
|
19
|
+
* Количество колонок, которое будет применяться, начиная от указанной ширины и меньше
|
|
20
|
+
* @example 2
|
|
21
|
+
*/
|
|
22
|
+
column: number;
|
|
23
|
+
}
|
|
24
|
+
export interface IDetailResponsive {
|
|
25
|
+
/**
|
|
26
|
+
* Перестраивать таблицу при ресайзе
|
|
27
|
+
*/
|
|
28
|
+
enable?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Брейкпоинты
|
|
31
|
+
*/
|
|
32
|
+
media: IDetailMedia[];
|
|
33
|
+
}
|
|
34
|
+
export interface IDetailProps {
|
|
35
|
+
/**
|
|
36
|
+
* Размер ячеек в таблице
|
|
37
|
+
* @example 'sm'
|
|
38
|
+
*/
|
|
39
|
+
size?: Size;
|
|
40
|
+
/**
|
|
41
|
+
* Вариант расположения ячеек "ключ-значение"
|
|
42
|
+
* @example 'horizontal'
|
|
43
|
+
*/
|
|
44
|
+
layout?: DetailLayoutEnum;
|
|
45
|
+
/**
|
|
46
|
+
* Перестраивать таблицу при ресайзе
|
|
47
|
+
* @example {enable: true, media: [{breakpoint: 600, column: 2}]}
|
|
48
|
+
*/
|
|
49
|
+
responsive?: boolean | IDetailResponsive;
|
|
50
|
+
/**
|
|
51
|
+
* Максимальное количество колонок
|
|
52
|
+
* @example 3
|
|
53
|
+
*/
|
|
54
|
+
column?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Заголовок таблицы
|
|
57
|
+
* @example 'User info'
|
|
58
|
+
*/
|
|
59
|
+
title?: string | React.ReactNode;
|
|
60
|
+
/**
|
|
61
|
+
* Контролы, которые нужно расположить рядом с таблицей
|
|
62
|
+
* @example [{label: __(('Edit')), onClick: () => props.onClick()}]
|
|
63
|
+
*/
|
|
64
|
+
controls?: IControlItem[];
|
|
65
|
+
/**
|
|
66
|
+
* Переопределение view React компонента для кастомизации отображения
|
|
67
|
+
* @example MyCustomView
|
|
68
|
+
*/
|
|
69
|
+
view?: CustomView;
|
|
70
|
+
/**
|
|
71
|
+
* Дополнительный CSS-класс для таблицы
|
|
72
|
+
*/
|
|
73
|
+
className?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Дочерние компоненты
|
|
76
|
+
*/
|
|
77
|
+
children: React.ReactNode | React.ReactNode[];
|
|
78
|
+
[key: string]: any;
|
|
79
|
+
}
|
|
80
|
+
export interface IDetailItemOutputProps extends IDetailItemProps {
|
|
81
|
+
colspan: number;
|
|
82
|
+
value: IDetailItemProps['children'];
|
|
83
|
+
}
|
|
84
|
+
export interface IDetailViewProps extends IDetailProps {
|
|
85
|
+
rows: IDetailItemOutputProps[][];
|
|
86
|
+
resizedNodeRef?: (node: HTMLElement) => void;
|
|
87
|
+
}
|
|
88
|
+
export declare const constants: Readonly<{
|
|
89
|
+
MAX_COLUMN: number;
|
|
90
|
+
CELLS_IN_COLUMN: number;
|
|
91
|
+
TABLE_HEAD_COLSPAN: number;
|
|
92
|
+
}>;
|
|
93
|
+
declare function Detail(props: IDetailProps): JSX.Element;
|
|
94
|
+
declare namespace Detail {
|
|
95
|
+
var defaultProps: {
|
|
96
|
+
size: string;
|
|
97
|
+
layout: DetailLayoutEnum;
|
|
98
|
+
column: number;
|
|
99
|
+
responsive: boolean;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export default Detail;
|
|
@@ -0,0 +1,155 @@
|
|
|
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
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
26
|
+
if (mod && mod.__esModule) return mod;
|
|
27
|
+
var result = {};
|
|
28
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
29
|
+
__setModuleDefault(result, mod);
|
|
30
|
+
return result;
|
|
31
|
+
};
|
|
32
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
33
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
34
|
+
};
|
|
35
|
+
exports.__esModule = true;
|
|
36
|
+
exports.constants = exports.DetailLayoutEnum = void 0;
|
|
37
|
+
var react_1 = __importStar(require("react"));
|
|
38
|
+
var isArray_1 = __importDefault(require("lodash/isArray"));
|
|
39
|
+
var orderBy_1 = __importDefault(require("lodash/orderBy"));
|
|
40
|
+
var hooks_1 = require("../../../hooks");
|
|
41
|
+
var DetailItem_1 = __importDefault(require("./DetailItem"));
|
|
42
|
+
/**
|
|
43
|
+
* Detail
|
|
44
|
+
* Представление данных в виде таблицы, в которой поля группируются по принципу "ключ-значение".
|
|
45
|
+
*/
|
|
46
|
+
var DetailLayoutEnum;
|
|
47
|
+
(function (DetailLayoutEnum) {
|
|
48
|
+
DetailLayoutEnum["Horizontal"] = "horizontal";
|
|
49
|
+
DetailLayoutEnum["Vertical"] = "vertical";
|
|
50
|
+
})(DetailLayoutEnum = exports.DetailLayoutEnum || (exports.DetailLayoutEnum = {}));
|
|
51
|
+
exports.constants = Object.freeze({
|
|
52
|
+
MAX_COLUMN: 3,
|
|
53
|
+
CELLS_IN_COLUMN: 2,
|
|
54
|
+
TABLE_HEAD_COLSPAN: 1
|
|
55
|
+
});
|
|
56
|
+
var getDetailItems = function (children) { return (react_1["default"].Children.toArray(children)
|
|
57
|
+
.filter(function (child) { var _a; return ((_a = child === null || child === void 0 ? void 0 : child.type) === null || _a === void 0 ? void 0 : _a.displayName) === DetailItem_1["default"].displayName; })); };
|
|
58
|
+
var normalizeSpan = function (span, column) { return (span > column)
|
|
59
|
+
? column
|
|
60
|
+
: (span || 1); };
|
|
61
|
+
var createRows = function (detailItems, column, layout) {
|
|
62
|
+
var result = [];
|
|
63
|
+
var freeColumns = column;
|
|
64
|
+
var rowIndex = 0;
|
|
65
|
+
result[rowIndex] = [];
|
|
66
|
+
detailItems.forEach(function (detailItem, index) {
|
|
67
|
+
if (!freeColumns) {
|
|
68
|
+
freeColumns = column;
|
|
69
|
+
rowIndex += 1;
|
|
70
|
+
result[rowIndex] = [];
|
|
71
|
+
}
|
|
72
|
+
var isLastDetailItem = index === (detailItems.length - 1);
|
|
73
|
+
var span = normalizeSpan(detailItem.props.span, column);
|
|
74
|
+
var nextSpan = null;
|
|
75
|
+
if (!isLastDetailItem) {
|
|
76
|
+
nextSpan = normalizeSpan(detailItems[index + 1].props.span, column);
|
|
77
|
+
}
|
|
78
|
+
freeColumns -= span;
|
|
79
|
+
if (isLastDetailItem || nextSpan > freeColumns) {
|
|
80
|
+
span += freeColumns;
|
|
81
|
+
freeColumns = 0;
|
|
82
|
+
}
|
|
83
|
+
result[rowIndex].push(__assign(__assign({}, detailItem.props), { colspan: layout === DetailLayoutEnum.Horizontal
|
|
84
|
+
? span * exports.constants.CELLS_IN_COLUMN - exports.constants.TABLE_HEAD_COLSPAN
|
|
85
|
+
: span, value: detailItem }));
|
|
86
|
+
});
|
|
87
|
+
return result;
|
|
88
|
+
};
|
|
89
|
+
var normalizeResponsiveProps = function (props) { return (typeof props === 'boolean'
|
|
90
|
+
? {
|
|
91
|
+
enable: props,
|
|
92
|
+
media: [
|
|
93
|
+
{
|
|
94
|
+
breakpoint: 500,
|
|
95
|
+
column: 1
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
breakpoint: 700,
|
|
99
|
+
column: 2
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
breakpoint: 1000,
|
|
103
|
+
column: 3
|
|
104
|
+
},
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
: __assign(__assign({ enable: true }, props), { media: orderBy_1["default"](props.media, ['breakpoint'], ['asc']) })); };
|
|
108
|
+
function Detail(props) {
|
|
109
|
+
var components = hooks_1.useComponents();
|
|
110
|
+
var detailItems = react_1.useMemo(function () { return getDetailItems(props.children); }, [props.children]);
|
|
111
|
+
var responsiveProps = react_1.useMemo(function () { return normalizeResponsiveProps(props.responsive); }, [props.responsive]);
|
|
112
|
+
var _a = react_1.useState(props.column || exports.constants.MAX_COLUMN), column = _a[0], setColumn = _a[1];
|
|
113
|
+
var _b = react_1.useState(createRows(detailItems, column, props.layout)), rows = _b[0], setRows = _b[1];
|
|
114
|
+
// Add responsive option
|
|
115
|
+
var resizeObserver = react_1.useRef(new ResizeObserver(function (entries) {
|
|
116
|
+
entries.forEach(function (entry) {
|
|
117
|
+
if (!entry.borderBoxSize) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
var inlineSize = (isArray_1["default"](entry.borderBoxSize)
|
|
121
|
+
? entry.borderBoxSize[0]
|
|
122
|
+
: entry.borderBoxSize).inlineSize;
|
|
123
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
124
|
+
for (var _i = 0, _a = responsiveProps.media; _i < _a.length; _i++) {
|
|
125
|
+
var mediaItem = _a[_i];
|
|
126
|
+
if (inlineSize < mediaItem.breakpoint) {
|
|
127
|
+
setColumn(mediaItem.column);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
setColumn(props.column || exports.constants.MAX_COLUMN);
|
|
132
|
+
});
|
|
133
|
+
}));
|
|
134
|
+
var resizedNodeRef = react_1["default"].useCallback(function (node) {
|
|
135
|
+
if (!resizeObserver.current) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (node !== null) {
|
|
139
|
+
resizeObserver.current.observe(node);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
resizeObserver.current.disconnect();
|
|
143
|
+
}, [resizeObserver]);
|
|
144
|
+
react_1.useEffect(function () {
|
|
145
|
+
setRows(createRows(detailItems, column, props.layout));
|
|
146
|
+
}, [column, detailItems, props.layout]);
|
|
147
|
+
return components.ui.renderView(props.view || 'content.DetailView', __assign(__assign(__assign({}, props), { rows: rows }), (responsiveProps.enable ? { resizedNodeRef: resizedNodeRef } : {})));
|
|
148
|
+
}
|
|
149
|
+
exports["default"] = Detail;
|
|
150
|
+
Detail.defaultProps = {
|
|
151
|
+
size: 'sm',
|
|
152
|
+
layout: DetailLayoutEnum.Horizontal,
|
|
153
|
+
column: exports.constants.MAX_COLUMN,
|
|
154
|
+
responsive: true
|
|
155
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* DetailItem
|
|
4
|
+
* Элемент "ключ-значение" в таблице Detail
|
|
5
|
+
*/
|
|
6
|
+
export interface IDetailItemProps {
|
|
7
|
+
/**
|
|
8
|
+
* Наименование
|
|
9
|
+
* @example 'Product'
|
|
10
|
+
*/
|
|
11
|
+
label: string | number | React.ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* Значение
|
|
14
|
+
* @example 'Cloud Database'
|
|
15
|
+
*/
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Количество колонок, которое занимает элемент
|
|
19
|
+
* @example 3
|
|
20
|
+
*/
|
|
21
|
+
span?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Переопределение view React компонента для кастомизации отображения
|
|
24
|
+
* @example MyCustomView
|
|
25
|
+
*/
|
|
26
|
+
view?: CustomView;
|
|
27
|
+
/**
|
|
28
|
+
* Дополнительный CSS-класс для ячейки с наименованием
|
|
29
|
+
*/
|
|
30
|
+
labelClassName?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Дополнительный CSS-класс для ячейки со значением
|
|
33
|
+
*/
|
|
34
|
+
contentClassName?: string;
|
|
35
|
+
}
|
|
36
|
+
declare function DetailItem(props: IDetailItemProps): JSX.Element;
|
|
37
|
+
declare namespace DetailItem {
|
|
38
|
+
var defaultProps: {
|
|
39
|
+
span: number;
|
|
40
|
+
};
|
|
41
|
+
var displayName: string;
|
|
42
|
+
}
|
|
43
|
+
export default DetailItem;
|