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.
@@ -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 UIDialogView extends import_UIView.UIView {
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.setPosition(0, 0, 0, 0, 0, "100%");
148
- this.setPosition(
149
- 0,
150
- 0,
151
- 0,
152
- 0,
153
- (0, import_UIObject.FIRST)(
154
- (0, import_UIObject.IF)((_a = this.superview) == null ? void 0 : _a.isKindOfClass(import_UINativeScrollView.UINativeScrollView))(() => {
155
- var _a2, _b2;
156
- return (_b2 = (_a2 = this.superview) == null ? void 0 : _a2.scrollSize.height) != null ? _b2 : 0;
157
- }).ELSE_IF((_b = this.superview) == null ? void 0 : _b.isKindOfClass(import_UIScrollView.UIScrollView))(() => {
158
- var _a2, _b2;
159
- return (_b2 = (_a2 = this.superview) == null ? void 0 : _a2.scrollSize.height) != null ? _b2 : 0;
160
- }).ELSE(() => {
161
- var _a2, _b2;
162
- return (_b2 = (_a2 = this.superview) == null ? void 0 : _a2.frame.height) != null ? _b2 : 0;
163
- }),
164
- import_UIView.UIView.pageHeight
165
- ) / import_UIView.UIView.pageScale,
166
- "100%"
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 \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 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 \n animated = (animated && !IS_FIREFOX)\n \n this._appearedAnimated = animated\n \n this.willAppear(animated)\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 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 \n }\n \n }\n )\n \n }\n else {\n \n this.removeFromSuperview()\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 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 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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",
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,EAOxC,YACI,WACA,kBAAkB,MAClB,OAAiD,6BAAW,KAAK,WACnE;AAEE,UAAM,WAAW,MAAM,eAAe;AAEtC,SAAK,gBAAgB,gBAAgB,aAAa,QAAQ,MAAM;AAChE,SAAK,kBAAkB,uBAAQ;AAC/B,SAAK;AAAA,MACD,qBAAO,aAAa;AAAA,MACpB,CAAC,QAAQ,UAAU,OAAO,MAAM;AAAA,IACpC;AACA,SAAK,gBAAgB,gBAAgB,UAAU,CAAC,UAAU;AACtD,WAAK,uBAAuB,aAAY,aAAa,YAAY,KAAK;AAAA,IAC1E;AACA,SAAK,gBAAgB,MAAM,mBAAmB;AAC9C,SAAK,yBAAyB;AAC9B,SAAK,sBAAsB;AAC3B,SAAK,eAAe;AAAA,EAExB;AAAA,EAUA,IAAa,gCAAuF;AAChG,WAAQ,MAAM;AAAA,EAClB;AAAA,EAEA,IAAoB,kBAAkB;AAClC,WAAO,KAAK;AAAA,EAChB;AAAA,EAGA,IAAoB,KAAK,MAAc;AACnC,SAAK,gBAAgB,gBAAgB,QAAQ;AAAA,EACjD;AAAA,EAEA,IAAoB,OAAe;AAC/B,WAAO,KAAK,gBAAgB,gBAAgB;AAAA,EAChD;AAAA,EAGA,IAAW,gBAAgB,MAAc;AACrC,SAAK,gBAAgB,gBAAgB,cAAc;AAAA,EACvD;AAAA,EAEA,IAAW,kBAA0B;AACjC,WAAO,KAAK,gBAAgB,gBAAgB;AAAA,EAChD;AAAA,EAGA,mBAAmB,KAAa,eAAuB;AAEnD,SAAK,sBAAsB;AAC3B,SAAK,0BAA0B;AAE/B,UAAM,eAAe,qBAAO,gBAAgB;AAC5C,SAAK,kBAAkB,qBAAO,gBAAgB,aAAa,KAAK,cAAc,eAAe,mBAAG;AAAA,EAEpG;AAAA,EAGS,yBAAyB,OAA6B;AAE3D,UAAM,yBAAyB,KAAK;AAEpC,QAAI,MAAM,QAAQ,qBAAO,mBAAmB,mBAAmB,MAAM,QACjE,qBAAO,mBAAmB,iBAAiB;AAE3C,WAAK,iCAAiC;AAAA,IAE1C;AAAA,EAEJ;AAAA,EAGS,oBAAoB,WAAmB;AAE5C,UAAM,oBAAoB,SAAS;AAEnC,SAAK,iCAAiC;AAAA,EAE1C;AAAA,EAEA,mCAAmC;AAE/B,QAAI,KAAK,uBAAuB,KAAK,yBAAyB;AAE1D,WAAK,mBAAmB,KAAK,qBAAqB,KAAK,uBAAuB;AAAA,IAElF;AAAA,EAEJ;AAAA,EAGA,IAAW,WAAoB;AAC3B,UAAM,SAAU,KAAK,gBAAgB,gBAAgB,QAAQ;AAC7D,WAAO;AAAA,EACX;AAAA,EAEA,IAAW,SAAS,QAAiB;AACjC,QAAI,OAAO;AACX,QAAI,QAAQ;AACR,aAAO;AAAA,IACX;AACA,SAAK,gBAAgB,gBAAgB,OAAO;AAAA,EAChD;AAGJ;AA5HO,IAAM,cAAN;AAAM,YAgCO,eAAe,OAAO,OAAO,CAAC,GAAG,6BAAW,cAAc;AAAA,EAEtE,cAAc;AAElB,CAAC;",
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.148",
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",
@@ -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.setPosition(0, 0, 0, 0, 0, "100%")
231
- this.setPosition(
232
- 0,
233
- 0,
234
- 0,
235
- 0,
236
- FIRST(
237
- IF(this.superview?.isKindOfClass(UINativeScrollView))(() => this.superview?.scrollSize.height ?? 0)
238
- .ELSE_IF(this.superview?.isKindOfClass(UIScrollView))(() => this.superview?.scrollSize.height ?? 0)
239
- .ELSE(() => this.superview?.frame.height ?? 0),
240
- UIView.pageHeight
241
- ) / UIView.pageScale,
242
- "100%"
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
 
@@ -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
  }