@refinitiv-ui/elements 5.12.2 → 6.0.0-next.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 (160) hide show
  1. package/README.md +4 -4
  2. package/lib/accordion/index.js +2 -2
  3. package/lib/appstate-bar/index.d.ts +6 -0
  4. package/lib/appstate-bar/index.js +8 -3
  5. package/lib/autosuggest/index.js +10 -11
  6. package/lib/button/index.d.ts +2 -13
  7. package/lib/button/index.js +7 -42
  8. package/lib/button-bar/index.js +4 -5
  9. package/lib/calendar/constants.js +1 -1
  10. package/lib/calendar/index.d.ts +1 -1
  11. package/lib/calendar/index.js +39 -15
  12. package/lib/calendar/locales.js +5 -5
  13. package/lib/calendar/types.d.ts +1 -1
  14. package/lib/calendar/utils.js +5 -5
  15. package/lib/canvas/index.js +3 -4
  16. package/lib/card/index.js +6 -7
  17. package/lib/chart/index.js +18 -22
  18. package/lib/chart/plugins/doughnut-center-label.js +6 -11
  19. package/lib/checkbox/index.js +3 -3
  20. package/lib/clock/index.js +6 -6
  21. package/lib/clock/utils/TickManager.js +2 -2
  22. package/lib/collapse/index.js +7 -9
  23. package/lib/color-dialog/elements/color-palettes.js +1 -1
  24. package/lib/color-dialog/elements/grayscale-palettes.js +2 -2
  25. package/lib/color-dialog/elements/palettes.js +4 -5
  26. package/lib/color-dialog/helpers/value-model.js +1 -1
  27. package/lib/color-dialog/index.d.ts +1 -1
  28. package/lib/color-dialog/index.js +6 -6
  29. package/lib/combo-box/helpers/filter.d.ts +1 -1
  30. package/lib/combo-box/helpers/types.d.ts +1 -1
  31. package/lib/combo-box/index.d.ts +4 -4
  32. package/lib/combo-box/index.js +31 -14
  33. package/lib/counter/index.d.ts +6 -6
  34. package/lib/counter/index.js +8 -8
  35. package/lib/datetime-field/constants.d.ts +4 -0
  36. package/lib/datetime-field/constants.js +5 -0
  37. package/lib/datetime-field/custom-elements.json +345 -0
  38. package/lib/datetime-field/custom-elements.md +61 -0
  39. package/lib/datetime-field/index.d.ts +317 -0
  40. package/lib/datetime-field/index.js +660 -0
  41. package/lib/datetime-field/themes/halo/dark/index.js +3 -0
  42. package/lib/datetime-field/themes/halo/light/index.js +3 -0
  43. package/lib/datetime-field/themes/solar/charcoal/index.js +3 -0
  44. package/lib/datetime-field/themes/solar/pearl/index.js +3 -0
  45. package/lib/datetime-field/types.d.ts +10 -0
  46. package/lib/datetime-field/types.js +1 -0
  47. package/lib/datetime-field/utils.d.ts +25 -0
  48. package/lib/datetime-field/utils.js +79 -0
  49. package/lib/datetime-picker/index.js +6 -7
  50. package/lib/datetime-picker/utils.js +1 -1
  51. package/lib/dialog/draggable-element.js +1 -2
  52. package/lib/dialog/index.d.ts +1 -1
  53. package/lib/dialog/index.js +5 -5
  54. package/lib/email-field/index.d.ts +1 -1
  55. package/lib/email-field/index.js +8 -3
  56. package/lib/flag/index.js +3 -3
  57. package/lib/flag/utils/FlagLoader.d.ts +1 -1
  58. package/lib/flag/utils/FlagLoader.js +1 -1
  59. package/lib/header/index.js +2 -2
  60. package/lib/heatmap/helpers/color.d.ts +1 -1
  61. package/lib/heatmap/helpers/color.js +3 -5
  62. package/lib/heatmap/index.js +19 -28
  63. package/lib/icon/index.js +3 -3
  64. package/lib/icon/utils/IconLoader.d.ts +1 -1
  65. package/lib/icon/utils/IconLoader.js +1 -1
  66. package/lib/interactive-chart/helpers/types.d.ts +1 -1
  67. package/lib/interactive-chart/index.js +10 -14
  68. package/lib/item/helpers/types.d.ts +1 -1
  69. package/lib/item/index.d.ts +19 -17
  70. package/lib/item/index.js +45 -48
  71. package/lib/label/index.d.ts +1 -1
  72. package/lib/label/index.js +6 -6
  73. package/lib/layout/index.js +2 -2
  74. package/lib/led-gauge/index.js +2 -2
  75. package/lib/list/custom-elements.json +0 -13
  76. package/lib/list/custom-elements.md +9 -10
  77. package/lib/list/helpers/item-id.d.ts +8 -0
  78. package/lib/list/helpers/item-id.js +13 -0
  79. package/lib/list/helpers/{list-renderer.d.ts → renderer.d.ts} +4 -0
  80. package/lib/list/helpers/{list-renderer.js → renderer.js} +8 -0
  81. package/lib/list/helpers/types.d.ts +1 -1
  82. package/lib/list/index.d.ts +13 -12
  83. package/lib/list/index.js +30 -29
  84. package/lib/list/renderer.d.ts +1 -1
  85. package/lib/list/themes/halo/dark/index.js +1 -1
  86. package/lib/list/themes/halo/light/index.js +1 -1
  87. package/lib/list/themes/solar/charcoal/index.js +1 -1
  88. package/lib/list/themes/solar/pearl/index.js +1 -1
  89. package/lib/loader/index.js +1 -1
  90. package/lib/multi-input/helpers/types.d.ts +1 -1
  91. package/lib/multi-input/index.js +6 -7
  92. package/lib/notification/elements/notification-tray.js +4 -4
  93. package/lib/notification/elements/notification.d.ts +10 -0
  94. package/lib/notification/elements/notification.js +12 -3
  95. package/lib/number-field/index.d.ts +3 -3
  96. package/lib/number-field/index.js +14 -4
  97. package/lib/overlay/elements/overlay-backdrop.js +2 -2
  98. package/lib/overlay/elements/overlay-viewport.js +1 -1
  99. package/lib/overlay/elements/overlay.js +7 -5
  100. package/lib/overlay/managers/focus-manager.js +2 -3
  101. package/lib/overlay/managers/interaction-lock-manager.js +1 -1
  102. package/lib/overlay/managers/viewport-manager.js +4 -5
  103. package/lib/overlay/managers/zindex-manager.js +1 -1
  104. package/lib/overlay-menu/helpers/types.d.ts +1 -1
  105. package/lib/overlay-menu/index.js +12 -15
  106. package/lib/overlay-menu/managers/menu-manager.js +1 -1
  107. package/lib/pagination/index.d.ts +74 -91
  108. package/lib/pagination/index.js +205 -239
  109. package/lib/pagination/themes/halo/dark/index.js +1 -2
  110. package/lib/pagination/themes/halo/light/index.js +1 -2
  111. package/lib/pagination/themes/solar/charcoal/index.js +1 -2
  112. package/lib/pagination/themes/solar/pearl/index.js +1 -2
  113. package/lib/panel/index.js +2 -2
  114. package/lib/password-field/index.d.ts +2 -2
  115. package/lib/password-field/index.js +7 -4
  116. package/lib/pill/index.d.ts +16 -0
  117. package/lib/pill/index.js +36 -5
  118. package/lib/pill/themes/halo/dark/index.js +1 -1
  119. package/lib/pill/themes/halo/light/index.js +1 -1
  120. package/lib/pill/themes/solar/charcoal/index.js +1 -1
  121. package/lib/pill/themes/solar/pearl/index.js +1 -1
  122. package/lib/progress-bar/index.js +3 -3
  123. package/lib/radio-button/index.js +3 -3
  124. package/lib/radio-button/radio-button-registry.d.ts +1 -1
  125. package/lib/radio-button/radio-button-registry.js +4 -2
  126. package/lib/rating/index.js +4 -4
  127. package/lib/search-field/index.d.ts +2 -2
  128. package/lib/search-field/index.js +8 -4
  129. package/lib/select/index.js +11 -14
  130. package/lib/sidebar-layout/index.js +4 -4
  131. package/lib/slider/index.js +6 -8
  132. package/lib/sparkline/index.js +9 -10
  133. package/lib/swing-gauge/index.js +14 -8
  134. package/lib/tab/index.js +4 -4
  135. package/lib/tab-bar/index.js +6 -6
  136. package/lib/text-field/index.d.ts +14 -1
  137. package/lib/text-field/index.js +35 -11
  138. package/lib/time-picker/index.d.ts +1 -1
  139. package/lib/time-picker/index.js +11 -11
  140. package/lib/toggle/index.js +2 -2
  141. package/lib/tooltip/index.js +6 -8
  142. package/lib/tooltip/managers/tooltip-manager.js +2 -2
  143. package/lib/tornado-chart/elements/tornado-chart.js +2 -2
  144. package/lib/tornado-chart/elements/tornado-item.js +3 -3
  145. package/lib/tree/elements/tree-item.d.ts +3 -3
  146. package/lib/tree/elements/tree-item.js +5 -6
  147. package/lib/tree/elements/tree.d.ts +2 -3
  148. package/lib/tree/elements/tree.js +6 -7
  149. package/lib/tree/helpers/renderer.d.ts +4 -0
  150. package/lib/tree/helpers/renderer.js +8 -0
  151. package/lib/tree/helpers/types.d.ts +1 -1
  152. package/lib/tree/managers/tree-manager.d.ts +1 -1
  153. package/lib/tree/themes/halo/dark/index.js +1 -1
  154. package/lib/tree/themes/halo/light/index.js +1 -1
  155. package/lib/tree/themes/solar/charcoal/index.js +1 -1
  156. package/lib/tree/themes/solar/pearl/index.js +1 -1
  157. package/lib/tree-select/index.d.ts +3 -7
  158. package/lib/tree-select/index.js +39 -38
  159. package/lib/version.js +1 -1
  160. package/package.json +35 -295
