jsl-ui 9.28.7 → 10.0.0

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 (166) hide show
  1. package/docs/AutoSuggestComponent.md +17 -0
  2. package/docs/ButtonComponent.md +14 -0
  3. package/docs/CheckBoxComponent.md +12 -0
  4. package/docs/DateComponent.md +12 -0
  5. package/docs/DateRangeComponent.md +13 -0
  6. package/docs/DateTimeComponent.md +13 -0
  7. package/docs/DialogComponent.md +15 -0
  8. package/docs/ExpanderComponent.md +13 -0
  9. package/docs/FormComponent.md +15 -0
  10. package/docs/FormFieldComponent.md +15 -0
  11. package/docs/GridComponent.md +19 -0
  12. package/docs/InputComponent.md +15 -0
  13. package/docs/IntervalComponent.md +13 -0
  14. package/docs/LoadingComponent.md +12 -0
  15. package/docs/NavigationComponent.md +17 -0
  16. package/docs/Notification.md +14 -0
  17. package/docs/NotificationComponent.md +13 -0
  18. package/docs/NumberComponent.md +12 -0
  19. package/docs/OverlayComponent.md +12 -0
  20. package/docs/ProgressComponent.md +12 -0
  21. package/docs/README.md +24 -0
  22. package/docs/RibbonMenuComponent.md +14 -0
  23. package/docs/SelectComponent.md +15 -0
  24. package/docs/SplitterComponent.md +14 -0
  25. package/docs/StackPanelComponent.md +13 -0
  26. package/docs/TabsComponent.md +16 -0
  27. package/docs/TimeComponent.md +13 -0
  28. package/docs/TreeViewComponent.md +16 -0
  29. package/examples/showcase/checks-and-expanders.ts +163 -0
  30. package/examples/showcase/cultures.ts +39 -0
  31. package/examples/showcase/dates.ts +182 -0
  32. package/examples/showcase/dialogs.ts +184 -0
  33. package/examples/showcase/feedback-and-navigation.ts +174 -0
  34. package/examples/showcase/fields.ts +178 -0
  35. package/examples/showcase/fonts/Jost-Variable.ttf +0 -0
  36. package/examples/showcase/fonts/OFL-Jost.txt +93 -0
  37. package/examples/showcase/grids.ts +150 -0
  38. package/examples/showcase/index.html +60 -0
  39. package/examples/showcase/layout-and-navigation.ts +47 -0
  40. package/examples/showcase/nivona.css +98 -0
  41. package/examples/showcase/selects.ts +158 -0
  42. package/examples/showcase/showcase.css +231 -0
  43. package/examples/showcase/showcase.ts +214 -0
  44. package/examples/showcase/tabs.ts +161 -0
  45. package/examples/showcase/themes.css +83 -0
  46. package/examples/showcase/themes.ts +54 -0
  47. package/lib/components/IntervalComponent.d.ts +5 -0
  48. package/lib/components/IntervalComponent.js +29 -13
  49. package/lib/components/auto-suggest/AutoSuggestComponent.d.ts +11 -9
  50. package/lib/components/auto-suggest/AutoSuggestComponent.js +25 -38
  51. package/lib/components/button/ButtonComponent.d.ts +30 -1
  52. package/lib/components/button/ButtonComponent.js +85 -4
  53. package/lib/components/checkbox/CheckBoxComponent.d.ts +11 -1
  54. package/lib/components/checkbox/CheckBoxComponent.js +66 -56
  55. package/lib/components/checkbox/CheckBoxStyle.scss +72 -85
  56. package/lib/components/date/DateComponent.d.ts +10 -0
  57. package/lib/components/date/DateComponent.js +92 -44
  58. package/lib/components/date-range/DateRangeComponent.d.ts +14 -3
  59. package/lib/components/date-range/DateRangeComponent.js +96 -86
  60. package/lib/components/date-range/DateRangeStyle.scss +35 -11
  61. package/lib/components/date-time/DateTimeComponent.d.ts +8 -0
  62. package/lib/components/date-time/DateTimeComponent.js +64 -23
  63. package/lib/components/date-time/DateTimeStyle.scss +10 -7
  64. package/lib/components/dialog/DialogComponent.d.ts +21 -7
  65. package/lib/components/dialog/DialogComponent.js +179 -122
  66. package/lib/components/expander/ExpanderComponent.d.ts +15 -1
  67. package/lib/components/expander/ExpanderComponent.js +85 -64
  68. package/lib/components/expander/ExpanderStyle.scss +61 -47
  69. package/lib/components/form-field/FormFieldComponent.d.ts +45 -15
  70. package/lib/components/form-field/FormFieldComponent.js +249 -96
  71. package/lib/components/form-field/FormFieldStyle.scss +36 -87
  72. package/lib/components/form-field/create-control.d.ts +7 -0
  73. package/lib/components/form-field/create-control.js +48 -0
  74. package/lib/components/input/InputComponent.d.ts +18 -1
  75. package/lib/components/input/InputComponent.js +68 -93
  76. package/lib/components/loading/LoadingComponent.d.ts +9 -2
  77. package/lib/components/loading/LoadingComponent.js +13 -12
  78. package/lib/components/loading/LoadingStyle.css +19 -29
  79. package/lib/components/navigation/NavigationComponent.d.ts +34 -10
  80. package/lib/components/navigation/NavigationComponent.js +261 -33
  81. package/lib/components/navigation/NavigationStyle.scss +62 -226
  82. package/lib/components/notification/Notification.d.ts +37 -4
  83. package/lib/components/notification/Notification.js +160 -41
  84. package/lib/components/notification/Notification.scss +103 -19
  85. package/lib/components/number/NumberComponent.d.ts +16 -2
  86. package/lib/components/number/NumberComponent.js +54 -53
  87. package/lib/components/overlay/OverlayComponent.d.ts +13 -7
  88. package/lib/components/overlay/OverlayComponent.js +46 -114
  89. package/lib/components/overlay/overlay.css +18 -57
  90. package/lib/components/progress/ProgressComponent.d.ts +1 -0
  91. package/lib/components/progress/ProgressComponent.js +6 -6
  92. package/lib/components/progress/ProgressStyle.scss +5 -15
  93. package/lib/components/ribbon-menu/RibbonMenuComponent.js +2 -2
  94. package/lib/components/ribbon-menu/RibbonMenuStyle.scss +6 -76
  95. package/lib/components/select/SelectComponent.d.ts +33 -3
  96. package/lib/components/select/SelectComponent.js +312 -278
  97. package/lib/components/select/SelectDDAreaComponent.d.ts +13 -7
  98. package/lib/components/select/SelectDDAreaComponent.js +215 -256
  99. package/lib/components/select/SelectStyle.scss +204 -186
  100. package/lib/components/slider/nouislider.css +40 -54
  101. package/lib/components/stack-panel/SplitterComponent.d.ts +19 -3
  102. package/lib/components/stack-panel/SplitterComponent.js +94 -111
  103. package/lib/components/stack-panel/SplitterStyle.scss +9 -45
  104. package/lib/components/stack-panel/StackPanelComponent.js +3 -3
  105. package/lib/components/stack-panel/StackPanelStyle.scss +10 -52
  106. package/lib/components/tabs/TabsComponent.d.ts +17 -1
  107. package/lib/components/tabs/TabsComponent.js +247 -123
  108. package/lib/components/tabs/TabsStyle.scss +138 -75
  109. package/lib/components/time/TimeComponent.d.ts +5 -0
  110. package/lib/components/time/TimeComponent.js +61 -69
  111. package/lib/components/time/TimeComponent.scss +4 -4
  112. package/lib/components/tree-view/TreeViewComponent.d.ts +10 -4
  113. package/lib/components/tree-view/TreeViewComponent.js +65 -32
  114. package/lib/components/tree-view/TreeViewStyle.scss +12 -96
  115. package/lib/core/date.d.ts +2 -0
  116. package/lib/core/date.js +6 -0
  117. package/lib/core/jq.js +11 -8
  118. package/lib/grid/slick-default-theme.css +107 -31
  119. package/lib/grid/slick.creator.js +23 -5
  120. package/lib/grid/slick.formatters.js +4 -3
  121. package/lib/grid/slick.grid.css +38 -26
  122. package/lib/grid/slick.grid.d.ts +1 -0
  123. package/lib/grid/slick.grid.js +2 -3
  124. package/lib/grid.css +3413 -454
  125. package/lib/index.css +2500 -1031
  126. package/lib/index.css.map +1 -1
  127. package/lib/index.d.ts +1 -0
  128. package/lib/index.js +1 -1
  129. package/lib/index.js.map +1 -1
  130. package/lib/interaction/moveable.d.ts +1 -0
  131. package/lib/interaction/moveable.js +8 -0
  132. package/lib/interaction/resizable.d.ts +1 -0
  133. package/lib/interaction/resizable.js +9 -0
  134. package/lib/ui/auto.suggest.css +31 -14
  135. package/lib/ui/auto.suggest.d.ts +1 -0
  136. package/lib/ui/auto.suggest.js +88 -18
  137. package/lib/ui/base.css +2 -48
  138. package/lib/ui/button.css +134 -0
  139. package/lib/ui/date-input.css +11 -0
  140. package/lib/ui/date.picker/css/tiny-date-picker.css +124 -325
  141. package/lib/ui/date.picker/date-picker-options.js +4 -3
  142. package/lib/ui/date.picker/lib/date-manip.js +9 -0
  143. package/lib/ui/date.picker/mode/base-mode.d.ts +2 -1
  144. package/lib/ui/date.picker/mode/base-mode.js +112 -22
  145. package/lib/ui/date.picker/mode/dropdown-mode.d.ts +2 -4
  146. package/lib/ui/date.picker/mode/dropdown-mode.js +29 -42
  147. package/lib/ui/date.picker/mode/index.d.ts +2 -1
  148. package/lib/ui/date.picker/mode/modal-mode.d.ts +2 -1
  149. package/lib/ui/date.picker/mode/modal-mode.js +4 -2
  150. package/lib/ui/date.picker/mode/permanent-mode.d.ts +2 -1
  151. package/lib/ui/date.picker/views/day-picker.js +24 -15
  152. package/lib/ui/date.picker/views/month-picker.js +1 -1
  153. package/lib/ui/date.picker/views/year-picker.js +3 -2
  154. package/lib/ui/date.picker.d.ts +2 -1
  155. package/lib/ui/dialog.css +144 -108
  156. package/lib/ui/dialog.d.ts +19 -1
  157. package/lib/ui/dialog.js +178 -60
  158. package/lib/ui/input.css +35 -0
  159. package/lib/ui/number.input.js +50 -37
  160. package/lib/ui/theme.css +28 -0
  161. package/package.json +12 -8
  162. package/lib/components/drop-down/DropDownComponent.d.ts +0 -27
  163. package/lib/components/drop-down/DropDownComponent.js +0 -60
  164. package/lib/components/expander/OldExpanderStyle.scss +0 -37
  165. package/lib/ui/drop.down.d.ts +0 -52
  166. package/lib/ui/drop.down.js +0 -2112
