uicore-ts 1.1.148 → 1.1.152
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/compiledScripts/UIDialogView.d.ts +2 -0
- package/compiledScripts/UIDialogView.js +50 -24
- package/compiledScripts/UIDialogView.js.map +2 -2
- package/compiledScripts/UITextField.d.ts +14 -0
- package/compiledScripts/UITextField.js +52 -0
- package/compiledScripts/UITextField.js.map +2 -2
- package/package.json +1 -1
- package/scripts/UIDialogView.ts +55 -27
- package/scripts/UITextField.ts +84 -0
|
@@ -7,6 +7,8 @@ export declare class UIDialogView<ViewType extends UIView = UIView> extends UIVi
|
|
|
7
7
|
_zIndex: number;
|
|
8
8
|
isVisible: boolean;
|
|
9
9
|
dismissesOnTapOutside: boolean;
|
|
10
|
+
static _activeDialogCount: number;
|
|
11
|
+
_fillsViewport: boolean;
|
|
10
12
|
constructor(elementID?: string, viewHTMLElement?: HTMLElement);
|
|
11
13
|
didDetectTapOutside(sender: UIView, event: Event): void;
|
|
12
14
|
set zIndex(zIndex: number);
|
|
@@ -28,7 +28,7 @@ var import_UINativeScrollView = require("./UINativeScrollView");
|
|
|
28
28
|
var import_UIObject = require("./UIObject");
|
|
29
29
|
var import_UIScrollView = require("./UIScrollView");
|
|
30
30
|
var import_UIView = require("./UIView");
|
|
31
|
-
class
|
|
31
|
+
const _UIDialogView = class extends import_UIView.UIView {
|
|
32
32
|
constructor(elementID, viewHTMLElement) {
|
|
33
33
|
super(elementID, viewHTMLElement);
|
|
34
34
|
this._isAUIDialogView = import_UIObject.YES;
|
|
@@ -37,6 +37,7 @@ class UIDialogView extends import_UIView.UIView {
|
|
|
37
37
|
this._zIndex = 100;
|
|
38
38
|
this.isVisible = import_UIObject.NO;
|
|
39
39
|
this.dismissesOnTapOutside = import_UIObject.YES;
|
|
40
|
+
this._fillsViewport = import_UIObject.NO;
|
|
40
41
|
this.addTargetForControlEvent(
|
|
41
42
|
import_UIView.UIView.controlEvent.PointerTap,
|
|
42
43
|
function(sender, event) {
|
|
@@ -81,9 +82,16 @@ class UIDialogView extends import_UIView.UIView {
|
|
|
81
82
|
this.style.opacity = "0";
|
|
82
83
|
}
|
|
83
84
|
showInView(containerView, animated) {
|
|
85
|
+
this._fillsViewport = containerView.rootView == containerView;
|
|
84
86
|
animated = animated && !import_ClientCheckers.IS_FIREFOX;
|
|
85
87
|
this._appearedAnimated = animated;
|
|
86
88
|
this.willAppear(animated);
|
|
89
|
+
if (this._fillsViewport) {
|
|
90
|
+
_UIDialogView._activeDialogCount++;
|
|
91
|
+
if (_UIDialogView._activeDialogCount >= 1) {
|
|
92
|
+
document.body.style.overflow = "hidden";
|
|
93
|
+
}
|
|
94
|
+
}
|
|
87
95
|
containerView.addSubview(this);
|
|
88
96
|
this.view.setNeedsLayoutUpToRootView();
|
|
89
97
|
if (animated) {
|
|
@@ -113,6 +121,14 @@ class UIDialogView extends import_UIView.UIView {
|
|
|
113
121
|
if (animated == void 0) {
|
|
114
122
|
animated = this._appearedAnimated;
|
|
115
123
|
}
|
|
124
|
+
const unlockScroll = () => {
|
|
125
|
+
if (this._fillsViewport) {
|
|
126
|
+
_UIDialogView._activeDialogCount = Math.max(0, _UIDialogView._activeDialogCount - 1);
|
|
127
|
+
if (_UIDialogView._activeDialogCount === 0) {
|
|
128
|
+
document.body.style.overflow = "";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
116
132
|
if (animated) {
|
|
117
133
|
import_UIView.UIView.animateViewOrViewsWithDurationDelayAndFunction(
|
|
118
134
|
this,
|
|
@@ -125,11 +141,13 @@ class UIDialogView extends import_UIView.UIView {
|
|
|
125
141
|
() => {
|
|
126
142
|
if (this.isVisible == import_UIObject.NO) {
|
|
127
143
|
this.removeFromSuperview();
|
|
144
|
+
unlockScroll();
|
|
128
145
|
}
|
|
129
146
|
}
|
|
130
147
|
);
|
|
131
148
|
} else {
|
|
132
149
|
this.removeFromSuperview();
|
|
150
|
+
unlockScroll();
|
|
133
151
|
}
|
|
134
152
|
this.isVisible = import_UIObject.NO;
|
|
135
153
|
}
|
|
@@ -140,31 +158,37 @@ class UIDialogView extends import_UIView.UIView {
|
|
|
140
158
|
}
|
|
141
159
|
}
|
|
142
160
|
layoutSubviews() {
|
|
143
|
-
var _a, _b;
|
|
161
|
+
var _a, _b, _c, _d;
|
|
144
162
|
if (!(0, import_UIObject.IS)(this.view)) {
|
|
145
163
|
return;
|
|
146
164
|
}
|
|
147
|
-
this.
|
|
148
|
-
|
|
149
|
-
0
|
|
150
|
-
0,
|
|
151
|
-
|
|
152
|
-
0,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
165
|
+
if (this._fillsViewport) {
|
|
166
|
+
const containerRect = (_b = (_a = this.superview) == null ? void 0 : _a.viewHTMLElement) == null ? void 0 : _b.getBoundingClientRect();
|
|
167
|
+
const topOffset = containerRect ? -containerRect.top / import_UIView.UIView.pageScale : 0;
|
|
168
|
+
this.setPosition(0, 0, 0, topOffset, window.innerHeight / import_UIView.UIView.pageScale, "100%");
|
|
169
|
+
} else {
|
|
170
|
+
this.setPosition(0, 0, 0, 0, 0, "100%");
|
|
171
|
+
this.setPosition(
|
|
172
|
+
0,
|
|
173
|
+
0,
|
|
174
|
+
0,
|
|
175
|
+
0,
|
|
176
|
+
(0, import_UIObject.FIRST)(
|
|
177
|
+
(0, import_UIObject.IF)((_c = this.superview) == null ? void 0 : _c.isKindOfClass(import_UINativeScrollView.UINativeScrollView))(() => {
|
|
178
|
+
var _a2, _b2;
|
|
179
|
+
return (_b2 = (_a2 = this.superview) == null ? void 0 : _a2.scrollSize.height) != null ? _b2 : 0;
|
|
180
|
+
}).ELSE_IF((_d = this.superview) == null ? void 0 : _d.isKindOfClass(import_UIScrollView.UIScrollView))(() => {
|
|
181
|
+
var _a2, _b2;
|
|
182
|
+
return (_b2 = (_a2 = this.superview) == null ? void 0 : _a2.scrollSize.height) != null ? _b2 : 0;
|
|
183
|
+
}).ELSE(() => {
|
|
184
|
+
var _a2, _b2;
|
|
185
|
+
return (_b2 = (_a2 = this.superview) == null ? void 0 : _a2.frame.height) != null ? _b2 : 0;
|
|
186
|
+
}),
|
|
187
|
+
import_UIView.UIView.pageHeight
|
|
188
|
+
) / import_UIView.UIView.pageScale,
|
|
189
|
+
"100%"
|
|
190
|
+
);
|
|
191
|
+
}
|
|
168
192
|
const bounds = this.bounds;
|
|
169
193
|
const margin = 20;
|
|
170
194
|
this.view.style.position = "relative";
|
|
@@ -172,7 +196,9 @@ class UIDialogView extends import_UIView.UIView {
|
|
|
172
196
|
this.view.setNeedsLayout();
|
|
173
197
|
super.layoutSubviews();
|
|
174
198
|
}
|
|
175
|
-
}
|
|
199
|
+
};
|
|
200
|
+
let UIDialogView = _UIDialogView;
|
|
201
|
+
UIDialogView._activeDialogCount = 0;
|
|
176
202
|
// Annotate the CommonJS export names for ESM import in node:
|
|
177
203
|
0 && (module.exports = {
|
|
178
204
|
UIDialogView
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/UIDialogView.ts"],
|
|
4
|
-
"sourcesContent": ["import { IS_FIREFOX } from \"./ClientCheckers\"\nimport { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { UINativeScrollView } from \"./UINativeScrollView\"\nimport { FIRST, IF, IS, nil, NO, YES } from \"./UIObject\"\nimport { UIScrollView } from \"./UIScrollView\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UIDialogView<ViewType extends UIView = UIView> extends UIView {\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA2B;AAC3B,qBAAwB;AACxB,oBAAuB;AACvB,gCAAmC;AACnC,sBAA4C;AAC5C,0BAA6B;AAC7B,oBAA6C;AAGtC,MAAM,
|
|
4
|
+
"sourcesContent": ["import { IS_FIREFOX } from \"./ClientCheckers\"\nimport { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { UINativeScrollView } from \"./UINativeScrollView\"\nimport { FIRST, IF, IS, nil, NO, YES } from \"./UIObject\"\nimport { UIScrollView } from \"./UIScrollView\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UIDialogView<ViewType extends UIView = UIView> extends UIView {\n\n _isAUIDialogView = YES\n _view: ViewType = new UIView() as any\n _appearedAnimated?: boolean\n animationDuration: number = 0.25\n _zIndex: number = 100\n isVisible: boolean = NO\n dismissesOnTapOutside = YES\n\n static _activeDialogCount = 0\n _fillsViewport = NO\n \n constructor(elementID?: string, viewHTMLElement?: HTMLElement) {\n \n \n super(elementID, viewHTMLElement)\n \n this.addTargetForControlEvent(\n UIView.controlEvent.PointerTap,\n function (this: UIDialogView, sender: UIView, event: Event) {\n \n this.didDetectTapOutside(sender, event)\n \n }.bind(this)\n )\n \n this.backgroundColor = UIColor.colorWithRGBA(0, 10, 25).colorWithAlpha(0.75) //CBColor.primaryContentColor.colorWithAlpha(0.75)\n \n this.zIndex = this._zIndex\n \n }\n \n \n didDetectTapOutside(sender: UIView, event: Event) {\n \n if (event.target == this.viewHTMLElement && this.dismissesOnTapOutside) {\n this.dismiss(this._appearedAnimated)\n }\n \n }\n \n \n set zIndex(zIndex: number) {\n \n this._zIndex = zIndex\n this.style.zIndex = \"\" + zIndex\n \n }\n \n get zIndex() {\n \n return this._zIndex\n \n }\n \n \n set view(view: ViewType) {\n \n this._view?.removeFromSuperview()\n \n this._view = view\n \n this.addSubview(view)\n \n }\n \n \n get view(): ViewType {\n \n return this._view\n \n }\n \n \n override willAppear(animated: boolean = NO) {\n \n if (animated) {\n \n this.style.opacity = \"0\"\n \n }\n \n this.style.height = \"\"\n \n this._frame = nil\n \n }\n \n \n animateAppearing() {\n \n this.style.opacity = \"1\"\n \n }\n \n animateDisappearing() {\n \n this.style.opacity = \"0\"\n \n }\n \n \n showInView(containerView: UIView, animated: boolean) {\n \n this._fillsViewport = containerView.rootView == containerView\n animated = (animated && !IS_FIREFOX)\n \n this._appearedAnimated = animated\n \n this.willAppear(animated)\n \n \n if (this._fillsViewport) {\n UIDialogView._activeDialogCount++\n if (UIDialogView._activeDialogCount >= 1) {\n document.body.style.overflow = \"hidden\"\n }\n }\n\n containerView.addSubview(this)\n this.view.setNeedsLayoutUpToRootView()\n \n if (animated) {\n \n UIView.layoutViewsIfNeeded()\n this.layoutSubviews()\n \n UIView.animateViewOrViewsWithDurationDelayAndFunction(\n this,\n this.animationDuration,\n 0,\n undefined,\n () => this.animateAppearing(),\n nil\n )\n \n \n }\n else {\n \n this.setNeedsLayout()\n \n }\n \n this.isVisible = YES\n \n }\n \n \n showInRootView(animated: boolean) {\n \n this.showInView(UICore.main.rootViewController.view, animated)\n\n }\n \n \n dismiss(animated?: boolean) {\n \n if (!this.isVisible) {\n return\n }\n \n animated = (animated && !IS_FIREFOX)\n \n if (animated == undefined) {\n \n animated = this._appearedAnimated\n \n }\n \n const unlockScroll = () => {\n if (this._fillsViewport) {\n UIDialogView._activeDialogCount = Math.max(0, UIDialogView._activeDialogCount - 1)\n if (UIDialogView._activeDialogCount === 0) {\n document.body.style.overflow = \"\"\n }\n }\n }\n\n if (animated) {\n\n UIView.animateViewOrViewsWithDurationDelayAndFunction(\n this,\n this.animationDuration,\n 0,\n undefined,\n (() => {\n\n this.animateDisappearing()\n\n }).bind(this),\n () => {\n\n if (this.isVisible == NO) {\n\n this.removeFromSuperview()\n unlockScroll()\n\n }\n\n }\n )\n\n }\n else {\n\n this.removeFromSuperview()\n unlockScroll()\n\n }\n \n this.isVisible = NO\n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n if (event.name == UICore.broadcastEventName.WindowDidResize) {\n \n this.setNeedsLayout()\n \n }\n \n }\n \n \n override layoutSubviews() {\n \n \n if (!IS(this.view)) {\n \n return\n \n }\n \n //this.frame = this.superview.bounds;\n \n if (this._fillsViewport) {\n const containerRect = this.superview?.viewHTMLElement?.getBoundingClientRect()\n const topOffset = containerRect ? -containerRect.top / UIView.pageScale : 0\n this.setPosition(0, 0, 0, topOffset, window.innerHeight / UIView.pageScale, \"100%\")\n }\n else {\n this.setPosition(0, 0, 0, 0, 0, \"100%\")\n this.setPosition(\n 0,\n 0,\n 0,\n 0,\n FIRST(\n IF(this.superview?.isKindOfClass(UINativeScrollView))(() => this.superview?.scrollSize.height ?? 0)\n .ELSE_IF(this.superview?.isKindOfClass(UIScrollView))(() => this.superview?.scrollSize.height ?? 0)\n .ELSE(() => this.superview?.frame.height ?? 0),\n UIView.pageHeight\n ) / UIView.pageScale,\n \"100%\"\n )\n }\n \n const bounds = this.bounds\n \n const margin = 20\n \n //this.view.centerInContainer();\n \n this.view.style.position = \"relative\"\n \n this.view.style.zIndex = \"\" + this.zIndex\n \n this.view.setNeedsLayout()\n \n // this.view.style.maxHeight = \"\" + (bounds.height - margin * 2).integerValue + \"px\";\n // this.view.style.maxWidth = \"\" + (bounds.width - margin * 2).integerValue + \"px\";\n \n \n // var viewIntrinsicRectangle = this.view.intrinsicContentSize();\n // this.view.frame = new UIRectangle((bounds.width - viewIntrinsicRectangle.width)*0.5, )\n \n super.layoutSubviews()\n \n }\n \n \n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["_a", "_b"]
|
|
7
7
|
}
|
|
@@ -5,6 +5,9 @@ export declare class UITextField extends UITextView {
|
|
|
5
5
|
_placeholderTextKey?: string;
|
|
6
6
|
_defaultPlaceholderText?: string;
|
|
7
7
|
_viewHTMLElement: HTMLInputElement;
|
|
8
|
+
private _datalistElement?;
|
|
9
|
+
private _nativeAutocompleteData;
|
|
10
|
+
minCharactersForAutocomplete: number;
|
|
8
11
|
constructor(elementID?: string, viewHTMLElement?: null, type?: string | ValueOf<typeof UITextView.type>);
|
|
9
12
|
static controlEvent: {
|
|
10
13
|
readonly PointerDown: "PointerDown";
|
|
@@ -43,4 +46,15 @@ export declare class UITextField extends UITextView {
|
|
|
43
46
|
_setPlaceholderFromKeyIfPossible(): void;
|
|
44
47
|
get isSecure(): boolean;
|
|
45
48
|
set isSecure(secure: boolean);
|
|
49
|
+
/**
|
|
50
|
+
* Sets the data for native browser autocomplete using HTML datalist.
|
|
51
|
+
* Setting an empty array will remove the autocomplete functionality.
|
|
52
|
+
*
|
|
53
|
+
* @param data Array of strings to show as autocomplete suggestions
|
|
54
|
+
*/
|
|
55
|
+
set nativeAutocompleteData(data: string[]);
|
|
56
|
+
get nativeAutocompleteData(): string[];
|
|
57
|
+
private updateDatalist;
|
|
58
|
+
private _updateDatalistVisibility;
|
|
59
|
+
wasRemovedFromViewTree(): void;
|
|
46
60
|
}
|
|
@@ -29,6 +29,8 @@ var import_UIView = require("./UIView");
|
|
|
29
29
|
const _UITextField = class extends import_UITextView.UITextView {
|
|
30
30
|
constructor(elementID, viewHTMLElement = null, type = import_UITextView.UITextView.type.textField) {
|
|
31
31
|
super(elementID, type, viewHTMLElement);
|
|
32
|
+
this._nativeAutocompleteData = [];
|
|
33
|
+
this.minCharactersForAutocomplete = 0;
|
|
32
34
|
this.textElementView.viewHTMLElement.setAttribute("type", "text");
|
|
33
35
|
this.backgroundColor = import_UIColor.UIColor.whiteColor;
|
|
34
36
|
this.addTargetForControlEvent(
|
|
@@ -37,6 +39,7 @@ const _UITextField = class extends import_UITextView.UITextView {
|
|
|
37
39
|
);
|
|
38
40
|
this.textElementView.viewHTMLElement.oninput = (event) => {
|
|
39
41
|
this.sendControlEventForKey(_UITextField.controlEvent.TextChange, event);
|
|
42
|
+
this._updateDatalistVisibility();
|
|
40
43
|
};
|
|
41
44
|
this.textElementView.style.webkitUserSelect = "text";
|
|
42
45
|
this.nativeSelectionEnabled = import_UIObject.YES;
|
|
@@ -93,6 +96,55 @@ const _UITextField = class extends import_UITextView.UITextView {
|
|
|
93
96
|
}
|
|
94
97
|
this.textElementView.viewHTMLElement.type = type;
|
|
95
98
|
}
|
|
99
|
+
set nativeAutocompleteData(data) {
|
|
100
|
+
this._nativeAutocompleteData = data;
|
|
101
|
+
this.updateDatalist();
|
|
102
|
+
this._updateDatalistVisibility();
|
|
103
|
+
}
|
|
104
|
+
get nativeAutocompleteData() {
|
|
105
|
+
return this._nativeAutocompleteData;
|
|
106
|
+
}
|
|
107
|
+
updateDatalist() {
|
|
108
|
+
if (this._nativeAutocompleteData.length === 0) {
|
|
109
|
+
if (this._datalistElement) {
|
|
110
|
+
this._datalistElement.remove();
|
|
111
|
+
this.textElementView.viewHTMLElement.removeAttribute("list");
|
|
112
|
+
this._datalistElement = void 0;
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (!this._datalistElement) {
|
|
117
|
+
const datalistId = this.elementID + "_datalist";
|
|
118
|
+
this._datalistElement = document.createElement("datalist");
|
|
119
|
+
this._datalistElement.id = datalistId;
|
|
120
|
+
this.viewHTMLElement.appendChild(this._datalistElement);
|
|
121
|
+
this.textElementView.viewHTMLElement.setAttribute("list", datalistId);
|
|
122
|
+
}
|
|
123
|
+
this._datalistElement.innerHTML = "";
|
|
124
|
+
this._nativeAutocompleteData.forEach((item) => {
|
|
125
|
+
const option = document.createElement("option");
|
|
126
|
+
option.value = item;
|
|
127
|
+
this._datalistElement.appendChild(option);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
_updateDatalistVisibility() {
|
|
131
|
+
if (!this._datalistElement || this.minCharactersForAutocomplete === 0) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const shouldShow = this.text.length >= this.minCharactersForAutocomplete;
|
|
135
|
+
if (shouldShow) {
|
|
136
|
+
this.textElementView.viewHTMLElement.setAttribute("list", this._datalistElement.id);
|
|
137
|
+
} else {
|
|
138
|
+
this.textElementView.viewHTMLElement.removeAttribute("list");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
wasRemovedFromViewTree() {
|
|
142
|
+
super.wasRemovedFromViewTree();
|
|
143
|
+
if (this._datalistElement) {
|
|
144
|
+
this._datalistElement.remove();
|
|
145
|
+
this._datalistElement = void 0;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
96
148
|
};
|
|
97
149
|
let UITextField = _UITextField;
|
|
98
150
|
UITextField.controlEvent = Object.assign({}, import_UITextView.UITextView.controlEvent, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/UITextField.ts"],
|
|
4
|
-
"sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { nil, NO, ValueOf, YES } from \"./UIObject\"\nimport { UITextView } from \"./UITextView\"\nimport { UIView, UIViewAddControlEventTargetObject, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UITextField extends UITextView {\n \n _placeholderTextKey?: string\n _defaultPlaceholderText?: string\n \n override _viewHTMLElement!: HTMLInputElement\n \n constructor(\n elementID?: string,\n viewHTMLElement = null,\n type: string | ValueOf<typeof UITextView.type> = UITextView.type.textField\n ) {\n \n super(elementID, type, viewHTMLElement)\n \n this.textElementView.viewHTMLElement.setAttribute(\"type\", \"text\")\n this.backgroundColor = UIColor.whiteColor\n this.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (sender, event) => sender.focus()\n )\n this.textElementView.viewHTMLElement.oninput = (event) => {\n this.sendControlEventForKey(UITextField.controlEvent.TextChange, event)\n }\n this.textElementView.style.webkitUserSelect = \"text\"\n this.nativeSelectionEnabled = YES\n this.pausesPointerEvents = NO\n this.changesOften = YES\n \n }\n \n \n static override controlEvent = Object.assign({}, UITextView.controlEvent, {\n \n \"TextChange\": \"TextChange\"\n \n })\n \n \n override get controlEventTargetAccumulator(): UIViewAddControlEventTargetObject<typeof UITextField> {\n return (super.controlEventTargetAccumulator as any)\n }\n \n public override get viewHTMLElement() {\n return this._viewHTMLElement\n }\n \n \n public override set text(text: string) {\n this.textElementView.viewHTMLElement.value = text\n }\n \n public override get text(): string {\n return this.textElementView.viewHTMLElement.value\n }\n \n \n public set placeholderText(text: string) {\n this.textElementView.viewHTMLElement.placeholder = text\n }\n \n public get placeholderText(): string {\n return this.textElementView.viewHTMLElement.placeholder\n }\n \n \n setPlaceholderText(key: string, defaultString: string) {\n \n this._placeholderTextKey = key\n this._defaultPlaceholderText = defaultString\n \n const languageName = UICore.languageService.currentLanguageKey\n this.placeholderText = UICore.languageService.stringForKey(key, languageName, defaultString, nil)\n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n if (event.name == UIView.broadcastEventName.LanguageChanged || event.name ==\n UIView.broadcastEventName.AddedToViewTree) {\n \n this._setPlaceholderFromKeyIfPossible()\n \n }\n \n }\n \n \n override willMoveToSuperview(superview: UIView) {\n \n super.willMoveToSuperview(superview)\n \n this._setPlaceholderFromKeyIfPossible()\n \n }\n \n _setPlaceholderFromKeyIfPossible() {\n \n if (this._placeholderTextKey && this._defaultPlaceholderText) {\n \n this.setPlaceholderText(this._placeholderTextKey, this._defaultPlaceholderText)\n \n }\n \n }\n \n \n public get isSecure(): boolean {\n const result = (this.textElementView.viewHTMLElement.type == \"password\")\n return result\n }\n \n public set isSecure(secure: boolean) {\n let type = \"text\"\n if (secure) {\n type = \"password\"\n }\n this.textElementView.viewHTMLElement.type = type\n }\n \n \n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAwB;AACxB,oBAAuB;AACvB,sBAAsC;AACtC,wBAA2B;AAC3B,oBAAgF;AAGzE,MAAM,eAAN,cAA0B,6BAAW;AAAA,
|
|
4
|
+
"sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { nil, NO, ValueOf, YES } from \"./UIObject\"\nimport { UITextView } from \"./UITextView\"\nimport { UIView, UIViewAddControlEventTargetObject, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UITextField extends UITextView {\n \n _placeholderTextKey?: string\n _defaultPlaceholderText?: string\n \n override _viewHTMLElement!: HTMLInputElement\n \n // --- Native Autocomplete (HTML datalist) ---\n \n private _datalistElement?: HTMLDataListElement\n private _nativeAutocompleteData: string[] = []\n public minCharactersForAutocomplete: number = 0\n \n constructor(\n elementID?: string,\n viewHTMLElement = null,\n type: string | ValueOf<typeof UITextView.type> = UITextView.type.textField\n ) {\n \n super(elementID, type, viewHTMLElement)\n \n this.textElementView.viewHTMLElement.setAttribute(\"type\", \"text\")\n this.backgroundColor = UIColor.whiteColor\n this.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (sender, event) => sender.focus()\n )\n this.textElementView.viewHTMLElement.oninput = (event) => {\n this.sendControlEventForKey(UITextField.controlEvent.TextChange, event)\n this._updateDatalistVisibility()\n }\n this.textElementView.style.webkitUserSelect = \"text\"\n this.nativeSelectionEnabled = YES\n this.pausesPointerEvents = NO\n this.changesOften = YES\n \n }\n \n \n static override controlEvent = Object.assign({}, UITextView.controlEvent, {\n \n \"TextChange\": \"TextChange\"\n \n })\n \n \n override get controlEventTargetAccumulator(): UIViewAddControlEventTargetObject<typeof UITextField> {\n return (super.controlEventTargetAccumulator as any)\n }\n \n public override get viewHTMLElement() {\n return this._viewHTMLElement\n }\n \n \n public override set text(text: string) {\n this.textElementView.viewHTMLElement.value = text\n }\n \n public override get text(): string {\n return this.textElementView.viewHTMLElement.value\n }\n \n \n public set placeholderText(text: string) {\n this.textElementView.viewHTMLElement.placeholder = text\n }\n \n public get placeholderText(): string {\n return this.textElementView.viewHTMLElement.placeholder\n }\n \n \n setPlaceholderText(key: string, defaultString: string) {\n \n this._placeholderTextKey = key\n this._defaultPlaceholderText = defaultString\n \n const languageName = UICore.languageService.currentLanguageKey\n this.placeholderText = UICore.languageService.stringForKey(key, languageName, defaultString, nil)\n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n if (event.name == UIView.broadcastEventName.LanguageChanged || event.name ==\n UIView.broadcastEventName.AddedToViewTree) {\n \n this._setPlaceholderFromKeyIfPossible()\n \n }\n \n }\n \n \n override willMoveToSuperview(superview: UIView) {\n \n super.willMoveToSuperview(superview)\n \n this._setPlaceholderFromKeyIfPossible()\n \n }\n \n _setPlaceholderFromKeyIfPossible() {\n \n if (this._placeholderTextKey && this._defaultPlaceholderText) {\n \n this.setPlaceholderText(this._placeholderTextKey, this._defaultPlaceholderText)\n \n }\n \n }\n \n \n public get isSecure(): boolean {\n const result = (this.textElementView.viewHTMLElement.type == \"password\")\n return result\n }\n \n public set isSecure(secure: boolean) {\n let type = \"text\"\n if (secure) {\n type = \"password\"\n }\n this.textElementView.viewHTMLElement.type = type\n }\n \n \n // --- Native Autocomplete Methods ---\n \n \n \n /**\n * Sets the data for native browser autocomplete using HTML datalist.\n * Setting an empty array will remove the autocomplete functionality.\n *\n * @param data Array of strings to show as autocomplete suggestions\n */\n public set nativeAutocompleteData(data: string[]) {\n this._nativeAutocompleteData = data\n this.updateDatalist()\n this._updateDatalistVisibility()\n }\n \n public get nativeAutocompleteData(): string[] {\n return this._nativeAutocompleteData\n }\n \n private updateDatalist() {\n // If no data, remove the datalist\n if (this._nativeAutocompleteData.length === 0) {\n if (this._datalistElement) {\n this._datalistElement.remove()\n this.textElementView.viewHTMLElement.removeAttribute(\"list\")\n this._datalistElement = undefined\n }\n return\n }\n \n // Create datalist if it doesn't exist\n if (!this._datalistElement) {\n const datalistId = this.elementID + \"_datalist\"\n this._datalistElement = document.createElement(\"datalist\")\n this._datalistElement.id = datalistId\n // Add datalist as a sibling to the text element within this view's container\n this.viewHTMLElement.appendChild(this._datalistElement)\n this.textElementView.viewHTMLElement.setAttribute(\"list\", datalistId)\n }\n \n // Update the options\n this._datalistElement.innerHTML = \"\"\n this._nativeAutocompleteData.forEach(item => {\n const option = document.createElement(\"option\")\n option.value = item\n this._datalistElement!.appendChild(option)\n })\n }\n \n private _updateDatalistVisibility() {\n if (!this._datalistElement || this.minCharactersForAutocomplete === 0) {\n return\n }\n \n const shouldShow = this.text.length >= this.minCharactersForAutocomplete\n \n if (shouldShow) {\n this.textElementView.viewHTMLElement.setAttribute(\"list\", this._datalistElement.id)\n } else {\n this.textElementView.viewHTMLElement.removeAttribute(\"list\")\n }\n }\n \n override wasRemovedFromViewTree() {\n \n super.wasRemovedFromViewTree()\n \n // Clean up datalist element when text field is removed\n if (this._datalistElement) {\n this._datalistElement.remove()\n this._datalistElement = undefined\n }\n \n }\n \n \n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uicore-ts",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.152",
|
|
4
4
|
"description": "UICore is a library to build native-like user interfaces using pure Typescript. No HTML is needed at all. Components are described as TS classes and all user interactions are handled explicitly. This library is strongly inspired by the UIKit framework that is used in IOS. In addition, UICore has tools to handle URL based routing, array sorting and filtering and adds a number of other utilities for convenience.",
|
|
5
5
|
"main": "compiledScripts/index.js",
|
|
6
6
|
"types": "compiledScripts/index.d.ts",
|
package/scripts/UIDialogView.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { UIView, UIViewBroadcastEvent } from "./UIView"
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
export class UIDialogView<ViewType extends UIView = UIView> extends UIView {
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
_isAUIDialogView = YES
|
|
13
13
|
_view: ViewType = new UIView() as any
|
|
14
14
|
_appearedAnimated?: boolean
|
|
@@ -16,6 +16,9 @@ export class UIDialogView<ViewType extends UIView = UIView> extends UIView {
|
|
|
16
16
|
_zIndex: number = 100
|
|
17
17
|
isVisible: boolean = NO
|
|
18
18
|
dismissesOnTapOutside = YES
|
|
19
|
+
|
|
20
|
+
static _activeDialogCount = 0
|
|
21
|
+
_fillsViewport = NO
|
|
19
22
|
|
|
20
23
|
constructor(elementID?: string, viewHTMLElement?: HTMLElement) {
|
|
21
24
|
|
|
@@ -109,7 +112,7 @@ export class UIDialogView<ViewType extends UIView = UIView> extends UIView {
|
|
|
109
112
|
|
|
110
113
|
showInView(containerView: UIView, animated: boolean) {
|
|
111
114
|
|
|
112
|
-
|
|
115
|
+
this._fillsViewport = containerView.rootView == containerView
|
|
113
116
|
animated = (animated && !IS_FIREFOX)
|
|
114
117
|
|
|
115
118
|
this._appearedAnimated = animated
|
|
@@ -117,6 +120,13 @@ export class UIDialogView<ViewType extends UIView = UIView> extends UIView {
|
|
|
117
120
|
this.willAppear(animated)
|
|
118
121
|
|
|
119
122
|
|
|
123
|
+
if (this._fillsViewport) {
|
|
124
|
+
UIDialogView._activeDialogCount++
|
|
125
|
+
if (UIDialogView._activeDialogCount >= 1) {
|
|
126
|
+
document.body.style.overflow = "hidden"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
120
130
|
containerView.addSubview(this)
|
|
121
131
|
this.view.setNeedsLayoutUpToRootView()
|
|
122
132
|
|
|
@@ -150,7 +160,7 @@ export class UIDialogView<ViewType extends UIView = UIView> extends UIView {
|
|
|
150
160
|
showInRootView(animated: boolean) {
|
|
151
161
|
|
|
152
162
|
this.showInView(UICore.main.rootViewController.view, animated)
|
|
153
|
-
|
|
163
|
+
|
|
154
164
|
}
|
|
155
165
|
|
|
156
166
|
|
|
@@ -168,34 +178,45 @@ export class UIDialogView<ViewType extends UIView = UIView> extends UIView {
|
|
|
168
178
|
|
|
169
179
|
}
|
|
170
180
|
|
|
181
|
+
const unlockScroll = () => {
|
|
182
|
+
if (this._fillsViewport) {
|
|
183
|
+
UIDialogView._activeDialogCount = Math.max(0, UIDialogView._activeDialogCount - 1)
|
|
184
|
+
if (UIDialogView._activeDialogCount === 0) {
|
|
185
|
+
document.body.style.overflow = ""
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
171
190
|
if (animated) {
|
|
172
|
-
|
|
191
|
+
|
|
173
192
|
UIView.animateViewOrViewsWithDurationDelayAndFunction(
|
|
174
193
|
this,
|
|
175
194
|
this.animationDuration,
|
|
176
195
|
0,
|
|
177
196
|
undefined,
|
|
178
197
|
(() => {
|
|
179
|
-
|
|
198
|
+
|
|
180
199
|
this.animateDisappearing()
|
|
181
|
-
|
|
200
|
+
|
|
182
201
|
}).bind(this),
|
|
183
202
|
() => {
|
|
184
|
-
|
|
203
|
+
|
|
185
204
|
if (this.isVisible == NO) {
|
|
186
|
-
|
|
205
|
+
|
|
187
206
|
this.removeFromSuperview()
|
|
188
|
-
|
|
207
|
+
unlockScroll()
|
|
208
|
+
|
|
189
209
|
}
|
|
190
|
-
|
|
210
|
+
|
|
191
211
|
}
|
|
192
212
|
)
|
|
193
|
-
|
|
213
|
+
|
|
194
214
|
}
|
|
195
215
|
else {
|
|
196
|
-
|
|
216
|
+
|
|
197
217
|
this.removeFromSuperview()
|
|
198
|
-
|
|
218
|
+
unlockScroll()
|
|
219
|
+
|
|
199
220
|
}
|
|
200
221
|
|
|
201
222
|
this.isVisible = NO
|
|
@@ -227,20 +248,27 @@ export class UIDialogView<ViewType extends UIView = UIView> extends UIView {
|
|
|
227
248
|
|
|
228
249
|
//this.frame = this.superview.bounds;
|
|
229
250
|
|
|
230
|
-
this.
|
|
231
|
-
|
|
232
|
-
0
|
|
233
|
-
0,
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
251
|
+
if (this._fillsViewport) {
|
|
252
|
+
const containerRect = this.superview?.viewHTMLElement?.getBoundingClientRect()
|
|
253
|
+
const topOffset = containerRect ? -containerRect.top / UIView.pageScale : 0
|
|
254
|
+
this.setPosition(0, 0, 0, topOffset, window.innerHeight / UIView.pageScale, "100%")
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
this.setPosition(0, 0, 0, 0, 0, "100%")
|
|
258
|
+
this.setPosition(
|
|
259
|
+
0,
|
|
260
|
+
0,
|
|
261
|
+
0,
|
|
262
|
+
0,
|
|
263
|
+
FIRST(
|
|
264
|
+
IF(this.superview?.isKindOfClass(UINativeScrollView))(() => this.superview?.scrollSize.height ?? 0)
|
|
265
|
+
.ELSE_IF(this.superview?.isKindOfClass(UIScrollView))(() => this.superview?.scrollSize.height ?? 0)
|
|
266
|
+
.ELSE(() => this.superview?.frame.height ?? 0),
|
|
267
|
+
UIView.pageHeight
|
|
268
|
+
) / UIView.pageScale,
|
|
269
|
+
"100%"
|
|
270
|
+
)
|
|
271
|
+
}
|
|
244
272
|
|
|
245
273
|
const bounds = this.bounds
|
|
246
274
|
|
package/scripts/UITextField.ts
CHANGED
|
@@ -12,6 +12,12 @@ export class UITextField extends UITextView {
|
|
|
12
12
|
|
|
13
13
|
override _viewHTMLElement!: HTMLInputElement
|
|
14
14
|
|
|
15
|
+
// --- Native Autocomplete (HTML datalist) ---
|
|
16
|
+
|
|
17
|
+
private _datalistElement?: HTMLDataListElement
|
|
18
|
+
private _nativeAutocompleteData: string[] = []
|
|
19
|
+
public minCharactersForAutocomplete: number = 0
|
|
20
|
+
|
|
15
21
|
constructor(
|
|
16
22
|
elementID?: string,
|
|
17
23
|
viewHTMLElement = null,
|
|
@@ -28,6 +34,7 @@ export class UITextField extends UITextView {
|
|
|
28
34
|
)
|
|
29
35
|
this.textElementView.viewHTMLElement.oninput = (event) => {
|
|
30
36
|
this.sendControlEventForKey(UITextField.controlEvent.TextChange, event)
|
|
37
|
+
this._updateDatalistVisibility()
|
|
31
38
|
}
|
|
32
39
|
this.textElementView.style.webkitUserSelect = "text"
|
|
33
40
|
this.nativeSelectionEnabled = YES
|
|
@@ -129,4 +136,81 @@ export class UITextField extends UITextView {
|
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
|
|
139
|
+
// --- Native Autocomplete Methods ---
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Sets the data for native browser autocomplete using HTML datalist.
|
|
145
|
+
* Setting an empty array will remove the autocomplete functionality.
|
|
146
|
+
*
|
|
147
|
+
* @param data Array of strings to show as autocomplete suggestions
|
|
148
|
+
*/
|
|
149
|
+
public set nativeAutocompleteData(data: string[]) {
|
|
150
|
+
this._nativeAutocompleteData = data
|
|
151
|
+
this.updateDatalist()
|
|
152
|
+
this._updateDatalistVisibility()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public get nativeAutocompleteData(): string[] {
|
|
156
|
+
return this._nativeAutocompleteData
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
private updateDatalist() {
|
|
160
|
+
// If no data, remove the datalist
|
|
161
|
+
if (this._nativeAutocompleteData.length === 0) {
|
|
162
|
+
if (this._datalistElement) {
|
|
163
|
+
this._datalistElement.remove()
|
|
164
|
+
this.textElementView.viewHTMLElement.removeAttribute("list")
|
|
165
|
+
this._datalistElement = undefined
|
|
166
|
+
}
|
|
167
|
+
return
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Create datalist if it doesn't exist
|
|
171
|
+
if (!this._datalistElement) {
|
|
172
|
+
const datalistId = this.elementID + "_datalist"
|
|
173
|
+
this._datalistElement = document.createElement("datalist")
|
|
174
|
+
this._datalistElement.id = datalistId
|
|
175
|
+
// Add datalist as a sibling to the text element within this view's container
|
|
176
|
+
this.viewHTMLElement.appendChild(this._datalistElement)
|
|
177
|
+
this.textElementView.viewHTMLElement.setAttribute("list", datalistId)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Update the options
|
|
181
|
+
this._datalistElement.innerHTML = ""
|
|
182
|
+
this._nativeAutocompleteData.forEach(item => {
|
|
183
|
+
const option = document.createElement("option")
|
|
184
|
+
option.value = item
|
|
185
|
+
this._datalistElement!.appendChild(option)
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private _updateDatalistVisibility() {
|
|
190
|
+
if (!this._datalistElement || this.minCharactersForAutocomplete === 0) {
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const shouldShow = this.text.length >= this.minCharactersForAutocomplete
|
|
195
|
+
|
|
196
|
+
if (shouldShow) {
|
|
197
|
+
this.textElementView.viewHTMLElement.setAttribute("list", this._datalistElement.id)
|
|
198
|
+
} else {
|
|
199
|
+
this.textElementView.viewHTMLElement.removeAttribute("list")
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
override wasRemovedFromViewTree() {
|
|
204
|
+
|
|
205
|
+
super.wasRemovedFromViewTree()
|
|
206
|
+
|
|
207
|
+
// Clean up datalist element when text field is removed
|
|
208
|
+
if (this._datalistElement) {
|
|
209
|
+
this._datalistElement.remove()
|
|
210
|
+
this._datalistElement = undefined
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
|
|
132
216
|
}
|