@@ -44,19 +44,10 @@ export declare class Item extends ControlElement {
44
44
  * Set the icon name from the ef-icon list
45
45
  */
46
46
  icon: string | null;
47
- private _selected;
48
47
  /**
49
48
  * Indicates that the item is selected
50
- * @param value selected value
51
- * @default false
52
49
  */
53
- set selected(value: boolean);
54
- get selected(): boolean;
55
- /**
56
- * Aria indicating current select state
57
- * @ignore
58
- */
59
- ariaSelected: string;
50
+ selected: boolean;
60
51
  /**
61
52
  * Is the item part of a multiple selection
62
53
  */
@@ -93,10 +84,26 @@ export declare class Item extends ControlElement {
93
84
  */
94
85
  private checkSlotChildren;
95
86
  /**
96
- * @override
87
+ * Handles aria-selected or aria-checked when toggle between single and multiple selection mode
88
+ * @returns {void}
89
+ **/
90
+ private multipleChanged;
91
+ /**
92
+ * Handles aria when selected state changes
97
93
  * @returns {void}
98
94
  */
99
- protected update(changedProperties: PropertyValues): void;
95
+ private selectedChanged;
96
+ /**
97
+ * Control State behaviour will update tabindex based on the property
98
+ * @returns {void}
99
+ */
100
+ private typeChanged;
101
+ /**
102
+ * Invoked before update() to compute values needed during the update.
103
+ * @param changedProperties changed properties
104
+ * @returns {void}
105
+ */
106
+ protected willUpdate(changedProperties: PropertyValues): void;
100
107
  /**
101
108
  * Get icon template if icon attribute is defined
102
109
  */
@@ -131,11 +138,6 @@ export declare class Item extends ControlElement {
131
138
  * @returns whether element is truncated or not
132
139
  */
133
140
  get isTruncated(): boolean;
134
- /**
135
- * Control State behaviour will update tabindex based on the property
136
- * @returns {void}
137
- */
138
- private typeChanged;
139
141
  /**
140
142
  * A `TemplateResult` that will be used
141
143
  * to render the updated internal template.
package/lib/item/index.js CHANGED
@@ -1,17 +1,14 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { ControlElement, css, html } from '@refinitiv-ui/core';
3
- import { customElement } from '@refinitiv-ui/core/lib/decorators/custom-element.js';
4
- import { property } from '@refinitiv-ui/core/lib/decorators/property.js';
5
- import { query } from '@refinitiv-ui/core/lib/decorators/query.js';
3
+ import { customElement } from '@refinitiv-ui/core/decorators/custom-element.js';
4
+ import { property } from '@refinitiv-ui/core/decorators/property.js';
5
+ import { query } from '@refinitiv-ui/core/decorators/query.js';
6
6
  import { VERSION } from '../version.js';
7
7
  import '../icon/index.js';
8
8
  import '../checkbox/index.js';
9
9
  export * from './helpers/types';
10
- const isAllWhitespaceTextNode = (node) => {
11
- var _a;
12
- return node.nodeType === document.TEXT_NODE
13
- && !((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.trim());
14
- };
10
+ const isAllWhitespaceTextNode = (node) => node.nodeType === document.TEXT_NODE
11
+ && !node.textContent?.trim();
15
12
  /**
16
13
  * Used as a basic building block to compose complex custom elements,
17
14
  * additionally it can be used by applications
@@ -43,12 +40,10 @@ let Item = class Item extends ControlElement {
43
40
  * Set the icon name from the ef-icon list
44
41
  */
45
42
  this.icon = null;
46
- this._selected = false;
47
43
  /**
48
- * Aria indicating current select state
49
- * @ignore
44
+ * Indicates that the item is selected
50
45
  */
51
- this.ariaSelected = 'false';
46
+ this.selected = false;
52
47
  /**
53
48
  * Is the item part of a multiple selection
54
49
  */
@@ -114,22 +109,6 @@ let Item = class Item extends ControlElement {
114
109
  }
115
110
  `;
116
111
  }
117
- /**
118
- * Indicates that the item is selected
119
- * @param value selected value
120
- * @default false
121
- */
122
- set selected(value) {
123
- const oldValue = this._selected;
124
- if (oldValue !== value) {
125
- this._selected = value;
126
- this.ariaSelected = String(value);
127
- void this.requestUpdate('selected', oldValue);
128
- }
129
- }
130
- get selected() {
131
- return this._selected;
132
- }
133
112
  /**
134
113
  * @param node that should be checked
135
114
  * @returns whether node can be ignored.
@@ -139,14 +118,48 @@ let Item = class Item extends ControlElement {
139
118
  || isAllWhitespaceTextNode(node);
140
119
  }
141
120
  /**
142
- * @override
121
+ * Handles aria-selected or aria-checked when toggle between single and multiple selection mode
122
+ * @returns {void}
123
+ **/
124
+ multipleChanged() {
125
+ this.removeAttribute(this.multiple ? 'aria-selected' : 'aria-checked');
126
+ this.selectedChanged();
127
+ }
128
+ /**
129
+ * Handles aria when selected state changes
130
+ * @returns {void}
131
+ */
132
+ selectedChanged() {
133
+ this.setAttribute(this.multiple ? 'aria-checked' : 'aria-selected', String(this.selected));
134
+ }
135
+ /**
136
+ * Control State behaviour will update tabindex based on the property
137
+ * @returns {void}
138
+ */
139
+ typeChanged() {
140
+ const noInteraction = this.type === 'header' || this.type === 'divider' || this.disabled;
141
+ if (noInteraction) {
142
+ this.disableFocus();
143
+ }
144
+ else if (!this.disabled) {
145
+ this.enableFocus();
146
+ }
147
+ }
148
+ /**
149
+ * Invoked before update() to compute values needed during the update.
150
+ * @param changedProperties changed properties
143
151
  * @returns {void}
144
152
  */
145
- update(changedProperties) {
153
+ willUpdate(changedProperties) {
146
154
  if (changedProperties.has('type')) {
147
155
  this.typeChanged();
148
156
  }
149
- super.update(changedProperties);
157
+ if (changedProperties.has('multiple')) {
158
+ this.multipleChanged();
159
+ }
160
+ else if (changedProperties.has('selected')) {
161
+ this.selectedChanged();
162
+ }
150
163
  }
151
164
  /**
152
165
  * Get icon template if icon attribute is defined
@@ -197,19 +210,6 @@ let Item = class Item extends ControlElement {
197
210
  get isTruncated() {
198
211
  return !!(this.labelEl && (this.labelEl.offsetWidth < this.labelEl.scrollWidth));
199
212
  }
200
- /**
201
- * Control State behaviour will update tabindex based on the property
202
- * @returns {void}
203
- */
204
- typeChanged() {
205
- const noInteraction = this.type === 'header' || this.type === 'divider' || this.disabled;
206
- if (noInteraction) {
207
- this.disableFocus();
208
- }
209
- else if (!this.disabled) {
210
- this.enableFocus();
211
- }
212
- }
213
213
  /**
214
214
  * A `TemplateResult` that will be used
215
215
  * to render the updated internal template.
@@ -245,10 +245,7 @@ __decorate([
245
245
  ], Item.prototype, "icon", void 0);
246
246
  __decorate([
247
247
  property({ type: Boolean, reflect: true })
248
- ], Item.prototype, "selected", null);
249
- __decorate([
250
- property({ type: String, reflect: true, attribute: 'aria-selected' })
251
- ], Item.prototype, "ariaSelected", void 0);
248
+ ], Item.prototype, "selected", void 0);
252
249
  __decorate([
253
250
  property({ type: Boolean, reflect: true })
254
251
  ], Item.prototype, "multiple", void 0);
@@ -63,7 +63,7 @@ export declare class Label extends BasicElement {
63
63
  protected shouldShowTooltip(tooltipTarget: HTMLElement): boolean;
64
64
  /**
65
65
  * Handles any modifications to the internal HTML
66
- * @param [mutation=false] is the request from a mutation event?
66
+ * @param [mutation=false] is the request from a mutation event ? ( reserved for future used )
67
67
  * @returns {void}
68
68
  */
69
69
  protected recalculate(mutation?: boolean): void;
@@ -1,10 +1,10 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { BasicElement, html, css } from '@refinitiv-ui/core';
3
- import { customElement } from '@refinitiv-ui/core/lib/decorators/custom-element.js';
4
- import { property } from '@refinitiv-ui/core/lib/decorators/property.js';
5
- import { styleMap } from '@refinitiv-ui/core/lib/directives/style-map.js';
3
+ import { customElement } from '@refinitiv-ui/core/decorators/custom-element.js';
4
+ import { property } from '@refinitiv-ui/core/decorators/property.js';
5
+ import { styleMap } from '@refinitiv-ui/core/directives/style-map.js';
6
6
  import { VERSION } from '../version.js';
7
- import { isIE } from '@refinitiv-ui/utils/lib/browser.js';
7
+ import { isIE } from '@refinitiv-ui/utils/browser.js';
8
8
  import { addTooltipCondition, removeTooltipCondition } from '../tooltip/index.js';
9
9
  /**
10
10
  * Configuration object
@@ -149,11 +149,11 @@ let Label = class Label extends BasicElement {
149
149
  }
150
150
  /**
151
151
  * Handles any modifications to the internal HTML
152
- * @param [mutation=false] is the request from a mutation event?
152
+ * @param [mutation=false] is the request from a mutation event ? ( reserved for future used )
153
153
  * @returns {void}
154
154
  */
155
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
155
156
  recalculate(mutation = false) {
156
- mutation; // keeping here for future use
157
157
  const oldValue = this.text;
158
158
  const raw = this.textContent || '';
159
159
  this.chunks = raw.split(_).map(chunk => chunk.trim()).filter(chunk => chunk);
@@ -1,7 +1,7 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { ResponsiveElement, html, css } from '@refinitiv-ui/core';
3
- import { customElement } from '@refinitiv-ui/core/lib/decorators/custom-element.js';
4
- import { property } from '@refinitiv-ui/core/lib/decorators/property.js';
3
+ import { customElement } from '@refinitiv-ui/core/decorators/custom-element.js';
4
+ import { property } from '@refinitiv-ui/core/decorators/property.js';
5
5
  import { VERSION } from '../version.js';
6
6
  /**
7
7
  * Layout component for creating responsive applications and components
@@ -1,7 +1,7 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { BasicElement, html, css } from '@refinitiv-ui/core';
3
- import { customElement } from '@refinitiv-ui/core/lib/decorators/custom-element.js';
4
- import { property } from '@refinitiv-ui/core/lib/decorators/property.js';
3
+ import { customElement } from '@refinitiv-ui/core/decorators/custom-element.js';
4
+ import { property } from '@refinitiv-ui/core/decorators/property.js';
5
5
  import { VERSION } from '../version.js';
6
6
  import '../canvas/index.js';
7
7
  const ZERO_MAP = {
@@ -11,12 +11,6 @@
11
11
  "type": "boolean",
12
12
  "default": "false"
13
13
  },
14
- {
15
- "name": "aria-multiselectable",
16
- "description": "Aria indicating that list supports multiple selection",
17
- "type": "string",
18
- "default": "false"
19
- },
20
14
  {
21
15
  "name": "multiple",
22
16
  "description": "Allow multiple selections",
@@ -50,13 +44,6 @@
50
44
  "type": "boolean",
51
45
  "default": "false"
52
46
  },
53
- {
54
- "name": "ariaMultiselectable",
55
- "attribute": "aria-multiselectable",
56
- "description": "Aria indicating that list supports multiple selection",
57
- "type": "string",
58
- "default": "false"
59
- },
60
47
  {
61
48
  "name": "multiple",
62
49
  "attribute": "multiple",
@@ -4,16 +4,15 @@ Provides listing and immutable selection
4
4
 
5
5
  ## Properties
6
6
 
7
- | Property | Attribute | Type | Default | Description |
8
- |-----------------------------|------------------------|----------------|--------------------------|--------------------------------------------------|
9
- | `ariaMultiselectable` | `aria-multiselectable` | `string` | false | Aria indicating that list supports multiple selection |
10
- | `data` | | `ListData` | null | The data object, used to render the list. |
11
- | `delegatesFocus (readonly)` | | `false` | false | Element focus delegation.<br />Set to `false` and relies on native focusing. |
12
- | `multiple` | `multiple` | `boolean` | false | Allow multiple selections |
13
- | `renderer` | | `ListRenderer` | "new ListRenderer(this)" | Renderer used to render list item elements |
14
- | `stateless` | `stateless` | `boolean` | false | Disable selections |
15
- | `value` | `value` | `string` | "" | Returns the first selected item value.<br />Use `values` when multiple selection mode is enabled. |
16
- | `values` | | `string[]` | [] | Returns a values collection of the currently<br />selected item values |
7
+ | Property | Attribute | Type | Default | Description |
8
+ |-----------------------------|-------------|----------------|--------------------------|--------------------------------------------------|
9
+ | `data` | | `ListData` | null | The data object, used to render the list. |
10
+ | `delegatesFocus (readonly)` | | `false` | false | Element focus delegation.<br />Set to `false` and relies on native focusing. |
11
+ | `multiple` | `multiple` | `boolean` | false | Allow multiple selections |
12
+ | `renderer` | | `ListRenderer` | "new ListRenderer(this)" | Renderer used to render list item elements |
13
+ | `stateless` | `stateless` | `boolean` | false | Disable selections |
14
+ | `value` | `value` | `string` | "" | Returns the first selected item value.<br />Use `values` when multiple selection mode is enabled. |
15
+ | `values` | | `string[]` | [] | Returns a values collection of the currently<br />selected item values |
17
16
 
18
17
  ## Methods
19
18
 
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Combines prefix and a string to give unique item id used by aria-activedescendant
3
+ * @param prefix a unique randomly generated string
4
+ * @param value a string of valid item value
5
+ * @returns a unique item id
6
+ */
7
+ declare const getItemId: (prefix: string, value: string | undefined) => string;
8
+ export { getItemId };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Combines prefix and a string to give unique item id used by aria-activedescendant
3
+ * @param prefix a unique randomly generated string
4
+ * @param value a string of valid item value
5
+ * @returns a unique item id
6
+ */
7
+ const getItemId = (prefix, value) => {
8
+ if (!prefix || !value) {
9
+ return '';
10
+ }
11
+ return `${prefix}-${value}`;
12
+ };
13
+ export { getItemId };
@@ -5,5 +5,9 @@ import { Renderer } from '../renderer.js';
5
5
  * This is the default renderer for lists.
6
6
  */
7
7
  export declare class ListRenderer extends Renderer {
8
+ /**
9
+ * Renderer key prefix, used in combination with item value to give unique id to each item
10
+ */
11
+ key: string;
8
12
  constructor(context?: unknown);
9
13
  }
@@ -1,4 +1,6 @@
1
+ import { uuid } from '@refinitiv-ui/utils/uuid.js';
1
2
  import '../../item/index.js';
3
+ import { getItemId } from './item-id.js';
2
4
  import { Renderer } from '../renderer.js';
3
5
  /**
4
6
  * Renders list items as `ef-item` elements.
@@ -21,6 +23,7 @@ export class ListRenderer extends Renderer {
21
23
  el.label = composer.getItemPropertyValue(item, 'label');
22
24
  el.subLabel = composer.getItemPropertyValue(item, 'subLabel');
23
25
  el.value = composer.getItemPropertyValue(item, 'value');
26
+ el.id = getItemId(this.key, el.value);
24
27
  el.icon = composer.getItemPropertyValue(item, 'icon');
25
28
  el.highlighted = composer.getItemPropertyValue(item, 'highlighted') === true;
26
29
  el.selected = composer.getItemPropertyValue(item, 'selected') === true;
@@ -29,9 +32,14 @@ export class ListRenderer extends Renderer {
29
32
  el.type = composer.getItemPropertyValue(item, 'type');
30
33
  el.multiple = !!context && context.multiple === true;
31
34
  const itemRole = el.type === 'text' || !el.type ? 'option' : 'presentation';
35
+ el.tabIndex = -1;
32
36
  el.setAttribute('role', itemRole);
33
37
  tooltip ? el.setAttribute('title', tooltip) : el.removeAttribute('title');
34
38
  return el;
35
39
  });
40
+ /**
41
+ * Renderer key prefix, used in combination with item value to give unique id to each item
42
+ */
43
+ this.key = uuid();
36
44
  }
37
45
  }
@@ -1,3 +1,3 @@
1
- import type { CollectionComposer, DataItem } from '@refinitiv-ui/utils/lib/collection.js';
1
+ import type { CollectionComposer, DataItem } from '@refinitiv-ui/utils/collection.js';
2
2
  import type { ItemData } from '../../item';
3
3
  export declare type ListData<T extends DataItem = ItemData> = T[] | CollectionComposer<T> | null;
@@ -1,9 +1,9 @@
1
1
  import { JSXInterface } from '../jsx';
2
2
  import { ControlElement, CSSResultGroup, PropertyValues, TapEvent, TemplateResult } from '@refinitiv-ui/core';
3
- import { CollectionComposer, DataItem } from '@refinitiv-ui/utils/lib/collection.js';
3
+ import { CollectionComposer, DataItem } from '@refinitiv-ui/utils/collection.js';
4
4
  import type { ItemData } from '../item';
5
5
  import type { ListData } from './helpers/types';
6
- import { ListRenderer } from './helpers/list-renderer.js';
6
+ import { ListRenderer } from './helpers/renderer.js';
7
7
  import '../item/index.js';
8
8
  export type { ListData };
9
9
  export { ListRenderer };
@@ -48,10 +48,6 @@ export declare class List<T extends DataItem = ItemData> extends ControlElement
48
48
  * Composer used to query and modify item state.
49
49
  */
50
50
  protected composer: CollectionComposer<T>;
51
- /**
52
- * Use default `tabindex` so that items are priority focus targets
53
- */
54
- protected readonly defaultTabIndex: null;
55
51
  /**
56
52
  * Element focus delegation.
57
53
  * Set to `false` and relies on native focusing.
@@ -66,10 +62,6 @@ export declare class List<T extends DataItem = ItemData> extends ControlElement
66
62
  * Disable selections
67
63
  */
68
64
  stateless: boolean;
69
- /**
70
- * Aria indicating that list supports multiple selection
71
- */
72
- ariaMultiselectable: string;
73
65
  /**
74
66
  * Allow multiple selections
75
67
  */
@@ -280,9 +272,18 @@ export declare class List<T extends DataItem = ItemData> extends ControlElement
280
272
  * @returns {void}
281
273
  */
282
274
  protected renderLightDOM(): void;
275
+ /**
276
+ * Invoked when the element is first updated. Implement to perform one time work on the element after update.
277
+ * @param changeProperties changed properties
278
+ * @returns {void}
279
+ */
283
280
  protected firstUpdated(changeProperties: PropertyValues): void;
284
- protected update(changeProperties: PropertyValues): void;
285
- protected updated(changedProperties: PropertyValues): void;
281
+ /**
282
+ * Invoked before update() to compute values needed during the update.
283
+ * @param changeProperties changed properties
284
+ * @returns {void}
285
+ */
286
+ protected willUpdate(changeProperties: PropertyValues): void;
286
287
  /**
287
288
  * A `CSSResultGroup` that will be used
288
289
  * to style the host, slotted children
package/lib/list/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { ControlElement, css, html, WarningNotice } from '@refinitiv-ui/core';
3
- import { customElement } from '@refinitiv-ui/core/lib/decorators/custom-element.js';
4
- import { property } from '@refinitiv-ui/core/lib/decorators/property.js';
3
+ import { customElement } from '@refinitiv-ui/core/decorators/custom-element.js';
4
+ import { property } from '@refinitiv-ui/core/decorators/property.js';
5
5
  import { VERSION } from '../version.js';
6
- import { CollectionComposer } from '@refinitiv-ui/utils/lib/collection.js';
7
- import { ListRenderer } from './helpers/list-renderer.js';
6
+ import { CollectionComposer } from '@refinitiv-ui/utils/collection.js';
7
+ import { getItemId } from './helpers/item-id.js';
8
+ import { ListRenderer } from './helpers/renderer.js';
8
9
  import '../item/index.js';
9
10
  export { ListRenderer };
10
11
  /**
@@ -49,10 +50,6 @@ let List = class List extends ControlElement {
49
50
  * Composer used to query and modify item state.
50
51
  */
51
52
  this.composer = new CollectionComposer([]);
52
- /**
53
- * Use default `tabindex` so that items are priority focus targets
54
- */
55
- this.defaultTabIndex = null;
56
53
  /**
57
54
  * Element focus delegation.
58
55
  * Set to `false` and relies on native focusing.
@@ -67,10 +64,6 @@ let List = class List extends ControlElement {
67
64
  * Disable selections
68
65
  */
69
66
  this.stateless = false;
70
- /**
71
- * Aria indicating that list supports multiple selection
72
- */
73
- this.ariaMultiselectable = 'false';
74
67
  /**
75
68
  * Allow multiple selections
76
69
  */
@@ -209,7 +202,7 @@ let List = class List extends ControlElement {
209
202
  * @returns {void}
210
203
  */
211
204
  first() {
212
- const firstItem = this.itemMap.get(this.tabbableElements[0]);
205
+ const firstItem = this.itemMap.get(this.tabbableItems[0]);
213
206
  this.highlightItem(firstItem, true);
214
207
  }
215
208
  /**
@@ -217,7 +210,7 @@ let List = class List extends ControlElement {
217
210
  * @returns {void}
218
211
  */
219
212
  last() {
220
- const lastItem = this.itemMap.get(this.tabbableElements[this.tabbableElements.length - 1]);
213
+ const lastItem = this.itemMap.get(this.tabbableItems[this.tabbableItems.length - 1]);
221
214
  this.highlightItem(lastItem, true);
222
215
  }
223
216
  /**
@@ -300,11 +293,10 @@ let List = class List extends ControlElement {
300
293
  */
301
294
  highlightItem(item, scrollToItem = false) {
302
295
  if (item) {
303
- const elementToFocus = this.elementFromItem(item);
304
- const focus = this.activeElement && this.activeElement !== elementToFocus;
305
296
  this.clearHighlighted();
306
297
  this.composer.setItemPropertyValue(item, 'highlighted', true);
307
- focus && (elementToFocus === null || elementToFocus === void 0 ? void 0 : elementToFocus.focus({ preventScroll: true }));
298
+ const id = getItemId(this.renderer.key, item.value);
299
+ this.tabIndex >= 0 && id && this.setAttribute('aria-activedescendant', id);
308
300
  scrollToItem && this.scrollToItem(item);
309
301
  }
310
302
  }
@@ -312,8 +304,15 @@ let List = class List extends ControlElement {
312
304
  * Gets the available tabbable elements
313
305
  */
314
306
  get tabbableItems() {
315
- return Array.from(this.children)
316
- .filter((el) => el.tabIndex >= 0);
307
+ return Array.from(this.children).filter((el) => {
308
+ if (el instanceof HTMLElement) {
309
+ const role = el.getAttribute('role');
310
+ const isEnabled = !el.hasAttribute('disabled');
311
+ const isOption = role ? ['option', 'treeitem'].includes(role) : false;
312
+ return isOption && isEnabled;
313
+ }
314
+ return false;
315
+ });
317
316
  }
318
317
  /**
319
318
  * Returns the current focused element
@@ -443,6 +442,7 @@ let List = class List extends ControlElement {
443
442
  */
444
443
  onBlur() {
445
444
  this.clearHighlighted();
445
+ this.removeAttribute('aria-activedescendant');
446
446
  }
447
447
  /**
448
448
  * Tries to find a known item element,
@@ -564,6 +564,11 @@ let List = class List extends ControlElement {
564
564
  }
565
565
  });
566
566
  }
567
+ /**
568
+ * Invoked when the element is first updated. Implement to perform one time work on the element after update.
569
+ * @param changeProperties changed properties
570
+ * @returns {void}
571
+ */
567
572
  firstUpdated(changeProperties) {
568
573
  super.firstUpdated(changeProperties);
569
574
  this.addEventListener('keydown', this.onKeyDown);
@@ -573,15 +578,14 @@ let List = class List extends ControlElement {
573
578
  this.addEventListener('focusin', this.onFocus);
574
579
  this.addEventListener('focusout', this.onBlur);
575
580
  }
576
- update(changeProperties) {
581
+ /**
582
+ * Invoked before update() to compute values needed during the update.
583
+ * @param changeProperties changed properties
584
+ * @returns {void}
585
+ */
586
+ willUpdate(changeProperties) {
577
587
  if (changeProperties.has('multiple')) {
578
588
  this.renderTimestamp.clear(); // force render of all items
579
- }
580
- return super.update(changeProperties);
581
- }
582
- updated(changedProperties) {
583
- super.updated(changedProperties);
584
- if (changedProperties.has('multiple')) {
585
589
  this.setAttribute('aria-multiselectable', this.multiple ? 'true' : 'false');
586
590
  }
587
591
  }
@@ -617,9 +621,6 @@ __decorate([
617
621
  __decorate([
618
622
  property({ type: Boolean })
619
623
  ], List.prototype, "stateless", void 0);
620
- __decorate([
621
- property({ type: String, reflect: true, attribute: 'aria-multiselectable' })
622
- ], List.prototype, "ariaMultiselectable", void 0);
623
624
  __decorate([
624
625
  property({ type: Boolean })
625
626
  ], List.prototype, "multiple", void 0);
@@ -1,5 +1,5 @@
1
1
  import { ExtensibleFunction } from './extensible-function.js';
2
- import type { DataItem, CollectionComposer } from '@refinitiv-ui/utils/lib/collection.js';
2
+ import type { DataItem, CollectionComposer } from '@refinitiv-ui/utils/collection.js';
3
3
  /**
4
4
  * Render function interface
5
5
  * TODO: Move this to @refinitiv-ui/utils
@@ -1,3 +1,3 @@
1
1
  import '@refinitiv-ui/elements/lib/item/themes/halo/dark';
2
2
 
3
- elf.customStyles.define('ef-list', ':host{--item-indent:8px;--item-height:24px;color:#ccc;background-color:transparent;touch-action:manipulation;scrollbar-face-color:#595959;scrollbar-shadow-color:#595959;scrollbar-highlight-color:#595959;scrollbar-arrow-color:#595959;scrollbar-track-color:#1a1a1a;scrollbar-3dlight-color:#1a1a1a;scrollbar-darkshadow-color:#1a1a1a;scrollbar-color:#595959 #1a1a1a;scrollbar-width:thin}:host(:focus){outline:0}:host([readonly]) [part=list-item]{cursor:default}::-webkit-scrollbar-corner{background:0 0}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:#595959;border-radius:0;border:1px solid transparent}::-webkit-scrollbar-thumb:hover{background:#334bff}::-webkit-scrollbar-thumb:active{background:#0f1e8a}::-webkit-scrollbar-track{background:#1a1a1a}::-webkit-scrollbar-thumb:horizontal{background-size:auto 6px;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#595959,#595959);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:horizontal:hover{background-image:linear-gradient(to bottom,#334bff,#334bff);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:horizontal:active{background-image:linear-gradient(to bottom,#0f1e8a,#0f1e8a);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:vertical{background-size:6px auto;background-repeat:repeat-y;background-image:linear-gradient(to right,#595959,#595959);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:vertical:hover{background-image:linear-gradient(to right,#334bff,#334bff);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:vertical:active{background-image:linear-gradient(to right,#0f1e8a,#0f1e8a);background-color:transparent;background-position:center}::-webkit-scrollbar-track:horizontal{border-top:1px solid #0d0d0d;border-bottom:1px solid #0d0d0d}::-webkit-scrollbar-track:vertical{border-left:1px solid #0d0d0d;border-right:1px solid #0d0d0d}::-webkit-scrollbar-button{background:0 0/1px 2px no-repeat #1a1a1a;height:16px;width:16px;display:none;border:1px solid #0d0d0d}::-webkit-scrollbar-button:end:decrement,::-webkit-scrollbar-button:start:increment{display:none}::-webkit-scrollbar-button:hover{background-color:#334bff;border:1px solid #334bff}::-webkit-scrollbar-button:active{background-color:#0f1e8a;border:1px solid #0d0d0d}::-webkit-scrollbar-button:horizontal{background-size:2px 1px}::-webkit-scrollbar-button:vertical:start:decrement{border-bottom-color:#0d0d0d;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-position:10.55px 8px,9.55px 7px,8.55px 6px,7.55px 5px,6.55px 4px,5.55px 5px,4.55px 6px,3.55px 7px,2.55px 8px}::-webkit-scrollbar-button:vertical:start:decrement:hover{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:10.55px 8px,9.55px 7px,8.55px 6px,7.55px 5px,6.55px 4px,5.55px 5px,4.55px 6px,3.55px 7px,2.55px 8px;border-bottom-color:#334bff}::-webkit-scrollbar-button:vertical:start:decrement:active{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:10.55px 8px,9.55px 7px,8.55px 6px,7.55px 5px,6.55px 4px,5.55px 5px,4.55px 6px,3.55px 7px,2.55px 8px;border-bottom-color:#0d0d0d}::-webkit-scrollbar-button:vertical:end:increment{border-top-color:#0d0d0d;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-position:10.55px 4px,9.55px 5px,8.55px 6px,7.55px 7px,6.55px 8px,5.55px 7px,4.55px 6px,3.55px 5px,2.55px 4px}::-webkit-scrollbar-button:vertical:end:increment:hover{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:10.55px 4px,9.55px 5px,8.55px 6px,7.55px 7px,6.55px 8px,5.55px 7px,4.55px 6px,3.55px 5px,2.55px 4px;border-top-color:#334bff}::-webkit-scrollbar-button:vertical:end:increment:active{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:10.55px 4px,9.55px 5px,8.55px 6px,7.55px 7px,6.55px 8px,5.55px 7px,4.55px 6px,3.55px 5px,2.55px 4px;border-top-color:#0d0d0d}::-webkit-scrollbar-button:horizontal:start:decrement{border-right-color:#0d0d0d;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-position:7.5px 10.55px,6.5px 9.55px,5.5px 8.55px,4.5px 7.55px,3.5px 6.55px,4.5px 5.55px,5.5px 4.55px,6.5px 3.55px,7.5px 2.55px}::-webkit-scrollbar-button:horizontal:start:decrement:hover{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:7.5px 10.55px,6.5px 9.55px,5.5px 8.55px,4.5px 7.55px,3.5px 6.55px,4.5px 5.55px,5.5px 4.55px,6.5px 3.55px,7.5px 2.55px;border-right-color:#334bff}::-webkit-scrollbar-button:horizontal:start:decrement:active{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:7.5px 10.55px,6.5px 9.55px,5.5px 8.55px,4.5px 7.55px,3.5px 6.55px,4.5px 5.55px,5.5px 4.55px,6.5px 3.55px,7.5px 2.55px;border-right-color:#0d0d0d}::-webkit-scrollbar-button:horizontal:end:increment{border-left-color:#0d0d0d;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-position:5px 10.55px,6px 9.55px,7px 8.55px,8px 7.55px,9px 6.55px,8px 5.55px,7px 4.55px,6px 3.55px,5px 2.55px}::-webkit-scrollbar-button:horizontal:end:increment:hover{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:5px 10.55px,6px 9.55px,7px 8.55px,8px 7.55px,9px 6.55px,8px 5.55px,7px 4.55px,6px 3.55px,5px 2.55px;border-left-color:#334bff}::-webkit-scrollbar-button:horizontal:end:increment:active{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:5px 10.55px,6px 9.55px,7px 8.55px,8px 7.55px,9px 6.55px,8px 5.55px,7px 4.55px,6px 3.55px,5px 2.55px;border-left-color:#0d0d0d}');
3
+ elf.customStyles.define('ef-list', ':host{--item-indent:8px;--item-height:24px;color:#ccc;background-color:transparent;touch-action:manipulation;scrollbar-face-color:#595959;scrollbar-shadow-color:#595959;scrollbar-highlight-color:#595959;scrollbar-arrow-color:#595959;scrollbar-track-color:#1a1a1a;scrollbar-3dlight-color:#1a1a1a;scrollbar-darkshadow-color:#1a1a1a;scrollbar-color:#595959 #1a1a1a;scrollbar-width:thin}:host(:focus){outline:0}:host([focused=visible]){outline:#334bff solid 1px}:host([readonly]) [part=list-item]{cursor:default}::-webkit-scrollbar-corner{background:0 0}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-thumb{background:#595959;border-radius:0;border:1px solid transparent}::-webkit-scrollbar-thumb:hover{background:#334bff}::-webkit-scrollbar-thumb:active{background:#0f1e8a}::-webkit-scrollbar-track{background:#1a1a1a}::-webkit-scrollbar-thumb:horizontal{background-size:auto 6px;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#595959,#595959);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:horizontal:hover{background-image:linear-gradient(to bottom,#334bff,#334bff);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:horizontal:active{background-image:linear-gradient(to bottom,#0f1e8a,#0f1e8a);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:vertical{background-size:6px auto;background-repeat:repeat-y;background-image:linear-gradient(to right,#595959,#595959);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:vertical:hover{background-image:linear-gradient(to right,#334bff,#334bff);background-color:transparent;background-position:center}::-webkit-scrollbar-thumb:vertical:active{background-image:linear-gradient(to right,#0f1e8a,#0f1e8a);background-color:transparent;background-position:center}::-webkit-scrollbar-track:horizontal{border-top:1px solid #0d0d0d;border-bottom:1px solid #0d0d0d}::-webkit-scrollbar-track:vertical{border-left:1px solid #0d0d0d;border-right:1px solid #0d0d0d}::-webkit-scrollbar-button{background:0 0/1px 2px no-repeat #1a1a1a;height:16px;width:16px;display:none;border:1px solid #0d0d0d}::-webkit-scrollbar-button:end:decrement,::-webkit-scrollbar-button:start:increment{display:none}::-webkit-scrollbar-button:hover{background-color:#334bff;border:1px solid #334bff}::-webkit-scrollbar-button:active{background-color:#0f1e8a;border:1px solid #0d0d0d}::-webkit-scrollbar-button:horizontal{background-size:2px 1px}::-webkit-scrollbar-button:vertical:start:decrement{border-bottom-color:#0d0d0d;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-position:10.55px 8px,9.55px 7px,8.55px 6px,7.55px 5px,6.55px 4px,5.55px 5px,4.55px 6px,3.55px 7px,2.55px 8px}::-webkit-scrollbar-button:vertical:start:decrement:hover{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:10.55px 8px,9.55px 7px,8.55px 6px,7.55px 5px,6.55px 4px,5.55px 5px,4.55px 6px,3.55px 7px,2.55px 8px;border-bottom-color:#334bff}::-webkit-scrollbar-button:vertical:start:decrement:active{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:10.55px 8px,9.55px 7px,8.55px 6px,7.55px 5px,6.55px 4px,5.55px 5px,4.55px 6px,3.55px 7px,2.55px 8px;border-bottom-color:#0d0d0d}::-webkit-scrollbar-button:vertical:end:increment{border-top-color:#0d0d0d;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-position:10.55px 4px,9.55px 5px,8.55px 6px,7.55px 7px,6.55px 8px,5.55px 7px,4.55px 6px,3.55px 5px,2.55px 4px}::-webkit-scrollbar-button:vertical:end:increment:hover{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:10.55px 4px,9.55px 5px,8.55px 6px,7.55px 7px,6.55px 8px,5.55px 7px,4.55px 6px,3.55px 5px,2.55px 4px;border-top-color:#334bff}::-webkit-scrollbar-button:vertical:end:increment:active{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:10.55px 4px,9.55px 5px,8.55px 6px,7.55px 7px,6.55px 8px,5.55px 7px,4.55px 6px,3.55px 5px,2.55px 4px;border-top-color:#0d0d0d}::-webkit-scrollbar-button:horizontal:start:decrement{border-right-color:#0d0d0d;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-position:7.5px 10.55px,6.5px 9.55px,5.5px 8.55px,4.5px 7.55px,3.5px 6.55px,4.5px 5.55px,5.5px 4.55px,6.5px 3.55px,7.5px 2.55px}::-webkit-scrollbar-button:horizontal:start:decrement:hover{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:7.5px 10.55px,6.5px 9.55px,5.5px 8.55px,4.5px 7.55px,3.5px 6.55px,4.5px 5.55px,5.5px 4.55px,6.5px 3.55px,7.5px 2.55px;border-right-color:#334bff}::-webkit-scrollbar-button:horizontal:start:decrement:active{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:7.5px 10.55px,6.5px 9.55px,5.5px 8.55px,4.5px 7.55px,3.5px 6.55px,4.5px 5.55px,5.5px 4.55px,6.5px 3.55px,7.5px 2.55px;border-right-color:#0d0d0d}::-webkit-scrollbar-button:horizontal:end:increment{border-left-color:#0d0d0d;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-position:5px 10.55px,6px 9.55px,7px 8.55px,8px 7.55px,9px 6.55px,8px 5.55px,7px 4.55px,6px 3.55px,5px 2.55px}::-webkit-scrollbar-button:horizontal:end:increment:hover{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:5px 10.55px,6px 9.55px,7px 8.55px,8px 7.55px,9px 6.55px,8px 5.55px,7px 4.55px,6px 3.55px,5px 2.55px;border-left-color:#334bff}::-webkit-scrollbar-button:horizontal:end:increment:active{background-image:linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff),linear-gradient(#fff,#fff);background-position:5px 10.55px,6px 9.55px,7px 8.55px,8px 7.55px,9px 6.55px,8px 5.55px,7px 4.55px,6px 3.55px,5px 2.55px;border-left-color:#0d0d0d}');