@singularsystems/neo-react 0.10.61 → 0.10.63
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/dist/ReactComponents/DatePicker.d.ts +1 -0
- package/dist/ReactComponents/DatePicker.js +6 -2
- package/dist/ReactComponents/DropDown/AutoCompleteDropDown.d.ts +4 -0
- package/dist/ReactComponents/DropDown/AutoCompleteDropDown.js +4 -1
- package/dist/ReactComponents/Grid/ButtonColumn.js +1 -1
- package/dist/ReactComponents/Grid/Grid.d.ts +9 -0
- package/dist/ReactComponents/Grid/Grid.js +15 -2
- package/dist/ReactComponents/Grid/StickyTableHeader.d.ts +24 -0
- package/dist/ReactComponents/Grid/StickyTableHeader.js +98 -0
- package/dist/ReactComponents/Input.js +1 -1
- package/dist/ReactComponents/InputHelpers.d.ts +2 -2
- package/dist/ReactComponents/InputHelpers.js +3 -3
- package/dist/ReactComponents/Modal/Modal.js +4 -0
- package/dist/ReactComponents/NumberInput.js +14 -7
- package/dist/ReactComponents/PropTypes.d.ts +3 -10
- package/dist/ReactComponents/PropTypes.js +12 -2
- package/package.json +3 -3
- package/styles/DatePicker.scss +11 -0
- package/styles/Grid.scss +5 -0
|
@@ -12,6 +12,7 @@ export default class DatePicker extends ComponentBase<INeoDatePickerProps> {
|
|
|
12
12
|
private container;
|
|
13
13
|
private datePicker?;
|
|
14
14
|
private isReadOnly;
|
|
15
|
+
private inputRef;
|
|
15
16
|
constructor(props: INeoDatePickerProps);
|
|
16
17
|
componentDidMount(): void;
|
|
17
18
|
componentWillUnmount(): void;
|
|
@@ -11,6 +11,7 @@ var DatePicker = /** @class */ (function (_super) {
|
|
|
11
11
|
function DatePicker(props) {
|
|
12
12
|
var _this = _super.call(this, props) || this;
|
|
13
13
|
_this.isReadOnly = false;
|
|
14
|
+
_this.inputRef = React.createRef();
|
|
14
15
|
_this.container = React.createRef();
|
|
15
16
|
return _this;
|
|
16
17
|
}
|
|
@@ -33,6 +34,9 @@ var DatePicker = /** @class */ (function (_super) {
|
|
|
33
34
|
this.isReadOnly = !!domProps.readOnly;
|
|
34
35
|
var displayInfo = this.props.bind.validator.getDisplayState(this.context.validationDisplayMode);
|
|
35
36
|
displayInfo.applyToDom(domProps, !splitProps.inGroup);
|
|
37
|
+
if (splitProps.editor.inputElement) {
|
|
38
|
+
this.inputRef = splitProps.editor.inputElement;
|
|
39
|
+
}
|
|
36
40
|
if (this.datePicker) {
|
|
37
41
|
this.datePicker.update(splitProps.dateProps, this.props.bind, this.isReadOnly);
|
|
38
42
|
}
|
|
@@ -40,8 +44,8 @@ var DatePicker = /** @class */ (function (_super) {
|
|
|
40
44
|
// Create dependency on bound value on initial render.
|
|
41
45
|
void this.props.bind.value;
|
|
42
46
|
}
|
|
43
|
-
return (React.createElement("div", { className: "neo-datepicker-container", ref: this.container },
|
|
44
|
-
InputHelpers.surroundWithInputGroup(React.createElement("input", __assign({ type: "text" }, domProps, { ref:
|
|
47
|
+
return (React.createElement("div", { className: "neo-datepicker-container", ref: this.container }, Components.DatePicker.mustShowInput(splitProps.dateProps) &&
|
|
48
|
+
InputHelpers.surroundWithInputGroup(React.createElement("input", __assign({ type: "text" }, domProps, { ref: this.inputRef })), splitProps.editor, this.inputRef)));
|
|
45
49
|
};
|
|
46
50
|
DatePicker.contextType = FormContext;
|
|
47
51
|
DatePicker = __decorate([
|
|
@@ -21,6 +21,10 @@ interface IAutoCompleteCommonProps<T> extends ICommonEditorProps, Props<IOption,
|
|
|
21
21
|
items?: ItemSource<T>;
|
|
22
22
|
valueMember?: keyof T;
|
|
23
23
|
displayMember?: keyof T;
|
|
24
|
+
/**
|
|
25
|
+
* Function used to filter items out of the datasource.
|
|
26
|
+
* **Note:** this will only apply to the `items` prop. */
|
|
27
|
+
filterPredicate?: (item: T) => boolean;
|
|
24
28
|
/**
|
|
25
29
|
* Property of an item to use as the description.
|
|
26
30
|
*
|
|
@@ -134,6 +134,9 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
134
134
|
var defaultItems = undefined;
|
|
135
135
|
if (this.props.items) {
|
|
136
136
|
var items_1 = this.getItems(this.props.items);
|
|
137
|
+
if (this.props.filterPredicate !== undefined) {
|
|
138
|
+
items_1 = items_1.filter(this.props.filterPredicate);
|
|
139
|
+
}
|
|
137
140
|
defaultItems = this.mapTArrayToOptions(items_1);
|
|
138
141
|
if (descriptionMember === undefined && items_1.length > 0) {
|
|
139
142
|
if (EnumHelper.isEnumItem(items_1[0])) {
|
|
@@ -185,7 +188,7 @@ var AutoCompleteDropDown = /** @class */ (function (_super) {
|
|
|
185
188
|
if (nativeProps.isClearable === undefined) {
|
|
186
189
|
nativeProps.isClearable = true;
|
|
187
190
|
}
|
|
188
|
-
if (splitProps.editor.
|
|
191
|
+
if (BindPropsHelper.isReadOnly(splitProps.editor, this.context) || BindPropsHelper.isDisabled(splitProps.editor, this.context)) {
|
|
189
192
|
nativeProps.isDisabled = true;
|
|
190
193
|
}
|
|
191
194
|
nativeProps.className = Utils.joinWithSpaces("react-select-bs", nativeProps.className);
|
|
@@ -72,7 +72,7 @@ var ButtonColumn = /** @class */ (function (_super) {
|
|
|
72
72
|
React.createElement("th", __assign({}, domProps), this.section === "header" && label) :
|
|
73
73
|
React.createElement("td", __assign({}, domProps),
|
|
74
74
|
childAlignment === "right" ? buttons : undefined,
|
|
75
|
-
this.props.children,
|
|
75
|
+
this.props.children instanceof Function ? this.props.children() : this.props.children,
|
|
76
76
|
childAlignment !== "right" ? buttons : undefined));
|
|
77
77
|
};
|
|
78
78
|
ButtonColumn.isColumnComponent = true;
|
|
@@ -73,6 +73,11 @@ export interface IGridProps<T> extends React.HTMLProps<HTMLTableElement> {
|
|
|
73
73
|
* Set `showAddButton = false` if you don't want the default button.
|
|
74
74
|
*/
|
|
75
75
|
footerButtons?: () => React.ReactNode;
|
|
76
|
+
/**
|
|
77
|
+
* Will cause the header to stick to the top of the screen / scroll element when scrolling.
|
|
78
|
+
* Note: if your app has a fixed header, you need to specify this in the global neo settings.
|
|
79
|
+
*/
|
|
80
|
+
stickyHeader?: boolean;
|
|
76
81
|
}
|
|
77
82
|
export default class Grid<T> extends React.Component<IGridProps<T>> {
|
|
78
83
|
static contextType: React.Context<import("../../React/DataView").DataViewContextParams<unknown>>;
|
|
@@ -80,7 +85,11 @@ export default class Grid<T> extends React.Component<IGridProps<T>> {
|
|
|
80
85
|
private gridContext;
|
|
81
86
|
private prevItems?;
|
|
82
87
|
private headerItem;
|
|
88
|
+
private domRef;
|
|
89
|
+
private stickyHeaderHelper?;
|
|
83
90
|
constructor(props: IGridProps<T>);
|
|
91
|
+
componentDidMount(): void;
|
|
92
|
+
componentWillUnmount(): void;
|
|
84
93
|
render(): JSX.Element;
|
|
85
94
|
private setInitialSort;
|
|
86
95
|
}
|
|
@@ -4,6 +4,7 @@ import { Data, Utils, Misc } from '@singularsystems/neo-core';
|
|
|
4
4
|
import { observer, Observer } from 'mobx-react';
|
|
5
5
|
import NeoButton from '../Button';
|
|
6
6
|
import { DataViewContext } from '../../React/DataView';
|
|
7
|
+
import { StickyTableHeader } from './StickyTableHeader';
|
|
7
8
|
// Grid context
|
|
8
9
|
var GridContextParams = /** @class */ (function () {
|
|
9
10
|
function GridContextParams() {
|
|
@@ -27,12 +28,24 @@ var Grid = /** @class */ (function (_super) {
|
|
|
27
28
|
function Grid(props) {
|
|
28
29
|
var _this = _super.call(this, props) || this;
|
|
29
30
|
_this.gridContext = new GridContextParams();
|
|
31
|
+
_this.domRef = React.createRef();
|
|
30
32
|
_this.gridContext.section = "header";
|
|
31
33
|
return _this;
|
|
32
34
|
}
|
|
35
|
+
Grid.prototype.componentDidMount = function () {
|
|
36
|
+
var _a, _b;
|
|
37
|
+
if (this.domRef.current && (_a = this.props.stickyHeader, (_a !== null && _a !== void 0 ? _a : Misc.Settings.grid.useStickyHeaders))) {
|
|
38
|
+
this.stickyHeaderHelper = new StickyTableHeader(this.domRef.current, (_b = Misc.Settings.fixedAppHeaderElement) === null || _b === void 0 ? void 0 : _b.call(undefined));
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
Grid.prototype.componentWillUnmount = function () {
|
|
42
|
+
if (this.stickyHeaderHelper) {
|
|
43
|
+
this.stickyHeaderHelper.dispose();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
33
46
|
Grid.prototype.render = function () {
|
|
34
47
|
var _this = this;
|
|
35
|
-
var _a = this.props, items = _a.items, showAddButton = _a.showAddButton, addButton = _a.addButton, filterPredicate = _a.filterPredicate, keyProperty = _a.keyProperty, allowSort = _a.allowSort, expandAll = _a.expandAll, collapseAll = _a.collapseAll, initialSort = _a.initialSort, initialSortAscending = _a.initialSortAscending, isBordered = _a.isBordered, isStriped = _a.isStriped, isBorderless = _a.isBorderless, showHover = _a.showHover, isSmallTable = _a.isSmallTable, footerContent = _a.footerContent, footerButtons = _a.footerButtons, domProps = __rest(_a, ["items", "showAddButton", "addButton", "filterPredicate", "keyProperty", "allowSort", "expandAll", "collapseAll", "initialSort", "initialSortAscending", "isBordered", "isStriped", "isBorderless", "showHover", "isSmallTable", "footerContent", "footerButtons"]);
|
|
48
|
+
var _a = this.props, items = _a.items, showAddButton = _a.showAddButton, addButton = _a.addButton, filterPredicate = _a.filterPredicate, keyProperty = _a.keyProperty, allowSort = _a.allowSort, expandAll = _a.expandAll, collapseAll = _a.collapseAll, initialSort = _a.initialSort, initialSortAscending = _a.initialSortAscending, isBordered = _a.isBordered, isStriped = _a.isStriped, isBorderless = _a.isBorderless, showHover = _a.showHover, isSmallTable = _a.isSmallTable, footerContent = _a.footerContent, footerButtons = _a.footerButtons, stickyHeader = _a.stickyHeader, domProps = __rest(_a, ["items", "showAddButton", "addButton", "filterPredicate", "keyProperty", "allowSort", "expandAll", "collapseAll", "initialSort", "initialSortAscending", "isBordered", "isStriped", "isBorderless", "showHover", "isSmallTable", "footerContent", "footerButtons", "stickyHeader"]);
|
|
36
49
|
if (expandAll === true) {
|
|
37
50
|
this.gridContext.expandAll = true;
|
|
38
51
|
}
|
|
@@ -86,7 +99,7 @@ var Grid = /** @class */ (function (_super) {
|
|
|
86
99
|
}
|
|
87
100
|
this.headerItem = this.gridContext.dataView.getMetaItem();
|
|
88
101
|
}
|
|
89
|
-
return (React.createElement("table", __assign({}, domProps, { className: className }),
|
|
102
|
+
return (React.createElement("table", __assign({}, domProps, { className: className, ref: this.domRef }),
|
|
90
103
|
React.createElement(GridContext.Provider, { value: this.gridContext },
|
|
91
104
|
React.createElement(TableSection, { type: "header" }, this.headerItem && this.props.children(this.headerItem, this.headerItem.meta)),
|
|
92
105
|
React.createElement(TableSection, { type: "body" }, this.gridContext.dataView.getItems().map(function (item) { return (React.createElement(ItemGroup, { item: item, key: keyProperty ? item[keyProperty] : item.entityIdentifier, template: _this.props.children })); })),
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Watches for when a table header scrolls out of view.
|
|
3
|
+
* When it does, adds a cloned header that is fixed at the top of the scrolling element.
|
|
4
|
+
*/
|
|
5
|
+
export declare class StickyTableHeader {
|
|
6
|
+
private table;
|
|
7
|
+
private fixedElement?;
|
|
8
|
+
/**
|
|
9
|
+
* Creates the instance, and begins listening for scroll events.
|
|
10
|
+
* @param table The table to add sticky headers to.
|
|
11
|
+
* @param fixedElement A fixed element at the top of the screen to use as an anchor, rather than the top of the screen itself.
|
|
12
|
+
*/
|
|
13
|
+
constructor(table: HTMLTableElement, fixedElement?: HTMLElement | undefined);
|
|
14
|
+
private scrollParent?;
|
|
15
|
+
private header;
|
|
16
|
+
private headerCopy?;
|
|
17
|
+
private headerHeight;
|
|
18
|
+
private handleScroll;
|
|
19
|
+
private removeCopy;
|
|
20
|
+
private onPossibleContentChange;
|
|
21
|
+
private setColumnWidths;
|
|
22
|
+
dispose(): void;
|
|
23
|
+
private static getParentScrollElement;
|
|
24
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Watches for when a table header scrolls out of view.
|
|
3
|
+
* When it does, adds a cloned header that is fixed at the top of the scrolling element.
|
|
4
|
+
*/
|
|
5
|
+
var StickyTableHeader = /** @class */ (function () {
|
|
6
|
+
/**
|
|
7
|
+
* Creates the instance, and begins listening for scroll events.
|
|
8
|
+
* @param table The table to add sticky headers to.
|
|
9
|
+
* @param fixedElement A fixed element at the top of the screen to use as an anchor, rather than the top of the screen itself.
|
|
10
|
+
*/
|
|
11
|
+
function StickyTableHeader(table, fixedElement) {
|
|
12
|
+
this.table = table;
|
|
13
|
+
this.fixedElement = fixedElement;
|
|
14
|
+
this.headerHeight = 0;
|
|
15
|
+
if (!table.tHead) {
|
|
16
|
+
throw Error("Table must have a header section.");
|
|
17
|
+
}
|
|
18
|
+
this.header = table.tHead;
|
|
19
|
+
this.scrollParent = StickyTableHeader.getParentScrollElement(table);
|
|
20
|
+
this.handleScroll = this.handleScroll.bind(this);
|
|
21
|
+
this.onPossibleContentChange = this.onPossibleContentChange.bind(this);
|
|
22
|
+
document.addEventListener("scroll", this.handleScroll);
|
|
23
|
+
if (this.scrollParent) {
|
|
24
|
+
this.scrollParent.addEventListener("scroll", this.handleScroll);
|
|
25
|
+
}
|
|
26
|
+
table.addEventListener("keydown", this.onPossibleContentChange);
|
|
27
|
+
table.addEventListener("mouseup", this.onPossibleContentChange);
|
|
28
|
+
}
|
|
29
|
+
StickyTableHeader.prototype.handleScroll = function () {
|
|
30
|
+
var fixedElement = null;
|
|
31
|
+
if (!this.scrollParent && this.fixedElement && getComputedStyle(this.fixedElement).position === "fixed") {
|
|
32
|
+
fixedElement = this.fixedElement;
|
|
33
|
+
}
|
|
34
|
+
var topBoundary = this.scrollParent ? this.scrollParent.getBoundingClientRect().top : (fixedElement ? fixedElement.getBoundingClientRect().bottom : 0);
|
|
35
|
+
var tableBounds = this.table.getBoundingClientRect();
|
|
36
|
+
var tbodyBounds = this.table.tBodies[this.table.tBodies.length - 1].getBoundingClientRect();
|
|
37
|
+
if (tableBounds.top < topBoundary && tbodyBounds.bottom - this.headerHeight > topBoundary) {
|
|
38
|
+
if (!this.headerCopy) {
|
|
39
|
+
this.headerHeight = this.header.getBoundingClientRect().height;
|
|
40
|
+
this.headerCopy = this.header.cloneNode(true);
|
|
41
|
+
this.table.insertBefore(this.headerCopy, this.header);
|
|
42
|
+
this.header.classList.add("neo-grid-fixed-header");
|
|
43
|
+
this.setColumnWidths();
|
|
44
|
+
}
|
|
45
|
+
this.header.style.left = tableBounds.left + "px";
|
|
46
|
+
this.header.style.top = topBoundary + "px";
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.setColumnWidths(true);
|
|
50
|
+
this.removeCopy();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
StickyTableHeader.prototype.removeCopy = function () {
|
|
54
|
+
if (this.headerCopy) {
|
|
55
|
+
this.header.classList.remove("neo-grid-fixed-header");
|
|
56
|
+
this.table.removeChild(this.headerCopy);
|
|
57
|
+
this.headerCopy = undefined;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
StickyTableHeader.prototype.onPossibleContentChange = function () {
|
|
61
|
+
var _this = this;
|
|
62
|
+
setTimeout(function () { return _this.setColumnWidths(); }, 0);
|
|
63
|
+
};
|
|
64
|
+
StickyTableHeader.prototype.setColumnWidths = function (isRemoving) {
|
|
65
|
+
if (isRemoving === void 0) { isRemoving = false; }
|
|
66
|
+
if (this.headerCopy) {
|
|
67
|
+
for (var i = 0; i < this.header.rows.length; i++) {
|
|
68
|
+
var originalRow = this.header.rows[i], copyRow = this.headerCopy.rows[i];
|
|
69
|
+
for (var j = 0; j < originalRow.cells.length; j++) {
|
|
70
|
+
var originalCell = originalRow.cells[j], copyCell = copyRow.cells[j];
|
|
71
|
+
originalCell.style.width = isRemoving ? copyCell.style.width : window.getComputedStyle(copyCell).width;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
StickyTableHeader.prototype.dispose = function () {
|
|
77
|
+
document.removeEventListener("scroll", this.handleScroll);
|
|
78
|
+
if (this.scrollParent) {
|
|
79
|
+
this.scrollParent.removeEventListener("scroll", this.handleScroll);
|
|
80
|
+
}
|
|
81
|
+
this.table.removeEventListener("keydown", this.onPossibleContentChange);
|
|
82
|
+
this.table.removeEventListener("mouseup", this.onPossibleContentChange);
|
|
83
|
+
this.removeCopy();
|
|
84
|
+
};
|
|
85
|
+
StickyTableHeader.getParentScrollElement = function (element) {
|
|
86
|
+
var current = element;
|
|
87
|
+
while (current) {
|
|
88
|
+
if ((current.style.height || current.style.maxHeight) &&
|
|
89
|
+
(current.style.overflow === "scroll" || current.style.overflow === "auto" || current.style.overflowY === "scroll" || current.style.overflowY === "auto")) {
|
|
90
|
+
return current;
|
|
91
|
+
}
|
|
92
|
+
current = current.parentElement;
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
};
|
|
96
|
+
return StickyTableHeader;
|
|
97
|
+
}());
|
|
98
|
+
export { StickyTableHeader };
|
|
@@ -106,7 +106,7 @@ var Input = /** @class */ (function (_super) {
|
|
|
106
106
|
splitProps.editor.append = this.props.bind.value ?
|
|
107
107
|
React.createElement(Button, __assign({ size: "sm" }, buttonOptions, { icon: !this.showPassword ? "far-eye fa-fw" : "far-eye-slash fa-fw", onClick: function () { return _this.showPassword = !_this.showPassword; } })) : null;
|
|
108
108
|
}
|
|
109
|
-
return (InputHelpers.surroundWithInputGroup(inputElement, splitProps.editor));
|
|
109
|
+
return (InputHelpers.surroundWithInputGroup(inputElement, splitProps.editor, this.domRef));
|
|
110
110
|
};
|
|
111
111
|
Input.contextType = FormContext;
|
|
112
112
|
__decorate([
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
import { ICommonEditorProps } from './PropTypes';
|
|
3
3
|
export declare class InputHelpers {
|
|
4
4
|
private static iconFactory?;
|
|
5
|
-
static surroundWithInputGroup<T>(element: T, props: ICommonEditorProps): JSX.Element | T;
|
|
5
|
+
static surroundWithInputGroup<T>(element: T, props: ICommonEditorProps, inputRef?: React.RefObject<HTMLElement>): JSX.Element | T;
|
|
6
6
|
}
|
|
@@ -4,7 +4,7 @@ import { NeoReactTypes } from '../Modules/Types';
|
|
|
4
4
|
var InputHelpers = /** @class */ (function () {
|
|
5
5
|
function InputHelpers() {
|
|
6
6
|
}
|
|
7
|
-
InputHelpers.surroundWithInputGroup = function (element, props) {
|
|
7
|
+
InputHelpers.surroundWithInputGroup = function (element, props, inputRef) {
|
|
8
8
|
if (!this.iconFactory) {
|
|
9
9
|
this.iconFactory = Misc.Globals.appService.get(NeoReactTypes.Components.IconFactory);
|
|
10
10
|
}
|
|
@@ -13,12 +13,12 @@ var InputHelpers = /** @class */ (function () {
|
|
|
13
13
|
(props.prependText || props.prepend) &&
|
|
14
14
|
React.createElement("div", { className: "input-group-prepend" },
|
|
15
15
|
props.prepend && (props.prepend instanceof Function ? props.prepend() : props.prepend),
|
|
16
|
-
props.prependText && React.createElement("span", { className: "input-group-text" }, this.iconFactory.textOrIcon(props.prependText))),
|
|
16
|
+
props.prependText && React.createElement("span", { className: "input-group-text", onClick: function () { var _a, _b; return (_b = (_a = inputRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.focus(); } }, this.iconFactory.textOrIcon(props.prependText))),
|
|
17
17
|
element,
|
|
18
18
|
(props.appendText || props.append) &&
|
|
19
19
|
React.createElement("div", { className: "input-group-append" },
|
|
20
20
|
props.append && (props.append instanceof Function ? props.append() : props.append),
|
|
21
|
-
props.appendText && React.createElement("span", { className: "input-group-text" }, this.iconFactory.textOrIcon(props.appendText)))));
|
|
21
|
+
props.appendText && React.createElement("span", { className: "input-group-text", onClick: function () { var _a, _b; return (_b = (_a = inputRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.focus(); } }, this.iconFactory.textOrIcon(props.appendText)))));
|
|
22
22
|
}
|
|
23
23
|
else {
|
|
24
24
|
return element;
|
|
@@ -97,8 +97,15 @@ var NumberInput = /** @class */ (function (_super) {
|
|
|
97
97
|
}
|
|
98
98
|
NumberInput.prototype.onChanged = function (e) {
|
|
99
99
|
var newValue;
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
var stringValue = e.target.value;
|
|
101
|
+
if (stringValue !== "") {
|
|
102
|
+
if (NumberUtils.allowAsDecimalSeparator) {
|
|
103
|
+
var firstIndex = stringValue.indexOf(NumberUtils.allowAsDecimalSeparator), lastIndex = stringValue.lastIndexOf(NumberUtils.allowAsDecimalSeparator);
|
|
104
|
+
if (firstIndex >= 0 && firstIndex === lastIndex) {
|
|
105
|
+
stringValue = stringValue.replace(NumberUtils.allowAsDecimalSeparator, ".");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
var testValue = stringValue;
|
|
102
109
|
if (testValue[0] === "-") {
|
|
103
110
|
testValue = testValue.substring(1);
|
|
104
111
|
}
|
|
@@ -106,18 +113,18 @@ var NumberInput = /** @class */ (function (_super) {
|
|
|
106
113
|
return;
|
|
107
114
|
}
|
|
108
115
|
}
|
|
109
|
-
if (
|
|
116
|
+
if (stringValue == "") {
|
|
110
117
|
newValue = this.props.bind.propertyInfo.allowNulls ? null : new Decimal(0);
|
|
111
118
|
}
|
|
112
119
|
else if (this.formatState.isPercent && NumberUtils.transformPercent) {
|
|
113
|
-
newValue = new Decimal(
|
|
120
|
+
newValue = new Decimal(stringValue).dividedBy(100);
|
|
114
121
|
}
|
|
115
122
|
else if (this.numericType === Misc.DataType.Float || this.numericType === Misc.DataType.Decimal) {
|
|
116
|
-
newValue = new Decimal(
|
|
123
|
+
newValue = new Decimal(stringValue);
|
|
117
124
|
}
|
|
118
125
|
else {
|
|
119
126
|
// Rounds to zero.
|
|
120
|
-
newValue = new Decimal(
|
|
127
|
+
newValue = new Decimal(stringValue).toDecimalPlaces(0, Decimal.ROUND_DOWN);
|
|
121
128
|
}
|
|
122
129
|
if (newValue === null) {
|
|
123
130
|
this.props.bind.value = newValue;
|
|
@@ -249,7 +256,7 @@ var NumberInput = /** @class */ (function (_super) {
|
|
|
249
256
|
var decimals = NumberUtils.getDecimalPlaces(this.formatState.formatString);
|
|
250
257
|
domProps.step = decimals === 0 ? "1" : "0." + "0".repeat(decimals - 1) + "1";
|
|
251
258
|
}
|
|
252
|
-
return (InputHelpers.surroundWithInputGroup(React.createElement("input", __assign({}, domProps, { defaultValue: this.formatState.getFormattedValue(editorProps.bind.value), type: useNative ? "number" : "text", onChange: this.onChanged, ref: this.inputElement })), editorProps));
|
|
259
|
+
return (InputHelpers.surroundWithInputGroup(React.createElement("input", __assign({}, domProps, { defaultValue: this.formatState.getFormattedValue(editorProps.bind.value), type: useNative ? "number" : "text", onChange: this.onChanged, ref: this.inputElement })), editorProps, this.inputElement));
|
|
253
260
|
};
|
|
254
261
|
NumberInput.contextType = FormContext;
|
|
255
262
|
NumberInput = __decorate([
|
|
@@ -135,22 +135,15 @@ export declare class BindPropsHelper {
|
|
|
135
135
|
*/
|
|
136
136
|
static getBindProperty<T>(allProps: IEditorContainerProps<T, any>): Model.IPropertyInstance;
|
|
137
137
|
static splitCommonEditorProps<T extends ICommonEditorProps>(props: T): {
|
|
138
|
-
editor:
|
|
139
|
-
isReadOnly: boolean | undefined;
|
|
140
|
-
isDisabled: boolean | undefined;
|
|
141
|
-
prependText: string | undefined;
|
|
142
|
-
prepend: JSX.Element | (() => JSX.Element) | null | undefined;
|
|
143
|
-
appendText: string | undefined;
|
|
144
|
-
append: JSX.Element | (() => JSX.Element) | null | undefined;
|
|
145
|
-
inputElement: React.RefObject<HTMLElement> | undefined;
|
|
146
|
-
requiresGroup: boolean;
|
|
147
|
-
};
|
|
138
|
+
editor: ICommonEditorProps;
|
|
148
139
|
rest: Pick<T, Exclude<keyof T, "disabled" | "readOnly" | "isReadOnly" | "isDisabled" | "prependText" | "appendText" | "prepend" | "append" | "inputElement">>;
|
|
149
140
|
};
|
|
150
141
|
static normaliseContainerProps<T, TContainerDom = React.HTMLProps<T>>(component: IComponentBase, props: IEditorContainerProps<T, any> & TContainerDom, inGroup: boolean, isBootstrap?: boolean): IEditorContainerNormalisedProps<TContainerDom, any>;
|
|
151
142
|
static normaliseEditorProps<T, TDom = React.HTMLProps<T>>(component: IComponentBase, props: (IEditorAndSelectorProps<T, any> & TDom) | IEditorNormalisedProps<TDom, any>): IEditorNormalisedProps<TDom, any>;
|
|
152
143
|
static getPlaceholderText(placeholder: string | boolean | undefined, property: PropertyInfo): string | undefined;
|
|
153
144
|
static autoSetDomProperties<TDom extends React.HTMLProps<HTMLElement>>(props: IEditorNormalisedProps<TDom, any>, formContext: FormContextParams, componentBlurFn?: (e: React.FocusEvent<HTMLElement>) => void, componentFocusFn?: (e: React.FocusEvent<HTMLElement>) => void): TDom;
|
|
145
|
+
static isReadOnly(editorProps: ICommonEditorProps, formContext: FormContextParams): boolean;
|
|
146
|
+
static isDisabled(editorProps: ICommonEditorProps, formContext: FormContextParams): boolean;
|
|
154
147
|
/**
|
|
155
148
|
* Intercept the user specified blur event, and run the validation onBlur logic first.
|
|
156
149
|
* @param props Props specified on component.
|
|
@@ -204,12 +204,12 @@ var BindPropsHelper = /** @class */ (function () {
|
|
|
204
204
|
if (this.config.isTestOrDevelopment) {
|
|
205
205
|
domProps[BindPropsHelper.DataFieldName] = props.bind.propertyInfo.propertyName;
|
|
206
206
|
}
|
|
207
|
-
if (
|
|
207
|
+
if (this.isReadOnly(props.editor, formContext)) {
|
|
208
208
|
domProps.readOnly = true;
|
|
209
209
|
if (!domProps.tabIndex)
|
|
210
210
|
domProps.tabIndex = -1;
|
|
211
211
|
}
|
|
212
|
-
if (
|
|
212
|
+
if (this.isDisabled(props.editor, formContext)) {
|
|
213
213
|
domProps.disabled = true;
|
|
214
214
|
}
|
|
215
215
|
if (props.editor.placeholder) {
|
|
@@ -226,6 +226,16 @@ var BindPropsHelper = /** @class */ (function () {
|
|
|
226
226
|
domProps.onBlur = BindPropsHelper.blurIntercept(props.editor, domProps.onBlur, componentBlurFn);
|
|
227
227
|
return domProps;
|
|
228
228
|
};
|
|
229
|
+
BindPropsHelper.isReadOnly = function (editorProps, formContext) {
|
|
230
|
+
var _a;
|
|
231
|
+
var propsReadOnly = (_a = editorProps.isReadOnly, (_a !== null && _a !== void 0 ? _a : editorProps.readOnly));
|
|
232
|
+
return propsReadOnly || (formContext.allReadOnly && propsReadOnly === undefined);
|
|
233
|
+
};
|
|
234
|
+
BindPropsHelper.isDisabled = function (editorProps, formContext) {
|
|
235
|
+
var _a;
|
|
236
|
+
var propsDisabled = (_a = editorProps.isDisabled, (_a !== null && _a !== void 0 ? _a : editorProps.disabled));
|
|
237
|
+
return propsDisabled || (formContext.allDisabled && propsDisabled === undefined);
|
|
238
|
+
};
|
|
229
239
|
/**
|
|
230
240
|
* Intercept the user specified blur event, and run the validation onBlur logic first.
|
|
231
241
|
* @param props Props specified on component.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@singularsystems/neo-react",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.63",
|
|
4
4
|
"description": "React application logic and components for the Neo client library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@types/rc-slider": "^8.6.5",
|
|
34
34
|
"@types/react-color": "^3.0.1",
|
|
35
35
|
"@types/react-select": "3.1.0",
|
|
36
|
-
"@singularsystems/neo-core": "^0.10.
|
|
36
|
+
"@singularsystems/neo-core": "^0.10.74",
|
|
37
37
|
"axios": "^0.21.1",
|
|
38
38
|
"decimal.js-light": "2.5.1",
|
|
39
39
|
"history": "4.10.1",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"react-router-dom": "5.1.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@singularsystems/neo-core": ">=0.10.
|
|
50
|
+
"@singularsystems/neo-core": ">=0.10.74",
|
|
51
51
|
"axios": ">=0.21.1",
|
|
52
52
|
"inversify": ">=5.0.1",
|
|
53
53
|
"react": ">=16.13.1",
|
package/styles/DatePicker.scss
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
position: relative;
|
|
4
4
|
width: 100%;
|
|
5
5
|
color: initial;
|
|
6
|
+
|
|
7
|
+
&.neo-datepicker-always-show {
|
|
8
|
+
width: max-content;
|
|
9
|
+
|
|
10
|
+
input {
|
|
11
|
+
text-align: center;
|
|
12
|
+
padding: 0.125rem 0;
|
|
13
|
+
height: auto;
|
|
14
|
+
margin-bottom: 0.25rem;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
6
17
|
}
|
|
7
18
|
|
|
8
19
|
.neo-datepicker-popup {
|