q2-tecton-elements 1.28.2 → 1.29.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 (108) hide show
  1. package/dist/cjs/click-elsewhere_2.cjs.entry.js +8 -12
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/q2-action-sheet.cjs.entry.js +10 -5
  4. package/dist/cjs/q2-badge.cjs.entry.js +43 -0
  5. package/dist/cjs/q2-btn_2.cjs.entry.js +1 -1
  6. package/dist/cjs/q2-calendar.cjs.entry.js +3 -2
  7. package/dist/cjs/q2-checkbox.cjs.entry.js +16 -7
  8. package/dist/cjs/q2-data-table.cjs.entry.js +287 -0
  9. package/dist/cjs/{q2-badge_2.cjs.entry.js → q2-input.cjs.entry.js} +1 -38
  10. package/dist/cjs/q2-tecton-elements.cjs.js +1 -1
  11. package/dist/collection/collection-manifest.json +1 -0
  12. package/dist/collection/components/q2-action-sheet/index.js +26 -4
  13. package/dist/collection/components/q2-action-sheet/styles.css +2 -2
  14. package/dist/collection/components/q2-btn/styles.css +4 -0
  15. package/dist/collection/components/q2-calendar/index.js +19 -1
  16. package/dist/collection/components/q2-calendar/styles.css +16 -2
  17. package/dist/collection/components/q2-checkbox/index.js +15 -6
  18. package/dist/collection/components/q2-checkbox/styles.css +4 -0
  19. package/dist/collection/components/q2-data-table/index.js +539 -0
  20. package/dist/collection/components/q2-data-table/styles.css +192 -0
  21. package/dist/collection/components/q2-input/styles.css +1 -1
  22. package/dist/collection/components/q2-popover/index.js +7 -11
  23. package/dist/collection/components/q2-popover/styles.css +1 -2
  24. package/dist/components/index.d.ts +1 -0
  25. package/dist/components/index.js +1 -0
  26. package/dist/components/index10.js +72 -55
  27. package/dist/components/index11.js +56 -44
  28. package/dist/components/index12.js +42 -42
  29. package/dist/components/index13.js +40 -538
  30. package/dist/components/index14.js +518 -141
  31. package/dist/components/index15.js +174 -574
  32. package/dist/components/index16.js +589 -0
  33. package/dist/components/index3.js +1 -1
  34. package/dist/components/index5.js +3 -3
  35. package/dist/components/index6.js +93 -94
  36. package/dist/components/index7.js +112 -2927
  37. package/dist/components/index8.js +2919 -3347
  38. package/dist/components/index9.js +3343 -56
  39. package/dist/components/q2-action-sheet.js +18 -12
  40. package/dist/components/q2-calendar.js +10 -8
  41. package/dist/components/q2-card.js +2 -2
  42. package/dist/components/q2-carousel-pane.js +1 -1
  43. package/dist/components/q2-carousel.js +3 -3
  44. package/dist/components/q2-chart-area.js +1 -1
  45. package/dist/components/q2-chart-bar.js +1 -1
  46. package/dist/components/q2-chart-donut.js +2 -2
  47. package/dist/components/q2-checkbox-group.js +2 -2
  48. package/dist/components/q2-checkbox.js +1 -133
  49. package/dist/components/q2-data-table.d.ts +11 -0
  50. package/dist/components/q2-data-table.js +349 -0
  51. package/dist/components/q2-dropdown-item.js +1 -1
  52. package/dist/components/q2-dropdown.js +5 -5
  53. package/dist/components/q2-editable-field.js +4 -4
  54. package/dist/components/q2-icon.js +1 -1
  55. package/dist/components/q2-input.js +1 -1
  56. package/dist/components/q2-loading.js +1 -1
  57. package/dist/components/q2-loc.js +1 -1
  58. package/dist/components/q2-message.js +1 -1
  59. package/dist/components/q2-month-picker.js +3 -3
  60. package/dist/components/q2-optgroup.js +1 -1
  61. package/dist/components/q2-option-list.js +1 -1
  62. package/dist/components/q2-option.js +1 -1
  63. package/dist/components/q2-pagination.js +4 -4
  64. package/dist/components/q2-pill.js +4 -4
  65. package/dist/components/q2-popover.js +1 -1
  66. package/dist/components/q2-radio-group.js +2 -2
  67. package/dist/components/q2-radio.js +1 -1
  68. package/dist/components/q2-section.js +3 -3
  69. package/dist/components/q2-select.js +6 -6
  70. package/dist/components/q2-stepper-pane.js +1 -1
  71. package/dist/components/q2-stepper-vertical.js +2 -2
  72. package/dist/components/q2-stepper.js +3 -3
  73. package/dist/components/q2-tab-container.js +3 -3
  74. package/dist/components/q2-tag.js +4 -4
  75. package/dist/components/q2-textarea.js +2 -2
  76. package/dist/components/q2-tooltip.js +1 -1
  77. package/dist/docs.json +301 -3
  78. package/dist/esm/click-elsewhere_2.entry.js +8 -12
  79. package/dist/esm/loader.js +1 -1
  80. package/dist/esm/q2-action-sheet.entry.js +10 -5
  81. package/dist/esm/q2-badge.entry.js +39 -0
  82. package/dist/esm/q2-btn_2.entry.js +1 -1
  83. package/dist/esm/q2-calendar.entry.js +3 -2
  84. package/dist/esm/q2-checkbox.entry.js +16 -7
  85. package/dist/esm/q2-data-table.entry.js +283 -0
  86. package/dist/esm/{q2-badge_2.entry.js → q2-input.entry.js} +3 -39
  87. package/dist/esm/q2-tecton-elements.js +1 -1
  88. package/dist/q2-tecton-elements/p-00b2c345.entry.js +1 -0
  89. package/dist/q2-tecton-elements/p-0112df78.entry.js +1 -0
  90. package/dist/q2-tecton-elements/p-08286237.entry.js +1 -0
  91. package/dist/q2-tecton-elements/p-42d03011.entry.js +1 -0
  92. package/dist/q2-tecton-elements/p-47aefcc2.entry.js +1 -0
  93. package/dist/q2-tecton-elements/{p-5e14a790.entry.js → p-807e2e44.entry.js} +1 -1
  94. package/dist/q2-tecton-elements/p-9a327827.entry.js +1 -0
  95. package/dist/q2-tecton-elements/p-c9abc814.entry.js +1 -0
  96. package/dist/q2-tecton-elements/q2-tecton-elements.esm.js +1 -1
  97. package/dist/types/components/q2-action-sheet/index.d.ts +1 -0
  98. package/dist/types/components/q2-calendar/index.d.ts +1 -0
  99. package/dist/types/components/q2-checkbox/index.d.ts +4 -0
  100. package/dist/types/components/q2-data-table/index.d.ts +94 -0
  101. package/dist/types/components.d.ts +49 -0
  102. package/package.json +3 -3
  103. package/dist/q2-tecton-elements/p-0b7003c4.entry.js +0 -1
  104. package/dist/q2-tecton-elements/p-1b9e07b4.entry.js +0 -1
  105. package/dist/q2-tecton-elements/p-3bf06809.entry.js +0 -1
  106. package/dist/q2-tecton-elements/p-b9bbfaf7.entry.js +0 -1
  107. package/dist/q2-tecton-elements/p-d6824ce5.entry.js +0 -1
  108. /package/dist/types/workspace/workspace/{tecton-production_release_1.28.x → Tecton_tecton-production_master}/packages/q2-tecton-elements/.stencil/test/helpers.d.ts +0 -0
