@singularsystems/neo-core 1.0.12 → 1.0.13
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/Components/DatePicker/DatePicker.d.ts +2 -1
- package/dist/Components/DatePicker/DatePicker.js +28 -17
- package/dist/Components/PositionHelper.d.ts +12 -3
- package/dist/Components/PositionHelper.js +41 -15
- package/dist/Data/Deserialiser.js +1 -1
- package/dist/Model/ObservableValue.d.ts +8 -0
- package/dist/Model/ObservableValue.js +17 -0
- package/dist/Model/index.d.ts +1 -1
- package/dist/Model/index.js +1 -1
- package/package.json +1 -1
|
@@ -10,7 +10,7 @@ export default class DatePicker {
|
|
|
10
10
|
private headerAnimationHelper;
|
|
11
11
|
private inputHasChanged;
|
|
12
12
|
private input;
|
|
13
|
-
private popup
|
|
13
|
+
private popup?;
|
|
14
14
|
private headerContainer;
|
|
15
15
|
private currentHeaderLabel;
|
|
16
16
|
private prevButton;
|
|
@@ -22,6 +22,7 @@ export default class DatePicker {
|
|
|
22
22
|
private boundDateNoTime;
|
|
23
23
|
private today;
|
|
24
24
|
private currentViewDate;
|
|
25
|
+
private positionHelper?;
|
|
25
26
|
constructor(container: HTMLDivElement, options?: IPartialDateProps);
|
|
26
27
|
static mustShowInput(options?: IPartialDateProps): boolean | undefined;
|
|
27
28
|
inputFocused(e: FocusEvent): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import DateUtils from '../../Dates/DateUtils';
|
|
2
2
|
import AnimationHelper from '../AnimationHelper';
|
|
3
3
|
import { YearsInYearView, ProcessedDatePickerOptions } from './DatePickerOptions';
|
|
4
|
-
import
|
|
4
|
+
import { FixedPositionHelper } from '../PositionHelper';
|
|
5
5
|
// TODO: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
|
|
6
6
|
// TODO: Allow input to be shown with inline picker, and specify position.
|
|
7
7
|
var ViewType;
|
|
@@ -114,6 +114,7 @@ var DatePicker = /** @class */ (function () {
|
|
|
114
114
|
}
|
|
115
115
|
};
|
|
116
116
|
DatePicker.prototype.removePopup = function (animate) {
|
|
117
|
+
var _a;
|
|
117
118
|
if (this.popup && !this.options.alwaysShow) {
|
|
118
119
|
if (animate) {
|
|
119
120
|
AnimationHelper.scale(this.popup, DatePicker.AnimationClassName, 1, 0);
|
|
@@ -124,7 +125,9 @@ var DatePicker = /** @class */ (function () {
|
|
|
124
125
|
}
|
|
125
126
|
this.currentHeaderLabel = null;
|
|
126
127
|
this.currentContentTable = null;
|
|
127
|
-
this.popup =
|
|
128
|
+
this.popup = undefined;
|
|
129
|
+
(_a = this.positionHelper) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
130
|
+
this.positionHelper = undefined;
|
|
128
131
|
}
|
|
129
132
|
};
|
|
130
133
|
DatePicker.prototype.setBindValue = function (dateValue, options) {
|
|
@@ -140,7 +143,7 @@ var DatePicker = /** @class */ (function () {
|
|
|
140
143
|
if (options.close) {
|
|
141
144
|
this.removePopup(true);
|
|
142
145
|
}
|
|
143
|
-
if (!options.close ||
|
|
146
|
+
if (!options.close || options.forceDraw) {
|
|
144
147
|
this.resetCurrentViewDate();
|
|
145
148
|
this.populateContentContainer(true);
|
|
146
149
|
}
|
|
@@ -173,9 +176,12 @@ var DatePicker = /** @class */ (function () {
|
|
|
173
176
|
}
|
|
174
177
|
};
|
|
175
178
|
DatePicker.prototype.positionPopup = function (fromBottom) {
|
|
176
|
-
if (this.popup) {
|
|
179
|
+
if (this.popup && !this.options.alwaysShow) {
|
|
177
180
|
var textAlign = this.options.popupAlignRight ? undefined : window.getComputedStyle(this.input).textAlign;
|
|
178
|
-
|
|
181
|
+
if (!this.positionHelper) {
|
|
182
|
+
this.positionHelper = new FixedPositionHelper(this.container, this.popup);
|
|
183
|
+
}
|
|
184
|
+
this.positionHelper.positionPopup(this.options.popupAlignRight, textAlign, fromBottom);
|
|
179
185
|
}
|
|
180
186
|
};
|
|
181
187
|
/**
|
|
@@ -234,15 +240,15 @@ var DatePicker = /** @class */ (function () {
|
|
|
234
240
|
this.popup.addEventListener("mouseenter", function () { return _this.positionPopup(false); });
|
|
235
241
|
this.popup.addEventListener("mouseleave", function () { return _this.positionPopup(true); });
|
|
236
242
|
}
|
|
237
|
-
this.createHeader();
|
|
238
|
-
this.createContentContainer();
|
|
243
|
+
this.createHeader(this.popup);
|
|
244
|
+
this.createContentContainer(this.popup);
|
|
239
245
|
}
|
|
240
246
|
else {
|
|
241
247
|
this.populateContentContainer(true);
|
|
242
248
|
}
|
|
243
249
|
};
|
|
244
|
-
DatePicker.prototype.createHeader = function () {
|
|
245
|
-
var header = this.createAndAppend(
|
|
250
|
+
DatePicker.prototype.createHeader = function (parent) {
|
|
251
|
+
var header = this.createAndAppend(parent, "div", "neo-datepicker-header");
|
|
246
252
|
header.addEventListener("mousedown", function (e) { return e.preventDefault(); });
|
|
247
253
|
this.prevButton = this.createAndAppend(header, "button", "left-button");
|
|
248
254
|
this.prevButton.type = "button";
|
|
@@ -258,7 +264,7 @@ var DatePicker = /** @class */ (function () {
|
|
|
258
264
|
this.nextButton.tabIndex = -1;
|
|
259
265
|
this.nextButton.addEventListener("mousedown", this.nextClick.bind(this));
|
|
260
266
|
};
|
|
261
|
-
DatePicker.prototype.createHeaderLabel = function () {
|
|
267
|
+
DatePicker.prototype.createHeaderLabel = function (displayImmediately) {
|
|
262
268
|
this.currentHeaderLabel = this.createAndAppend(this.headerContainer, "div", "header-text");
|
|
263
269
|
if (this.currentViewType == ViewType.Days) {
|
|
264
270
|
this.currentHeaderLabel.innerText = DateUtils.format(this.currentViewDate, "MMMM yyyy");
|
|
@@ -273,10 +279,15 @@ var DatePicker = /** @class */ (function () {
|
|
|
273
279
|
this.currentHeaderLabel.className += " selectable";
|
|
274
280
|
}
|
|
275
281
|
this.headerAnimationHelper.addChild(this.currentHeaderLabel, false);
|
|
276
|
-
|
|
282
|
+
if (displayImmediately) {
|
|
283
|
+
this.headerAnimationHelper.replace();
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
this.headerAnimationHelper.fade();
|
|
287
|
+
}
|
|
277
288
|
};
|
|
278
|
-
DatePicker.prototype.createContentContainer = function () {
|
|
279
|
-
this.contentContainer = this.createAndAppend(
|
|
289
|
+
DatePicker.prototype.createContentContainer = function (parent) {
|
|
290
|
+
this.contentContainer = this.createAndAppend(parent, "div", "neo-datepicker-content");
|
|
280
291
|
this.contentContainer.addEventListener("mousedown", this.contentClick.bind(this));
|
|
281
292
|
this.contentAnimationHelper = new AnimationHelper(this.contentContainer, DatePicker.AnimationClassName);
|
|
282
293
|
this.populateContentContainer(!!this.options.alwaysShow);
|
|
@@ -298,7 +309,7 @@ var DatePicker = /** @class */ (function () {
|
|
|
298
309
|
this.currentViewDate.setFullYear(this.currentViewDate.getFullYear() - this.options.yearsBeforeInYearView);
|
|
299
310
|
this.createYearsView();
|
|
300
311
|
}
|
|
301
|
-
this.createHeaderLabel();
|
|
312
|
+
this.createHeaderLabel(displayImmediately);
|
|
302
313
|
this.contentAnimationHelper.addChild(this.currentContentTable, true);
|
|
303
314
|
if (displayImmediately) {
|
|
304
315
|
this.contentAnimationHelper.replace();
|
|
@@ -412,12 +423,12 @@ var DatePicker = /** @class */ (function () {
|
|
|
412
423
|
};
|
|
413
424
|
DatePicker.prototype.dayClicked = function (datePartsString) {
|
|
414
425
|
var dateParts = datePartsString.split(",");
|
|
415
|
-
this.setBindValue(new Date(parseInt(dateParts[0]), parseInt(dateParts[1]), parseInt(dateParts[2])), { preserveTime: true, close: true });
|
|
426
|
+
this.setBindValue(new Date(parseInt(dateParts[0]), parseInt(dateParts[1]), parseInt(dateParts[2])), { preserveTime: true, close: true, forceDraw: this.options.alwaysShow });
|
|
416
427
|
};
|
|
417
428
|
DatePicker.prototype.monthClicked = function (monthString) {
|
|
418
429
|
this.currentViewDate.setMonth(parseInt(monthString));
|
|
419
430
|
if (this.options.monthView) {
|
|
420
|
-
this.setBindValue(this.currentViewDate, { preserveTime: true, close: true });
|
|
431
|
+
this.setBindValue(this.currentViewDate, { preserveTime: true, close: true, forceDraw: this.options.alwaysShow });
|
|
421
432
|
}
|
|
422
433
|
else {
|
|
423
434
|
this.currentViewType = ViewType.Days;
|
|
@@ -428,7 +439,7 @@ var DatePicker = /** @class */ (function () {
|
|
|
428
439
|
DatePicker.prototype.yearClicked = function (yearString) {
|
|
429
440
|
this.currentViewDate.setFullYear(parseInt(yearString));
|
|
430
441
|
if (this.options.yearView) {
|
|
431
|
-
this.setBindValue(this.currentViewDate, { preserveTime: true, close: true });
|
|
442
|
+
this.setBindValue(this.currentViewDate, { preserveTime: true, close: true, forceDraw: this.options.alwaysShow });
|
|
432
443
|
}
|
|
433
444
|
else {
|
|
434
445
|
this.currentViewType = ViewType.Months;
|
|
@@ -17,6 +17,10 @@ export default class PositionHelper {
|
|
|
17
17
|
* @param hAlign Horizontal alignment of the popup edge relative to the anchor edge. Overrides alignRight
|
|
18
18
|
*/
|
|
19
19
|
static checkScreenBounds(anchor: HTMLElement, popup: HTMLElement, fromBottom?: boolean, alignRight?: boolean, hAlign?: "left" | "center" | "right"): void;
|
|
20
|
+
/**
|
|
21
|
+
* Used internally by neo. Use `checkScreenBounds` instead of this method.
|
|
22
|
+
*/
|
|
23
|
+
static positionElement(popup: HTMLElement, position: IRelativePosition, fromBottom?: boolean): void;
|
|
20
24
|
/**
|
|
21
25
|
* Ensures that a popup element is positioned so that it remains in the bounds of the screen by left/right/top/bottom aligning it relative to the anchor element.
|
|
22
26
|
* @param anchor The element to which the popup is anchored
|
|
@@ -26,14 +30,19 @@ export default class PositionHelper {
|
|
|
26
30
|
*/
|
|
27
31
|
static getRelativePosition(anchor: HTMLElement, popup: HTMLElement, alignRight?: boolean, hAlign?: "left" | "center" | "right"): IRelativePosition;
|
|
28
32
|
}
|
|
29
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Helper used to position elements with position: fixed relative to another element, while maintaining position on scroll.
|
|
35
|
+
* If popupElement has a display of 'absolute', then normal positioning is performed.
|
|
36
|
+
*/
|
|
30
37
|
export declare class FixedPositionHelper implements IDisposable {
|
|
31
38
|
private anchorElement;
|
|
32
39
|
private popupElement;
|
|
40
|
+
private isFixed;
|
|
33
41
|
private topOffset;
|
|
34
42
|
private positionInfo;
|
|
35
|
-
constructor(anchorElement: HTMLElement, popupElement: HTMLElement
|
|
36
|
-
|
|
43
|
+
constructor(anchorElement: HTMLElement, popupElement: HTMLElement);
|
|
44
|
+
positionPopup(alignRight?: boolean, hAlign?: "left" | "center" | "right", fromBottom?: boolean): void;
|
|
45
|
+
private positionFixedPopup;
|
|
37
46
|
dispose(): void;
|
|
38
47
|
}
|
|
39
48
|
export {};
|
|
@@ -13,6 +13,13 @@ var PositionHelper = /** @class */ (function () {
|
|
|
13
13
|
if (fromBottom === void 0) { fromBottom = true; }
|
|
14
14
|
if (alignRight === void 0) { alignRight = false; }
|
|
15
15
|
var position = this.getRelativePosition(anchor, popup, alignRight, hAlign);
|
|
16
|
+
this.positionElement(popup, position, fromBottom);
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Used internally by neo. Use `checkScreenBounds` instead of this method.
|
|
20
|
+
*/
|
|
21
|
+
PositionHelper.positionElement = function (popup, position, fromBottom) {
|
|
22
|
+
if (fromBottom === void 0) { fromBottom = true; }
|
|
16
23
|
if (position.onTop) {
|
|
17
24
|
if (fromBottom) {
|
|
18
25
|
popup.style.top = "auto";
|
|
@@ -84,28 +91,45 @@ var PositionHelper = /** @class */ (function () {
|
|
|
84
91
|
return PositionHelper;
|
|
85
92
|
}());
|
|
86
93
|
export default PositionHelper;
|
|
87
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* Helper used to position elements with position: fixed relative to another element, while maintaining position on scroll.
|
|
96
|
+
* If popupElement has a display of 'absolute', then normal positioning is performed.
|
|
97
|
+
*/
|
|
88
98
|
var FixedPositionHelper = /** @class */ (function () {
|
|
89
|
-
function FixedPositionHelper(anchorElement, popupElement
|
|
90
|
-
if (alignRight === void 0) { alignRight = false; }
|
|
99
|
+
function FixedPositionHelper(anchorElement, popupElement) {
|
|
91
100
|
this.anchorElement = anchorElement;
|
|
92
101
|
this.popupElement = popupElement;
|
|
102
|
+
this.isFixed = false;
|
|
93
103
|
this.topOffset = 0;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
if (window.getComputedStyle(popupElement).position === "fixed") {
|
|
105
|
+
this.isFixed = true;
|
|
106
|
+
window.addEventListener("scroll", this.positionFixedPopup.bind(this), { capture: true });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
FixedPositionHelper.prototype.positionPopup = function (alignRight, hAlign, fromBottom) {
|
|
110
|
+
if (alignRight === void 0) { alignRight = false; }
|
|
111
|
+
if (fromBottom === void 0) { fromBottom = true; }
|
|
112
|
+
this.positionInfo = PositionHelper.getRelativePosition(this.anchorElement, this.popupElement, alignRight, hAlign);
|
|
113
|
+
if (this.isFixed) {
|
|
114
|
+
// Fixed, need to add scroll listener.
|
|
115
|
+
if (this.positionInfo.onTop) {
|
|
116
|
+
var style = window.getComputedStyle(this.popupElement);
|
|
117
|
+
var marginHeight = parseFloat(style.marginBottom) + parseFloat(style.marginTop);
|
|
118
|
+
this.topOffset = -(this.positionInfo.popupHeight + marginHeight);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
this.topOffset = this.positionInfo.anchorHeight;
|
|
122
|
+
}
|
|
123
|
+
this.positionFixedPopup();
|
|
99
124
|
}
|
|
100
125
|
else {
|
|
101
|
-
|
|
126
|
+
// Simple positioning relative to container.
|
|
127
|
+
PositionHelper.positionElement(this.popupElement, this.positionInfo, fromBottom);
|
|
102
128
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
FixedPositionHelper.prototype.positionPopup = function () {
|
|
129
|
+
};
|
|
130
|
+
FixedPositionHelper.prototype.positionFixedPopup = function () {
|
|
107
131
|
var rect = this.anchorElement.getBoundingClientRect();
|
|
108
|
-
this.popupElement.style.top = (rect.top + this.topOffset) + "px";
|
|
132
|
+
this.popupElement.style.top = (Math.floor(rect.top) + this.topOffset) + "px";
|
|
109
133
|
this.popupElement.style.right = "auto";
|
|
110
134
|
if (this.positionInfo.left !== undefined) {
|
|
111
135
|
this.popupElement.style.left = (rect.left + this.positionInfo.left) + "px";
|
|
@@ -115,7 +139,9 @@ var FixedPositionHelper = /** @class */ (function () {
|
|
|
115
139
|
}
|
|
116
140
|
};
|
|
117
141
|
FixedPositionHelper.prototype.dispose = function () {
|
|
118
|
-
|
|
142
|
+
if (this.isFixed) {
|
|
143
|
+
window.removeEventListener("scroll", this.positionFixedPopup);
|
|
144
|
+
}
|
|
119
145
|
};
|
|
120
146
|
return FixedPositionHelper;
|
|
121
147
|
}());
|
|
@@ -227,7 +227,7 @@ var Deserialiser = /** @class */ (function () {
|
|
|
227
227
|
from.entityIdentifier && from.entityIdentifier.indexOf('000000000000') === -1) {
|
|
228
228
|
toModel.entityIdentifier = from.entityIdentifier;
|
|
229
229
|
}
|
|
230
|
-
if (!this.options.isMap) {
|
|
230
|
+
if (!this.options.isMap && to.isSelfDirty !== undefined) {
|
|
231
231
|
if (!from.trackingState) {
|
|
232
232
|
toModel.isSelfDirty = false;
|
|
233
233
|
toModel.isNew = false;
|
|
@@ -7,3 +7,11 @@ export declare class ObservableValue<T> implements IObservableValue<T> {
|
|
|
7
7
|
constructor(initialValue: T);
|
|
8
8
|
get peek(): T;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Creates a wrapper around a value with a getter and setter for reading and writing the value.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ValueWrapper<T> implements IObservableValue<T> {
|
|
14
|
+
constructor(getter: () => T, setter: (value: T) => void);
|
|
15
|
+
value: T;
|
|
16
|
+
get peek(): T;
|
|
17
|
+
}
|
|
@@ -24,3 +24,20 @@ var ObservableValue = /** @class */ (function () {
|
|
|
24
24
|
return ObservableValue;
|
|
25
25
|
}());
|
|
26
26
|
export { ObservableValue };
|
|
27
|
+
/**
|
|
28
|
+
* Creates a wrapper around a value with a getter and setter for reading and writing the value.
|
|
29
|
+
*/
|
|
30
|
+
var ValueWrapper = /** @class */ (function () {
|
|
31
|
+
function ValueWrapper(getter, setter) {
|
|
32
|
+
Object.defineProperty(this, "value", { get: getter, set: setter });
|
|
33
|
+
}
|
|
34
|
+
Object.defineProperty(ValueWrapper.prototype, "peek", {
|
|
35
|
+
get: function () {
|
|
36
|
+
return this.value;
|
|
37
|
+
},
|
|
38
|
+
enumerable: false,
|
|
39
|
+
configurable: true
|
|
40
|
+
});
|
|
41
|
+
return ValueWrapper;
|
|
42
|
+
}());
|
|
43
|
+
export { ValueWrapper };
|
package/dist/Model/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { IBindableBase, IModelBase, NeoModelConstructor, PlainObject, PlainTrack
|
|
|
2
2
|
export { ILookupBase } from './LookupBase';
|
|
3
3
|
export { IPropertyInstance, PropertyAccessor } from './PropertyInstance';
|
|
4
4
|
import PropertyInfo from './PropertyInfo';
|
|
5
|
-
export { IObservableValue, ObservableValue } from './ObservableValue';
|
|
5
|
+
export { IObservableValue, ObservableValue, ValueWrapper } from './ObservableValue';
|
|
6
6
|
export { ObservableProperty } from './ObservableProperty';
|
|
7
7
|
export { ISelectedItem } from './Misc';
|
|
8
8
|
export { ModelFieldInfo, IModelFieldInfoContainer } from './ModelFieldInfo';
|
package/dist/Model/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { PropertyAccessor } from './PropertyInstance';
|
|
2
2
|
import PropertyInfo from './PropertyInfo';
|
|
3
|
-
export { ObservableValue } from './ObservableValue';
|
|
3
|
+
export { ObservableValue, ValueWrapper } from './ObservableValue';
|
|
4
4
|
export { ObservableProperty } from './ObservableProperty';
|
|
5
5
|
export { ModelFieldInfo } from './ModelFieldInfo';
|
|
6
6
|
import * as GraphTraverser from './ModelGraphTraverser';
|