@refinitiv-ui/elements 6.14.2 → 6.15.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.
@@ -1,5 +1,5 @@
1
1
  import { __decorate } from "tslib";
2
- import { ControlElement, FocusedPropertyKey, css, html } from '@refinitiv-ui/core';
2
+ import { FocusedPropertyKey, FormFieldElement, css, html, nothing } from '@refinitiv-ui/core';
3
3
  import { customElement } from '@refinitiv-ui/core/decorators/custom-element.js';
4
4
  import { property } from '@refinitiv-ui/core/decorators/property.js';
5
5
  import { createRef, ref } from '@refinitiv-ui/core/directives/ref.js';
@@ -21,6 +21,12 @@ const observerOptions = {
21
21
  characterData: true,
22
22
  attributeFilter: ['label', 'value', 'selected', 'disabled', 'readonly']
23
23
  };
24
+ // the same event listener options should be used with both addEventListener() & removeEventListener()
25
+ // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener#matching_event_listeners_for_removal
26
+ const eventListenerOptions = {
27
+ /* need this for IE11, otherwise the event is not removed */ capture: true,
28
+ passive: true
29
+ };
24
30
  const LABEL_SEPARATOR = ', '; // TODO: for multiselect
25
31
  const POPUP_POSITION = ['bottom-start', 'top-start'];
26
32
  const KEY_SEARCH_DEBOUNCER = 300;
@@ -38,13 +44,21 @@ var Navigation;
38
44
  * @attr {boolean} disabled - Set disabled state
39
45
  * @prop {boolean} [disabled=false] - Set disabled state
40
46
  *
47
+ * @attr {string} placeholder - Set placeholder text
48
+ * @prop {string} [placeholder=""] - Set placeholder text
49
+ *
50
+ * @attr {boolean} error - Set error state
51
+ * @prop {boolean} [error=false] - Set error state
52
+ *
53
+ * @attr {boolean} warning - Set warning state
54
+ * @prop {boolean} [warning=false] - Set warning state
55
+ *
41
56
  * @fires value-changed - Fired when the user commits a value change. The event is not triggered if `value` property is changed programmatically.
42
57
  * @fires opened-changed - Fired when the user opens or closes control's popup. The event is not triggered if `opened` property is changed programmatically.
43
58
  */