@@ -1,193 +1,570 @@
1
- import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
2
- import { r as resizeIframe, w as waitForNextPaint } from './index15.js';
1
+ import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
2
+ import { o as overrideFocus, w as waitForNextPaint, n as nextPaint, a as isEventFromElement } from './index16.js';
3
3
 
4
- const stylesCss = "*{box-sizing:border-box}*:active{outline:none}*:focus{outline:none;box-shadow:var(--const-double-focus-ring, 0 0 0 2px #ffffff, 0 0 0 4px #33b4ff #06C)}:host{box-shadow:none !important}::-moz-focus-inner{border:none}input,textarea,button{font-family:inherit;font-size:inherit;font-stretch:inherit}:host(.sr),:host(.sr) button{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.sr,.sr button{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.hidden{display:none}:host([hidden]){display:none}.invisible{visibility:hidden}:host{display:block;width:100%}:host([align=right]){display:block;position:absolute;right:0;text-align:end;left:unset}.container{display:none;overflow:hidden;opacity:0;height:0;position:absolute;top:var(--tct-popover-top, var(--t-popover-top, initial));visibility:hidden;background-color:var(--tct-popover-background-color, var(--t-popover-background-color, var(--app-white, #ffffff)));color:var(--tct-popover-text-color, var(--t-popover-text-color, var(--t-text, #4d4d4d)));z-index:var(--tct-popover-z-index, var(--t-popover-z-index, 100));width:max-content;min-width:var(--tct-popover-min-width, var(--t-popover-min-width, 135px));box-shadow:var(--tct-popover-box-shadow, var(--t-popover-box-shadow, var(--app-shadow-1, 0 2px 4px rgba(0, 0, 0, 0.3))));text-align:start;left:0;transition:opacity var(--app-tween-1, 0.2s ease), max-height var(--app-tween-1, 0.2s ease);border-radius:var(--tct-popover-border-radius, var(--t-popover-border-radius, 0));max-height:var(--comp-pop-max-height);--comp-scrollbar-size:var(--tct-scrollbar-size, var(--t-scrollbar-size, var(--app-scale-1x, 5px)));--comp-scrollbar-border-radius:var(--tct-scrollbar-border-radius, var(--t-scrollbar-border-radius, var(--app-border-radius-1, 3px)));--comp-scrollbar-color:var(--tct-scrollbar-color, var(--t-scrollbar-color, var(--t-a11y-gray-color, #747474)));scrollbar-width:thin;scrollbar-color:var(--comp-scrollbar-color) transparent}.container::-webkit-scrollbar{width:var(--comp-scrollbar-size);height:var(--comp-scrollbar-size);margin:5px}.container::-webkit-scrollbar-thumb{background:var(--comp-scrollbar-color);border-radius:var(--comp-scrollbar-border-radius)}.container::-webkit-scrollbar-track{background:transparent;border-radius:var(--comp-scrollbar-border-radius)}:host([block]) .container{left:unset;right:unset;width:100%;min-width:unset}:host([align=right]) .container{right:0;text-align:end;left:unset}.container :host([open]){display:block}:host([open]) .container.show{height:auto;overflow:auto;opacity:1;visibility:visible}.container.up{bottom:var(--comp-pop-offset)}click-elsewhere{position:relative;display:block}.content{height:auto}";
4
+ const stylesCss = "*{box-sizing:border-box}*:active{outline:none}*:focus{outline:none;box-shadow:var(--const-double-focus-ring, 0 0 0 2px #ffffff, 0 0 0 4px #33b4ff #06C)}:host{box-shadow:none !important}::-moz-focus-inner{border:none}input,textarea,button{font-family:inherit;font-size:inherit;font-stretch:inherit}:host(.sr),:host(.sr) button{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.sr,.sr button{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.hidden{display:none}:host([hidden]){display:none}.invisible{visibility:hidden}:host{position:relative;width:100%;display:block;line-height:var(--tct-option-list-line-height, var(--t-option-list-line-height, var(--app-line-height, 1.428571429em)))}.content{text-align:start}:host([is-sizeable]) .content{display:block;height:auto}";
5
5
 
