@refinitiv-ui/elements 6.11.0 → 6.13.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,28 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [6.13.0](https://github.com/Refinitiv/refinitiv-ui/compare/@refinitiv-ui/elements@6.12.0...@refinitiv-ui/elements@6.13.0) (2023-09-25)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **interactive-chart:** legend not update when add new seriesList ([#959](https://github.com/Refinitiv/refinitiv-ui/issues/959)) ([215a6ba](https://github.com/Refinitiv/refinitiv-ui/commit/215a6badbd24dae46d631150b1bdb945e633c080))
11
+ - **tree-select:** show invalid values when click on cancel button on … ([#965](https://github.com/Refinitiv/refinitiv-ui/issues/965)) ([a3abd4f](https://github.com/Refinitiv/refinitiv-ui/commit/a3abd4f543dd0662129c9656a8bd2be40c954bd9))
12
+
13
+ ### Features
14
+
15
+ - **calendar:** introduce before-cell-render event ([#950](https://github.com/Refinitiv/refinitiv-ui/issues/950)) ([7889413](https://github.com/Refinitiv/refinitiv-ui/commit/7889413d4dbf690fab5c3a3fd8c526ba25fb1dbe))
16
+
17
+ # [6.12.0](https://github.com/Refinitiv/refinitiv-ui/compare/@refinitiv-ui/elements@6.11.0...@refinitiv-ui/elements@6.12.0) (2023-09-18)
18
+
19
+ ### Bug Fixes
20
+
21
+ - **slider:** incorrect updating to value ([#947](https://github.com/Refinitiv/refinitiv-ui/issues/947)) ([f883987](https://github.com/Refinitiv/refinitiv-ui/commit/f883987482cf91c7b6b687c9c67d733bf7a9e4d3))
22
+ - **slider:** number field not revalidate when error state changes ([#953](https://github.com/Refinitiv/refinitiv-ui/issues/953)) ([d4b952e](https://github.com/Refinitiv/refinitiv-ui/commit/d4b952e9d376b0e751584afc6de7a5527dbc11c3))
23
+
24
+ ### Features
25
+
26
+ - **utils:** add `selectedAt` property to `DataItem` interface ([181066b](https://github.com/Refinitiv/refinitiv-ui/commit/181066bad6842f0b06d0607150d3d633bf89f0e7))
27
+
6
28
  # [6.11.0](https://github.com/Refinitiv/refinitiv-ui/compare/@refinitiv-ui/elements@6.10.2...@refinitiv-ui/elements@6.11.0) (2023-09-11)
7
29
 
8
30
  ### Features
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright © 2023, Refinitiv.
1
+ Copyright © 2023, LSEG
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Element Framework
2
2
 
3
- Element Framework (EF) is a collection of elements that includes theming capability within the Refinitiv Workspace's design system. The elements are a set of web components which is a standard web technology and can be utilized across all browsers.
3
+ Element Framework (EF) is a collection of elements that includes theming capability within the LSEG Workspace's design system. The elements are a set of web components which is a standard web technology and can be utilized across all browsers.
4
4
 
5
5
  ## Usage
6
6
 
@@ -10,17 +10,17 @@ EF elements are published under single package.
10
10
  npm install @refinitiv-ui/elements
11
11
  ```
12
12
 
13
- The elements are required theme to instantiate itself in the app. Refinitiv Workspace's design system is called Halo theme and you can install it from npm command.
13
+ The elements are required theme to instantiate itself in the app. LSEG Workspace's design system is called Halo theme and you can install it from npm command.
14
14
 
15
15
  ```sh
16
16
  npm install @refinitiv-ui/halo-theme
17
17
  ```
18
18
 
19
- Finally, import both elements that you want to use and its themes into your application and it is ready to go. To follow Refinitiv Workspace's design system, it is required styles of some native elements e.g. typography.
19
+ Finally, import both elements that you want to use and its themes into your application and it is ready to go. To follow LSEG Workspace's design system, it is required styles of some native elements e.g. typography.
20
20
 
21
21
  <br>
22
22
 
23
- > The font "Proxima Nova Fin" shall only be used within Refinitiv products or services. The copyright owner must approve any use of such font outside of Refinitiv products or services, which may be subject to a fee. Please see https://www.fontspring.com/lic/fontspring/webfont#license_text
23
+ > The font "Proxima Nova Fin" shall only be used within LSEG products or services. The copyright owner must approve any use of such font outside of LSEG products or services, which may be subject to a fee. Please see https://www.fontspring.com/lic/fontspring/webfont#license_text
24
24
 
25
25
  <br>
26
26
 
@@ -57,4 +57,4 @@ See list of elements, demo and more tutorial by visiting [EF Documentation](http
57
57
 
58
58
  # License
59
59
 
60
- Apache License 2.0. However, Halo theme shall only be used within Refinitiv products or services due to license of the font "Proxima Nova Fin".
60
+ Apache License 2.0. However, Halo theme shall only be used within LSEG products or services due to license of the font "Proxima Nova Fin".
@@ -1,4 +1,4 @@
1
- export declare enum RenderView {
1
+ export declare enum CalendarRenderView {
2
2
  DAY = "day",
3
3
  MONTH = "month",
4
4
  YEAR = "year"
@@ -1,10 +1,11 @@
1
1
  import { uuid } from '@refinitiv-ui/utils/uuid.js';
2
- export var RenderView;
3
- (function (RenderView) {
4
- RenderView["DAY"] = "day";
5
- RenderView["MONTH"] = "month";
6
- RenderView["YEAR"] = "year";
7
- })(RenderView || (RenderView = {}));
2
+ // public API
3
+ export var CalendarRenderView;
4
+ (function (CalendarRenderView) {
5
+ CalendarRenderView["DAY"] = "day";
6
+ CalendarRenderView["MONTH"] = "month";
7
+ CalendarRenderView["YEAR"] = "year";
8
+ })(CalendarRenderView || (CalendarRenderView = {}));
8
9
  export const FIRST_DAY_OF_WEEK = 0; // 0 for Sunday
9
10
  export const YEARS_PER_YEAR_VIEW = 16; /* must be a square number */
10
11
  export const DAY_VIEW = {
@@ -181,6 +181,10 @@
181
181
  }
182
182
  ],
183
183
  "events": [
184
+ {
185
+ "name": "before-cell-render",
186
+ "description": "Fired before calendar renders each cell along with `cell` model."
187
+ },
184
188
  {
185
189
  "name": "value-changed",
186
190
  "description": "Fired when the user commits a date change. The event is not triggered if `value` is changed programmatically."
@@ -23,10 +23,11 @@ Standard calendar element
23
23
 
24
24
  ## Events
25
25
 
26
- | Event | Description |
27
- |-----------------|--------------------------------------------------|
28
- | `value-changed` | Fired when the user commits a date change. The event is not triggered if `value` is changed programmatically. |
29
- | `view-changed` | Fired when the user changes a view of calendar e.g. changed to next month page. The event is not triggered if `view` property is changed programmatically. |
26
+ | Event | Description |
27
+ |----------------------|--------------------------------------------------|
28
+ | `before-cell-render` | Fired before calendar renders each cell along with `cell` model. |
29
+ | `value-changed` | Fired when the user commits a date change. The event is not triggered if `value` is changed programmatically. |
30
+ | `view-changed` | Fired when the user changes a view of calendar e.g. changed to next month page. The event is not triggered if `view` property is changed programmatically. |
30
31
 
31
32
  ## Slots
32
33
 
@@ -3,12 +3,16 @@ import { CSSResultGroup, ControlElement, MultiValue, PropertyValues, TemplateRes
3
3
  import '@refinitiv-ui/phrasebook/locale/en/calendar.js';
4
4
  import { TranslateDirective, TranslatePromise } from '@refinitiv-ui/translate';
5
5
  import '../button/index.js';
6
+ import { CalendarRenderView } from './constants.js';
6
7
  import './locales.js';
7
- import type { CalendarFilter } from './types';
8
- export { CalendarFilter };
8
+ import type { BeforeCellRenderEvent, CalendarFilter } from './types';
9
+ export { CalendarRenderView };
10
+ export type { CalendarCell } from './types';
11
+ export type { CalendarFilter, BeforeCellRenderEvent };
9
12
  /**
10
13
  * Standard calendar element
11
14
  *
15
+ * @fires before-cell-render - Fired before calendar renders each cell along with `cell` model.
12
16
  * @fires value-changed - Fired when the user commits a date change. The event is not triggered if `value` is changed programmatically.
13
17
  * @fires view-changed - Fired when the user changes a view of calendar e.g. changed to next month page. The event is not triggered if `view` property is changed programmatically.
14
18
  *
@@ -381,9 +385,15 @@ export declare class Calendar extends ControlElement implements MultiValue {
381
385
  * @returns key Translate label key
382
386
  */
383
387
  private getCellLabelKey;
388
+ /**
389
+ * fire 'before-cell-render' event
390
+ * @param cell Cell
391
+ * @returns {void}
392
+ */
393
+ private dispatchBeforeCellRender;
384
394
  /**
385
395
  * Render cell template. Cell can be a day, month or year
386
- * @param cell Cell object
396
+ * @param cell Cell
387
397
  * @returns template result
388
398
  */
389
399
  private renderCell;
@@ -13,12 +13,14 @@ import { DateFormat, addMonths, format, isAfter, isBefore, isSameDay, isSameMont
13
13
  import { down, first, last, left, right, up } from '@refinitiv-ui/utils/navigation.js';
14
14
  import '../button/index.js';
15
15
  import { VERSION } from '../version.js';
16
- import { CalendarLocaleScope, DAY_VIEW, FIRST_DAY_OF_WEEK, MONTH_VIEW, RenderView, YEARS_PER_YEAR_VIEW, YEAR_VIEW } from './constants.js';
16
+ import { CalendarLocaleScope, CalendarRenderView, DAY_VIEW, FIRST_DAY_OF_WEEK, MONTH_VIEW, YEARS_PER_YEAR_VIEW, YEAR_VIEW } from './constants.js';
17
17
  import './locales.js';
18
- import { ViewFormatTranslateParams, formatLocaleDate, monthInfo, monthsNames, weekdaysNames } from './utils.js';
18
+ import { ViewFormatTranslateParams, formatLocaleDate, monthInfo, monthsNames, toCalendarCell, weekdaysNames } from './utils.js';
19
+ export { CalendarRenderView };
19
20
  /**
20
21
  * Standard calendar element
21
22
  *
23
+ * @fires before-cell-render - Fired before calendar renders each cell along with `cell` model.
22
24
  * @fires value-changed - Fired when the user commits a date change. The event is not triggered if `value` is changed programmatically.
23
25
  * @fires view-changed - Fired when the user changes a view of calendar e.g. changed to next month page. The event is not triggered if `view` property is changed programmatically.
24
26
  *
@@ -73,7 +75,7 @@ let Calendar = class Calendar extends ControlElement {
73
75
  /**
74
76
  * Used for internal navigation between render views
75
77
  */
76
- this._renderView = RenderView.DAY;
78
+ this._renderView = CalendarRenderView.DAY;
77
79
  /**
78
80
  * Used for keyboard navigation when trying
79
81
  * to restore focus on re-render and control navigation
@@ -579,7 +581,8 @@ let Calendar = class Calendar extends ControlElement {
579
581
  */
580
582
  onRenderViewTap(event) {
581
583
  if (!event.defaultPrevented) {
582
- this.renderView = this.renderView === RenderView.DAY ? RenderView.YEAR : RenderView.DAY;
584
+ this.renderView =
585
+ this.renderView === CalendarRenderView.DAY ? CalendarRenderView.YEAR : CalendarRenderView.DAY;
583
586
  }
584
587
  }
585
588
  /**
@@ -594,8 +597,8 @@ let Calendar = class Calendar extends ControlElement {
594
597
  switch (event.key) {
595
598
  case 'Esc':
596
599
  case 'Escape':
597
- if (this.renderView === RenderView.YEAR || this.renderView === RenderView.MONTH) {
598
- this.renderView = RenderView.DAY;
600
+ if (this.renderView === CalendarRenderView.YEAR || this.renderView === CalendarRenderView.MONTH) {
601
+ this.renderView = CalendarRenderView.DAY;
599
602
  break;
600
603
  }
601
604
  return;
@@ -662,20 +665,20 @@ let Calendar = class Calendar extends ControlElement {
662
665
  this.activeCellIndex = cell.index;
663
666
  const cellSegment = toDateSegment(cell.value);
664
667
  const viewSegment = toDateSegment(this.view);
665
- if (this.renderView === RenderView.YEAR) {
668
+ if (this.renderView === CalendarRenderView.YEAR) {
666
669
  /* YEAR -> MONTH */
667
670
  viewSegment.year = cellSegment.year;
668
671
  if (this.notifyViewChange(viewSegment)) {
669
- this.renderView = RenderView.MONTH;
672
+ this.renderView = CalendarRenderView.MONTH;
670
673
  }
671
674
  return;
672
675
  }
673
- if (this.renderView === RenderView.MONTH) {
676
+ if (this.renderView === CalendarRenderView.MONTH) {
674
677
  /* MONTH -> DAY */
675
678
  viewSegment.year = cellSegment.year;
676
679
  viewSegment.month = cellSegment.month;
677
680
  if (this.notifyViewChange(viewSegment)) {
678
- this.renderView = RenderView.DAY;
681
+ this.renderView = CalendarRenderView.DAY;
679
682
  }
680
683
  return;
681
684
  }
@@ -759,13 +762,13 @@ let Calendar = class Calendar extends ControlElement {
759
762
  toNextView() {
760
763
  let viewSegment = toDateSegment(this.view);
761
764
  switch (this.renderView) {
762
- case RenderView.DAY:
765
+ case CalendarRenderView.DAY:
763
766
  viewSegment = toDateSegment(addMonths(this.view, 1));
764
767
  break;
765
- case RenderView.MONTH:
768
+ case CalendarRenderView.MONTH:
766
769
  viewSegment.year += 1;
767
770
  break;
768
- case RenderView.YEAR:
771
+ case CalendarRenderView.YEAR:
769
772
  viewSegment.year += YEARS_PER_YEAR_VIEW;
770
773
  break;
771
774
  // no default
@@ -779,13 +782,13 @@ let Calendar = class Calendar extends ControlElement {
779
782
  toPreviousView() {
780
783
  let viewSegment = toDateSegment(this.view);
781
784
  switch (this.renderView) {
782
- case RenderView.DAY:
785
+ case CalendarRenderView.DAY:
783
786
  viewSegment = toDateSegment(subMonths(this.view, 1));
784
787
  break;
785
- case RenderView.MONTH:
788
+ case CalendarRenderView.MONTH:
786
789
  viewSegment.year -= 1;
787
790
  break;
788
- case RenderView.YEAR:
791
+ case CalendarRenderView.YEAR:
789
792
  viewSegment.year -= YEARS_PER_YEAR_VIEW;
790
793
  break;
791
794
  // no default
@@ -886,9 +889,9 @@ let Calendar = class Calendar extends ControlElement {
886
889
  get formattedViewRender() {
887
890
  const segment = toDateSegment(this.view);
888
891
  switch (this.renderView) {
889
- case RenderView.MONTH:
892
+ case CalendarRenderView.MONTH:
890
893
  return this.viewFormattedDate(segment);
891
- case RenderView.YEAR:
894
+ case CalendarRenderView.YEAR:
892
895
  const month = segment.month;
893
896
  const day = segment.day;
894
897
  const fromYear = Math.floor(segment.year / YEARS_PER_YEAR_VIEW) * YEARS_PER_YEAR_VIEW;
@@ -896,7 +899,7 @@ let Calendar = class Calendar extends ControlElement {
896
899
  const fromView = this.viewFormattedDate({ year: fromYear, month, day });
897
900
  const toView = this.viewFormattedDate({ year: toYear, month, day });
898
901
  return html `${fromView} - ${toView}`;
899
- case RenderView.DAY:
902
+ case CalendarRenderView.DAY:
900
903
  default:
901
904
  return this.viewFormattedDate(segment, true);
902
905
  }
@@ -950,7 +953,7 @@ let Calendar = class Calendar extends ControlElement {
950
953
  * Get year view template
951
954
  */
952
955
  get yearView() {
953
- const view = RenderView.YEAR;
956
+ const view = CalendarRenderView.YEAR;
954
957
  const currentYear = toDateSegment(this.view).year;
955
958
  const startIdx = Math.floor(currentYear / YEARS_PER_YEAR_VIEW) * YEARS_PER_YEAR_VIEW;
956
959
  const years = [];
@@ -985,7 +988,7 @@ let Calendar = class Calendar extends ControlElement {
985
988
  * Get month view template
986
989
  */
987
990
  get monthView() {
988
- const view = RenderView.MONTH;
991
+ const view = CalendarRenderView.MONTH;
989
992
  const currentYear = toDateSegment(this.view).year;
990
993
  const columnCount = MONTH_VIEW.columnCount;
991
994
  const monthCount = 12;
@@ -1030,7 +1033,7 @@ let Calendar = class Calendar extends ControlElement {
1030
1033
  * Get day view template
1031
1034
  */
1032
1035
  get dayView() {
1033
- const view = RenderView.DAY;
1036
+ const view = CalendarRenderView.DAY;
1034
1037
  const firstDayOfWeek = this.firstDayOfWeek;
1035
1038
  const padding = (7 + utcParse(this.view).getUTCDay() - firstDayOfWeek) % 7;
1036
1039
  const viewMonth = monthInfo(this.view);
@@ -1123,13 +1126,13 @@ let Calendar = class Calendar extends ControlElement {
1123
1126
  get viewRender() {
1124
1127
  let renderView;
1125
1128
  switch (this.renderView) {
1126
- case RenderView.MONTH:
1129
+ case CalendarRenderView.MONTH:
1127
1130
  renderView = this.monthView;
1128
1131
  break;
1129
- case RenderView.YEAR:
1132
+ case CalendarRenderView.YEAR:
1130
1133
  renderView = this.yearView;
1131
1134
  break;
1132
- case RenderView.DAY:
1135
+ case CalendarRenderView.DAY:
1133
1136
  default:
1134
1137
  renderView = this.dayView;
1135
1138
  }
@@ -1152,12 +1155,32 @@ let Calendar = class Calendar extends ControlElement {
1152
1155
  }
1153
1156
  return 'CELL_LABEL';
1154
1157
  }
1158
+ /**
1159
+ * fire 'before-cell-render' event
1160
+ * @param cell Cell
1161
+ * @returns {void}
1162
+ */
1163
+ dispatchBeforeCellRender(cell) {
1164
+ const calendarCell = toCalendarCell(cell);
1165
+ const event = new CustomEvent('before-cell-render', {
1166
+ cancelable: false,
1167
+ composed: true,
1168
+ detail: {
1169
+ cell: calendarCell
1170
+ }
1171
+ });
1172
+ this.dispatchEvent(event);
1173
+ }
1155
1174
  /**
1156
1175
  * Render cell template. Cell can be a day, month or year
1157
- * @param cell Cell object
1176
+ * @param cell Cell
1158
1177
  * @returns template result
1159
1178
  */
1160
1179
  renderCell(cell) {
1180
+ // there is no slot for cells with falsy value
1181
+ if (cell.value) {
1182
+ this.dispatchBeforeCellRender(cell);
1183
+ }
1161
1184
  const isSelection = cell.value !== undefined;
1162
1185
  const isSelectable = isSelection && !cell.disabled;
1163
1186
  const isSelected = cell.selected ? 'true' : 'false';
@@ -1214,12 +1237,12 @@ let Calendar = class Calendar extends ControlElement {
1214
1237
  let nextBtnAriaLabel = this.t('NEXT_MONTH');
1215
1238
  let viewBtnAriaLabel = this.t('YEAR_SELECTOR');
1216
1239
  switch (this.renderView) {
1217
- case RenderView.YEAR:
1240
+ case CalendarRenderView.YEAR:
1218
1241
  prevBtnAriaLabel = this.t('PREVIOUS_DECADE');
1219
1242
  nextBtnAriaLabel = this.t('NEXT_DECADE');
1220
1243
  viewBtnAriaLabel = this.t('DATE_SELECTOR');
1221
1244
  break;
1222
- case RenderView.MONTH:
1245
+ case CalendarRenderView.MONTH:
1223
1246
  prevBtnAriaLabel = this.t('PREVIOUS_YEAR');
1224
1247
  nextBtnAriaLabel = this.t('NEXT_YEAR');
1225
1248
  viewBtnAriaLabel = this.t('DATE_SELECTOR');
@@ -1239,7 +1262,7 @@ let Calendar = class Calendar extends ControlElement {
1239
1262
  aria-description="${viewBtnAriaLabel}"
1240
1263
  part="btn-view"
1241
1264
  textpos="before"
1242
- .icon="${this.renderView === RenderView.DAY ? 'down' : 'up'}"
1265
+ .icon="${this.renderView === CalendarRenderView.DAY ? 'down' : 'up'}"
1243
1266
  @tap="${this.onRenderViewTap}"
1244
1267
  >${this.formattedViewRender}</ef-button
1245
1268
  >
@@ -1,5 +1,5 @@
1
1
  import { CellIndex } from '@refinitiv-ui/utils/navigation.js';
2
- import { RenderView } from './constants.js';
2
+ import { CalendarRenderView } from './constants.js';
3
3
  export interface CellSelectionModel {
4
4
  selected?: boolean;
5
5
  range?: boolean;
@@ -9,7 +9,7 @@ export interface CellSelectionModel {
9
9
  lastDate?: boolean;
10
10
  }
11
11
  export interface Cell extends CellSelectionModel {
12
- view: RenderView;
12
+ view: CalendarRenderView;
13
13
  text?: string;
14
14
  active?: boolean;
15
15
  value?: string;
@@ -30,3 +30,22 @@ export type WeekdayName = {
30
30
  narrow: string;
31
31
  long: string;
32
32
  };
33
+ export type CalendarCell = {
34
+ active: boolean;
35
+ disabled: boolean;
36
+ firstDate: boolean;
37
+ idle: boolean;
38
+ index: CellIndex;
39
+ lastDate: boolean;
40
+ now: boolean;
41
+ range: boolean;
42
+ rangeFrom: boolean;
43
+ rangeTo: boolean;
44
+ selected: boolean;
45
+ text: string;
46
+ value: string;
47
+ view: CalendarRenderView;
48
+ };
49
+ export type BeforeCellRenderEvent = CustomEvent<{
50
+ cell: CalendarCell;
51
+ }>;
@@ -1,4 +1,5 @@
1
1
  import { TranslateParams } from '@refinitiv-ui/i18n';
2
+ import { CalendarCell, Cell } from './types.js';
2
3
  export type MonthInfo = {
3
4
  days: number;
4
5
  month: number;
@@ -39,4 +40,11 @@ declare const formatLocaleDate: (date: Date, locale: string, includeMonth?: bool
39
40
  * Used to format views
40
41
  */
41
42
  declare const ViewFormatTranslateParams: TranslateParams;
42
- export { monthInfo, weekdaysNames, monthsNames, formatLocaleDate, ViewFormatTranslateParams };
43
+ /**
44
+ * convert internal Cell to CellModel
45
+ * avoid introducing breaking changes to the API
46
+ * @param cell Cell
47
+ * @returns CellModel
48
+ */
49
+ declare const toCalendarCell: (cell: Cell) => CalendarCell;
50
+ export { monthInfo, weekdaysNames, monthsNames, formatLocaleDate, toCalendarCell, ViewFormatTranslateParams };
@@ -117,4 +117,27 @@ const ViewFormatTranslateParams = {
117
117
  },
118
118
  formats: DateMessageFormats
119
119
  };
120
- export { monthInfo, weekdaysNames, monthsNames, formatLocaleDate, ViewFormatTranslateParams };
120
+ /**
121
+ * convert internal Cell to CellModel
122
+ * avoid introducing breaking changes to the API
123
+ * @param cell Cell
124
+ * @returns CellModel
125
+ */
126
+ const toCalendarCell = (cell) => {
127
+ return {
128
+ ...cell,
129
+ active: cell.active || false,
130
+ disabled: cell.disabled || false,
131
+ firstDate: cell.firstDate || false,
132
+ idle: cell.idle || false,
133
+ lastDate: cell.lastDate || false,
134
+ now: cell.now || false,
135
+ range: cell.range || false,
136
+ rangeFrom: cell.rangeFrom || false,
137
+ rangeTo: cell.rangeTo || false,
138
+ selected: cell.selected || false,
139
+ text: cell.text ?? '',
140
+ value: cell.value ?? ''
141
+ };
142
+ };
143
+ export { monthInfo, weekdaysNames, monthsNames, formatLocaleDate, toCalendarCell, ViewFormatTranslateParams };
@@ -288,9 +288,11 @@ let ComboBox = class ComboBox extends FormFieldElement {
288
288
  * @returns {void}
289
289
  */
290
290
  updateComposerValues(newValues) {
291
+ const selectedAt = Date.now();
291
292
  this.queryItems((item, composer) => {
292
293
  if (newValues.includes(composer.getItemPropertyValue(item, 'value'))) {
293
294
  composer.setItemPropertyValue(item, 'selected', true);
295
+ composer.setItemPropertyValue(item, 'selectedAt', selectedAt + newValues.indexOf(item.value ?? '')); // Sequential selection
294
296
  return true;
295
297
  }
296
298
  composer.setItemPropertyValue(item, 'selected', false);
@@ -980,6 +980,7 @@ let InteractiveChart = InteractiveChart_1 = class InteractiveChart extends Respo
980
980
  const dataSet = series.data || [];
981
981
  const latestData = dataSet[dataSet.length - 1];
982
982
  if (latestData) {
983
+ this.hasDataPoint = dataSet.length > 0;
983
984
  const value = chartType === 'bar' || chartType === 'candlestick' ? latestData : latestData.value; // latestData
984
985
  const priceColor = this.getColorInSeries(latestData, chartType, idx);
985
986
  // Render legend by series type
@@ -177,7 +177,7 @@
177
177
  },
178
178
  {
179
179
  "name": "input",
180
- "description": "Fired when the user inputs a value by interacting with the slider or updating its input field."
180
+ "description": "Fired with the value of the input in `e.detail.value` like another custom events when the user inputs a value by interacting with the slider or updating its input field."
181
181
  },
182
182
  {
183
183
  "name": "from-input",
@@ -25,7 +25,7 @@ Allows users to make selections from a range of values
25
25
  |-----------------|--------------------------------------------------|
26
26
  | `from-changed` | Fired when the user changes from's value. The event is not triggered if `from` property is changed programmatically. |
27
27
  | `from-input` | Fired when the user inputs from's value by interacting with the slider or updating its input field. |
28
- | `input` | Fired when the user inputs a value by interacting with the slider or updating its input field. |
28
+ | `input` | Fired with the value of the input in `e.detail.value` like another custom events when the user inputs a value by interacting with the slider or updating its input field. |
29
29
  | `to-changed` | Fired when the user changes to's value. The event is not triggered if `to` property is changed programmatically. |
30
30
  | `to-input` | Fired when the user inputs to's value by interacting with the slider or updating its input field. |
31
31
  | `value-changed` | Fired when the user commits a value change. The event is not triggered if `value` property is changed programmatically. |
@@ -18,7 +18,7 @@ import '../number-field/index.js';
18
18
  * @fires value-changed - Fired when the user commits a value change. The event is not triggered if `value` property is changed programmatically.
19
19
  * @fires from-changed - Fired when the user changes from's value. The event is not triggered if `from` property is changed programmatically.
20
20
  * @fires to-changed - Fired when the user changes to's value. The event is not triggered if `to` property is changed programmatically.
21
- * @fires input - Fired when the user inputs a value by interacting with the slider or updating its input field.
21
+ * @fires input - Fired with the value of the input in `e.detail.value` like another custom events when the user inputs a value by interacting with the slider or updating its input field.
22
22
  * @fires from-input - Fired when the user inputs from's value by interacting with the slider or updating its input field.
23
23
  * @fires to-input - Fired when the user inputs to's value by interacting with the slider or updating its input field.
24
24
  */
@@ -341,6 +341,11 @@ export declare class Slider extends ControlElement {
341
341
  * @returns validated to value.
342
342
  */
343
343
  private validateTo;
344
+ /**
345
+ * Validate number field from changed thumb
346
+ * @returns {void}
347
+ */
348
+ private validateNumberField;
344
349
  /**
345
350
  * Calculate the nearest possible step value depending on step interval
346
351
  * @param thumbPosition current thumb position in fraction
@@ -27,7 +27,7 @@ import { clamp, countDecimalPlace, isDecimalNumber, preventDefault } from './uti
27
27
  * @fires value-changed - Fired when the user commits a value change. The event is not triggered if `value` property is changed programmatically.
28
28
  * @fires from-changed - Fired when the user changes from's value. The event is not triggered if `from` property is changed programmatically.
29
29
  * @fires to-changed - Fired when the user changes to's value. The event is not triggered if `to` property is changed programmatically.
30
- * @fires input - Fired when the user inputs a value by interacting with the slider or updating its input field.
30
+ * @fires input - Fired with the value of the input in `e.detail.value` like another custom events when the user inputs a value by interacting with the slider or updating its input field.
31
31
  * @fires from-input - Fired when the user inputs from's value by interacting with the slider or updating its input field.
32
32
  * @fires to-input - Fired when the user inputs to's value by interacting with the slider or updating its input field.
33
33
  */
@@ -766,6 +766,7 @@ let Slider = class Slider extends ControlElement {
766
766
  this.valuePreviousInput = this.value;
767
767
  }
768
768
  this.onDrag(event);
769
+ this.validateNumberField();
769
770
  if (event.changedTouches) {
770
771
  this.addEventListener('touchmove', this.onDrag);
771
772
  this.addEventListener('touchend', this.onDragEnd);
@@ -859,6 +860,17 @@ let Slider = class Slider extends ControlElement {
859
860
  }
860
861
  return this.fromNumber + this.minRangeNumber;
861
862
  }
863
+ /**
864
+ * Validate number field from changed thumb
865
+ * @returns {void}
866
+ */
867
+ validateNumberField() {
868
+ if (this.isShowInputField) {
869
+ const name = this.changedThumb?.getAttribute('name');
870
+ const numberField = this[`${name}Input`];
871
+ requestAnimationFrame(() => numberField.reportValidity());
872
+ }
873
+ }
862
874
  /**
863
875
  * Calculate the nearest possible step value depending on step interval
864
876
  * @param thumbPosition current thumb position in fraction
@@ -1000,7 +1012,7 @@ let Slider = class Slider extends ControlElement {
1000
1012
  if (valueFor === SliderDataName.to && value < this.fromNumber + this.minRangeNumber) {
1001
1013
  return false;
1002
1014
  }
1003
- else if (value > this.toNumber - this.minRangeNumber) {
1015
+ else if (valueFor === SliderDataName.from && value > this.toNumber - this.minRangeNumber) {
1004
1016
  return false;
1005
1017
  }
1006
1018
  }
@@ -376,7 +376,7 @@ let Tree = class Tree extends List {
376
376
  */
377
377
  get values() {
378
378
  return this.manager.checkedItems.map((item) => {
379
- return this.composer.getItemPropertyValue(item, 'value') || '';
379
+ return this.composer.getItemPropertyValue(item, 'value') ?? '';
380
380
  });
381
381
  }
382
382
  set values(values) {
@@ -386,9 +386,9 @@ let Tree = class Tree extends List {
386
386
  }
387
387
  else {
388
388
  // Clone value arrays
389
- const newValue = [...values].sort().toString();
390
- const oldValue = [...this.values].sort().toString();
391
- if (newValue !== oldValue) {
389
+ const newValue = [...values];
390
+ const oldValue = [...this.values];
391
+ if (newValue.toString() !== oldValue.toString()) {
392
392
  this.manager.uncheckAllItems();
393
393
  values.some((value) => {
394
394
  this.queryItemsByPropertyValue('value', value).forEach((item) => {
@@ -24,6 +24,10 @@ export declare class TreeManager<T extends TreeDataItem> {
24
24
  * Mode (algorithm) the tree manage is using
25
25
  */
26
26
  private mode;
27
+ /**
28
+ * Last selected item timestamp
29
+ */
30
+ private lastSelectedAt?;
27
31
  constructor(composer: CollectionComposer<T>, mode?: TreeManagerMode);
28
32
  /**
29
33
  * Is the manager maintaining parent/child relationships
@@ -42,6 +46,10 @@ export declare class TreeManager<T extends TreeDataItem> {
42
46
  * When managing relationships, this excludes groups/parents from the result.
43
47
  */
44
48
  get checkedItems(): readonly T[];
49
+ /**
50
+ * Compare items function order by sequential selected timestamp
51
+ */
52
+ protected get orderBySelectedAt(): (itemA: T, itemB: T) => number;
45
53
  /**
46
54
  * Items which should be visibly displayed.
47
55
  * This can be used to render items.
@@ -47,12 +47,24 @@ export class TreeManager {
47
47
  * When managing relationships, this excludes groups/parents from the result.
48
48
  */
49
49
  get checkedItems() {
50
- return this.composer.queryItems((item) => {
50
+ const items = this.composer.queryItems((item) => {
51
51
  if (this.manageRelationships && this.isItemParent(item)) {
52
52
  return false;
53
53
  }
54
54
  return this.isItemChecked(item);
55
55
  }, Infinity);
56
+ return Object.freeze(items.slice().sort(this.orderBySelectedAt));
57
+ }
58
+ /**
59
+ * Compare items function order by sequential selected timestamp
60
+ */
61
+ get orderBySelectedAt() {
62
+ // Order by sequential selected timestamp
63
+ return (itemA, itemB) => {
64
+ const timeA = this.composer.getItemPropertyValue(itemA, 'selectedAt') ?? 0;
65
+ const timeB = this.composer.getItemPropertyValue(itemB, 'selectedAt') ?? 0;
66
+ return timeA - timeB;
67
+ };
56
68
  }
57
69
  /**
58
70
  * Items which should be visibly displayed.
@@ -341,7 +353,13 @@ export class TreeManager {
341
353
  }
342
354
  _checkItem(item, manageRelationships = this.manageRelationships) {
343
355
  if (this.canCheckItem(item)) {
356
+ // Create unique timestamp base on the latest selection for sequential selection.
357
+ const timestamp = Date.now();
358
+ this.lastSelectedAt =
359
+ this.lastSelectedAt && this.lastSelectedAt >= timestamp ? this.lastSelectedAt + 1 : timestamp;
360
+ // Set item selected with timestamp
344
361
  this.composer.setItemPropertyValue(item, 'selected', true);
362
+ this.composer.setItemPropertyValue(item, 'selectedAt', this.lastSelectedAt);
345
363
  if (manageRelationships) {
346
364
  this.forceUpdateOnPath(item);
347
365
  this.getItemDescendants(item).forEach((descendant) => this._checkItem(descendant, false));
@@ -59,7 +59,11 @@ export declare class TreeSelect extends ComboBox<TreeSelectDataItem> {
59
59
  /**
60
60
  * Extracted values from {@link this.checkedGroupedItems}
61
61
  */
62
- protected pillsData: TreeSelectDataItem[];
62
+ protected pillsData: Readonly<TreeSelectDataItem[]>;
63
+ /**
64
+ * Cache old selection timestamps for revert selected timestamps when cancel selection
65
+ */
66
+ protected oldSelection: Map<string, number | undefined>;
63
67
  /**
64
68
  * Are there pills visible
65
69
  */
@@ -207,10 +211,15 @@ export declare class TreeSelect extends ComboBox<TreeSelectDataItem> {
207
211
  */
208
212
  protected persistSelection(): void;
209
213
  /**
210
- * Reverse selection. Run on Esc or Cancel
214
+ * Revert modified selection to old values. Run on Esc or Cancel
215
+ * @returns {void}
216
+ */
217
+ protected revertModifiedSelection(): void;
218
+ /**
219
+ * Revert all selected timestamps to the previous state which affect to item sorting
211
220
  * @returns {void}
212
221
  */
213
- protected cancelSelection(): void;
222
+ protected revertSelectionTimestamps(): void;
214
223
  /**
215
224
  * Update memoized track
216
225
  *
@@ -1,5 +1,5 @@
1
1
  import { __decorate } from "tslib";
2
- import { css, html, nothing, triggerResize } from '@refinitiv-ui/core';
2
+ import { WarningNotice, css, html, nothing, triggerResize } 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 { query } from '@refinitiv-ui/core/decorators/query.js';
@@ -21,6 +21,7 @@ import { VERSION } from '../version.js';
21
21
  export { TreeSelectRenderer };
22
22
  const MEMO_THROTTLE = 16;
23
23
  const POPUP_POSITION = ['bottom-start', 'top-start'];
24
+ const valueFormatWarning = new WarningNotice("The specified 'values' format does not conform to the required format.");
24
25
  /**
25
26
  * Dropdown control that allows selection from the tree list
26
27
  *
@@ -65,6 +66,10 @@ let TreeSelect = class TreeSelect extends ComboBox {
65
66
  * Extracted values from {@link this.checkedGroupedItems}
66
67
  */
67
68
  this.pillsData = [];
69
+ /**
70
+ * Cache old selection timestamps for revert selected timestamps when cancel selection
71
+ */
72
+ this.oldSelection = new Map();
68
73
  /**
69
74
  * Are there pills visible
70
75
  */
@@ -165,8 +170,26 @@ let TreeSelect = class TreeSelect extends ComboBox {
165
170
  return this._values;
166
171
  }
167
172
  set values(values) {
168
- super.values = values;
169
- this._values = values;
173
+ if (!Array.isArray(values)) {
174
+ valueFormatWarning.show();
175
+ this.values = [];
176
+ return;
177
+ }
178
+ // Update the selection state when found new value
179
+ const newValues = values.slice(0, this.multiple ? values.length : 1);
180
+ const oldValues = this.values.slice();
181
+ if (newValues.toString() !== oldValues.toString()) {
182
+ this._values = values;
183
+ this.updateComposerValues(values);
184
+ this.updatePills();
185
+ if (this.freeText) {
186
+ // free text mode is only supported in single selection mode
187
+ // so if there is no valid selection in the composer, we can assume
188
+ // the first item can be used as the free text item.
189
+ this.freeTextValue = !this.composerValues.length ? newValues[0] : '';
190
+ }
191
+ this.requestUpdate('values', oldValues);
192
+ }
170
193
  }
171
194
  /**
172
195
  * Set maximum number of selected items
@@ -228,7 +251,7 @@ let TreeSelect = class TreeSelect extends ComboBox {
228
251
  * @override
229
252
  */
230
253
  get selectedLabels() {
231
- return this.checkedGroupedItems.map((selected) => this.getItemPropertyValue(selected, 'label') || '');
254
+ return this.checkedGroupedItems.map((selected) => this.getItemPropertyValue(selected, 'label') ?? '');
232
255
  }
233
256
  /**
234
257
  * Returns memoized selected state
@@ -332,29 +355,37 @@ let TreeSelect = class TreeSelect extends ComboBox {
332
355
  * @returns {void}
333
356
  */
334
357
  persistSelection() {
335
- const oldValues = this.values.slice();
358
+ const oldValues = this.values;
336
359
  const newValues = this.composerValues;
337
- const oldComparison = oldValues.sort().toString();
338
- const newComparison = newValues.sort().toString();
339
- if (oldComparison !== newComparison) {
360
+ if (oldValues.toString() !== newValues.toString()) {
361
+ // Set new values order by sequential selection
340
362
  this.values = newValues;
341
363
  this.notifyPropertyChange('value', this.value);
342
364
  }
343
365
  }
344
366
  /**
345
- * Reverse selection. Run on Esc or Cancel
367
+ * Revert modified selection to old values. Run on Esc or Cancel
346
368
  * @returns {void}
347
369
  */
348
- cancelSelection() {
349
- const oldValues = this.values.slice();
370
+ revertModifiedSelection() {
371
+ const oldValues = this.values;
350
372
  const newValues = this.composerValues;
351
- const oldComparison = oldValues.sort().toString();
352
- const newComparison = newValues.sort().toString();
353
- if (oldComparison !== newComparison) {
354
- // revert selected item by updating the collection composer
355
- this.updateComposerValues(this._values);
373
+ if (oldValues.toString() !== newValues.toString()) {
374
+ // Revert selected item by updating the collection composer
375
+ this.updateComposerValues(oldValues);
356
376
  }
357
377
  }
378
+ /**
379
+ * Revert all selected timestamps to the previous state which affect to item sorting
380
+ * @returns {void}
381
+ */
382
+ revertSelectionTimestamps() {
383
+ this.selection.forEach((item) => {
384
+ const oldSelectedAt = this.oldSelection.get(item.value);
385
+ this.composer.setItemPropertyValue(item, 'selectedAt', oldSelectedAt);
386
+ });
387
+ this.oldSelection.clear(); // Clear cache old selection
388
+ }
358
389
  /**
359
390
  * Update memoized track
360
391
  *
@@ -419,6 +450,7 @@ let TreeSelect = class TreeSelect extends ComboBox {
419
450
  const event = new CustomEvent('cancel');
420
451
  this.dispatchEvent(event);
421
452
  if (!event.defaultPrevented) {
453
+ this.revertSelectionTimestamps();
422
454
  this.closeAndReset();
423
455
  // reset always happens on popup close action
424
456
  }
@@ -487,6 +519,10 @@ let TreeSelect = class TreeSelect extends ComboBox {
487
519
  onPopupOpened() {
488
520
  super.onPopupOpened();
489
521
  this.clearSelectionFilter();
522
+ // Cache current selection timestamps for reverting modified selection when user cancel
523
+ this.selection.forEach((item) => {
524
+ this.oldSelection.set(item.value, this.getItemPropertyValue(item, 'selectedAt'));
525
+ });
490
526
  this.updatePills();
491
527
  this.updateMemo();
492
528
  }
@@ -503,9 +539,8 @@ let TreeSelect = class TreeSelect extends ComboBox {
503
539
  */
504
540
  onPopupClosed() {
505
541
  super.onPopupClosed();
506
- this.updateMemo();
507
- this.cancelSelection();
508
- this.exitEditSelection();
542
+ this.exitEditSelection(); // selection filter should be removed before reverting modified selection
543
+ this.revertModifiedSelection();
509
544
  }
510
545
  /**
511
546
  * Filter the internal items by query. Changes items' hidden state.
@@ -731,7 +766,7 @@ let TreeSelect = class TreeSelect extends ComboBox {
731
766
  */
732
767
  updatePills() {
733
768
  if (this.showPills) {
734
- this.pillsData = this.checkedGroupedItems.slice();
769
+ this.pillsData = this.checkedGroupedItems;
735
770
  this.hasPills = !!this.pillsData.length;
736
771
  }
737
772
  }
package/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '6.11.0';
1
+ export const VERSION = '6.13.0';
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@refinitiv-ui/elements",
3
- "version": "6.11.0",
3
+ "version": "6.13.0",
4
4
  "description": "Element Framework Elements",
5
- "author": "Refinitiv",
5
+ "author": "LSEG",
6
6
  "license": "Apache-2.0",
7
7
  "main": "./lib/index.js",
8
8
  "module": "./lib/index.js",
@@ -339,8 +339,8 @@
339
339
  },
340
340
  "dependencies": {
341
341
  "@lit-labs/context": "^0.3.1",
342
- "@refinitiv-ui/halo-theme": "^6.6.0",
343
- "@refinitiv-ui/solar-theme": "^6.4.0",
342
+ "@refinitiv-ui/halo-theme": "^6.6.1",
343
+ "@refinitiv-ui/solar-theme": "^6.4.1",
344
344
  "@types/chart.js": "^2.9.31",
345
345
  "chart.js": "~2.9.4",
346
346
  "d3-interpolate": "^3.0.1",
@@ -349,25 +349,25 @@
349
349
  "tslib": "^2.3.1"
350
350
  },
351
351
  "devDependencies": {
352
- "@refinitiv-ui/core": "^6.5.0",
353
- "@refinitiv-ui/demo-block": "^6.1.11",
354
- "@refinitiv-ui/i18n": "^6.0.17",
355
- "@refinitiv-ui/phrasebook": "^6.3.6",
356
- "@refinitiv-ui/test-helpers": "^6.0.14",
357
- "@refinitiv-ui/translate": "^6.0.26",
358
- "@refinitiv-ui/utils": "^6.2.9",
352
+ "@refinitiv-ui/core": "^6.5.1",
353
+ "@refinitiv-ui/demo-block": "^6.1.12",
354
+ "@refinitiv-ui/i18n": "^6.0.18",
355
+ "@refinitiv-ui/phrasebook": "^6.3.7",
356
+ "@refinitiv-ui/test-helpers": "^6.0.15",
357
+ "@refinitiv-ui/translate": "^6.0.27",
358
+ "@refinitiv-ui/utils": "^6.3.0",
359
359
  "@types/d3-interpolate": "^3.0.1"
360
360
  },
361
361
  "peerDependencies": {
362
362
  "@refinitiv-ui/browser-sparkline": "^1.0.0 || ^2.0.0",
363
- "@refinitiv-ui/core": "^6.5.0",
364
- "@refinitiv-ui/i18n": "^6.0.17",
365
- "@refinitiv-ui/phrasebook": "^6.3.6",
366
- "@refinitiv-ui/translate": "^6.0.26",
367
- "@refinitiv-ui/utils": "^6.2.9"
363
+ "@refinitiv-ui/core": "^6.5.1",
364
+ "@refinitiv-ui/i18n": "^6.0.18",
365
+ "@refinitiv-ui/phrasebook": "^6.3.7",
366
+ "@refinitiv-ui/translate": "^6.0.27",
367
+ "@refinitiv-ui/utils": "^6.3.0"
368
368
  },
369
369
  "publishConfig": {
370
370
  "access": "public"
371
371
  },
372
- "gitHead": "fc7e8d1a792bc0f33ccf70360397abb37f1e4e3a"
372
+ "gitHead": "55ebf6e2b7bc388fe8cbc4fb48e16314af3942cb"
373
373
  }