44
- let Select = class Select extends ControlElement {
59
+ let Select = class Select extends FormFieldElement {
45
60
  constructor() {
46
61
  super(...arguments);
47
- this.defaultRole = 'combobox';
48
62
  this.composer = new CollectionComposer([]);
49
63
  this._data = null;
50
64
  this.popupDynamicStyles = {}; /* set popup min-width based on select width or CSS vars */
@@ -54,22 +68,10 @@ let Select = class Select extends ControlElement {
54
68
  this.keySearchTerm = ''; /* used for quick search */
55
69
  this.keySearchThrottler = new TimeoutTaskRunner(KEY_SEARCH_DEBOUNCER);
56
70
  this.resizeThrottler = new AnimationTaskRunner();
57
- /**
58
- * Placeholder to display when no value is set
59
- */
60
- this.placeholder = '';
61
71
  /**
62
72
  * Toggles the opened state of the list
63
73
  */
64
74
  this.opened = false;
65
- /**
66
- * Set error state
67
- */
68
- this.error = false;
69
- /**
70
- * Set warning state
71
- */
72
- this.warning = false;
73
75
  /**
74
76
  * This variable is here to ensure that the value and data are in sync when data is set after the value.
75
77
  * This is developer error to use both, selected and value to control the selections.
@@ -145,6 +147,9 @@ let Select = class Select extends ControlElement {
145
147
  display: none;
146
148
  }
147
149
  #box {
150
+ outline: none;
151
+ width: 100%;
152
+ height: 100%;
148
153
  align-items: center;
149
154
  display: inline-flex;
150
155
  flex-flow: row nowrap;
@@ -167,19 +172,6 @@ let Select = class Select extends ControlElement {
167
172
  left: 0;
168
173
  cursor: pointer;
169
174
  }
170
- #select {
171
- position: absolute;
172
- top: 0;
173
- left: 0;
174
- right: 0;
175
- bottom: 0;
176
- width: 100%;
177
- height: 100%;
178
- opacity: 0;
179
- border: none;
180
- padding: 0;
181
- margin: 0;
182
- }
183
175
  `;
184
176
  }
185
177
  /**
@@ -273,15 +265,6 @@ let Select = class Select extends ControlElement {
273
265
  }
274
266
  return this.selectedSlotItems.map((item) => this.getItemValue(item));
275
267
  }
276
- /**
277
- * Called when connected to DOM
278
- * @returns {void}
279
- */
280
- connectedCallback() {
281
- super.connectedCallback();
282
- // Indicating that this select has a popup of type listbox
283
- this.setAttribute('aria-haspopup', 'listbox');
284
- }
285
268
  /**
286
269
  * Updates the element
287
270
  * @param changedProperties Properties that has changed
@@ -306,10 +289,6 @@ let Select = class Select extends ControlElement {
306
289
  else {
307
290
  this.closing();
308
291
  }
309
- this.setAttribute('aria-expanded', this.opened ? 'true' : 'false');
310
- }
311
- if (changedProperties.has('error')) {
312
- this.setAttribute('aria-invalid', this.error ? 'true' : 'false');
313
292
  }
314
293
  super.update(changedProperties);
315
294
  }
@@ -483,22 +462,14 @@ let Select = class Select extends ControlElement {
483
462
  onPopupOpened({ target }) {
484
463
  this.scrollToSelected();
485
464
  this.setItemHighlight(this.getSelectedElements()[0]);
486
- const eventOptions = {
487
- capture: true,
488
- passive: true
489
- };
490
- target?.addEventListener('scroll', this.onPopupScroll, eventOptions);
465
+ target?.addEventListener('scroll', this.onPopupScroll, eventListenerOptions);
491
466
  }
492
467
  /**
493
468
  * Run when popup gets closed
494
469
  * @returns {void}
495
470
  */
496
471
  onPopupClosed({ target }) {
497
- const eventOptions = {
498
- /* need this for IE11, otherwise the event is not removed */ capture: true,
499
- passive: true
500
- };
501
- target?.removeEventListener('scroll', this.onPopupScroll, eventOptions);
472
+ target?.removeEventListener('scroll', this.onPopupScroll, eventListenerOptions);
502
473
  this.setItemHighlight();
503
474
  this.popupScrollTop = 0;
504
475
  }
@@ -877,17 +848,6 @@ let Select = class Select extends ControlElement {
877
848
  get labelTemplate() {
878
849
  return html `<div part="label" ${ref(this.labelRef)}>${this.labelText}</div>`;
879
850
  }
880
- /**
881
- * Edit template when select is not readonly or disabled
882
- */
883
- get editTemplate() {
884
- if (!this.readonly && !this.disabled) {
885
- return html `
886
- <div id="trigger" @tapstart="${this.toggleOpened}"></div>
887
- ${this.popupTemplate}
888
- `;
889
- }
890
- }
891
851
  /**
892
852
  * Get default slot template
893
853
  */
@@ -901,37 +861,46 @@ let Select = class Select extends ControlElement {
901
861
  return html `${this.composer.queryItems(() => true).map((item) => this.toItem(item))}`;
902
862
  }
903
863
  /**
904
- * Edit template when select is not readonly or disabled
905
- */
906
- get popupTemplate() {
907
- if (this.lazyRendered) {
908
- return html `<ef-overlay
909
- ${ref(this.menuRef)}
910
- tabindex="-1"
911
- id="menu"
912
- part="list"
913
- role="listbox"
914
- style=${styleMap(this.popupDynamicStyles)}
915
- with-shadow
916
- lock-position-target
917
- .positionTarget=${this}
918
- .position=${POPUP_POSITION}
919
- ?opened=${this.opened}
920
- @tap=${this.onPopupTap}
921
- @mousemove=${this.onPopupMouseMove}
922
- @keydown=${this.onPopupKeyDown}
923
- @opened-changed="${this.onPopupOpenedChanged}"
924
- @opened="${this.onPopupOpened}"
925
- @refit=${this.onPopupRefit}
926
- @closed="${this.onPopupClosed}"
927
- >${this.hasDataItems() ? this.dataContent : this.slottedContent}</ef-overlay
928
- >`;
929
- }
930
- else {
931
- // This code is required because IE11 polyfill need items to be within a slot
932
- // to make MutationObserver to observe items correctly
933
- return html `<div style="display: none !important;"><slot></slot></div>`;
934
- }
864
+ * `ef-items` template generated from slot or `data`
865
+ */
866
+ get itemsTemplate() {
867
+ return this.hasDataItems() ? this.dataContent : this.slottedContent;
868
+ }
869
+ /**
870
+ * Template of a listbox containing ef-item(s)
871
+ */
872
+ get listboxTemplate() {
873
+ return this.lazyRendered
874
+ ? html `<ef-overlay
875
+ ${ref(this.menuRef)}
876
+ tabindex="-1"
877
+ id="menu"
878
+ part="list"
879
+ role="listbox"
880
+ style=${styleMap(this.popupDynamicStyles)}
881
+ with-shadow
882
+ lock-position-target
883
+ .positionTarget=${this}
884
+ .position=${POPUP_POSITION}
885
+ ?opened=${this.opened}
886
+ @tap=${this.onPopupTap}
887
+ @mousemove=${this.onPopupMouseMove}
888
+ @keydown=${this.onPopupKeyDown}
889
+ @opened-changed="${this.onPopupOpenedChanged}"
890
+ @opened="${this.onPopupOpened}"
891
+ @refit=${this.onPopupRefit}
892
+ @closed="${this.onPopupClosed}"
893
+ >${this.itemsTemplate}</ef-overlay
894
+ >`
895
+ : // This code is required because IE11 polyfill need items to be within a slot
896
+ // to make MutationObserver to observe items correctly
897
+ html `<div style="display: none !important;"><slot></slot></div>`;
898
+ }
899
+ /**
900
+ * Area that allows select to be clickable and toggle between open and close
901
+ */
902
+ get triggerTemplate() {
903
+ return html ` <div id="trigger" @tapstart="${this.toggleOpened}"></div>`;
935
904
  }
936
905
  /**
937
906
  * A `TemplateResult` that will be used
@@ -939,11 +908,25 @@ let Select = class Select extends ControlElement {
939
908
  * @return Render template
940
909
  */
941
910
  render() {
942
- return html ` <div id="box">
911
+ return html `<div
912
+ id="box"
913
+ tabindex="0"
914
+ role="combobox"
915
+ placeholder=${this.placeholder || nothing}
916
+ aria-haspopup="listbox"
917
+ aria-controls="menu"
918
+ aria-invalid=${this.error ? 'true' : 'false'}
919
+ aria-expanded=${this.opened ? 'true' : 'false'}
920
+ aria-required=${this.inputAriaRequired}
921
+ aria-label=${this.inputAriaLabel ?? nothing}
922
+ aria-description=${this.inputAriaDescription ?? nothing}
923
+ >
943
924
  <div id="text">${this.placeholderHidden() ? this.labelTemplate : this.placeholderTemplate}</div>
944
- <ef-icon icon="down" part="icon"></ef-icon>
925
+ <ef-icon aria-hidden="true" icon="down" part="icon"></ef-icon>
945
926
  </div>
946
- ${this.editTemplate}`;
927
+ ${!this.readonly && !this.disabled
928
+ ? html ` ${this.triggerTemplate} ${this.listboxTemplate} `
929
+ : nothing}`;
947
930
  }
948
931
  };
949
932
  __decorate([
@@ -952,18 +935,9 @@ __decorate([
952
935
  __decorate([
953
936
  property({ type: Array, attribute: false })
954
937
  ], Select.prototype, "labels", null);
955
- __decorate([
956
- property({ type: String })
957
- ], Select.prototype, "placeholder", void 0);
958
938
  __decorate([
959
939
  property({ type: Boolean, reflect: true })
960
940
  ], Select.prototype, "opened", void 0);
961
- __decorate([
962
- property({ type: Boolean, reflect: true })
963
- ], Select.prototype, "error", void 0);
964
- __decorate([
965
- property({ type: Boolean, reflect: true })
966
- ], Select.prototype, "warning", void 0);
967
941
  __decorate([
968
942
  property({ type: Boolean })
969
943
  ], Select.prototype, "multiple", null);
@@ -0,0 +1,49 @@
1
+ import { JSXInterface } from '../../jsx';
2
+ import { BasicElement, CSSResultGroup, PropertyValues, TemplateResult } from '@refinitiv-ui/core';
3
+ export declare class SliderMarker extends BasicElement {
4
+ /**
5
+ * Element version number
6
+ * @returns version number
7
+ */
8
+ static get version(): string;
9
+ static get styles(): CSSResultGroup;
10
+ /**
11
+ * Used to determine the position of the marker on the scale.
12
+ */
13
+ value: string;
14
+ /**
15
+ * Specify label alignment
16
+ */
17
+ labelAlign: 'left' | 'right' | 'center' | null;
18
+ /**
19
+ * On first updated lifecycle
20
+ * @param changedProperties changed properties
21
+ * @returns {void}
22
+ */
23
+ protected firstUpdated(changedProperties: PropertyValues): void;
24
+ /**
25
+ * A `TemplateResult` that will be used
26
+ * to render the updated internal template.
27
+ * @returns Render template
28
+ */
29
+ protected render(): TemplateResult;
30
+ }
31
+ declare global {
32
+ interface HTMLElementTagNameMap {
33
+ 'ef-slider-marker': SliderMarker;
34
+ }
35
+ }
36
+
37
+ declare global {
38
+ interface HTMLElementTagNameMap {
39
+ 'ef-slider-marker': SliderMarker;
40
+ }
41
+
42
+ namespace JSX {
43
+ interface IntrinsicElements {
44
+ 'ef-slider-marker': Partial<SliderMarker> | JSXInterface.HTMLAttributes<SliderMarker>;
45
+ }
46
+ }
47
+ }
48
+
49
+ export {};
@@ -0,0 +1,72 @@
1
+ import { __decorate } from "tslib";
2
+ import { BasicElement, css, html } from '@refinitiv-ui/core';
3
+ import { customElement } from '@refinitiv-ui/core/decorators/custom-element.js';
4
+ import { property } from '@refinitiv-ui/core/decorators/property.js';
5
+ import { VERSION } from '../../version.js';
6
+ let SliderMarker = class SliderMarker extends BasicElement {
7
+ constructor() {
8
+ super(...arguments);
9
+ /**
10
+ * Used to determine the position of the marker on the scale.
11
+ */
12
+ this.value = '';
13
+ /**
14
+ * Specify label alignment
15
+ */
16
+ this.labelAlign = null;
17
+ }
18
+ /**
19
+ * Element version number
20
+ * @returns version number
21
+ */
22
+ static get version() {
23
+ return VERSION;
24
+ }
25
+ static get styles() {
26
+ return css `
27
+ :host {
28
+ position: absolute;
29
+ }
30
+ [part='marker'] {
31
+ width: 100%;
32
+ height: 100%;
33
+ }
34
+ [part='label'] {
35
+ white-space: nowrap;
36
+ position: absolute;
37
+ }
38
+ `;
39
+ }
40
+ /**
41
+ * On first updated lifecycle
42
+ * @param changedProperties changed properties
43
+ * @returns {void}
44
+ */
45
+ firstUpdated(changedProperties) {
46
+ super.firstUpdated(changedProperties);
47
+ this.setAttribute('aria-hidden', 'true');
48
+ }
49
+ /**
50
+ * A `TemplateResult` that will be used
51
+ * to render the updated internal template.
52
+ * @returns Render template
53
+ */
54
+ render() {
55
+ return html `
56
+ <div part="marker"></div>
57
+ <div part="label">
58
+ <slot></slot>
59
+ </div>
60
+ `;
61
+ }
62
+ };
63
+ __decorate([
64
+ property({ type: String })
65
+ ], SliderMarker.prototype, "value", void 0);
66
+ __decorate([
67
+ property({ type: String, reflect: true, attribute: 'label-align' })
68
+ ], SliderMarker.prototype, "labelAlign", void 0);
69
+ SliderMarker = __decorate([
70
+ customElement('ef-slider-marker')
71
+ ], SliderMarker);
72
+ export { SliderMarker };