6
- const Q2Popover = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
6
+ const Q2OptionList = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
7
7
  constructor() {
8
8
  super();
9
9
  this.__registerHost();
10
10
  this.__attachShadow();
11
- this.popoverStateChanged = createEvent(this, "popoverStateChanged", 7);
11
+ this.change = createEvent(this, "change", 7);
12
+ this.popoverState = createEvent(this, "popoverState", 7);
13
+ this.ready = createEvent(this, "ready", 3);
12
14
  this.scheduledAfterRender = [];
13
- /// Helpers ///
14
- this.viewPortChanged = () => {
15
- if (!this.open)
16
- return;
17
- this.determinePopDirection();
15
+ this.keyStore = {
16
+ queue: [],
17
+ lastPressedAt: new Date(),
18
18
  };
19
- this.direction = undefined;
19
+ this.searchAndFocus = (keyValue, shouldSelect) => {
20
+ // pseudo search in non-searchable select
21
+ const reorder = () => {
22
+ this.pivotIndex = this.pivotIndex === undefined ? 0 : (this.activeIndex || 0) + 1;
23
+ const list = this.allOptions.map((element, index) => ({ element, index }));
24
+ return [...list.slice(this.pivotIndex), ...list.slice(0, this.pivotIndex)];
25
+ };
26
+ const buildQueue = () => {
27
+ const now = new Date();
28
+ if (now.getTime() - this.keyStore.lastPressedAt.getTime() > 1000) {
29
+ // empty stored keys if delay > 1s
30
+ this.keyStore.queue.length = 0;
31
+ }
32
+ if (this.keyStore.queue.length !== 1 || this.keyStore.queue[0] !== keyValue) {
33
+ this.keyStore.queue.push(keyValue);
34
+ }
35
+ this.keyStore.lastPressedAt = now;
36
+ };
37
+ const searchIndex = (list) => {
38
+ const keyStr = this.keyStore.queue.join('');
39
+ return list.find(v => {
40
+ return (!v.element.disabled &&
41
+ v.element.display &&
42
+ (v.element.display.match(new RegExp(`^${keyStr}`, 'i')) ||
43
+ v.element.display.replace(/\s/g, '').match(new RegExp(`^${keyStr}`, 'i'))));
44
+ });
45
+ };
46
+ const setFocus = ({ index }) => {
47
+ if (this.multiple) {
48
+ // multiple: should open to make sure that which options are selected
49
+ this.openDropdownWithActiveElement(index);
50
+ }
51
+ else {
52
+ this.activeIndex = index;
53
+ if (shouldSelect)
54
+ this.selectOption(this.allOptions[index]);
55
+ else
56
+ this.setActiveElement(index);
57
+ }
58
+ };
59
+ buildQueue();
60
+ const matched = searchIndex(reorder());
61
+ if (matched) {
62
+ setFocus(matched);
63
+ }
64
+ };
65
+ /// Event Handlers ///
66
+ /* tslint:disable:cyclomatic-complexity */
67
+ this.externalKeydownHandler = (event) => {
68
+ event.stopPropagation();
69
+ const { activeIndex, customSearch, allOptions } = this;
70
+ const { key } = event;
71
+ let nextIndex;
72
+ switch (key) {
73
+ case ' ':
74
+ if (this.searchString) {
75
+ if (customSearch)
76
+ break;
77
+ this.searchOptions(key, true);
78
+ break;
79
+ }
80
+ else if (this.role === 'menu') {
81
+ this.activeIndex = 0;
82
+ this.openDropdownWithActiveElement(0);
83
+ }
84
+ else {
85
+ this.setDefaultActiveElement();
86
+ }
87
+ break;
88
+ case 'Enter':
89
+ if (this.role === 'menu') {
90
+ this.activeIndex = 0;
91
+ this.openDropdownWithActiveElement(0);
92
+ }
93
+ else {
94
+ this.setDefaultActiveElement();
95
+ }
96
+ break;
97
+ case 'ArrowUp':
98
+ event.preventDefault();
99
+ this.activeIndex = 0;
100
+ nextIndex = !!this.selectedOptions.length ? this.getDefaultActiveIndex() : this.getNextVisibleIndex(-1);
101
+ if (nextIndex === -1)
102
+ break;
103
+ this.openDropdownWithActiveElement(nextIndex);
104
+ break;
105
+ case 'ArrowDown':
106
+ event.preventDefault();
107
+ this.activeIndex = 0;
108
+ nextIndex = !!this.selectedOptions.length ? this.getDefaultActiveIndex() : this.getNextVisibleIndex(0);
109
+ if (nextIndex === -1)
110
+ break;
111
+ this.openDropdownWithActiveElement(nextIndex);
112
+ break;
113
+ case 'Home':
114
+ event.preventDefault();
115
+ this.openDropdownWithActiveElement(0);
116
+ break;
117
+ case 'End':
118
+ event.preventDefault();
119
+ this.openDropdownWithActiveElement(allOptions.length - 1);
120
+ break;
121
+ case 'PageUp':
122
+ event.preventDefault();
123
+ this.openDropdownWithActiveElement(Math.max((activeIndex || 0) - 10, 0));
124
+ break;
125
+ case 'PageDown':
126
+ event.preventDefault();
127
+ this.openDropdownWithActiveElement(Math.min((activeIndex || 0) + 10, allOptions.length - 1));
128
+ break;
129
+ case 'Tab':
130
+ this.popoverState.emit({ open: false, action: 'close' });
131
+ break;
132
+ case 'Esc':
133
+ case 'Escape':
134
+ if (this.noSelect)
135
+ this.setActiveElement(null);
136
+ this.popoverState.emit({ open: false, action: 'close' });
137
+ break;
138
+ default:
139
+ if (customSearch)
140
+ break;
141
+ if (!key.match(/^[\w]$/))
142
+ break;
143
+ this.searchOptions(key, true);
144
+ break;
145
+ }
146
+ };
147
+ this.internalKeydownHandler = (event) => {
148
+ event.stopPropagation();
149
+ const { activeIndex, customSearch, allOptions } = this;
150
+ const { key, shiftKey } = event;
151
+ let newOption;
152
+ switch (key) {
153
+ case ' ':
154
+ if (this.searchString && !this.multiple) {
155
+ if (customSearch)
156
+ break;
157
+ this.searchOptions(key, false);
158
+ break;
159
+ }
160
+ event.preventDefault();
161
+ newOption = allOptions.find(element => element.active);
162
+ if (!newOption || newOption.disabled)
163
+ break;
164
+ this.selectOption(newOption);
165
+ break;
166
+ case 'Enter':
167
+ event.preventDefault();
168
+ newOption = allOptions.find(element => element.active);
169
+ if (!newOption || newOption.disabled)
170
+ break;
171
+ this.selectOption(newOption);
172
+ break;
173
+ case 'ArrowUp':
174
+ event.preventDefault();
175
+ const isFirstOptionActive = activeIndex === 0;
176
+ if (isFirstOptionActive)
177
+ break;
178
+ if (activeIndex === undefined) {
179
+ this.setDefaultActiveElement();
180
+ break;
181
+ }
182
+ else {
183
+ const nextIndex = this.getNextVisibleIndex(-1);
184
+ if (nextIndex === -1)
185
+ break;
186
+ this.adjustActiveOptionAndScroll(nextIndex - activeIndex);
187
+ break;
188
+ }
189
+ case 'ArrowDown':
190
+ event.preventDefault();
191
+ const isLastOptionActive = activeIndex === allOptions.length - 1;
192
+ if (isLastOptionActive)
193
+ break;
194
+ if (activeIndex === undefined) {
195
+ this.setDefaultActiveElement();
196
+ break;
197
+ }
198
+ else {
199
+ const nextIndex = this.getNextVisibleIndex(1);
200
+ if (nextIndex === -1)
201
+ break;
202
+ this.adjustActiveOptionAndScroll(nextIndex - activeIndex);
203
+ break;
204
+ }
205
+ case 'Home':
206
+ event.preventDefault();
207
+ this.openDropdownWithActiveElement(0);
208
+ break;
209
+ case 'End':
210
+ event.preventDefault();
211
+ this.openDropdownWithActiveElement(allOptions.length - 1);
212
+ break;
213
+ case 'PageUp':
214
+ event.preventDefault();
215
+ this.openDropdownWithActiveElement(Math.max(activeIndex - 10, 0));
216
+ break;
217
+ case 'PageDown':
218
+ event.preventDefault();
219
+ this.openDropdownWithActiveElement(Math.min(activeIndex + 10, allOptions.length - 1));
220
+ break;
221
+ case 'Tab':
222
+ if (shiftKey)
223
+ break;
224
+ if (this.multiple && this.role === 'listbox')
225
+ break;
226
+ newOption = allOptions.find(element => element.active);
227
+ if (!newOption || newOption.disabled)
228
+ return;
229
+ this.selectOption(newOption);
230
+ break;
231
+ case 'Esc':
232
+ case 'Escape':
233
+ if (this.noSelect)
234
+ this.setActiveElement(null);
235
+ this.popoverState.emit({ open: false, action: 'close' });
236
+ break;
237
+ default:
238
+ if (customSearch)
239
+ break;
240
+ if (!key.match(/^[\w]$/))
241
+ break;
242
+ this.searchOptions(key, false);
243
+ break;
244
+ }
245
+ };
246
+ /* tslint:enable:cyclomatic-complexity */
247
+ this.focusoutHandler = (event) => {
248
+ const { relatedTarget } = event;
249
+ const isInDropdown = this.allOptions.includes(relatedTarget);
250
+ const isInLightDom = !isInDropdown && this.hostElement.contains(relatedTarget);
251
+ if (isInDropdown || isInLightDom) {
252
+ event.stopPropagation();
253
+ }
254
+ };
255
+ this.clickHandler = (event) => {
256
+ const target = event.target;
257
+ const option = target.closest('q2-option');
258
+ this.selectOption(option);
259
+ };
260
+ this.role = 'listbox';
261
+ this.customSearch = undefined;
262
+ this.noSelect = undefined;
20
263
  this.align = undefined;
21
- this.open = undefined;
22
- this.block = undefined;
23
- this.minHeight = undefined;
24
- this.controlElement = undefined;
25
- this.currentDirection = undefined;
26
- this.show = false;
27
- }
28
- /// Lifecycle hooks ///
264
+ this.selectedOptions = [];
265
+ this.multiple = undefined;
266
+ this.disabled = undefined;
267
+ this.showSelected = undefined;
268
+ this.type = undefined;
269
+ this.hasOptions = undefined;
270
+ }
271
+ /// LifeCycle Hooks ///
272
+ componentWillLoad() {
273
+ this.hasOptions = !!this.hostElement.querySelectorAll('q2-option').length;
274
+ }
29
275
  componentDidLoad() {
30
- if (this.open)
31
- this.determinePopDirection();
276
+ overrideFocus(this.hostElement);
277
+ this.checkOptions();
278
+ this.selectedOptionsUpdated();
279
+ this.ready.emit();
32
280
  }
