swing-ui 0.1.25 → 1.0.1

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.
Files changed (116) hide show
  1. package/LICENSE +5 -4
  2. package/README.md +144 -7
  3. package/SwingUI.js +2611 -0
  4. package/classes/Arc.js +185 -0
  5. package/classes/Button.js +55 -0
  6. package/classes/CheckBox.js +33 -0
  7. package/classes/CheckBoxMenuItem.js +24 -0
  8. package/classes/ComboBox.js +329 -0
  9. package/classes/ComponentContainer.js +828 -0
  10. package/classes/ContextMenu.js +141 -0
  11. package/classes/DocumentEditor.js +168 -0
  12. package/classes/Ellipse.js +76 -0
  13. package/classes/InternalWindow.js +397 -0
  14. package/classes/InternalWindowContainer.js +93 -0
  15. package/classes/Label.js +52 -0
  16. package/classes/Line.js +105 -0
  17. package/classes/List.js +452 -0
  18. package/classes/MediaPlayer.js +504 -0
  19. package/classes/Menu.js +74 -0
  20. package/classes/MenuBar.js +56 -0
  21. package/classes/MenuItem.js +92 -0
  22. package/classes/Panel.js +50 -0
  23. package/classes/PasswordField.js +47 -0
  24. package/classes/Polygon.js +236 -0
  25. package/classes/Polyline.js +240 -0
  26. package/classes/ProgressBar.js +62 -0
  27. package/classes/RadioButton.js +110 -0
  28. package/classes/RadioButtonMenuItem.js +106 -0
  29. package/classes/Rectangle.js +199 -0
  30. package/classes/ScrollPane.js +53 -0
  31. package/classes/ScrollableComponent.js +141 -0
  32. package/classes/Separator.js +24 -0
  33. package/classes/Shape.js +584 -0
  34. package/classes/ShapeContainer.js +231 -0
  35. package/classes/Slider.js +172 -0
  36. package/classes/Spinner.js +172 -0
  37. package/classes/SplitView.js +82 -0
  38. package/classes/Stroke.js +115 -0
  39. package/classes/Table.js +982 -0
  40. package/classes/Tabs.js +228 -0
  41. package/classes/TextArea.js +125 -0
  42. package/classes/TextComponent.js +207 -0
  43. package/classes/TextField.js +128 -0
  44. package/classes/TextShape.js +123 -0
  45. package/classes/ToggleButton.js +147 -0
  46. package/classes/ToolBar.js +120 -0
  47. package/classes/TrayIcon.js +54 -0
  48. package/classes/Tree.js +569 -0
  49. package/classes/UIComponent.js +2113 -0
  50. package/classes/Window.js +609 -0
  51. package/enums.js +298 -0
  52. package/fonts.conf +32 -0
  53. package/functions.js +254 -0
  54. package/icon.png +0 -0
  55. package/index.js +109 -4
  56. package/jar/gui-11.jar +0 -0
  57. package/jar/lib/flatlaf.jar +0 -0
  58. package/jar/lib/jna.jar +0 -0
  59. package/package.json +58 -33
  60. package/typedefs.js +973 -0
  61. package/types/SwingUI.d.ts +727 -0
  62. package/types/classes/Arc.d.ts +111 -0
  63. package/types/classes/Button.d.ts +38 -0
  64. package/types/classes/CheckBox.d.ts +22 -0
  65. package/types/classes/CheckBoxMenuItem.d.ts +18 -0
  66. package/types/classes/ComboBox.d.ts +172 -0
  67. package/types/classes/ComponentContainer.d.ts +131 -0
  68. package/types/classes/ContextMenu.d.ts +74 -0
  69. package/types/classes/DocumentEditor.d.ts +95 -0
  70. package/types/classes/Ellipse.d.ts +34 -0
  71. package/types/classes/InternalWindow.d.ts +163 -0
  72. package/types/classes/InternalWindowContainer.d.ts +36 -0
  73. package/types/classes/Label.d.ts +33 -0
  74. package/types/classes/Line.d.ts +48 -0
  75. package/types/classes/List.d.ts +223 -0
  76. package/types/classes/MediaPlayer.d.ts +381 -0
  77. package/types/classes/Menu.d.ts +43 -0
  78. package/types/classes/MenuBar.d.ts +26 -0
  79. package/types/classes/MenuItem.d.ts +57 -0
  80. package/types/classes/Panel.d.ts +28 -0
  81. package/types/classes/PasswordField.d.ts +22 -0
  82. package/types/classes/Polygon.d.ts +93 -0
  83. package/types/classes/Polyline.d.ts +96 -0
  84. package/types/classes/ProgressBar.d.ts +36 -0
  85. package/types/classes/RadioButton.d.ts +70 -0
  86. package/types/classes/RadioButtonMenuItem.d.ts +71 -0
  87. package/types/classes/Rectangle.d.ts +82 -0
  88. package/types/classes/ScrollPane.d.ts +23 -0
  89. package/types/classes/ScrollableComponent.d.ts +81 -0
  90. package/types/classes/Separator.d.ts +14 -0
  91. package/types/classes/Shape.d.ts +223 -0
  92. package/types/classes/ShapeContainer.d.ts +92 -0
  93. package/types/classes/Slider.d.ts +107 -0
  94. package/types/classes/Spinner.d.ts +129 -0
  95. package/types/classes/SplitView.d.ts +47 -0
  96. package/types/classes/Stroke.d.ts +99 -0
  97. package/types/classes/Table.d.ts +652 -0
  98. package/types/classes/Tabs.d.ts +118 -0
  99. package/types/classes/TextArea.d.ts +45 -0
  100. package/types/classes/TextComponent.d.ts +136 -0
  101. package/types/classes/TextField.d.ts +94 -0
  102. package/types/classes/TextShape.d.ts +73 -0
  103. package/types/classes/ToggleButton.d.ts +84 -0
  104. package/types/classes/ToolBar.d.ts +82 -0
  105. package/types/classes/TrayIcon.d.ts +43 -0
  106. package/types/classes/Tree.d.ts +354 -0
  107. package/types/classes/UIComponent.d.ts +945 -0
  108. package/types/classes/Window.d.ts +334 -0
  109. package/types/enums.d.ts +437 -0
  110. package/types/functions.d.ts +109 -0
  111. package/types/index.d.ts +188 -0
  112. package/types/typedefs.d.ts +1626 -0
  113. package/ui-process-manager.js +317 -0
  114. package/video-devices-linux.sh +72 -0
  115. package/video-devices-mac.sh +33 -0
  116. package/CHANGES.md +0 -3
