uicore-ts 1.1.148 → 1.1.151
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.
|
@@ -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.151",
|
|
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/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
|
}
|