33
281
  componentDidRender() {
34
- setTimeout(() => {
35
- this.scheduledAfterRender.forEach(fn => fn());
36
- this.scheduledAfterRender = [];
37
- }, 25);
282
+ this.scheduledAfterRender.forEach(fn => fn());
283
+ this.scheduledAfterRender = [];
38
284
  }
39
- disconnectedCallback() {
40
- this.removeViewportListeners();
285
+ /// Getters ///
286
+ get allContents() {
287
+ const rootSlot = this.getRootSlot(this.hostElement);
288
+ const acceptedTags = ['Q2-OPTGROUP', 'Q2-OPTION'];
289
+ return rootSlot.filter(element => acceptedTags.includes(element.tagName));
41
290
  }
42
- /// Methods ///
43
- async toggle() {
44
- this.open = !this.open;
291
+ get allOptions() {
292
+ const contents = this.allContents;
293
+ const extractOptions = (elements) => {
294
+ return elements.reduce((acc, element) => {
295
+ if (element.tagName === 'Q2-OPTGROUP') {
296
+ return [...acc, ...extractOptions(Array.from(element.children))];
297
+ }
298
+ else if (element.tagName === 'Q2-OPTION') {
299
+ return [...acc, element];
300
+ }
301
+ else {
302
+ return acc;
303
+ }
304
+ }, []);
305
+ };
306
+ return extractOptions(contents);
45
307
  }
46
- /// Watchers ///
47
- openChanged(open) {
48
- this.popoverStateChanged.emit({ open });
49
- this.scheduledAfterRender.push(resizeIframe);
50
- if (open) {
51
- this.addViewportListeners();
52
- this.determinePopDirection();
308
+ get allVisibleOptions() {
309
+ return this.allOptions.filter(option => !option.hidden && !option._multiSelectHidden && !option.disabled && !option.disabledGroup);
310
+ }
311
+ /// Helpers ///
312
+ async checkOptions() {
313
+ const { type } = this;
314
+ const options = await this.getOptions();
315
+ if (!type)
316
+ return;
317
+ const optionRole = type === 'menu' ? 'menuitem' : 'option';
318
+ options.forEach(option => {
319
+ option.role = optionRole;
320
+ });
321
+ }
322
+ getRootSlot(element) {
323
+ var _a;
324
+ const slot = element.querySelector('slot');
325
+ const assignedElements = (_a = slot === null || slot === void 0 ? void 0 : slot.assignedElements()) !== null && _a !== void 0 ? _a : Array.from(element.children);
326
+ const hasAnotherSlot = !!assignedElements.length && assignedElements[0].tagName === 'SLOT';
327
+ if (hasAnotherSlot) {
328
+ return this.getRootSlot(assignedElements[0]);
53
329
  }
54
330
  else {
55
- this.removeViewportListeners();
56
- // Reset currentDirection after close transition completes
57
- this.containerElement.addEventListener('transitionend', () => {
58
- if (this.open)
59
- return;
60
- this.currentDirection = undefined;
61
- this.containerElement.style.removeProperty('display');
62
- this.containerElement.style.removeProperty('--comp-pop-max-height');
63
- }, { once: true });
64
- this.show = false;
331
+ return assignedElements;
65
332
  }
66
333
  }
67
- /// Listeners ///
68
- popoverStateHandler(event) {
69
- const { detail: { open }, } = event;
70
- if (open === this.open)
334
+ scrollToActiveOption() {
335
+ const activeOption = this.allOptions[this.activeIndex];
336
+ activeOption === null || activeOption === void 0 ? void 0 : activeOption.scrollIntoView({ block: 'nearest' });
337
+ }
338
+ async openDropdownWithActiveElement(activeIndex) {
339
+ if (this.disabled)
71
340
  return;
72
- this.open = open;
73
- event.stopPropagation();
341
+ this.activeIndex = activeIndex;
342
+ this.popoverState.emit({ open: true, action: 'open' });
343
+ await waitForNextPaint();
344
+ this.setActiveOption();
345
+ await waitForNextPaint();
346
+ this.setFocusedOption();
347
+ this.scrollToActiveOption();
74
348
  }
75
- addViewportListeners() {
76
- // window.visualViewport.addEventListener('scroll', this.viewPortChanged);
77
- window.visualViewport.addEventListener('resize', this.viewPortChanged);
349
+ getDefaultActiveIndex() {
350
+ const { allOptions } = this;
351
+ const firstSelected = allOptions.findIndex(element => element.selected);
352
+ if (firstSelected > -1)
353
+ return firstSelected;
354
+ const firstEnabled = allOptions.findIndex(element => !element.hidden);
355
+ if (firstEnabled > -1)
356
+ return firstEnabled;
357
+ return 0;
78
358
  }
79
- removeViewportListeners() {
80
- // window.visualViewport.removeEventListener('scroll', this.viewPortChanged);
81
- window.visualViewport.removeEventListener('resize', this.viewPortChanged);
359
+ updateSingleOptionAttrs() {
360
+ var _a;
361
+ const { allOptions, selectedOptions } = this;
362
+ const selectedValue = ((_a = selectedOptions[0]) === null || _a === void 0 ? void 0 : _a.value) || undefined;
363
+ allOptions.forEach(element => {
364
+ element.selected = element.value === selectedValue;
365
+ });
82
366
  }
83
- async setDirectionAndShow(direction) {
84
- if (direction === 'up') {
85
- this.determinePopOffset();
367
+ updateMultipleOptionAttrs() {
368
+ const { allOptions, selectedOptions } = this;
369
+ const selectedValues = selectedOptions.map(({ value }) => value);
370
+ allOptions.forEach(element => {
371
+ element.selected = selectedValues.includes(element.value);
372
+ });
373
+ }
374
+ setActiveOption() {
375
+ const activeIndex = this.activeIndex;
376
+ this.allOptions.forEach((element, elementIndex) => {
377
+ element.active = activeIndex === elementIndex;
378
+ });
379
+ }
380
+ setFocusedOption() {
381
+ const option = this.allOptions[this.activeIndex];
382
+ if (!option)
383
+ return;
384
+ const isHostElementVisible = !!this.hostElement.offsetParent;
385
+ if (isHostElementVisible)
386
+ option.focus();
387
+ else
388
+ nextPaint(() => option.focus());
389
+ }
390
+ getNextVisibleIndex(direction) {
391
+ const { allVisibleOptions, allOptions, activeIndex } = this;
392
+ const activeOption = allOptions[activeIndex];
393
+ const visibleActiveOptionIndex = allVisibleOptions.indexOf(activeOption);
394
+ let nextVisibleOptionIndex = visibleActiveOptionIndex + direction;
395
+ if (nextVisibleOptionIndex < 0) {
396
+ nextVisibleOptionIndex = allVisibleOptions.length - 1;
86
397
  }
87
- this.currentDirection = direction;
88
- this.show = true;
89
- }
90
- async determinePopDirection() {
91
- var _a, _b, _c, _d, _e, _f, _g;
92
- const { containerElement, contentElement, direction, controlElement, currentDirection } = this;
93
- if (containerElement)
94
- containerElement.style.maxHeight = null;
95
- // If the direction is already set then use it, otherwise use the current direction
96
- const currentOrStatedDirection = direction !== null && direction !== void 0 ? direction : currentDirection;
97
- // Set the container to block so we can get the height
98
- containerElement.style.setProperty('display', 'block');
99
- await waitForNextPaint();
100
- // Determine the dimensions of the control element
101
- const { top: topOffset, height } = (_a = controlElement === null || controlElement === void 0 ? void 0 : controlElement.getBoundingClientRect()) !== null && _a !== void 0 ? _a : {
102
- top: 0,
103
- height: 0,
398
+ else if (nextVisibleOptionIndex > allVisibleOptions.length - 1) {
399
+ nextVisibleOptionIndex = 0;
400
+ }
401
+ const nextVisibleOption = allVisibleOptions[nextVisibleOptionIndex];
402
+ return allOptions.indexOf(nextVisibleOption);
403
+ }
404
+ focusSelectedSibling(option) {
405
+ const { allVisibleOptions, allOptions } = this;
406
+ const hasNoSiblings = allVisibleOptions.length < 2;
407
+ if (hasNoSiblings) {
408
+ this.showSelected = false;
409
+ return;
410
+ }
411
+ const selectedOptionVisibleIndex = allVisibleOptions.indexOf(option);
412
+ const nextVisibleSiblingIndex = selectedOptionVisibleIndex
413
+ ? selectedOptionVisibleIndex - 1
414
+ : selectedOptionVisibleIndex + 1;
415
+ const nextVisibleSibling = allVisibleOptions[nextVisibleSiblingIndex];
416
+ const nextSiblingIndex = allOptions.indexOf(nextVisibleSibling);
417
+ this.activeIndex = nextSiblingIndex;
418
+ this.setFocusedOption();
419
+ this.scheduledAfterRender.push(() => {
420
+ option._multiSelectHidden = !option.selected;
421
+ });
422
+ }
423
+ selectOption(selectedOption) {
424
+ const { multiple, noSelect, showSelected } = this;
425
+ if (!selectedOption || selectedOption.disabled || selectedOption.disabledGroup)
426
+ return;
427
+ const selectedValue = selectedOption.value;
428
+ const valueObject = {
429
+ value: selectedValue,
430
+ display: selectedOption.display || selectedOption.innerText.trim(),
104
431
  };
105
- const contentHeight = contentElement.clientHeight;
106
- const scrollY = ((_c = (_b = window.Tecton) === null || _b === void 0 ? void 0 : _b.platformDimensions) === null || _c === void 0 ? void 0 : _c.scrollY) ||
107
- ((_d = window.visualViewport) === null || _d === void 0 ? void 0 : _d.offsetTop) || // Only Android Chrome provides this which we need when scrolled
108
- 0;
109
- const innerHeight = ((_f = (_e = window.Tecton) === null || _e === void 0 ? void 0 : _e.platformDimensions) === null || _f === void 0 ? void 0 : _f.innerHeight) || ((_g = window.visualViewport) === null || _g === void 0 ? void 0 : _g.height) || window.innerHeight;
110
- const bottomOffset = scrollY + innerHeight - topOffset - height;
111
- const canShowFullSizeBelow = bottomOffset > contentHeight;
112
- const canShowFullSizeAbove = contentHeight <= topOffset;
113
- let determinedDirection;
114
- // Show the full-size popover below or above if it will fit
115
- if (currentOrStatedDirection === 'down' && canShowFullSizeBelow)
116
- return this.setDirectionAndShow('down');
117
- else if (currentOrStatedDirection === 'up' && canShowFullSizeAbove)
118
- return this.setDirectionAndShow('up');
119
- else if (currentOrStatedDirection === undefined && canShowFullSizeBelow)
120
- determinedDirection = 'down';
121
- else if (currentOrStatedDirection === undefined && canShowFullSizeAbove)
122
- determinedDirection = 'up';
123
- if (determinedDirection)
124
- return this.setDirectionAndShow(determinedDirection);
125
- // If full size will not fit then make it as tall as possible
126
- const { minHeight = 150 } = this;
127
- const displayBuffer = 5;
128
- const canShowMinHeightBelow = bottomOffset >= minHeight + displayBuffer;
129
- let maxHeight;
130
- if (currentOrStatedDirection === 'down') {
131
- maxHeight = Math.max(bottomOffset - displayBuffer, minHeight);
132
- determinedDirection = 'down';
432
+ let values = [];
433
+ if (multiple) {
434
+ const { selectedOptions } = this;
435
+ const isAlreadySelected = selectedOptions.find(option => option.value === selectedValue);
436
+ if (isAlreadySelected) {
437
+ values = selectedOptions.filter(({ value }) => value !== selectedValue);
438
+ }
439
+ else {
440
+ values = [...selectedOptions, valueObject];
441
+ }
442
+ if (showSelected)
443
+ this.focusSelectedSibling(selectedOption);
444
+ }
445
+ else {
446
+ values = [valueObject];
447
+ }
448
+ if (noSelect)
449
+ this.setActiveElement(null);
450
+ else
451
+ this.selectedOptions = values;
452
+ this.change.emit({ value: selectedValue, values });
453
+ if (multiple)
454
+ return;
455
+ this.popoverState.emit({ open: false, action: 'select' });
456
+ }
457
+ adjustActiveOptionAndScroll(numToAdd) {
458
+ this.activeIndex += numToAdd;
459
+ this.setActiveOption();
460
+ this.setFocusedOption();
461
+ this.scrollToActiveOption();
462
+ }
463
+ resetTimer() {
464
+ if (this.searchStringTimer) {
465
+ clearTimeout(this.searchStringTimer);
466
+ }
467
+ this.searchStringTimer = window.setTimeout(() => {
468
+ this.searchString = null;
469
+ }, 2000);
470
+ }
471
+ searchOptions(key, shouldSelect) {
472
+ this.searchString = key;
473
+ this.searchAndFocus(key, shouldSelect);
474
+ }
475
+ /// Watchers ///
476
+ showSelectedUpdated(showSelected) {
477
+ if (showSelected && this.selectedOptions.length === 0) {
478
+ this.showSelected = false;
479
+ return;
480
+ }
481
+ this.allOptions.forEach(option => (option._multiSelectHidden = showSelected ? !option.selected : false));
482
+ }
483
+ selectedOptionsUpdated() {
484
+ if (this.multiple) {
485
+ this.updateMultipleOptionAttrs();
133
486
  }
134
- else if (currentOrStatedDirection === 'up') {
135
- maxHeight = Math.max(topOffset - displayBuffer, minHeight);
136
- determinedDirection = 'up';
487
+ else {
488
+ this.updateSingleOptionAttrs();
137
489
  }
138
- else if (canShowMinHeightBelow) {
139
- maxHeight = Math.max(bottomOffset - displayBuffer, minHeight);
140
- determinedDirection = 'down';
490
+ }
491
+ /// Listeners ///
492
+ delegateFocus(event) {
493
+ if (!isEventFromElement(event, this.hostElement))
494
+ return;
495
+ this.popoverState.emit({ open: true, action: 'open' });
496
+ const { activeIndex } = this;
497
+ if (typeof activeIndex === 'number' && activeIndex > -1) {
498
+ this.setActiveOption();
499
+ this.setFocusedOption();
141
500
  }
142
501
  else {
143
- maxHeight = Math.max(topOffset - scrollY - displayBuffer, minHeight);
144
- determinedDirection = 'up';
502
+ this.setDefaultActiveElement();
145
503
  }
146
- containerElement.style.setProperty('--comp-pop-max-height', `${maxHeight}px`);
147
- return this.setDirectionAndShow(determinedDirection);
148
504
  }
149
- determinePopOffset() {
150
- var _a;
151
- const { controlElement, containerElement } = this;
152
- const dropdownHeight = (_a = controlElement === null || controlElement === void 0 ? void 0 : controlElement.getBoundingClientRect().height) !== null && _a !== void 0 ? _a : 0;
153
- containerElement.style.setProperty('--comp-pop-offset', `${dropdownHeight}px`);
505
+ handleClick(event) {
506
+ event.stopPropagation();
507
+ }
508
+ /// Public Methods ///
509
+ async setDefaultActiveElement() {
510
+ this.activeIndex = this.getDefaultActiveIndex();
511
+ this.setActiveOption();
512
+ this.setFocusedOption();
513
+ }
514
+ async setActiveElement(index) {
515
+ this.activeIndex = index;
516
+ this.setActiveOption();
517
+ this.setFocusedOption();
518
+ }
519
+ async handleExternalKeydown(event) {
520
+ this.externalKeydownHandler(event);
521
+ }
522
+ async getContents() {
523
+ return this.allContents;
524
+ }
525
+ async getOptions() {
526
+ return this.allOptions;
154
527
  }
155
528
  /// DOM ///
156
529
  render() {
157
- const containerClasses = ['container', this.currentDirection];
158
- if (this.show)
159
- containerClasses.push('show');
160
- return (h("div", { ref: el => (this.containerElement = el), class: containerClasses.join(' '), "test-id": "outerContainer" }, h("div", { ref: el => (this.contentElement = el), class: "content" }, h("slot", null))));
530
+ return (h(Host, null, h("div", { class: "content", ref: el => (this.contentElement = el), onFocusout: this.focusoutHandler }, h("div", { class: "options", role: this.type || 'listbox', onKeyDown: this.internalKeydownHandler, onClick: this.clickHandler }, h("slot", null)))));
161
531
  }
162
532
  get hostElement() { return this; }
163
533
  static get watchers() { return {
164
- "open": ["openChanged"]
534
+ "showSelected": ["showSelectedUpdated"],
535
+ "selectedOptions": ["selectedOptionsUpdated"]
165
536
  }; }
166
537
  static get style() { return stylesCss; }
167
- }, [1, "q2-popover", {
168
- "direction": [513],
538
+ }, [1, "q2-option-list", {
539
+ "role": [513],
540
+ "customSearch": [516, "custom-search"],
541
+ "noSelect": [516, "no-select"],
169
542
  "align": [513],
170
- "open": [1540],
171
- "block": [516],
172
- "minHeight": [2, "min-height"],
173
- "controlElement": [16],
174
- "currentDirection": [32],
175
- "show": [32],
176
- "toggle": [64]
177
- }, [[0, "popoverState", "popoverStateHandler"]]]);
543
+ "selectedOptions": [1040],
544
+ "multiple": [516],
545
+ "disabled": [516],
546
+ "showSelected": [1540, "show-selected"],
547
+ "type": [1],
548
+ "hasOptions": [32],
549
+ "setDefaultActiveElement": [64],
550
+ "setActiveElement": [64],
551
+ "handleExternalKeydown": [64],
552
+ "getContents": [64],
553
+ "getOptions": [64]
554
+ }, [[0, "focus", "delegateFocus"], [0, "click", "handleClick"]]]);
178
555
  function defineCustomElement() {
179
556
  if (typeof customElements === "undefined") {
180
557
  return;
181
558
  }
182
- const components = ["q2-popover"];
559
+ const components = ["q2-option-list"];
183
560
  components.forEach(tagName => { switch (tagName) {
184
- case "q2-popover":
561
+ case "q2-option-list":
185
562
  if (!customElements.get(tagName)) {
186
- customElements.define(tagName, Q2Popover);
563
+ customElements.define(tagName, Q2OptionList);
187
564
  }
188
565
  break;
189
566
  } });
190
567
  }
191
568
  defineCustomElement();
192
569
 
193
- export { Q2Popover as Q, defineCustomElement as d };
570
+ export { Q2OptionList as Q, defineCustomElement as d };