@danielgindi/selectbox 2.0.26 → 2.0.28

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/dist/lib.es6.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @danielgindi/selectbox 2.0.26
2
+ * @danielgindi/selectbox 2.0.28
3
3
  * git://github.com/danielgindi/selectbox.git
4
4
  */
5
5
  import { createElement, closestUntil, setElementAttrs, next, prev } from '@danielgindi/dom-utils/lib/Dom';
@@ -142,7 +142,7 @@ const hasOwnProperty = Object.prototype.hasOwnProperty;
142
142
  /** */
143
143
 
144
144
  /** @type {DropList.Options} */
145
- let defaultOptions$1 = {
145
+ const DefaultOptions$1 = {
146
146
  baseClassName: 'droplist',
147
147
 
148
148
  autoItemBlur: true,
@@ -201,7 +201,7 @@ class DropList {
201
201
  * @param {DropList.Options} options
202
202
  */
203
203
  constructor(options) {
204
- const o = { ...defaultOptions$1 };
204
+ const o = { ...DefaultOptions$1 };
205
205
 
206
206
  for (let [key, value] of Object.entries(/**@type Object*/options))
207
207
  if (value !== undefined)
@@ -3388,6 +3388,7 @@ const inputBackbufferCssProps = [
3388
3388
  * @property {string|string[]} [additionalClasses]
3389
3389
  * @property {'ltr'|'rtl'|'auto'} [direction='auto']
3390
3390
  * @property {boolean} [disabled=false] Should start as disabled?
3391
+ * @property {boolean} [readonly=false] Should start as readonly?
3391
3392
  * @property {boolean} [clearable=true] Has clear button?
3392
3393
  * @property {boolean} [hasOpenIndicator=true] has open/close indicator?
3393
3394
  * @property {string} [placeholder=''] Placeholder text
@@ -3406,6 +3407,7 @@ const inputBackbufferCssProps = [
3406
3407
  * @property {string} [labelProp='label']
3407
3408
  * @property {string} [valueProp='value']
3408
3409
  * @property {string} [multiItemLabelProp='short_label']
3410
+ * @property {'after'|'before'|'none'} [multiItemRemovePosition='after']
3409
3411
  * @property {number} [maxMultiItems] maximum number of multi items. The rest will get a single item to represent.
3410
3412
  * @property {function(count: number, items: DropList.ItemBase[]):string} [multiItemsRestLabelProvider] label for the item representing the rest of the items.
3411
3413
  * @property {DropList.ItemBase[]|null} [items] initial items
@@ -3428,10 +3430,11 @@ const inputBackbufferCssProps = [
3428
3430
  * @property {boolean} [closeListWhenLoading] whether we should close the list automatically when loading
3429
3431
  * @property {string[]} [clearInputWhen=['single_close','multi_select_single']] clear input box when closing the droplist or selecting <code>['single_close', 'multi_close', 'multi_select_single']</code>
3430
3432
  * */
3431
- const defaultOptions = {
3433
+ const DefaultOptions = {
3432
3434
  el: null,
3433
3435
  baseClassName: 'selectbox',
3434
3436
  disabled: false,
3437
+ readonly: false,
3435
3438
  clearable: true,
3436
3439
  hasOpenIndicator: true,
3437
3440
  placeholder: '',
@@ -3455,6 +3458,7 @@ const defaultOptions = {
3455
3458
  labelProp: 'label',
3456
3459
  valueProp: 'value',
3457
3460
  multiItemLabelProp: 'short_label',
3461
+ multiItemRemovePosition: 'after',
3458
3462
  maxMultiItems: null,
3459
3463
  multiItemsRestLabelProvider: null,
3460
3464
  items: [],
@@ -3513,7 +3517,7 @@ class SelectBox {
3513
3517
  * @param {SelectBox.Options} options
3514
3518
  */
3515
3519
  constructor(options) {
3516
- const o = { ...defaultOptions };
3520
+ const o = { ...DefaultOptions };
3517
3521
 
3518
3522
  for (let [key, value] of Object.entries(/**@type Object*/options))
3519
3523
  if (value !== undefined)
@@ -3529,6 +3533,7 @@ class SelectBox {
3529
3533
  listOptions: o.listOptions,
3530
3534
 
3531
3535
  disabled: !!o.disabled,
3536
+ readonly: !!o.readonly,
3532
3537
  clearable: !!o.clearable,
3533
3538
  hasOpenIndicator: !!o.hasOpenIndicator,
3534
3539
  placeholder: o.placeholder,
@@ -3551,6 +3556,7 @@ class SelectBox {
3551
3556
  labelProp: o.labelProp,
3552
3557
  valueProp: o.valueProp,
3553
3558
  multiItemLabelProp: o.multiItemLabelProp,
3559
+ multiItemRemovePosition: o.multiItemRemovePosition,
3554
3560
 
3555
3561
  maxMultiItems: o.maxMultiItems,
3556
3562
  multiItemsRestLabelProvider: o.multiItemsRestLabelProvider,
@@ -3610,6 +3616,7 @@ class SelectBox {
3610
3616
  p.multiItemEls = [];
3611
3617
 
3612
3618
  this.enable(!p.disabled);
3619
+ this.setReadOnly(!p.readonly);
3613
3620
 
3614
3621
  this._setupDropdownMenu();
3615
3622
 
@@ -3836,6 +3843,32 @@ class SelectBox {
3836
3843
  return this._p.disabled;
3837
3844
  }
3838
3845
 
3846
+ /**
3847
+ * Sets read only mode
3848
+ * @param {boolean=true} readonly Should the control be read only?
3849
+ * @returns {SelectBox}
3850
+ */
3851
+ setReadOnly(readonly) {
3852
+ const p = this._p;
3853
+
3854
+ if (readonly === undefined) {
3855
+ readonly = true;
3856
+ }
3857
+ p.readonly = !readonly;
3858
+ p.el.setAttribute('aria-readonly', p.readonly.toString());
3859
+ p.input.readonly = !!p.readonly;
3860
+
3861
+ return this;
3862
+ }
3863
+
3864
+ /**
3865
+ * Is the control enabled?
3866
+ * @returns {boolean}
3867
+ */
3868
+ isReadOnly() {
3869
+ return !this._p.readonly;
3870
+ }
3871
+
3839
3872
  /**
3840
3873
  * @param {string|string[]} classes
3841
3874
  * @returns {SelectBox}
@@ -4463,6 +4496,18 @@ class SelectBox {
4463
4496
  setMultiItemLabelProp(prop) {
4464
4497
  const p = this._p;
4465
4498
  p.multiItemLabelProp = prop;
4499
+ this._scheduleSync('render_items');
4500
+ return this;
4501
+ }
4502
+
4503
+ /**
4504
+ * @param {'before'|'after'|'none'} position
4505
+ * @returns {SelectBox}
4506
+ */
4507
+ setMultiItemRemovePosition(position) {
4508
+ const p = this._p;
4509
+ p.multiItemRemovePosition = position;
4510
+ this._scheduleSync('render_items');
4466
4511
  return this;
4467
4512
  }
4468
4513
 
@@ -4985,7 +5030,7 @@ class SelectBox {
4985
5030
  if (!closestUntil(evt.target, `.${p.baseClassName}__item_remove`, evt.currentTarget))
4986
5031
  return;
4987
5032
 
4988
- if (p.disabled) return;
5033
+ if (p.disabled || p.readonly) return;
4989
5034
 
4990
5035
  this._removeMultiItemFromEvent(
4991
5036
  /**@type Element*/
@@ -5038,6 +5083,7 @@ class SelectBox {
5038
5083
  if (p.hasOpenIndicator) {
5039
5084
  p.openIndicator = createElement('span', { class: `${p.baseClassName}__open_indicator` });
5040
5085
  p.el.appendChild(p.openIndicator);
5086
+ p.el.classList.add(`${p.baseClassName}__has_open_indicator`);
5041
5087
  } else {
5042
5088
  remove(p.openIndicator);
5043
5089
  delete p.openIndicator;
@@ -5352,7 +5398,7 @@ class SelectBox {
5352
5398
 
5353
5399
  setTimeout(() => {
5354
5400
  if (this[DestroyedSymbol]) return; // destroyed by event handler
5355
- if (p.disabled) return;
5401
+ if (p.disabled || p.readonly) return;
5356
5402
 
5357
5403
  this._trigger('search:blur');
5358
5404
 
@@ -5495,7 +5541,8 @@ class SelectBox {
5495
5541
  p.lastKeyAllowsNonTypeKeys &&
5496
5542
  !p.multi &&
5497
5543
  !dropList.hasFocusedItem() &&
5498
- !p.disabled
5544
+ !p.disabled &&
5545
+ !p.readonly
5499
5546
  )) {
5500
5547
  this.toggleList();
5501
5548
  evt.preventDefault();
@@ -5507,20 +5554,20 @@ class SelectBox {
5507
5554
  if (p.input) {
5508
5555
  p.sink
5509
5556
  .add(p.input, 'input.dropdown', () => {
5510
- if (p.disabled) return;
5557
+ if (p.disabled || p.readonly) return;
5511
5558
 
5512
5559
  p.filterTerm = p.input.value.trim();
5513
5560
  p.dropList?.setSearchTerm(p.filterTerm, true);
5514
5561
  })
5515
5562
  .add(p.input, 'click.dropdown', () => {
5516
- if (p.disabled) return;
5563
+ if (p.disabled || p.readonly) return;
5517
5564
 
5518
5565
  if (!p.multi && p.searchable) {
5519
5566
  this.openList();
5520
5567
  }
5521
5568
  })
5522
5569
  .add(p.input, 'focus.dropdown', () => {
5523
- if (p.disabled) return;
5570
+ if (p.disabled || p.readonly) return;
5524
5571
 
5525
5572
  this._trigger('search:focus');
5526
5573
 
@@ -5537,7 +5584,7 @@ class SelectBox {
5537
5584
 
5538
5585
  p.sink
5539
5586
  .add(p.el, 'mousedown.dropdown', () => {
5540
- if (!p.multi && !p.searchable && !avoidToggleFromClick && !p.disabled) {
5587
+ if (!p.multi && !p.searchable && !avoidToggleFromClick && !p.disabled && !p.readonly) {
5541
5588
  this.toggleList();
5542
5589
  }
5543
5590
  avoidToggleFromClick = false;
@@ -5546,7 +5593,7 @@ class SelectBox {
5546
5593
  if (currentTouchId) return;
5547
5594
  currentTouchId = evt.changedTouches[0].identifier;
5548
5595
 
5549
- if (this.isDisabled())
5596
+ if (this.isDisabled() || this.isReadOnly())
5550
5597
  return;
5551
5598
 
5552
5599
  if (closestUntil(evt.target, `.${p.baseClassName}__item,.${p.baseClassName}__clear`, p.el))
@@ -5986,7 +6033,7 @@ class SelectBox {
5986
6033
  p.el.classList.add(`${p.baseClassName}__has_clear`);
5987
6034
 
5988
6035
  p.sink.add(p.clearButton, 'click', () => {
5989
- if (this.isDisabled()) return;
6036
+ if (this.isDisabled() || this.isReadOnly()) return;
5990
6037
  this.clear();
5991
6038
  });
5992
6039
  }
@@ -6183,22 +6230,29 @@ class SelectBox {
6183
6230
  if (label === false)
6184
6231
  return null;
6185
6232
 
6233
+ const elRemove = createElement('span', {
6234
+ class: `${p.baseClassName}__item_remove`,
6235
+ role: 'presentation',
6236
+ });
6237
+
6186
6238
  const itemEl = createElement('li',
6187
6239
  {
6188
6240
  class: `${p.baseClassName}__item`,
6189
6241
  tabindex: '0',
6190
6242
  title: label,
6191
6243
  },
6192
- [
6193
- createElement('span', {
6194
- class: `${p.baseClassName}__item_remove`,
6195
- role: 'presentation',
6196
- }),
6197
- ],
6198
6244
  );
6199
6245
 
6246
+ if (p.multiItemRemovePosition === 'before') {
6247
+ itemEl.appendChild(elRemove);
6248
+ }
6249
+
6200
6250
  this._renderMultiItemContent(item, itemEl);
6201
6251
 
6252
+ if (p.multiItemRemovePosition === 'after') {
6253
+ itemEl.appendChild(elRemove);
6254
+ }
6255
+
6202
6256
  itemEl[ItemSymbol] = item;
6203
6257
 
6204
6258
  return itemEl;
@@ -6515,7 +6569,7 @@ class SelectBox {
6515
6569
  _handleMultiKeydown(event) {
6516
6570
  const p = this._p;
6517
6571
 
6518
- if (p.disabled) return;
6572
+ if (p.disabled || p.readonly) return;
6519
6573
 
6520
6574
  const isRtl = getComputedStyle(p.el).direction === 'rtl';
6521
6575