@rivtn/noseur 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +2 -0
- package/dist/esm/Template.d.ts +7 -0
- package/dist/esm/Template.js +13 -0
- package/dist/esm/compose/Composed.css +437 -0
- package/dist/esm/compose/exotic/ColorPicker.d.ts +41 -0
- package/dist/esm/compose/exotic/ColorPicker.js +85 -0
- package/dist/esm/compose/exotic/ColorSlider.d.ts +30 -0
- package/dist/esm/compose/exotic/ColorSlider.js +99 -0
- package/dist/esm/compose/form/ComposedPassword.d.ts +25 -0
- package/dist/esm/compose/form/ComposedPassword.js +103 -0
- package/dist/esm/compose/form/DateTimeInput.d.ts +28 -0
- package/dist/esm/compose/form/DateTimeInput.js +154 -0
- package/dist/esm/compose/form/DateTimePicker.d.ts +341 -0
- package/dist/esm/compose/form/DateTimePicker.js +1265 -0
- package/dist/esm/compose/form/FormControl.d.ts +33 -0
- package/dist/esm/compose/form/FormControl.js +163 -0
- package/dist/esm/compose/form/FormGroup.d.ts +14 -0
- package/dist/esm/compose/form/FormGroup.js +58 -0
- package/dist/esm/compose/overlay/Alert.d.ts +56 -0
- package/dist/esm/compose/overlay/Alert.js +267 -0
- package/dist/esm/constants/Alignment.d.ts +17 -0
- package/dist/esm/constants/Alignment.js +18 -0
- package/dist/esm/constants/Direction.d.ts +26 -0
- package/dist/esm/constants/Direction.js +22 -0
- package/dist/esm/constants/Orientation.d.ts +8 -0
- package/dist/esm/constants/Orientation.js +9 -0
- package/dist/esm/constants/Scheme.d.ts +39 -0
- package/dist/esm/constants/Scheme.js +43 -0
- package/dist/esm/constants/Transition.d.ts +81 -0
- package/dist/esm/constants/Transition.js +85 -0
- package/dist/esm/constants/Types.d.ts +74 -0
- package/dist/esm/constants/Types.js +14 -0
- package/dist/esm/core/ComponentBaseProps.d.ts +53 -0
- package/dist/esm/core/ComponentBaseProps.js +33 -0
- package/dist/esm/core/noseur.css +2390 -0
- package/dist/esm/data/Column.d.ts +235 -0
- package/dist/esm/data/Column.js +98 -0
- package/dist/esm/data/Data.css +213 -0
- package/dist/esm/data/Data.d.ts +98 -0
- package/dist/esm/data/Data.js +142 -0
- package/dist/esm/data/List.d.ts +14 -0
- package/dist/esm/data/List.js +117 -0
- package/dist/esm/data/Table.d.ts +22 -0
- package/dist/esm/data/Table.js +236 -0
- package/dist/esm/form/Button.d.ts +35 -0
- package/dist/esm/form/Button.js +131 -0
- package/dist/esm/form/Calendar.d.ts +20 -0
- package/dist/esm/form/Calendar.js +46 -0
- package/dist/esm/form/Checkbox.d.ts +20 -0
- package/dist/esm/form/Checkbox.js +155 -0
- package/dist/esm/form/ColorMap.d.ts +22 -0
- package/dist/esm/form/ColorMap.js +43 -0
- package/dist/esm/form/ColorPalette.d.ts +28 -0
- package/dist/esm/form/ColorPalette.js +87 -0
- package/dist/esm/form/Dropdown.d.ts +78 -0
- package/dist/esm/form/Dropdown.js +360 -0
- package/dist/esm/form/FileInput.d.ts +134 -0
- package/dist/esm/form/FileInput.js +523 -0
- package/dist/esm/form/Form.css +467 -0
- package/dist/esm/form/Input.d.ts +45 -0
- package/dist/esm/form/Input.js +186 -0
- package/dist/esm/form/RadioButton.d.ts +21 -0
- package/dist/esm/form/RadioButton.js +178 -0
- package/dist/esm/form/Slider.d.ts +21 -0
- package/dist/esm/form/Slider.js +163 -0
- package/dist/esm/hooks/useSearchParams.d.ts +15 -0
- package/dist/esm/hooks/useSearchParams.js +50 -0
- package/dist/esm/hooks/useSubscription.d.ts +9 -0
- package/dist/esm/hooks/useSubscription.js +26 -0
- package/dist/esm/index.d.ts +60 -0
- package/dist/esm/index.js +73 -0
- package/dist/esm/layout/GridView.d.ts +23 -0
- package/dist/esm/layout/GridView.js +34 -0
- package/dist/esm/layout/Layout.css +5 -0
- package/dist/esm/misc/Misc.css +164 -0
- package/dist/esm/misc/ProgressBar.d.ts +22 -0
- package/dist/esm/misc/ProgressBar.js +86 -0
- package/dist/esm/overlay/Dialog.d.ts +46 -0
- package/dist/esm/overlay/Dialog.js +290 -0
- package/dist/esm/overlay/Message.d.ts +35 -0
- package/dist/esm/overlay/Message.js +187 -0
- package/dist/esm/overlay/Overlay.css +382 -0
- package/dist/esm/overlay/Popover.d.ts +30 -0
- package/dist/esm/overlay/Popover.js +245 -0
- package/dist/esm/overlay/Portal.d.ts +11 -0
- package/dist/esm/overlay/Portal.js +29 -0
- package/dist/esm/overlay/Toast.d.ts +49 -0
- package/dist/esm/overlay/Toast.js +341 -0
- package/dist/esm/panel/Accordion.d.ts +26 -0
- package/dist/esm/panel/Accordion.js +127 -0
- package/dist/esm/panel/Panel.css +317 -0
- package/dist/esm/panel/Panel.d.ts +43 -0
- package/dist/esm/panel/Panel.js +125 -0
- package/dist/esm/panel/ScrollPanel.d.ts +27 -0
- package/dist/esm/panel/ScrollPanel.js +43 -0
- package/dist/esm/panel/TabPane.d.ts +82 -0
- package/dist/esm/panel/TabPane.js +237 -0
- package/dist/esm/presentation/Chart.d.ts +49 -0
- package/dist/esm/presentation/Chart.js +62 -0
- package/dist/esm/presentation/Paginator.d.ts +90 -0
- package/dist/esm/presentation/Paginator.js +331 -0
- package/dist/esm/presentation/Presentation.css +23 -0
- package/dist/esm/sensor/DragSensor.d.ts +50 -0
- package/dist/esm/sensor/DragSensor.js +156 -0
- package/dist/esm/sensor/ViewportSensor.d.ts +18 -0
- package/dist/esm/sensor/ViewportSensor.js +85 -0
- package/dist/esm/utils/BoolHelper.d.ts +13 -0
- package/dist/esm/utils/BoolHelper.js +105 -0
- package/dist/esm/utils/Classname.d.ts +9 -0
- package/dist/esm/utils/Classname.js +20 -0
- package/dist/esm/utils/ColorHelper.d.ts +127 -0
- package/dist/esm/utils/ColorHelper.js +198 -0
- package/dist/esm/utils/DOMUtils.d.ts +142 -0
- package/dist/esm/utils/DOMUtils.js +759 -0
- package/dist/esm/utils/DateHelper.d.ts +115 -0
- package/dist/esm/utils/DateHelper.js +338 -0
- package/dist/esm/utils/Debugger.d.ts +12 -0
- package/dist/esm/utils/Debugger.js +30 -0
- package/dist/esm/utils/FileHelper.d.ts +8 -0
- package/dist/esm/utils/FileHelper.js +65 -0
- package/dist/esm/utils/FunctionStackManager.d.ts +13 -0
- package/dist/esm/utils/FunctionStackManager.js +59 -0
- package/dist/esm/utils/InputHelper.d.ts +37 -0
- package/dist/esm/utils/InputHelper.js +70 -0
- package/dist/esm/utils/MicroBuilder.d.ts +24 -0
- package/dist/esm/utils/MicroBuilder.js +61 -0
- package/dist/esm/utils/ObjectHelper.d.ts +51 -0
- package/dist/esm/utils/ObjectHelper.js +334 -0
- package/dist/esm/utils/StringHelper.d.ts +10 -0
- package/dist/esm/utils/StringHelper.js +54 -0
- package/dist/esm/utils/Subscriber.d.ts +14 -0
- package/dist/esm/utils/Subscriber.js +27 -0
- package/dist/esm/utils/Timer.d.ts +32 -0
- package/dist/esm/utils/Timer.js +68 -0
- package/dist/esm/utils/TypeChecker.d.ts +12 -0
- package/dist/esm/utils/TypeChecker.js +38 -0
- package/package.json +63 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Classname } from "../utils/Classname";
|
|
3
|
+
import { ObjectHelper } from "../utils/ObjectHelper";
|
|
4
|
+
import { Paginator } from "../presentation/Paginator";
|
|
5
|
+
import { DOMHelper } from "../utils/DOMUtils";
|
|
6
|
+
;
|
|
7
|
+
export class DataComponent extends React.Component {
|
|
8
|
+
rowContentElementMaps = {};
|
|
9
|
+
componentDidMount() {
|
|
10
|
+
ObjectHelper.resolveManageRef(this, {
|
|
11
|
+
getData: () => this.state.activeData,
|
|
12
|
+
setData: (data) => this.setState({ activeData: data }),
|
|
13
|
+
toggleContent: (row) => this.internalToggleRowContent(row),
|
|
14
|
+
setLoadingState: (isLoading) => this.setState({ isLoading }),
|
|
15
|
+
expandContent: (row) => this.internalToggleRowContent(row, true),
|
|
16
|
+
collapseContent: (row) => this.internalToggleRowContent(row, false),
|
|
17
|
+
setAndExpandRowContent: (row, content) => this.internalToggleRowContent(row, undefined, content)
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
componentWillUnmount() {
|
|
21
|
+
ObjectHelper.resolveManageRef(this, null);
|
|
22
|
+
}
|
|
23
|
+
renderEmptyState() {
|
|
24
|
+
if (this.state.activeData?.length !== 0)
|
|
25
|
+
return null;
|
|
26
|
+
return React.createElement("div", { className: "noseur-data-empty-state" }, this.props.emptyState);
|
|
27
|
+
}
|
|
28
|
+
renderLoadingState() {
|
|
29
|
+
if (!!this.state.activeData && !this.state.isLoading)
|
|
30
|
+
return null;
|
|
31
|
+
return React.createElement("div", { className: "noseur-data-loading-state" }, this.props.loadingState);
|
|
32
|
+
}
|
|
33
|
+
renderFixtures(fixture, className) {
|
|
34
|
+
if (!fixture)
|
|
35
|
+
return null;
|
|
36
|
+
return React.createElement("div", { className: className }, fixture());
|
|
37
|
+
}
|
|
38
|
+
buildRowProps(data) {
|
|
39
|
+
const valuedRowProps = this.props.valuedRowProps ? this.props.valuedRowProps(data) : {};
|
|
40
|
+
return ObjectHelper.merge(this.props.rowProps ?? {}, valuedRowProps);
|
|
41
|
+
}
|
|
42
|
+
onPageChange(event) {
|
|
43
|
+
this.setState({
|
|
44
|
+
currentPage: event.currentPage,
|
|
45
|
+
dataOffset: (event.currentPage - 1) * this.props.rowsPerPage
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
renderPaginator(hasFooter) {
|
|
49
|
+
if (!this.props.paginate)
|
|
50
|
+
return null;
|
|
51
|
+
const props = {
|
|
52
|
+
...(this.props.paginatorProps || {}),
|
|
53
|
+
rowsPerPage: this.props.rowsPerPage,
|
|
54
|
+
template: this.props.paginatorTemplate,
|
|
55
|
+
scheme: this.props.paginatorProps?.scheme || this.props.scheme,
|
|
56
|
+
totalRecords: this.props.totalRecords || this.props.data?.length,
|
|
57
|
+
};
|
|
58
|
+
const cachedOnPageChange = props.onPageChange;
|
|
59
|
+
props.onPageChange = (event) => {
|
|
60
|
+
this.onPageChange(event);
|
|
61
|
+
if (cachedOnPageChange)
|
|
62
|
+
cachedOnPageChange(event);
|
|
63
|
+
if (this.props.onPageChange)
|
|
64
|
+
this.props.onPageChange(event);
|
|
65
|
+
};
|
|
66
|
+
const className = Classname.build(props.className, {
|
|
67
|
+
"noseur-data-grid-f": !hasFooter && this.props.showGridLines,
|
|
68
|
+
"noseur-no-bd-t": !hasFooter && this.props.data?.length && this.props.showGridLines,
|
|
69
|
+
});
|
|
70
|
+
return (React.createElement(Paginator, { ...props, className: className }));
|
|
71
|
+
}
|
|
72
|
+
internalToggleRowContent(row, expand, content) {
|
|
73
|
+
if (expand === true && (row in this.state.rowsContent))
|
|
74
|
+
return;
|
|
75
|
+
if (expand === false && !(row in this.state.rowsContent))
|
|
76
|
+
return;
|
|
77
|
+
const rowsContent = this.toggleRowContent(row, (this.state.activeData ?? {})[row - 1], expand, content);
|
|
78
|
+
this.setState({ rowsContent });
|
|
79
|
+
}
|
|
80
|
+
toggleRowContent(row, data, expand, content) {
|
|
81
|
+
let rowsContent = this.state.rowsContent;
|
|
82
|
+
if (expand === false || row in rowsContent) {
|
|
83
|
+
delete rowsContent[row];
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
if (!this.props.multiRowExpansion) {
|
|
87
|
+
rowsContent = {};
|
|
88
|
+
}
|
|
89
|
+
if (content) {
|
|
90
|
+
rowsContent[row] = content;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
if (!!this.props.rowExpansionTemplate) {
|
|
94
|
+
rowsContent[row] = this.props.rowExpansionTemplate(data);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
rowsContent[row] = this.props.rowsContent[row];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return rowsContent;
|
|
102
|
+
}
|
|
103
|
+
renderRowContents() {
|
|
104
|
+
const rowsContents = this.state.rowsContent;
|
|
105
|
+
return Object.keys(rowsContents).map((row) => {
|
|
106
|
+
if (!(row in this.rowContentElementMaps))
|
|
107
|
+
this.rowContentElementMaps[row] = {};
|
|
108
|
+
return (React.createElement("div", { key: row, ref: (r) => {
|
|
109
|
+
if (!this.rowContentElementMaps[row]) {
|
|
110
|
+
this.setState({ rowsContent: {} });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.rowContentElementMaps[row].contentElement = r;
|
|
114
|
+
}, className: "noseur-data-row-content" }, rowsContents[row]));
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
resolveRowContentPositions() {
|
|
118
|
+
const rows = Object.keys(this.rowContentElementMaps);
|
|
119
|
+
for (let row of rows) {
|
|
120
|
+
const rowContentElementMap = this.rowContentElementMaps[row];
|
|
121
|
+
if (!rowContentElementMap.rowElement || !rowContentElementMap.contentElement) {
|
|
122
|
+
if (rowContentElementMap.expanded && rowContentElementMap.rowElement) {
|
|
123
|
+
rowContentElementMap.rowElement.style.height = rowContentElementMap.originalHeight + "px";
|
|
124
|
+
}
|
|
125
|
+
delete this.rowContentElementMaps[row];
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (!rowContentElementMap || rowContentElementMap.expanded)
|
|
129
|
+
continue;
|
|
130
|
+
const contentHeight = DOMHelper.calculateHeight(rowContentElementMap.contentElement);
|
|
131
|
+
const rowStyle = DOMHelper.getElementStyle(rowContentElementMap.rowElement);
|
|
132
|
+
const rowHeight = DOMHelper.sanitizeStyleValue(rowStyle.height);
|
|
133
|
+
const rowSuperfluousHeight = DOMHelper.getElementSuperfluousHeight(rowContentElementMap.rowElement, true);
|
|
134
|
+
const rowOffsetTopPlusHeight = rowContentElementMap.rowElement.offsetTop + rowHeight + rowSuperfluousHeight;
|
|
135
|
+
rowContentElementMap.rowElement.style.height = (rowHeight + contentHeight) + "px";
|
|
136
|
+
rowContentElementMap.contentElement.style.top = rowOffsetTopPlusHeight + "px";
|
|
137
|
+
this.rowContentElementMaps[row].originalHeight = rowHeight;
|
|
138
|
+
this.rowContentElementMaps[row].expanded = true;
|
|
139
|
+
}
|
|
140
|
+
;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import "./Data.css";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { DataProps, RowControlOptions } from "./Data";
|
|
4
|
+
import { NoseurElement } from '../constants/Types';
|
|
5
|
+
export type ListTemplateHandler = (value: any, rowControlOptions?: RowControlOptions) => NoseurElement;
|
|
6
|
+
export interface ListProps<D> extends DataProps<HTMLUListElement, D> {
|
|
7
|
+
dataKey: string;
|
|
8
|
+
sortField: string;
|
|
9
|
+
children: undefined;
|
|
10
|
+
selectionMode: SelectionMode;
|
|
11
|
+
sortOrder: null | 0 | 1 | -1;
|
|
12
|
+
template: ListTemplateHandler | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare const List: <D>({ ref, ...props }: Partial<ListProps<D>>) => React.JSX.Element;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import "./Data.css";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Classname } from "../utils/Classname";
|
|
4
|
+
import { BoolHelper } from "../utils/BoolHelper";
|
|
5
|
+
import { ObjectHelper } from "../utils/ObjectHelper";
|
|
6
|
+
import { DataComponent } from "./Data";
|
|
7
|
+
import { SortDirection } from '../constants/Types';
|
|
8
|
+
;
|
|
9
|
+
class ListComponent extends DataComponent {
|
|
10
|
+
static defaultProps = {
|
|
11
|
+
paginate: false,
|
|
12
|
+
rowsPerPage: 10,
|
|
13
|
+
rowsContent: {},
|
|
14
|
+
dataRefreshKeys: [],
|
|
15
|
+
internalElementProps: {},
|
|
16
|
+
};
|
|
17
|
+
state = {
|
|
18
|
+
dataOffset: 0,
|
|
19
|
+
currentPage: 1,
|
|
20
|
+
activeData: this.props.data,
|
|
21
|
+
rowsContent: ObjectHelper.clone(this.props.rowsContent),
|
|
22
|
+
};
|
|
23
|
+
constructor(props) {
|
|
24
|
+
super(props);
|
|
25
|
+
}
|
|
26
|
+
componentDidUpdate(prevProps, _) {
|
|
27
|
+
if (prevProps.totalRecords !== this.props.totalRecords ||
|
|
28
|
+
!BoolHelper.deepEqual(prevProps.data, this.props.data, [...this.props.dataRefreshKeys])
|
|
29
|
+
|| ((!this.state.activeData || !this.state.activeData.length) && this.props.data?.length)) {
|
|
30
|
+
this.setState({ activeData: this.props.data ?? [] });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
sortData() {
|
|
34
|
+
const data = this.state.activeData;
|
|
35
|
+
const sortField = this.props.sortField;
|
|
36
|
+
if (!data)
|
|
37
|
+
return;
|
|
38
|
+
data.sort((p, c) => {
|
|
39
|
+
const prev = ObjectHelper.objectGetWithStringTemplate(p, sortField), current = ObjectHelper.objectGetWithStringTemplate(c, sortField);
|
|
40
|
+
if (this.props.compareData)
|
|
41
|
+
return this.props.compareData(SortDirection.FORWARD, sortField, prev, current);
|
|
42
|
+
const comp = BoolHelper.compare(prev, current);
|
|
43
|
+
return comp;
|
|
44
|
+
});
|
|
45
|
+
this.setState({ activeData: data });
|
|
46
|
+
}
|
|
47
|
+
renderListBody() {
|
|
48
|
+
if (!this.state.activeData || this.state.isLoading)
|
|
49
|
+
return;
|
|
50
|
+
let data = this.state.activeData.slice(this.state.dataOffset, (this.props.rowsPerPage + this.state.dataOffset));
|
|
51
|
+
if (!data.length && !this.props.allowNoDataPagination)
|
|
52
|
+
data = this.state.activeData;
|
|
53
|
+
const rowsContents = this.state.rowsContent;
|
|
54
|
+
return data.map((rowData, index) => {
|
|
55
|
+
const row = index + 1;
|
|
56
|
+
let valuedRowProps = this.buildRowProps(data);
|
|
57
|
+
const value = this.props.dataKey ? ObjectHelper.objectGetWithStringTemplate(rowData, this.props.dataKey) : rowData;
|
|
58
|
+
return (React.createElement("li", { key: index, role: "row", "data-n-group": "row", ...valuedRowProps, ref: (r) => {
|
|
59
|
+
if (!r)
|
|
60
|
+
return;
|
|
61
|
+
if (!(row in rowsContents))
|
|
62
|
+
return;
|
|
63
|
+
if (!(row in this.rowContentElementMaps))
|
|
64
|
+
this.rowContentElementMaps[row] = {};
|
|
65
|
+
this.rowContentElementMaps[row].rowElement = r;
|
|
66
|
+
}, onClick: this.props.onRowSelection
|
|
67
|
+
? () => this.props.onRowSelection(rowData, index) : undefined }, this.props.template
|
|
68
|
+
? this.props.template(value, {
|
|
69
|
+
toggleContent: (() => {
|
|
70
|
+
this.setState({ rowsContent: this.toggleRowContent(row, data) });
|
|
71
|
+
}).bind(this)
|
|
72
|
+
})
|
|
73
|
+
: `${value}`));
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
renderList(hasHeader, hasFooter) {
|
|
77
|
+
const props = {
|
|
78
|
+
id: this.props.id,
|
|
79
|
+
...this.props.internalElementProps,
|
|
80
|
+
};
|
|
81
|
+
const listBody = this.renderListBody();
|
|
82
|
+
const className = Classname.build('noseur-data-container noseur-list', {
|
|
83
|
+
"noseur-disabled": this.props.disabled,
|
|
84
|
+
"noseur-data-striped": this.props.stripedRows,
|
|
85
|
+
"noseur-data-grid-h": !hasHeader && this.props.showGridLines,
|
|
86
|
+
"noseur-data-grid-f": !hasFooter && this.props.showGridLines && this.props.data?.length,
|
|
87
|
+
}, this.props.internalElementProps.className);
|
|
88
|
+
return (React.createElement("ul", { ...props, role: "list", "data-n-group": "list", className: className, ref: this.props.forwardRef }, listBody));
|
|
89
|
+
}
|
|
90
|
+
render() {
|
|
91
|
+
const props = {
|
|
92
|
+
key: this.props.key,
|
|
93
|
+
id: this.props.dataId,
|
|
94
|
+
style: this.props.style,
|
|
95
|
+
};
|
|
96
|
+
const emptyState = this.renderEmptyState();
|
|
97
|
+
const rowContents = this.renderRowContents();
|
|
98
|
+
const loadingState = this.renderLoadingState();
|
|
99
|
+
const header = this.renderFixtures(this.props.header, "noseur-data-header");
|
|
100
|
+
const footer = this.renderFixtures(this.props.footer, "noseur-data-footer");
|
|
101
|
+
const className = Classname.build('noseur-data-compound', {
|
|
102
|
+
"noseur-data-grid": this.props.showGridLines,
|
|
103
|
+
"noseur-data-no-divider": this.props.noDivider && !this.props.showGridLines,
|
|
104
|
+
}, this.props.className, (this.props.scheme ? `${this.props.scheme}-vars` : null));
|
|
105
|
+
const paginator = this.renderPaginator(!!footer);
|
|
106
|
+
const list = this.renderList(!!header, !!footer);
|
|
107
|
+
return (React.createElement("div", { ...props, className: className, ref: (_) => this.resolveRowContentPositions() },
|
|
108
|
+
header,
|
|
109
|
+
list,
|
|
110
|
+
emptyState,
|
|
111
|
+
loadingState,
|
|
112
|
+
paginator,
|
|
113
|
+
footer,
|
|
114
|
+
rowContents));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export const List = ({ ref, ...props }) => (React.createElement(ListComponent, { ...props, forwardRef: ref }));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import "./Data.css";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { DataProps } from "./Data";
|
|
4
|
+
import { NoseurElement, SortIcons, SortMode } from '../constants/Types';
|
|
5
|
+
export declare enum TableSelectionMode {
|
|
6
|
+
NONE = 0,
|
|
7
|
+
SINGLE = 1,
|
|
8
|
+
MULTIPLE = 2
|
|
9
|
+
}
|
|
10
|
+
export type TableSelectionEventHandler = (value: any) => NoseurElement;
|
|
11
|
+
export interface TableProps<D> extends DataProps<HTMLTableElement, D> {
|
|
12
|
+
sortMode: SortMode;
|
|
13
|
+
sortIcons: SortIcons;
|
|
14
|
+
hideHeaders: boolean;
|
|
15
|
+
cellSelection: boolean;
|
|
16
|
+
canDisableSort: boolean;
|
|
17
|
+
sortOrder: null | 0 | 1 | -1;
|
|
18
|
+
selectionMode: TableSelectionMode;
|
|
19
|
+
children: React.JSX.Element | React.JSX.Element[] | React.ReactElement | React.ReactElement[];
|
|
20
|
+
onColumnSelection: TableSelectionEventHandler;
|
|
21
|
+
}
|
|
22
|
+
export declare const Table: <D>({ ref, ...props }: Partial<TableProps<D>>) => React.JSX.Element;
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import "./Data.css";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Classname } from "../utils/Classname";
|
|
4
|
+
import { BoolHelper } from "../utils/BoolHelper";
|
|
5
|
+
import { ObjectHelper } from "../utils/ObjectHelper";
|
|
6
|
+
import { ColumnComponent } from "./Column";
|
|
7
|
+
import { DataComponent } from "./Data";
|
|
8
|
+
import { SortDirection, SortMode } from '../constants/Types';
|
|
9
|
+
export var TableSelectionMode;
|
|
10
|
+
(function (TableSelectionMode) {
|
|
11
|
+
TableSelectionMode[TableSelectionMode["NONE"] = 0] = "NONE";
|
|
12
|
+
TableSelectionMode[TableSelectionMode["SINGLE"] = 1] = "SINGLE";
|
|
13
|
+
TableSelectionMode[TableSelectionMode["MULTIPLE"] = 2] = "MULTIPLE";
|
|
14
|
+
})(TableSelectionMode || (TableSelectionMode = {}));
|
|
15
|
+
;
|
|
16
|
+
;
|
|
17
|
+
class TableComponent extends DataComponent {
|
|
18
|
+
static defaultProps = {
|
|
19
|
+
rowsContent: {},
|
|
20
|
+
paginate: false,
|
|
21
|
+
rowsPerPage: 10,
|
|
22
|
+
dataRefreshKeys: [],
|
|
23
|
+
internalElementProps: {},
|
|
24
|
+
sortMode: SortMode.SINGLE,
|
|
25
|
+
sortIcons: {
|
|
26
|
+
asc: "fa fa-sort-asc",
|
|
27
|
+
unsorted: "fa fa-sort",
|
|
28
|
+
desc: "fa fa-sort-desc",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
state = {
|
|
32
|
+
dataOffset: 0,
|
|
33
|
+
currentPage: 1,
|
|
34
|
+
activeData: this.props.data,
|
|
35
|
+
rowsContent: ObjectHelper.clone(this.props.rowsContent),
|
|
36
|
+
};
|
|
37
|
+
usedDataKeys = [];
|
|
38
|
+
columnSelfRefs = {};
|
|
39
|
+
constructor(props) {
|
|
40
|
+
super(props);
|
|
41
|
+
this.onSort = this.onSort.bind(this);
|
|
42
|
+
this.resolveRowContentPositions = this.resolveRowContentPositions.bind(this);
|
|
43
|
+
}
|
|
44
|
+
componentDidUpdate(prevProps, _) {
|
|
45
|
+
if (prevProps.totalRecords !== this.props.totalRecords ||
|
|
46
|
+
!BoolHelper.deepEqual(prevProps.data, this.props.data, [this.usedDataKeys, ...this.props.dataRefreshKeys])
|
|
47
|
+
|| ((!this.state.activeData || !this.state.activeData.length) && this.props.data?.length)) {
|
|
48
|
+
this.setState({ activeData: this.props.data });
|
|
49
|
+
Object.keys(this.columnSelfRefs).forEach((dk) => {
|
|
50
|
+
this.columnSelfRefs[dk].unSort();
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
onSort(sortDirection, dataKey) {
|
|
55
|
+
if (!dataKey)
|
|
56
|
+
return;
|
|
57
|
+
let data = ((this.props.sortMode == SortMode.MULTIPLE || this.state.lastSortColumn == dataKey) ? (this.state.activeData ?? []) : (this.props.data ?? [])).map(a => { return { ...a }; });
|
|
58
|
+
if (this.props.sortMode != SortMode.MULTIPLE) {
|
|
59
|
+
Object.keys(this.columnSelfRefs).forEach((dk) => {
|
|
60
|
+
if (dk == dataKey)
|
|
61
|
+
return;
|
|
62
|
+
this.columnSelfRefs[dk].unSort();
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (sortDirection == SortDirection.NONE) {
|
|
66
|
+
this.setState({
|
|
67
|
+
activeData: (this.props.data || []).map((v, index) => {
|
|
68
|
+
v[dataKey] = ObjectHelper.objectGetWithStringTemplate((this.props.data ?? [])[index], dataKey);
|
|
69
|
+
return v;
|
|
70
|
+
}), lastSortColumn: dataKey
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
data.sort((p, c) => {
|
|
75
|
+
const prev = ObjectHelper.objectGetWithStringTemplate(p, dataKey), current = ObjectHelper.objectGetWithStringTemplate(c, dataKey);
|
|
76
|
+
if (this.props.compareData)
|
|
77
|
+
return this.props.compareData(sortDirection, dataKey, prev, current);
|
|
78
|
+
const comp = BoolHelper.compare(prev, current);
|
|
79
|
+
if (comp == 1 && sortDirection == SortDirection.BACKWARD)
|
|
80
|
+
return -1;
|
|
81
|
+
return comp;
|
|
82
|
+
});
|
|
83
|
+
this.setState({ activeData: data, lastSortColumn: dataKey });
|
|
84
|
+
}
|
|
85
|
+
renderTableBody() {
|
|
86
|
+
if (!this.state.activeData || this.state.isLoading)
|
|
87
|
+
return;
|
|
88
|
+
let data = this.state.activeData.slice(this.state.dataOffset, (this.props.rowsPerPage + this.state.dataOffset));
|
|
89
|
+
if (!data.length && !this.props.allowNoDataPagination)
|
|
90
|
+
data = this.state.activeData;
|
|
91
|
+
const children = ObjectHelper.flattenChildren(this.props.children);
|
|
92
|
+
const rowsContents = this.state.rowsContent;
|
|
93
|
+
const rows = data.map((data, index) => {
|
|
94
|
+
const row = index + 1;
|
|
95
|
+
const columns = children?.filter((child) => !child.props?.doNotRender)?.map((child, sindex) => {
|
|
96
|
+
return React.createElement(ColumnComponent, {
|
|
97
|
+
...(child.props),
|
|
98
|
+
sortable: false,
|
|
99
|
+
key: (child.props.key ?? child.props.dataKey ?? (child.props.header ? `${child.props.header}` : undefined) ?? sindex),
|
|
100
|
+
rowControlOptions: {
|
|
101
|
+
toggleContent: (() => {
|
|
102
|
+
this.setState({ rowsContent: this.toggleRowContent(row, data) });
|
|
103
|
+
}).bind(this)
|
|
104
|
+
},
|
|
105
|
+
value: (child.props.dataKey ? ObjectHelper.objectGetWithStringTemplate(data, child.props.dataKey) : data),
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
let valuedRowProps = this.buildRowProps(data);
|
|
109
|
+
return (React.createElement("tr", { key: `row-${index}`, role: "row", "data-n-group": "body-row", ...valuedRowProps, ref: (r) => {
|
|
110
|
+
if (!r)
|
|
111
|
+
return;
|
|
112
|
+
if (!(row in rowsContents))
|
|
113
|
+
return;
|
|
114
|
+
if (!(row in this.rowContentElementMaps))
|
|
115
|
+
this.rowContentElementMaps[row] = {};
|
|
116
|
+
this.rowContentElementMaps[row].rowElement = r;
|
|
117
|
+
}, onClick: this.props.onRowSelection ? () => this.props.onRowSelection(data, index) : undefined }, columns));
|
|
118
|
+
});
|
|
119
|
+
return (React.createElement("tbody", { key: "body", className: "noseur-tbody", "data-n-group": "body" }, rows));
|
|
120
|
+
}
|
|
121
|
+
renderTableHeader() {
|
|
122
|
+
const children = ObjectHelper.flattenChildren(this.props.children);
|
|
123
|
+
const columns = children?.filter((child) => !child.props.doNotRender)?.map((child, index) => {
|
|
124
|
+
const cachedOnSort = child.props.onSort;
|
|
125
|
+
const onSort = (sortDirection) => {
|
|
126
|
+
if (cachedOnSort)
|
|
127
|
+
cachedOnSort(sortDirection);
|
|
128
|
+
this.onSort(sortDirection, child.props.dataKey);
|
|
129
|
+
};
|
|
130
|
+
if (child.props.dataKey && !this.usedDataKeys.includes(child.props.dataKey))
|
|
131
|
+
this.usedDataKeys.push(child.props.dataKey);
|
|
132
|
+
let columnSelfRef;
|
|
133
|
+
if (child.props.sortable && this.props.sortMode + SortMode.MULTIPLE) {
|
|
134
|
+
const cachedManageRef = child.props.manageRef;
|
|
135
|
+
columnSelfRef = (r) => {
|
|
136
|
+
if (cachedManageRef) {
|
|
137
|
+
if (typeof cachedManageRef == "function")
|
|
138
|
+
cachedManageRef(r);
|
|
139
|
+
else
|
|
140
|
+
cachedManageRef.current = r;
|
|
141
|
+
}
|
|
142
|
+
this.columnSelfRefs[child.props.dataKey] = r;
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
columnSelfRef = child.props.manageRef;
|
|
147
|
+
}
|
|
148
|
+
return React.createElement(ColumnComponent, {
|
|
149
|
+
...(child.props),
|
|
150
|
+
element: "th",
|
|
151
|
+
onSort: onSort,
|
|
152
|
+
template: undefined,
|
|
153
|
+
group: "column-header",
|
|
154
|
+
manageRef: columnSelfRef,
|
|
155
|
+
key: (child.props.key ?? child.props.dataKey ?? (child.props.header ? `${child.props.header}` : undefined) ?? index),
|
|
156
|
+
valueClassName: "noseur-column-header",
|
|
157
|
+
sortIcons: (this.props.sortIcons || child.props.sortIcons),
|
|
158
|
+
value: (typeof child.props.header == "function"
|
|
159
|
+
? child.props.header()
|
|
160
|
+
: React.createElement("span", { className: "noseur-column-header-content" }, child.props.header || React.createElement("span", null, "\u00A0"))),
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
return (React.createElement("thead", { key: "header", className: "noseur-thead", "data-n-group": "header" },
|
|
164
|
+
React.createElement("tr", { role: "row", "data-n-group": "header-row" }, columns)));
|
|
165
|
+
}
|
|
166
|
+
renderTableFooter() {
|
|
167
|
+
let hasNoFooter = true;
|
|
168
|
+
const children = ObjectHelper.flattenChildren(this.props.children);
|
|
169
|
+
const columns = children?.map((child, index) => {
|
|
170
|
+
if (child.props.footer)
|
|
171
|
+
hasNoFooter = false;
|
|
172
|
+
return React.createElement(ColumnComponent, {
|
|
173
|
+
...(child.props),
|
|
174
|
+
element: "th",
|
|
175
|
+
group: "column-footer",
|
|
176
|
+
key: (child.props.key ?? child.props.dataKey ?? (child.props.header ? `${child.props.header}` : undefined) ?? index),
|
|
177
|
+
valueClassName: "noseur-column-footer",
|
|
178
|
+
value: (typeof child.props.footer == "function"
|
|
179
|
+
? child.props.footer()
|
|
180
|
+
: React.createElement("span", { className: "noseur-column-footer-content" }, child.props.footer || React.createElement("span", null, "\u00A0"))),
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
if (hasNoFooter)
|
|
184
|
+
return null;
|
|
185
|
+
return (React.createElement("tfoot", { key: "footer", className: "noseur-tfoot", "data-n-group": "footer" },
|
|
186
|
+
React.createElement("tr", { role: "row", "data-n-group": "footer-row" }, columns)));
|
|
187
|
+
}
|
|
188
|
+
renderTable(hasHeader, hasFooter) {
|
|
189
|
+
const props = {
|
|
190
|
+
id: this.props.id,
|
|
191
|
+
...this.props.internalElementProps,
|
|
192
|
+
};
|
|
193
|
+
if (!this.props.children)
|
|
194
|
+
return null;
|
|
195
|
+
const tableBody = this.renderTableBody();
|
|
196
|
+
const tableFooter = this.renderTableFooter();
|
|
197
|
+
const tableHeader = this.props.hideHeaders ? null : this.renderTableHeader();
|
|
198
|
+
const className = Classname.build('noseur-data-container noseur-table', {
|
|
199
|
+
"noseur-disabled": this.props.disabled,
|
|
200
|
+
"noseur-data-striped": this.props.stripedRows,
|
|
201
|
+
"noseur-data-grid-h": !hasHeader && this.props.showGridLines,
|
|
202
|
+
"noseur-data-grid-f": !hasFooter && this.props.showGridLines && this.props.data?.length,
|
|
203
|
+
}, this.props.internalElementProps.className);
|
|
204
|
+
return (React.createElement("table", { ...props, role: "table", "data-n-group": "table", className: className, ref: this.props.forwardRef },
|
|
205
|
+
tableHeader,
|
|
206
|
+
tableBody,
|
|
207
|
+
tableFooter));
|
|
208
|
+
}
|
|
209
|
+
render() {
|
|
210
|
+
const props = {
|
|
211
|
+
key: this.props.key,
|
|
212
|
+
id: this.props.dataId,
|
|
213
|
+
style: this.props.style,
|
|
214
|
+
};
|
|
215
|
+
const emptyState = this.renderEmptyState();
|
|
216
|
+
const rowContents = this.renderRowContents();
|
|
217
|
+
const loadingState = this.renderLoadingState();
|
|
218
|
+
const header = this.renderFixtures(this.props.header, "noseur-data-header");
|
|
219
|
+
const footer = this.renderFixtures(this.props.footer, "noseur-data-footer");
|
|
220
|
+
const className = Classname.build('noseur-data-compound', {
|
|
221
|
+
"noseur-data-grid": this.props.showGridLines,
|
|
222
|
+
"noseur-data-no-divider": this.props.noDivider && !this.props.showGridLines,
|
|
223
|
+
}, this.props.className, (this.props.scheme ? `${this.props.scheme}-vars` : null));
|
|
224
|
+
const paginator = this.renderPaginator(!!footer);
|
|
225
|
+
const table = this.renderTable(!!header, !!footer);
|
|
226
|
+
return (React.createElement("div", { ...props, className: className, ref: (_) => this.resolveRowContentPositions() },
|
|
227
|
+
header,
|
|
228
|
+
table,
|
|
229
|
+
emptyState,
|
|
230
|
+
loadingState,
|
|
231
|
+
paginator,
|
|
232
|
+
footer,
|
|
233
|
+
rowContents));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
export const Table = ({ ref, ...props }) => (React.createElement(TableComponent, { ...props, forwardRef: ref }));
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import "./Form.css";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Alignment } from '../constants/Alignment';
|
|
4
|
+
import { ComponentBaseProps, LoadingProps } from '../core/ComponentBaseProps';
|
|
5
|
+
import { NoseurButtonElement, NoseurElement, NoseurIconElement } from '../constants/Types';
|
|
6
|
+
export type NoseurButtonOnClickHandler = React.EventHandler<NoseurButtonOnClickEvent>;
|
|
7
|
+
export type NoseurButtonOnClickEvent = {
|
|
8
|
+
manageRef?: ButtonManageRef;
|
|
9
|
+
} & React.MouseEvent<NoseurButtonElement>;
|
|
10
|
+
export interface ButtonManageRef {
|
|
11
|
+
setLoadingState: (isLoading: boolean) => void;
|
|
12
|
+
}
|
|
13
|
+
export interface ButtonProps extends ComponentBaseProps<NoseurButtonElement, ButtonManageRef>, LoadingProps<ButtonProps> {
|
|
14
|
+
type: string;
|
|
15
|
+
link: string;
|
|
16
|
+
fill: boolean;
|
|
17
|
+
raised: boolean;
|
|
18
|
+
rounded: boolean;
|
|
19
|
+
iconOnly: boolean;
|
|
20
|
+
textOnly: boolean;
|
|
21
|
+
outlined: boolean;
|
|
22
|
+
linkTarget: string;
|
|
23
|
+
text: NoseurElement;
|
|
24
|
+
borderless: boolean;
|
|
25
|
+
fillOnHover: boolean;
|
|
26
|
+
fillLeftIcon: boolean;
|
|
27
|
+
rippleEffect: boolean;
|
|
28
|
+
leftIcon: NoseurIconElement;
|
|
29
|
+
rightIcon: NoseurIconElement;
|
|
30
|
+
leftIconRelativeAlignment: Alignment;
|
|
31
|
+
rightIconRelativeAlignment: Alignment;
|
|
32
|
+
onClick?: NoseurButtonOnClickHandler;
|
|
33
|
+
}
|
|
34
|
+
export declare const Button: ({ ref, ...props }: Partial<ButtonProps>) => React.JSX.Element;
|
|
35
|
+
export declare function buildButtonControl(control: Partial<ButtonProps> | NoseurElement, customNonOverridingProps: Partial<ButtonProps>, cb?: (e: any) => void, className?: string): any;
|