@@ -1,4 +1,4 @@
1
- import { IJSLComponent, IJSLVNode } from "jsl-render";
1
+ import { IJSLComponent, IJSLVNode, JSLRender } from "jsl-render";
2
2
  import { ISelectComponentOptions, SelectComponent } from "./SelectComponent";
3
3
  import { EventHandler } from "../../interaction/eventhandler";
4
4
  interface IDDArguments {
@@ -9,24 +9,30 @@ export declare class SelectDDAreaComponent implements IJSLComponent {
9
9
  private options;
10
10
  private component;
11
11
  private args;
12
- private static ESCAPE_KEY;
13
- private static DOWN_KEY;
14
- private static UP_KEY;
15
- private static ENTER_KEY;
16
- private static TAB_KEY;
17
12
  onRender: EventHandler<any[], void>;
18
13
  private filteredData;
19
14
  private renderedData;
20
15
  private dom;
21
16
  private scrollContainer;
22
- private isScrolling;
17
+ private renderer;
18
+ private virtualList;
19
+ private searchText;
20
+ private optionPositions;
21
+ private optionCount;
23
22
  constructor(options: ISelectComponentOptions<any>, component: SelectComponent, args: IDDArguments);
23
+ onInit(renderer: JSLRender): void;
24
24
  onCreate(node: IJSLVNode): void;
25
25
  render(): IJSLVNode;
26
26
  navigateDown(): void;
27
27
  navigateUp(): void;
28
28
  search(term: string): void;
29
29
  clearSearch(): void;
30
+ private isGroup;
31
+ private renderRow;
30
32
  private focusFirst;
33
+ private navigate;
34
+ private scrollToFocus;
35
+ private selectFocused;
36
+ private keydown;
31
37
  }
32
38
  export {};
@@ -1,303 +1,262 @@
1
1
  import { VirtualRenderComponent } from "../virtual-render/VirtualRenderComponent";
2
2
  import { EventHandler } from "../../interaction/eventhandler";
3
- function isInternetExplorer() {
4
- return window.navigator.userAgent.indexOf("MSIE ") > 0 || !!window.navigator.userAgent.match(/Trident.*rv\:11\./);
5
- }
6
3
  export class SelectDDAreaComponent {
7
4
  constructor(options, component, args) {
5
+ var _a;
8
6
  this.options = options;
9
7
  this.component = component;
10
8
  this.args = args;
11
9
  this.onRender = new EventHandler();
12
- this.isScrolling = false;
13
- if (args.searchTxt) {
14
- this.search(args.searchTxt);
10
+ this.optionPositions = new Map();
11
+ this.optionCount = 0;
12
+ this.searchText = (_a = args.searchTxt) !== null && _a !== void 0 ? _a : "";
13
+ if (this.searchText) {
14
+ this.search(this.searchText);
15
15
  }
16
16
  this.focusFirst();
17
+ this.virtualList = new VirtualRenderComponent({
18
+ class: "sel-dd-items" + (options.multiple ? " multiple" : ""),
19
+ data: [], rowHeight: options.rowHeight,
20
+ style: "height:100%;", viewportSizeInPX: args.renderHeight,
21
+ bufferSizeInPx: options.rowHeight * 2,
22
+ renderRow: arg => this.renderRow(arg.rowData, arg.index)
23
+ });
17
24
  }
25
+ onInit(renderer) { this.renderer = renderer; }
18
26
  onCreate(node) {
19
- var _a, _b;
20
27
  this.dom = node.dom;
21
28
  this.scrollContainer = this.dom.querySelector(".sel-dd-items");
22
- let item = this.component.getSelected();
23
- if (item != null) {
24
- if (Array.isArray(item)) {
25
- item = item[0];
26
- }
27
- if (item != null) {
28
- const d = (_b = (_a = this.renderedData) !== null && _a !== void 0 ? _a : this.filteredData) !== null && _b !== void 0 ? _b : this.options.data;
29
- const idx = d.indexOf(item);
30
- this.scrollContainer.scrollTop = this.options.rowHeight * idx;
31
- }
32
- }
33
- //bugfix for IE -> blur event of search box is called when user clicks scroll bar
34
- if (isInternetExplorer()) {
35
- this.scrollContainer.addEventListener("scroll", (e) => {
36
- this.isScrolling = true;
37
- setTimeout(() => {
38
- this.isScrolling = false;
39
- this.dom.querySelector(".sel-search input").focus();
40
- }, 20);
41
- });
42
- this.scrollContainer.addEventListener("mousedown", (e) => {
43
- if (e.offsetX > this.scrollContainer.clientWidth || e.offsetY > this.scrollContainer.clientHeight) {
44
- this.isScrolling = true;
45
- setTimeout(() => {
46
- this.isScrolling = false;
47
- this.dom.querySelector(".sel-search input").focus();
48
- }, 20);
49
- }
50
- });
51
- }
29
+ this.scrollToFocus();
30
+ this.renderer.refresh();
52
31
  }
53
32
  render() {
54
- var _a;
33
+ var _a, _b, _c, _d;
55
34
  let data = (_a = this.filteredData) !== null && _a !== void 0 ? _a : this.options.data;
56
35
  if (this.options.groupProperty != null) {
57
- const sortedData = [...data];
58
- sortedData.sort((a, b) => {
59
- return a[this.options.groupProperty] < b[this.options.groupProperty] ? -1
60
- : a[this.options.groupProperty] > b[this.options.groupProperty] ? 1 : (data.indexOf(a) - data.indexOf(b) // preserve order if it is for same group
61
- );
62
- });
36
+ const property = this.options.groupProperty;
37
+ const sorted = [...data].sort((a, b) => a[property] < b[property] ? -1 : a[property] > b[property] ? 1 : 0);
63
38
  data = [];
64
- let prevGroupVal = NaN;
65
- for (const x of sortedData) {
66
- if (x[this.options.groupProperty] !== prevGroupVal) {
67
- // create group entry
68
- data.push({ __isGroup: true, __groupValue: x[this.options.groupProperty] });
69
- prevGroupVal = x[this.options.groupProperty];
39
+ let hasGroup = false;
40
+ let group;
41
+ for (const item of sorted) {
42
+ if (!hasGroup || item[property] !== group) {
43
+ group = item[property];
44
+ hasGroup = true;
45
+ data.push({ __isGroup: true, __groupValue: group });
70
46
  }
71
- data.push(x);
47
+ data.push(item);
72
48
  }
73
49
  }
74
- this.onRender.notify(data);
75
50
  this.renderedData = data;
76
- const ddNode = {
77
- tag: "div", animation: this.options.enableAnimation ? { attr: "opacity", from: "0", to: "1", duration: 400 } : undefined, children: [
51
+ this.optionPositions.clear();
52
+ this.optionCount = 0;
53
+ for (const item of data) {
54
+ if (!this.isGroup(item)) {
55
+ this.optionPositions.set(item, ++this.optionCount);
56
+ }
57
+ }
58
+ const focusedIndex = data.indexOf(this.component.getFocus());
59
+ const activeId = focusedIndex >= 0 ? this.component.getListId() + "-option-" + focusedIndex : undefined;
60
+ this.virtualList.setData(data);
61
+ this.onRender.notify(data);
62
+ const label = (_d = (_c = (_b = this.options.ariaLabel) !== null && _b !== void 0 ? _b : this.options.placeholder) !== null && _c !== void 0 ? _c : this.options.placehoder) !== null && _d !== void 0 ? _d : "Options";
63
+ return {
64
+ tag: "div", attr: {
65
+ class: "sel-dd-panel" + (this.options.enableAnimation ? " sel-dd-animate" : ""),
66
+ keydown: (event) => this.keydown(event)
67
+ }, children: [
78
68
  {
79
- tag: "div", attr: { class: "sel-search", style: this.options.enableSearch ? undefined : "height:0;padding:0;margin:0;border:none;" },
80
- children: [
81
- {
69
+ tag: "div", attr: { class: "sel-search", hidden: this.options.enableSearch ? undefined : "hidden" },
70
+ children: [{
82
71
  tag: "input", attr: {
83
- type: "text", value: this.args.searchTxt, placeholder: "Search", blur: (e) => {
84
- e.preventDefault();
85
- if (isInternetExplorer()) {
86
- requestAnimationFrame(() => {
87
- if (!this.isScrolling) {
88
- this.component.close();
89
- }
90
- });
91
- }
92
- else {
93
- this.component.close();
94
- }
95
- return false;
96
- }, input: (e, node) => {
97
- if (!this.options.enableSearch) {
98
- return false;
99
- }
100
- const term = node.dom.value;
101
- if (!term) {
102
- this.clearSearch();
103
- }
104
- else {
105
- this.search(term);
106
- }
107
- }, keydown: (e, node) => {
108
- var _a;
109
- if (!this.options.enableKeyboard) {
110
- return;
111
- }
112
- if (e.which === SelectDDAreaComponent.ESCAPE_KEY) {
113
- node.dom.blur();
114
- }
115
- else if (e.which === SelectDDAreaComponent.DOWN_KEY) {
116
- this.navigateDown();
117
- }
118
- else if (e.which === SelectDDAreaComponent.UP_KEY) {
119
- this.navigateUp();
120
- }
121
- else if (e.which === SelectDDAreaComponent.ENTER_KEY) { // TODO: multiselect
122
- // e.preventDefault();
123
- // e.stopPropagation();
124
- // e.stopImmediatePropagation();
125
- let focus = this.component.getFocus();
126
- if (focus == null) {
127
- // if only 1 result is left then auto select this entry
128
- const d = (_a = this.filteredData) !== null && _a !== void 0 ? _a : this.options.data;
129
- if (d.length === 1) {
130
- focus = d[0];
131
- }
132
- }
133
- if (this.options.multiple) {
134
- if (focus != null) {
135
- const currentSelection = this.component.getSelected();
136
- if (currentSelection.indexOf(focus) >= 0) {
137
- currentSelection.splice(currentSelection.indexOf(focus), 1);
138
- }
139
- else {
140
- currentSelection.push(focus);
141
- }
142
- this.component.setSelected(currentSelection);
143
- }
144
- }
145
- else {
146
- if (focus != null) {
147
- this.component.setSelected(focus);
148
- }
149
- node.dom.blur();
150
- }
151
- }
152
- else if (e.which === SelectDDAreaComponent.TAB_KEY) {
153
- e.preventDefault();
154
- node.dom.blur();
155
- }
156
- }
72
+ type: "text", autocomplete: "off", spellcheck: "false",
73
+ value: this.searchText, placeholder: this.options.searchPlaceholder,
74
+ role: "combobox", "aria-autocomplete": "list", "aria-expanded": "true",
75
+ "aria-controls": this.component.getListId(), "aria-activedescendant": activeId,
76
+ "aria-label": this.options.searchPlaceholder,
77
+ input: (event) => { this.search(event.target.value); }
157
78
  }
158
- }
159
- ]
79
+ }]
160
80
  },
161
- new VirtualRenderComponent({
162
- class: "sel-dd-items" + (this.options.multiple ? " multiple" : ""), data,
163
- style: this.options.enableSearch ? "height:calc(100% - 1.8rem)" : "height:100%",
164
- viewportSizeInPX: this.args.renderHeight + 20,
165
- bufferSizeInPx: 20,
166
- renderRow: (args) => {
167
- const result = { tag: "div", attr: { class: "sel-dd-item" } };
168
- if (this.options.groupProperty && args.rowData.__isGroup) {
169
- result.attr.class += " sel-dd-group";
170
- const groupValue = args.rowData.__groupValue;
171
- const groupArgs = {
172
- groupValue, node: result
173
- };
174
- const resGroup = this.options.onRenderGroup(groupArgs);
175
- if (resGroup != null) {
176
- result.children = [resGroup];
177
- }
178
- result.attr.mousedown = (evt) => {
179
- evt.preventDefault();
180
- evt.stopPropagation();
181
- evt.stopImmediatePropagation();
182
- };
183
- return result;
184
- }
185
- const renderArg = {
186
- data: args.rowData,
187
- node: result,
188
- isFocused: this.component.getFocus() === args.rowData,
189
- isSelected: this.options.multiple ?
190
- this.component.getSelected().indexOf(args.rowData) >= 0 :
191
- this.component.getSelected() === args.rowData,
192
- isCurrent: false
193
- };
194
- if (renderArg.isFocused) {
195
- result.attr.class += " focused";
196
- }
197
- if (renderArg.isSelected) {
198
- result.attr.class += " selected";
199
- }
200
- result.attr.mousedown = (evt) => {
201
- if (this.options.multiple) {
202
- evt.preventDefault();
203
- evt.stopPropagation();
204
- evt.stopImmediatePropagation();
205
- const currentSelection = this.component.getSelected();
206
- if (currentSelection.indexOf(args.rowData) >= 0) {
207
- currentSelection.splice(currentSelection.indexOf(args.rowData), 1);
208
- this.component.setSelected(currentSelection);
209
- }
210
- else {
211
- this.component.setSelected(args.rowData);
212
- }
213
- }
214
- else {
215
- this.component.setSelected(args.rowData);
216
- }
217
- };
218
- const res = this.options.onRender(renderArg);
219
- if (res != null) {
220
- result.children = [res];
221
- }
222
- return result;
223
- },
224
- rowHeight: this.options.rowHeight
225
- })
81
+ {
82
+ tag: "div", attr: {
83
+ id: this.component.getListId(), class: "sel-listbox", role: "listbox",
84
+ tabindex: this.options.enableSearch ? "-1" : "0",
85
+ "aria-label": label, "aria-multiselectable": this.options.multiple ? "true" : undefined,
86
+ "aria-activedescendant": this.options.enableSearch ? undefined : activeId
87
+ }, children: [
88
+ this.virtualList,
89
+ { tag: "div", attr: { class: "sel-empty", role: "status", hidden: data.length ? "hidden" : undefined }, content: this.options.emptyText }
90
+ ]
91
+ }
226
92
  ]
227
93
  };
228
- return ddNode;
229
94
  }
230
- navigateDown() {
231
- var _a, _b, _c;
232
- const d = (_b = (_a = this.renderedData) !== null && _a !== void 0 ? _a : this.filteredData) !== null && _b !== void 0 ? _b : this.options.data;
233
- let selItem = (_c = this.component.getFocus()) !== null && _c !== void 0 ? _c : this.component.getSelected();
234
- if (selItem == null) {
235
- this.component.setFocus(d.filter((x) => !x.__isGroup)[0]);
236
- return;
95
+ navigateDown() { this.navigate(1); }
96
+ navigateUp() { this.navigate(-1); }
97
+ search(term) {
98
+ var _a;
99
+ this.searchText = term;
100
+ this.filteredData = term ? this.options.data.filter(item => this.options.matchSearch(item, term)) : null;
101
+ if (this.scrollContainer) {
102
+ this.scrollContainer.scrollTop = 0;
237
103
  }
238
- if (Array.isArray(selItem)) {
239
- selItem = selItem[0];
104
+ if (this.virtualList) {
105
+ this.virtualList.State.scrollPos = 0;
240
106
  }
241
- let idx = d.indexOf(selItem);
242
- if (idx < 0) {
243
- this.component.setFocus(d.filter((x) => !x.__isGroup)[0]);
107
+ this.focusFirst();
108
+ (_a = this.renderer) === null || _a === void 0 ? void 0 : _a.refresh();
109
+ }
110
+ clearSearch() { this.search(""); }
111
+ isGroup(item) { return this.options.groupProperty != null && (item === null || item === void 0 ? void 0 : item.__isGroup) === true; }
112
+ renderRow(item, index) {
113
+ var _a, _b;
114
+ const result = { tag: "div", attr: { class: "sel-dd-item" } };
115
+ if (this.isGroup(item)) {
116
+ result.attr.class += " sel-dd-group";
117
+ result.attr.role = "presentation";
118
+ const args = { groupValue: item.__groupValue, node: result };
119
+ const rendered = this.options.onRenderGroup(args);
120
+ if (rendered != null) {
121
+ result.children = [rendered];
122
+ }
123
+ result.attr.mousedown = (event) => { event.preventDefault(); return false; };
124
+ return result;
244
125
  }
245
- else {
246
- while (idx < d.length - 1) {
247
- idx++;
248
- if (!d[idx].__isGroup) {
249
- this.component.setFocus(d[idx]);
250
- this.scrollContainer.scrollTop = this.options.rowHeight * idx;
251
- break;
252
- }
126
+ const selected = this.options.multiple ?
127
+ ((_a = this.component.getSelected()) !== null && _a !== void 0 ? _a : []).indexOf(item) >= 0 :
128
+ this.component.getSelected() === item;
129
+ const focused = this.component.getFocus() === item;
130
+ result.attr = {
131
+ ...result.attr, id: this.component.getListId() + "-option-" + index,
132
+ class: result.attr.class + (selected ? " selected" : "") + (focused ? " focused" : ""),
133
+ role: "option", "aria-selected": String(selected),
134
+ "aria-setsize": this.optionCount, "aria-posinset": this.optionPositions.get(item),
135
+ mousedown: (event) => { event.preventDefault(); return false; },
136
+ click: (event) => {
137
+ event.preventDefault();
138
+ event.stopPropagation();
139
+ this.component.setFocus(item);
140
+ this.selectFocused();
141
+ return false;
142
+ }
143
+ };
144
+ const renderArg = { data: item, node: result, isCurrent: false, isFocused: focused, isSelected: selected };
145
+ if (this.options.onRender) {
146
+ const rendered = this.options.onRender(renderArg);
147
+ if (rendered != null) {
148
+ result.children = [rendered];
253
149
  }
254
150
  }
151
+ else {
152
+ result.content = String((_b = item[this.options.textColumn]) !== null && _b !== void 0 ? _b : "");
153
+ }
154
+ return result;
255
155
  }
256
- navigateUp() {
156
+ focusFirst() {
157
+ var _a;
158
+ const data = (_a = this.filteredData) !== null && _a !== void 0 ? _a : this.options.data;
159
+ const selected = this.component.getSelected();
160
+ const item = Array.isArray(selected) ? selected[0] : selected;
161
+ this.component.setFocus(data.indexOf(item) >= 0 ? item : this.options.focusFirstItem ? data[0] : null);
162
+ }
163
+ navigate(direction) {
257
164
  var _a, _b, _c;
258
- const d = (_b = (_a = this.renderedData) !== null && _a !== void 0 ? _a : this.filteredData) !== null && _b !== void 0 ? _b : this.options.data;
259
- let selItem = (_c = this.component.getFocus()) !== null && _c !== void 0 ? _c : this.component.getSelected();
260
- if (selItem == null) {
261
- this.component.setFocus(d.filter((x) => !x.__isGroup)[0]);
165
+ const data = ((_b = (_a = this.renderedData) !== null && _a !== void 0 ? _a : this.filteredData) !== null && _b !== void 0 ? _b : this.options.data).filter(item => !this.isGroup(item));
166
+ if (!data.length) {
262
167
  return;
263
168
  }
264
- if (Array.isArray(selItem)) {
265
- selItem = selItem[0];
169
+ const index = data.indexOf(this.component.getFocus());
170
+ this.component.setFocus(data[index < 0 ? (direction < 0 ? data.length - 1 : 0) : Math.max(0, Math.min(data.length - 1, index + direction))]);
171
+ this.scrollToFocus();
172
+ (_c = this.renderer) === null || _c === void 0 ? void 0 : _c.refresh();
173
+ }
174
+ scrollToFocus() {
175
+ var _a, _b;
176
+ const index = (_b = (_a = this.renderedData) === null || _a === void 0 ? void 0 : _a.indexOf(this.component.getFocus())) !== null && _b !== void 0 ? _b : -1;
177
+ if (index < 0 || !this.scrollContainer) {
178
+ return;
266
179
  }
267
- let idx = d.indexOf(selItem);
268
- while (idx > 0) {
269
- idx--;
270
- if (!d[idx].__isGroup) {
271
- this.component.setFocus(d[idx]);
272
- this.scrollContainer.scrollTop = this.options.rowHeight * idx;
273
- return;
274
- }
180
+ const top = index * this.options.rowHeight;
181
+ const bottom = top + this.options.rowHeight;
182
+ const height = this.scrollContainer.clientHeight;
183
+ let scroll = this.scrollContainer.scrollTop;
184
+ if (top < scroll) {
185
+ scroll = top;
275
186
  }
276
- this.component.setFocus(d.filter((x) => !x.__isGroup)[0]);
277
- }
278
- search(term) {
279
- var _a, _b, _c, _d;
280
- const oldLen = (_b = (_a = this.filteredData) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
281
- this.filteredData = this.options.data.filter((d) => this.options.matchSearch(d, term));
282
- const newLen = (_d = (_c = this.filteredData) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0;
283
- if (oldLen !== newLen && this.scrollContainer != null) {
284
- this.scrollContainer.scrollTop = 0;
187
+ else if (bottom > scroll + height) {
188
+ scroll = Math.max(0, bottom - height);
285
189
  }
286
- this.focusFirst();
190
+ this.scrollContainer.scrollTop = scroll;
191
+ this.virtualList.State.scrollPos = scroll;
287
192
  }
288
- clearSearch() {
289
- this.filteredData = null;
290
- this.focusFirst();
193
+ selectFocused() {
194
+ var _a, _b;
195
+ let item = this.component.getFocus();
196
+ if (item == null) {
197
+ const data = (_a = this.filteredData) !== null && _a !== void 0 ? _a : this.options.data;
198
+ if (data.length === 1) {
199
+ item = data[0];
200
+ }
201
+ }
202
+ if (item == null) {
203
+ return;
204
+ }
205
+ if (this.options.multiple) {
206
+ const selected = [...(_b = this.component.getSelected()) !== null && _b !== void 0 ? _b : []];
207
+ const index = selected.indexOf(item);
208
+ if (index >= 0) {
209
+ if (!this.options.allowEmpty && selected.length === 1) {
210
+ return;
211
+ }
212
+ selected.splice(index, 1);
213
+ }
214
+ else {
215
+ selected.push(item);
216
+ }
217
+ this.component.setSelected(selected);
218
+ }
219
+ else {
220
+ this.component.setSelected(item);
221
+ this.component.close();
222
+ }
291
223
  }
292
- focusFirst() {
293
- var _a;
294
- if (this.options.focusFirstItem && (this.component.getSelected() == null || this.component.getSelected().length === 0)) /* TODO multiselect */ {
295
- this.component.setFocus(((_a = this.filteredData) !== null && _a !== void 0 ? _a : this.options.data)[0]);
224
+ keydown(event) {
225
+ var _a, _b;
226
+ if (event.isComposing || !this.options.enableKeyboard) {
227
+ return false;
228
+ }
229
+ const key = event.key;
230
+ if (key === "Escape") {
231
+ event.preventDefault();
232
+ event.stopPropagation();
233
+ this.component.close();
234
+ }
235
+ else if (key === "Tab") {
236
+ // Continue native tabbing from the field's position, including dialog traps.
237
+ this.component.close();
238
+ }
239
+ else if (key === "ArrowDown" || key === "ArrowUp") {
240
+ event.preventDefault();
241
+ event.stopPropagation();
242
+ this.navigate(key === "ArrowDown" ? 1 : -1);
243
+ }
244
+ else if (key === "Home" || key === "End") {
245
+ if (this.options.enableSearch && !event.ctrlKey) {
246
+ return false;
247
+ }
248
+ event.preventDefault();
249
+ event.stopPropagation();
250
+ const data = ((_a = this.renderedData) !== null && _a !== void 0 ? _a : []).filter(item => !this.isGroup(item));
251
+ this.component.setFocus(data[key === "Home" ? 0 : data.length - 1]);
252
+ this.scrollToFocus();
253
+ (_b = this.renderer) === null || _b === void 0 ? void 0 : _b.refresh();
254
+ }
255
+ else if (key === "Enter" || key === " " && !this.options.enableSearch) {
256
+ event.preventDefault();
257
+ event.stopPropagation();
258
+ this.selectFocused();
296
259
  }
260
+ return false;
297
261
  }
298
262
  }
299
- SelectDDAreaComponent.ESCAPE_KEY = 27;
300
- SelectDDAreaComponent.DOWN_KEY = 40;
301
- SelectDDAreaComponent.UP_KEY = 38;
302
- SelectDDAreaComponent.ENTER_KEY = 13;
303
- SelectDDAreaComponent.TAB_KEY = 9;