neo.mjs 4.4.17 → 4.4.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "4.4.17",
3
+ "version": "4.4.19",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -1,13 +1,15 @@
1
1
  .neo-pickerfield {
2
- .neo-picker-container {
3
- background-color: v(pickerfield-container-background-color);
4
- border : v(pickerfield-container-border);
5
- box-shadow : v(pickerfield-container-box-shadow);
6
- position : fixed;
7
- z-index : 20;
8
2
 
9
- &:focus {
10
- outline: none;
11
- }
3
+ }
4
+
5
+ .neo-picker-container {
6
+ background-color: v(pickerfield-container-background-color);
7
+ border : v(pickerfield-container-border);
8
+ box-shadow : v(pickerfield-container-box-shadow);
9
+ position : absolute;
10
+ z-index : 200;
11
+
12
+ &:focus {
13
+ outline: none;
12
14
  }
13
- }
15
+ }
@@ -89,8 +89,8 @@ class Picker extends Text {
89
89
  applyClientRects(silent) {
90
90
  let me = this,
91
91
  rects = me.clientRects,
92
- bodyRect = rects[2],
93
92
  inputRect = rects[1],
93
+ parentRect = rects[2],
94
94
  triggerRect = rects[0],
95
95
  vdom = me.picker.vdom,
96
96
  width = me.matchPickerWidth ? inputRect.width : me.pickerWidth;
@@ -100,6 +100,7 @@ class Picker extends Text {
100
100
  vdom.style = vdom.style || {};
101
101
 
102
102
  Object.assign(vdom.style, {
103
+ left : `${inputRect.left}px`,
103
104
  top : `${inputRect.bottom + 1}px`,
104
105
  width: `${width}px`
105
106
  });
@@ -123,7 +124,25 @@ class Picker extends Text {
123
124
  maxHeight: me.pickerMaxHeight,
124
125
  vdom : {cn: [], tabIndex: -1},
125
126
  width : me.pickerWidth,
126
- ...me.pickerConfig
127
+ ...me.pickerConfig,
128
+
129
+ // scoped to the field instance
130
+ onFocusLeave: data => {
131
+ let insideField = false,
132
+ item;
133
+
134
+ for (item of data.oldPath) {
135
+ if (item.id === me.id) {
136
+ insideField = true;
137
+ break;
138
+ }
139
+ }
140
+
141
+ if (!insideField) {
142
+ me.hidePicker();
143
+ super.onFocusLeave(data);
144
+ }
145
+ }
127
146
  });
128
147
  }
129
148
 
@@ -137,13 +156,13 @@ class Picker extends Text {
137
156
 
138
157
  /**
139
158
  * @param {Function} [callback]
140
- * @param {Function} [callbackScope]
159
+ * @param {Object} [callbackScope]
141
160
  */
142
161
  getClientRectsThenShow(callback, callbackScope) {
143
162
  let me = this,
144
163
  triggerId = me.getTriggerId('picker');
145
164
 
146
- me.getDomRect([triggerId, me.getInputWrapperId(), 'body']).then(data => {
165
+ me.getDomRect([triggerId, me.getInputWrapperId(), me.parentId]).then(data => {
147
166
  me.clientRects = data;
148
167
  me.showPicker(callback, callbackScope);
149
168
  });
@@ -171,24 +190,18 @@ class Picker extends Text {
171
190
  }
172
191
 
173
192
  /**
174
- * @param {Boolean} [silent=false]
193
+ *
175
194
  */
176
- hidePicker(silent=false) {
195
+ async hidePicker() {
177
196
  let me = this,
178
- picker = me.getPicker(),
179
- vdom = me.vdom;
197
+ picker = me.getPicker();
180
198
 
181
- me.pickerIsMounted && VDomUtil.removeVdomChild(vdom, me.getPickerId());
199
+ // avoid breaking selection model cls updates
200
+ await Neo.timeout(30);
182
201
 
183
- me.pickerIsMounted = false;
202
+ me.pickerIsMounted && picker.unmount();
184
203
 
185
- if (silent) {
186
- picker.mounted = false;
187
- } else {
188
- me.promiseVdomUpdate().then(data => {
189
- picker.mounted = me.pickerIsMounted;
190
- });
191
- }
204
+ me.pickerIsMounted = false;
192
205
  }
193
206
 
194
207
  /**
@@ -196,22 +209,27 @@ class Picker extends Text {
196
209
  * @protected
197
210
  */
198
211
  onFocusLeave(data) {
199
- let me = this;
212
+ let me = this,
213
+ insidePicker = false,
214
+ item;
215
+
216
+ for (item of data.oldPath) {
217
+ if (item.id === me.getPickerId()) {
218
+ insidePicker = true;
219
+ break;
220
+ }
221
+ }
200
222
 
201
- // inline will trigger an vdom update, so hide picker should be silent
202
- if (me.labelPosition === 'inline' && (me.value === '' || me.value === null)) {
203
- me.hidePicker(true);
204
- } else {
223
+ if (!insidePicker) {
205
224
  me.hidePicker();
225
+ super.onFocusLeave(data);
206
226
  }
207
-
208
- super.onFocusLeave(data);
209
227
  }
210
228
 
211
229
  /**
212
230
  * @param {Object} data
213
231
  * @param {Function} [callback]
214
- * @param {Function} [callbackScope]
232
+ * @param {Object} [callbackScope]
215
233
  * @protected
216
234
  */
217
235
  onKeyDownEnter(data, callback, callbackScope) {
@@ -242,23 +260,23 @@ class Picker extends Text {
242
260
 
243
261
  /**
244
262
  * @param {Function} [callback]
245
- * @param {Function} [callbackScope]
263
+ * @param {Object} [callbackScope]
246
264
  */
247
265
  showPicker(callback, callbackScope) {
248
266
  let me = this,
249
267
  picker = me.getPicker(),
250
- vdom = me.vdom;
268
+ listenerId;
251
269
 
252
270
  me.applyClientRects(true);
253
- vdom.cn.push(picker.vdom);
254
-
255
- me.promiseVdomUpdate().then(data => {
256
- me.pickerIsMounted = true;
257
271
 
258
- picker.mounted = me.pickerIsMounted;
272
+ listenerId = picker.on('mounted', () => {
273
+ picker.un('mounted', listenerId);
259
274
 
275
+ me.pickerIsMounted = true;
260
276
  callback?.apply(callbackScope || me);
261
277
  });
278
+
279
+ picker.render(true);
262
280
  }
263
281
  }
264
282
 
@@ -132,7 +132,6 @@ class Select extends Picker {
132
132
  displayField : me.displayField,
133
133
  parentId : me.id,
134
134
  selectionModel: {stayInList: false},
135
- silentSelect : true,
136
135
  store : me.store,
137
136
  ...me.listConfig
138
137
  });
@@ -227,6 +226,17 @@ class Select extends Picker {
227
226
  beforeSetStore(value, oldValue) {
228
227
  oldValue?.destroy();
229
228
 
229
+ // to reduce boilerplate code, a store config object without a defined model should default
230
+ // to displayField & valueField defaults
231
+ if (Neo.typeOf(value) === 'Object' && !value.model) {
232
+ value.model = {
233
+ fields: [
234
+ {name: 'id', type: 'String'},
235
+ {name: 'name', type: 'String'}
236
+ ]
237
+ }
238
+ }
239
+
230
240
  return ClassSystemUtil.beforeSetInstance(value, Store);
231
241
  }
232
242