@@ -0,0 +1,228 @@
1
+
2
+ import {ComponentContainer} from "./ComponentContainer.js";
3
+ import {UIComponent} from "./UIComponent.js";
4
+
5
+ /**
6
+ * A Tabs UI component is a set of linked panels where only one panel is visible at a time, and users can switch between them by clicking tab headers. It’s commonly used to organize related content into separate views. This helps save space and makes navigation more intuitive.
7
+ * Extends ComponentContainer, which extends UIComponent.
8
+ * @class
9
+ * @global
10
+ * @see ComponentContainer
11
+ * @example
12
+ * // Usage example
13
+ *
14
+ * // create new Tabs component
15
+ * this.tabs = new Tabs().addTo(this).position(15, 15, 15, 15).anchor("top right bottom left");
16
+ *
17
+ * // One way to add a Panel to Tabs
18
+ * this.loginPanel = new Panel().background(null);
19
+ * this.tabs.add(this.loginPanel, {text: "Sign In", enabled: true, tooltip: "Log in to your account", icon: "images/user.png"});
20
+ *
21
+ * // second way to add same panel and options
22
+ * this.loginPanel = new Panel("Sign In").background(null).icon("images/user.png").addTo(this.tabs);
23
+ * this.tabs.tooltipAt(0, "Log in to your account");
24
+ *
25
+ * // third way to add same panel and options
26
+ * this.loginPanel = new Panel().background(null);
27
+ * this.tabs.add(this.loginPanel).textAt(0, "Sign In").iconAt(0, "images/user.png").tooltipAt(0, "Log in to your account").enabledAt(0, true);
28
+ */
29
+ export class Tabs extends ComponentContainer
30
+ {
31
+ /**
32
+ * Creates a new Tabs component.
33
+ */
34
+ constructor()
35
+ {
36
+ super("Tabs", (new.target === Tabs));
37
+
38
+ this.finalize(Tabs, ComponentContainer);
39
+ }
40
+
41
+ /**
42
+ * Adds a new tab with provided component as the main component of that tab. If options are passed, they will be used for tab text, icon, tooltip, etc.
43
+ *
44
+ * @param {object} component - A component that is allowed to be added to Tabs:
45
+ * @param {string|object|undefined} [options=undefined] - Text of the new tab or an object containing one or more options {text:string, icon: string, tooltip: string, enabled: boolean, index: number}.
46
+ * @param {number|undefined} [index=undefined] - Index at which to insert the new tab. Default is last tab.
47
+ * @returns {Tabs} Returns `this` Tabs component for method chaining.
48
+ * @example
49
+ * // Setting multiple tab options
50
+ * tabs.add(panel, {text:"Tab Name",icon:"icons/user.png",enabled:true,tooltip:"Create new user"});
51
+ *
52
+ * // Setting tab name only (as a string)
53
+ * tabs.add(panel, "Tab Name");
54
+ *
55
+ * // Setting insert index
56
+ * tabs.add(panel, "Tab Name", 2);
57
+ */
58
+ add(component, options = undefined, index = undefined)
59
+ {
60
+ if(!(component instanceof UIComponent)) throw new Error(`Invalid first argument "${typeof component === "object" ? component.constructor.name : typeof component}" provided to Tabs.add(component). Expected swing-ui component or its derivative.`);
61
+ component.verifyComponent();
62
+
63
+ let data = {};
64
+
65
+ if(index != null) data.index = index;
66
+
67
+ if(options != null)
68
+ {
69
+ if(typeof options === "object")
70
+ {
71
+ Object.assign(data, options);
72
+ }
73
+ else
74
+ {
75
+ data.text = String(options);
76
+ }
77
+ }
78
+
79
+ return this.addChild(component, data);
80
+ }
81
+
82
+ /**
83
+ * Sets or gets a selected tab index.
84
+ *
85
+ * @param {number} [index] - Index of the tab to select. Out of bounds integer will not select anything)
86
+ * @returns {number|Tabs} When setting an index, `this` Tabs component is returned; otherwise currently selected tab index is returned.
87
+ */
88
+ selected()
89
+ {
90
+ if(arguments.length > 1 && arguments[1] !== null) arguments[1] = parseInt(arguments[1]);
91
+ return this.property("selected", arguments);
92
+ }
93
+
94
+ /**
95
+ * Gets information about selected Tab.
96
+ * Returned object format is: {index:number, text:string, tooltip:string, enables:boolean, component: object}.
97
+ *
98
+ * @type {object|null}
99
+ * @readonly
100
+ */
101
+ get selectedItem()
102
+ {
103
+ let item = this.property("selectedItem", []);
104
+
105
+ if(item === undefined) return null;
106
+ item.component = UIComponent.get(item.component);
107
+ return item;
108
+ }
109
+
110
+ /**
111
+ * Gets an array of objects about each tab.
112
+ * Each object format is: {text:string, tooltip:string, enables:boolean, selected:boolean, component: object}.
113
+ *
114
+ * @type {object[]}
115
+ * @readonly
116
+ */
117
+ get items()
118
+ {
119
+ let _items = this.property("items", []);
120
+
121
+ let _c = this.children;
122
+ for(let i in _items) _items[i].component = _c[i];
123
+
124
+ return _items;
125
+ }
126
+
127
+ /**
128
+ * Sets or gets whether the tab at specified index is enabled. Setting it to `false` makes it disabled.
129
+ *
130
+ * @param {number} i - Index of the tab
131
+ * @param {boolean} [enabled] - Set to `true` to enabled the tab, `false` to disable.
132
+ * @return {boolean|Tabs} When setting `enabled` argument, `this` Tabs component object is returned; otherwise current `enabled` state is returned.
133
+ */
134
+ enabledAt(i)
135
+ {
136
+ if(arguments.length > 1)
137
+ {
138
+ ui.sendToGUI({control: this.id, set: "enabledAt", value: arguments[1], data: i});
139
+ return this;
140
+ }
141
+ else
142
+ {
143
+ return ui.sendToGUI({control: this.id, get: "enabledAt", data: i});
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Sets or gets the text of the tab at specified index.
149
+ *
150
+ * @param {number} i - Index of the tab
151
+ * @param {string} [text] - New text for the tab
152
+ * @return {string|Tabs} When setting `text` argument, `this` Tabs component object is returned; otherwise current text is returned.
153
+ */
154
+ textAt(i)
155
+ {
156
+ if(arguments.length > 1)
157
+ {
158
+ ui.sendToGUI({control: this.id, set: "textAt", value: arguments[1], data: i});
159
+ return this;
160
+ }
161
+ else
162
+ {
163
+ return ui.sendToGUI({control: this.id, get: "textAt", data: i});
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Sets or gets the tooltip text for the tab at specified index.
169
+ *
170
+ * @param {number} i - Index of the tab
171
+ * @param {string} [tooltip] - New tooltip text for the tab
172
+ * @return {string|Tabs} When setting `tooltip` argument, `this` Tabs component object is returned; otherwise current tooltip text is returned.
173
+ */
174
+ tooltipAt(i)
175
+ {
176
+ if(arguments.length > 1)
177
+ {
178
+ ui.sendToGUI({control: this.id, set: "tooltipAt", value: arguments[1], data: i});
179
+ return this;
180
+ }
181
+ else
182
+ {
183
+ return ui.sendToGUI({control: this.id, get: "tooltipAt", data: i});
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Sets or gets the icon for the tab at specified index.
189
+ *
190
+ * @param {number} i - Index of the tab
191
+ * @param {string|null} [icon] - Icon's path (URL, relative or absolute path) or base64 encoded image. Set `null` to remove current icon.
192
+ * @return {string|null|Tabs} When setting `icon` argument, `this` Tabs component object is returned; otherwise current icon is returned as base64 encoded string or `null` if the icon was not set.
193
+ */
194
+ iconAt(i)
195
+ {
196
+ if(arguments.length > 1)
197
+ {
198
+ ui.sendToGUI({control: this.id, set: "iconAt", value: arguments[1], data: i});
199
+ return this;
200
+ }
201
+ else
202
+ {
203
+ return ui.sendToGUI({control: this.id, get: "iconAt", data: i});
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Position of tabs: left, right, top, or bottom. Default is top.
209
+ *
210
+ * @param {string} [position] - "top", "bottom", "left", or "right.
211
+ * @return {string|Tabs} If setting value, `this` Tabs component object is returned; otherwise current value is returned.
212
+ */
213
+ tabPosition(...args)
214
+ {
215
+ return this.property("tabPosition", args);
216
+ }
217
+
218
+ /**
219
+ * Sets or gets whether tabs on left or right side should be displayed vertically to take less space. Has no affect when tabs are at the top or bottom. Default is false.
220
+ *
221
+ * @param {boolean} [vertical] - `true` for vertical, `false` for horizontal menu-like tab list (default).
222
+ * @return {boolean|Tabs} If setting value, `this` Tabs component object is returned; otherwise current value is returned.
223
+ */
224
+ sideTabsVertical(...args)
225
+ {
226
+ return this.property("sideTabsVertical", args);
227
+ }
228
+ }
@@ -0,0 +1,125 @@
1
+ import zlib from "zlib"; // https://nodejs.org/api/zlib.html#class-options
2
+ import {TextComponent} from "./TextComponent.js";
3
+ import {ScrollableComponent} from "./ScrollableComponent.js";
4
+
5
+ /**
6
+ * TextArea is a multi-line text field with multiple text-wrapping modes.
7
+ * TextArea extends TextComponent and ScrollableComponent classes, which extend UIComponent class.
8
+ * @class
9
+ * @global
10
+ * @see TextComponent
11
+ * @see ScrollableComponent
12
+ */
13
+ class TextArea extends TextComponent
14
+ {
15
+ /**
16
+ * Creates an instance of TextArea object.
17
+ *
18
+ * @param {string} [text] - Initial text value of the component.
19
+ */
20
+ constructor()
21
+ {
22
+ super("TextArea", (new.target === TextArea), ...arguments);
23
+
24
+ this.prop.rows = 1;
25
+ this.prop.columns = 1;
26
+
27
+ this.finalize(TextArea, TextComponent);
28
+ }
29
+
30
+ /**
31
+ * Sets or Gets the text value of the text area.
32
+ *
33
+ * @param {string} [text=undefined] - Text value to replace existing text.
34
+ * @param {TextAction} [action=TextAction.Set] - Specific action to perform with text. One of: TextAction.Set, TextAction.Prepend, TextAction.Append, TextAction.Insert, TextAction.ReplaceSelection.
35
+ * @param {number} [insert_position=undefined)] - Position where to insert text. Applies only if `action` argument is TextAction.Insert.
36
+ * @return {string|TextArea} When setting text, `this` TextArea component is returned; otherwise current text is returned.
37
+ * @example
38
+ * const txt = textarea.text(); // gets text value
39
+ * textarea.text("New Text"); // sets new text value
40
+ * textarea.text("Appended Text", TextAction.Append); // Appends new text to the end of current text
41
+ * textarea.text("Inserted Text", TextAction.Insert); // Inserts at current caret position
42
+ * textarea.text("Inserted Text", TextAction.Insert, textarea.caretPosition() - 50); // Inserts at specified position
43
+ * textarea.text("New Text", TextAction.ReplaceSelection); // Replaces selected text or inserts at current cursor position if no text is selected
44
+ */
45
+ text(text = undefined, action = TextAction.Set, i = undefined)
46
+ {
47
+ if(text !== undefined)
48
+ {
49
+ text = String(text ?? "");
50
+ const opt = {action: action, index: i};
51
+
52
+ // Gzip and Base64Encode long text
53
+ if(text.length > 200)
54
+ {
55
+ text = zlib.gzipSync(text, {
56
+ level: zlib.constants.Z_BEST_COMPRESSION,
57
+ strategy: zlib.constants.Z_DEFAULT_STRATEGY
58
+ }).toString("base64");
59
+ opt.zipped = true;
60
+ }
61
+
62
+ ui.sendToGUI({control: this.id, set: "text", value: text, data: opt});
63
+ return this;
64
+ }
65
+ else
66
+ {
67
+ let r = this.property("text", arguments);
68
+
69
+ // base64 decode and Gunzip value before returning
70
+ return zlib.gunzipSync(Buffer.from(r, "base64"), {}).toString();
71
+ }
72
+ }
73
+
74
+ /**
75
+ * @internal
76
+ * @ignore
77
+ */
78
+ rows()
79
+ {
80
+ if(arguments.length > 0)
81
+ {
82
+ this.prop.rows = arguments[0];
83
+ ui.sendToGUI({control: this.id, set: "rows", value: arguments[0]});
84
+ return this;
85
+ }
86
+ else
87
+ {
88
+ return this.prop.rows;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * @internal
94
+ * @ignore
95
+ */
96
+ columns()
97
+ {
98
+ if(arguments.length > 0)
99
+ {
100
+ this.prop.columns = arguments[0];
101
+ ui.sendToGUI({control: this.id, set: "columns", value: arguments[0]});
102
+ return this;
103
+ }
104
+ else
105
+ {
106
+ return this.prop.columns;
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Sets or gets line wrapping mode. Line wrapping helps to display long lines without having to scroll horizontally.
112
+ *
113
+ * @param {LineWrap} [value] - One of: LineWrap.Word, LineWrap.Character, LineWrap.None (default).
114
+ * @return {LineWrap|TextArea} When setting a value, `this` TextArea component is returned; otherwise a current line wrapping value is returned.
115
+ * @see LineWrap
116
+ */
117
+ lineWrap(...args)
118
+ {
119
+ return this.property("lineWrap", args);
120
+ }
121
+ }
122
+
123
+ TextComponent.implementClass(TextArea, ScrollableComponent);
124
+
125
+ export {TextArea};
@@ -0,0 +1,207 @@
1
+
2
+ import {UIComponent} from "./UIComponent.js";
3
+
4
+ /**
5
+ * TextComponent is not a standalone component. TextComponent extends {@link UIComponent} and serves a purpose to implement text editor related methods and properties.
6
+ *
7
+ * TextComponent is extended by {@link TextField}, {@link PasswordField}, {@link TextArea}, {@link DocumentEditor}, {@link Spinner} and {@link ComboBox}.
8
+ * @class
9
+ * @global
10
+ */
11
+ export class TextComponent extends UIComponent
12
+ {
13
+ /**
14
+ * TextComponent constructor.
15
+ * @internal
16
+ * @ignore
17
+ */
18
+ constructor(...args)
19
+ {
20
+ super(...args);
21
+ }
22
+
23
+ /**
24
+ * Sets or gets whether component's text can be edited by user typing. Applies to components such as TextField, TextArea, DocumentEditor, ComboBox, Password, Spinner, Tree (to edit list item).
25
+ *
26
+ * @param {boolean} [editable] - enables or disables editing
27
+ * @return {Object|boolean} If arguments is passed, returns `this` component instance, otherwise returns `boolean` value.
28
+ */
29
+ editable()
30
+ {
31
+ return this.property("editable", arguments);
32
+ }
33
+
34
+ /**
35
+ * Gets a boolean indicating if undo operation can be performed on the text. Only applies to components where text can be types (excluding Table cell editor).
36
+ * @readonly
37
+ * @type {boolean}
38
+ */
39
+ get canUndo()
40
+ {
41
+ return this.property("canUndo", []);
42
+ }
43
+
44
+ /**
45
+ * Gets a boolean indicating if redo operation can be performed on the text. Only applies to components where text can be types (excluding Table cell editor).
46
+ * @readonly
47
+ * @type boolean
48
+ */
49
+ get canRedo()
50
+ {
51
+ return this.property("canRedo", []);
52
+ }
53
+
54
+ /**
55
+ * Attempts to perform undo operation and returns boolean specifying if undo operations can be performed on the text again. Only applies to components where text can be types (excluding Table cell editor).
56
+ * @return boolean
57
+ */
58
+ undo()
59
+ {
60
+ return this.property("undo", []);
61
+ }
62
+
63
+ /**
64
+ * Attempts to perform redo operation and returns boolean specifying if redo operations can be performed on the text again. Only applies to components where text can be types (excluding Table cell editor).
65
+ * @return boolean
66
+ */
67
+ redo()
68
+ {
69
+ return this.property("redo", []);
70
+ }
71
+
72
+ /**
73
+ * Sets or gets the maximum amount of last edits that can be undone.
74
+ * @param {number} [limit] - Value 0 disabled undo/redo operation. Default is 100.
75
+ * @return {this|number} Returns `this` component if argument is provided, otherwise returns `number` value.
76
+ */
77
+ undoLimit(...args)
78
+ {
79
+ if(args.length > 0) args[0] = Math.max(0, parseInt(args[0]));
80
+ return this.property("undoLimit", args);
81
+ }
82
+
83
+ /**
84
+ * Sets or gets whether GUI should handle key combinations CTRL+Z and CTRL+Y to perform undo and redo actions for text editing components. If disabled, undo and redo can still be performed by calling undo() and redo() methods.
85
+ * @param {boolean} enable - Enables/disables undo/redo performed by keyboard keys. Default is `true`.
86
+ * @return {this|boolean} Returns `this` component if argument is provided, otherwise returns `boolean` value.
87
+ */
88
+ undoEnabled(...args)
89
+ {
90
+ return this.property("undoEnabled", args);
91
+ }
92
+
93
+ /**
94
+ * Copies selected text to clipboard and removes it from text. Applies only to some text editing components, such as TextArea.
95
+ *
96
+ * @return {this} Returns `this` component
97
+ */
98
+ cutSelection()
99
+ {
100
+ return this.property("cutSelection", [true]);
101
+ }
102
+
103
+ /**
104
+ * Copies selected text to clipboard. Applies only to some text editing components, such as TextArea.
105
+ *
106
+ * @return {this} Returns `this` component
107
+ */
108
+ copySelection()
109
+ {
110
+ return this.property("copySelection", [true]);
111
+ }
112
+
113
+ /**
114
+ * Inserts clipboard text into component's text as current caret position. Applies only to some text editing components, such as TextArea.
115
+ *
116
+ * @return {this} Returns `this` component
117
+ */
118
+ paste()
119
+ {
120
+ return this.property("paste", [true]);
121
+ }
122
+
123
+ /**
124
+ * Removes selected text. Applies only to some text editing components, such as TextArea, Password, DocumentEditor, etc.
125
+ *
126
+ * @return {this} Returns `this` component instance for method chaining.
127
+ */
128
+ deleteSelection()
129
+ {
130
+ return this.property("deleteSelection", [true]);
131
+ }
132
+
133
+ /**
134
+ * Selects/deselects all text of the component. Applies only to some text editing components, such as TextArea.
135
+ *
136
+ * @param {boolean} [selected=true] - `true` to select all, `false` to deselect all.
137
+ * @return {this} Returns `this` component
138
+ */
139
+ selectAll(selected = true)
140
+ {
141
+ return this.property("selectAll", [selected === true]);
142
+ }
143
+
144
+ /**
145
+ * Selects text at specified position and length or gets current selection as an object {start:number, length:number, text:string}.
146
+ *
147
+ * @param {number} [start] - Beginning position of text to be selected.
148
+ * @param {number} [end] - End position of text to be selected. If `start` argument is provided but `end` is omitted, `end` will be same as `start`, simply placing cursor at the `start` position.
149
+ * @return {{start:number, end:number, text:string}|this} If arguments are provided, `this` TextField component is returned; otherwise current selection is returned as object {start:number, end:number, text:string}.
150
+ * @example
151
+ * // Setting selection
152
+ * textfield.selection(10, 30);
153
+ * @example
154
+ * // getting selection
155
+ * let s = textfield.selection();
156
+ * console.log(`Selected from ${s.start} to ${s.end}: ${s.text}`);
157
+ */
158
+ selection(...args)
159
+ {
160
+ let _param = [];
161
+ if(args.length > 0)
162
+ {
163
+ _param = [{start: Math.max(0, parseInt(args[0]))}];
164
+ _param[0].end = (args.length > 1) ? Math.max(0, parseInt(args[1])) : _param[0].start;
165
+ }
166
+
167
+ return this.property("selection", _param);
168
+ }
169
+
170
+ /**
171
+ * Set or gets a position of caret in text editing components. Used in some text editing components only.
172
+ *
173
+ * @param {number} [position] - The zero-based caret position to set. If omitted, returns current caret position.
174
+ * @return {this|number} If argument is provided, returns an instance of `this` component, otherwise a current caret position.
175
+ */
176
+ caretPosition(...args)
177
+ {
178
+ return this.property("caretPosition", args);
179
+ }
180
+
181
+ /**
182
+ * Gets, registers or unregisters an event handler function for caret position changes and text selection changes in text editing components.
183
+ *
184
+ * @param {function(CaretEvent): any} [callback=undefined] - The event handler function that receives a {@link CaretEvent} object. Pass `null` to unregister all handler functions.
185
+ * @param {boolean} [remove=false] - Set to `true` to unregister the event handler.
186
+ * @returns {this|function[]} An array of handler functions if no arguments are passed, otherwise `this` component for method chaining.
187
+ * @see CaretEvent
188
+ * @example
189
+ * // Example event object:
190
+ * const e = {
191
+ * target: object, // The component that triggered the event.
192
+ * type: string, // `change`.
193
+ * position: number, // New caret position
194
+ * selectionStart: number, // Start position of selected text
195
+ * selectionEnd: number, // End position of selected text
196
+ * line: number, // Line of text where caret is now. Present only in some components, such as DocumentEditor.
197
+ * column: number, // Position of caret from the beginning of the line where caret is now. Present only in multi-line text editing components, such as DocumentEditor.
198
+ * styles: object // Text formatting information of the text segment where caret is now. Present only for DocumentEditor component when HTML is enabled.
199
+ * path: string[], // HTML tag hierarchy. Present only for DocumentEditor component when HTML is enabled.
200
+ * };
201
+ */
202
+ onCaretEvents(...args)
203
+ {
204
+ if(args.length === 0) return this.event("onCaretEvents");
205
+ return this.event("onCaretEvents", args[0], args[1] ?? false);
206
+ }
207
+ }
@@ -0,0 +1,128 @@
1
+
2
+ import {TextComponent} from "./TextComponent.js";
3
+
4
+ /**
5
+ * TextField component is the most popular text input component used for name, address, email, and many other data types. It can be formatted to define a specific input format. It can also use a regular expression to only accept specified characters or predefined input text format.
6
+ *
7
+ * @class
8
+ * @global
9
+ * @see TextComponent
10
+ */
11
+ export class TextField extends TextComponent
12
+ {
13
+ /**
14
+ * Creates an instance of TextField component object.
15
+ */
16
+ constructor()
17
+ {
18
+ if(arguments.length > 0)
19
+ {
20
+ super("FormattedTextField", (new.target === TextField), arguments[0]);
21
+ }
22
+ else
23
+ {
24
+ super("FormattedTextField", (new.target === TextField));
25
+ }
26
+
27
+ this.finalize(TextField, TextComponent);
28
+ }
29
+
30
+ /**
31
+ * Sets or gets a text mask formatter with a specified mask string and a placeholder character.
32
+ *
33
+ * A mask string defines the allowed characters at each position.
34
+ * Each special character in the mask has a meaning:
35
+ *
36
+ * - `#` — A digit (0–9).
37
+ * - `U` — An uppercase letter (A–Z).
38
+ * - `L` — A lowercase letter (a–z).
39
+ * - `A` — Any letter (A–Z or a–z).
40
+ * - `?` — Any letter (case-insensitive).
41
+ * - `*` — Any character (letter or digit).
42
+ * - `H` — A hexadecimal character (0–9, A–F, a–f).
43
+ * - `.` , `,` , `:` , `-` , `/` — These are treated as **literal** characters and appear in the formatted text.
44
+ * - `'` (single quote) — Escape character. Place before a literal mask character if you don’t want it treated specially.
45
+ * Example: `"'#'###"` means literal `#` followed by three digits.
46
+ *
47
+ * Example masks:
48
+ * - `"###-##-####"` → U.S. Social Security number (digits with dashes).
49
+ * - `"(###) ###-####"` → U.S. phone number.
50
+ * - `"UUU-####"` → Three uppercase letters, dash, and four digits.
51
+ *
52
+ * @param {string} [mask] - Text mask string. Set to empty string or `null` to clear the mask.
53
+ * @param {string} [placeholder="_"] - A character to use for empty characters in the mask. Default is "_" character.
54
+ * @return {{mask:string, placeholder:string}|TextField} When setting a mask, returns `this` TextField component for chaining. When called without arguments, returns the current mask information object.
55
+ * @example
56
+ * // U.S. Phone number mask
57
+ * textfield.mask("(###) ###-####", "_");
58
+ *
59
+ * @example
60
+ * // Date input (MM/DD/YYYY)
61
+ * textfield.mask("##/##/####", "_");
62
+ *
63
+ * @example
64
+ * // Time input (HH:MM)
65
+ * textfield.mask("##:##", "_");
66
+ *
67
+ * @example
68
+ * // Product code input
69
+ * textfield.mask("AAAA-####", "_");
70
+ *
71
+ * @example
72
+ * // Get current mask settings
73
+ * const info = textfield.mask();
74
+ * console.log(info.mask, info.placeholder);
75
+ */
76
+ mask(...args)
77
+ {
78
+ if(args.length > 0)
79
+ {
80
+ const msg = {mask: args[0]};
81
+ if(args.length > 1) msg.placeholder = args[1];
82
+ return this.property("mask", [msg]);
83
+ }
84
+ else
85
+ {
86
+ return this.property("mask", []);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Sets or gets a text input filter regular expression that filters the input of text to allow only text that matches filter.
92
+ *
93
+ * The filter must match the **entire text** of the field, not just a single character.
94
+ *
95
+ * NOTE: When setting text to TextField that doesn't match this filter, the text will not be set and previous text will remain in the text field.
96
+ *
97
+ * @param {string} [regex_filter] - Regular expression filter string. Set to empty string to remove existing filter.
98
+ * @return {string|TextField} When setting a filter, `this` TextField component is returned. When called without arguments, returns the current filter string.
99
+ * @example
100
+ * // Allow only digits
101
+ * textfield.filter("^\\d*$");
102
+ *
103
+ * @example
104
+ * // Allow U.S. phone numbers in format 123-456-7890
105
+ * textfield.filter("^\\d{3}-\\d{3}-\\d{4}$");
106
+ *
107
+ * // Allow only characters valid for email address
108
+ * textfield.filter([A-Za-z0-9\.\_\%\+\-\@]);
109
+ *
110
+ * @example
111
+ * // Allow basic email addresses (accepts partial email)
112
+ * textfield.filter("^[a-zA-Z0-9.\\_\\%\\+\\-]+(@([a-zA-Z0-9-]*(\\.[a-zA-Z0-9-]*)*(\\.[a-zA-Z]*)?))?$");
113
+ *
114
+ * @example
115
+ * // Allow basic email addresses (email cannot be typed one character at at time, only pasted in full)
116
+ * textfield.filter("^[A-Za-z0-9\\.\\_\\%\\+\\-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
117
+ *
118
+ * @example
119
+ * // Remove filter
120
+ * textfield.filter("");
121
+ *
122
+ */
123
+ filter(...args)
124
+ {
125
+ if(args.length > 0 && args[0] != null) args[0] = String(args[0]);
126
+ return this.property("filter", args);
127
+ }
128
+ }