q2-tecton-elements 1.12.0-alpha.0 → 1.12.2

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 (162) hide show
  1. package/dist/cjs/{icons-4595ee47.js → icons-9bd0febe.js} +10 -0
  2. package/dist/cjs/{index-a55d3c34.js → index-773c3eec.js} +25 -12
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/q2-avatar.cjs.entry.js +1 -1
  5. package/dist/cjs/q2-btn_2.cjs.entry.js +3 -3
  6. package/dist/cjs/q2-calendar.cjs.entry.js +17 -5
  7. package/dist/cjs/q2-card.cjs.entry.js +89 -0
  8. package/dist/cjs/q2-carousel-pane.cjs.entry.js +1 -1
  9. package/dist/cjs/q2-carousel.cjs.entry.js +1 -1
  10. package/dist/cjs/q2-checkbox-group.cjs.entry.js +4 -1
  11. package/dist/cjs/q2-checkbox.cjs.entry.js +17 -6
  12. package/dist/cjs/q2-dropdown-item.cjs.entry.js +1 -1
  13. package/dist/cjs/q2-dropdown.cjs.entry.js +2 -2
  14. package/dist/cjs/q2-editable-field.cjs.entry.js +1 -1
  15. package/dist/cjs/q2-icon.cjs.entry.js +2 -2
  16. package/dist/cjs/q2-input.cjs.entry.js +12 -7
  17. package/dist/cjs/q2-loc.cjs.entry.js +1 -1
  18. package/dist/cjs/q2-message.cjs.entry.js +1 -1
  19. package/dist/cjs/q2-optgroup.cjs.entry.js +1 -1
  20. package/dist/cjs/q2-option-list.cjs.entry.js +357 -0
  21. package/dist/cjs/q2-option.cjs.entry.js +2 -10
  22. package/dist/cjs/q2-pagination.cjs.entry.js +118 -0
  23. package/dist/cjs/q2-pill.cjs.entry.js +137 -0
  24. package/dist/cjs/q2-radio-group.cjs.entry.js +40 -12
  25. package/dist/cjs/q2-radio.cjs.entry.js +20 -3
  26. package/dist/cjs/q2-section.cjs.entry.js +1 -1
  27. package/dist/cjs/q2-select.cjs.entry.js +28 -11
  28. package/dist/cjs/q2-stepper-pane.cjs.entry.js +1 -1
  29. package/dist/cjs/q2-stepper.cjs.entry.js +2 -2
  30. package/dist/cjs/q2-tab-container.cjs.entry.js +5 -1
  31. package/dist/cjs/q2-tag.cjs.entry.js +94 -0
  32. package/dist/cjs/q2-tecton-elements.cjs.js +1 -1
  33. package/dist/cjs/q2-textarea.cjs.entry.js +1 -1
  34. package/dist/collection/collection-manifest.json +5 -0
  35. package/dist/collection/components/q2-btn/styles.css +1 -1
  36. package/dist/collection/components/q2-calendar/helpers.js +6 -0
  37. package/dist/collection/components/q2-calendar/index.js +27 -4
  38. package/dist/collection/components/q2-calendar/styles.css +1 -1
  39. package/dist/collection/components/q2-card/index.js +290 -0
  40. package/dist/collection/components/q2-card/styles.css +161 -0
  41. package/dist/collection/components/q2-checkbox/index.js +32 -4
  42. package/dist/collection/components/q2-checkbox/styles.css +2 -1
  43. package/dist/collection/components/q2-checkbox-group/index.js +21 -0
  44. package/dist/collection/components/q2-dropdown/styles.css +3 -3
  45. package/dist/collection/components/q2-icon/icons.js +10 -0
  46. package/dist/collection/components/q2-input/index.js +63 -6
  47. package/dist/collection/components/q2-input/styles.css +25 -33
  48. package/dist/collection/components/q2-loading/styles.css +1 -1
  49. package/dist/collection/components/q2-option/index.js +19 -25
  50. package/dist/collection/components/q2-option/styles.css +5 -0
  51. package/dist/collection/components/q2-option-list/index.js +646 -0
  52. package/dist/collection/components/q2-option-list/styles.css +128 -0
  53. package/dist/collection/components/q2-pagination/index.js +277 -0
  54. package/dist/collection/components/q2-pagination/styles.css +120 -0
  55. package/dist/collection/components/q2-pill/index.js +324 -0
  56. package/dist/collection/components/q2-pill/styles.css +227 -0
  57. package/dist/collection/components/q2-radio/index.js +38 -1
  58. package/dist/collection/components/q2-radio-group/index.js +64 -19
  59. package/dist/collection/components/q2-select/index.js +44 -9
  60. package/dist/collection/components/q2-select/styles.css +4 -4
  61. package/dist/collection/components/q2-stepper/styles.css +8 -8
  62. package/dist/collection/components/q2-tab-container/index.js +4 -0
  63. package/dist/collection/components/q2-tag/index.js +200 -0
  64. package/dist/collection/components/q2-tag/styles.css +141 -0
  65. package/dist/collection/utils/index.js +24 -12
  66. package/dist/esm/{icons-3ee662ea.js → icons-6a143c2f.js} +10 -0
  67. package/dist/esm/{index-ec6660af.js → index-fa32f694.js} +25 -13
  68. package/dist/esm/loader.js +1 -1
  69. package/dist/esm/q2-avatar.entry.js +1 -1
  70. package/dist/esm/q2-btn_2.entry.js +3 -3
  71. package/dist/esm/q2-calendar.entry.js +17 -5
  72. package/dist/esm/q2-card.entry.js +85 -0
  73. package/dist/esm/q2-carousel-pane.entry.js +1 -1
  74. package/dist/esm/q2-carousel.entry.js +1 -1
  75. package/dist/esm/q2-checkbox-group.entry.js +4 -1
  76. package/dist/esm/q2-checkbox.entry.js +17 -6
  77. package/dist/esm/q2-dropdown-item.entry.js +1 -1
  78. package/dist/esm/q2-dropdown.entry.js +2 -2
  79. package/dist/esm/q2-editable-field.entry.js +1 -1
  80. package/dist/esm/q2-icon.entry.js +2 -2
  81. package/dist/esm/q2-input.entry.js +12 -7
  82. package/dist/esm/q2-loc.entry.js +1 -1
  83. package/dist/esm/q2-message.entry.js +1 -1
  84. package/dist/esm/q2-optgroup.entry.js +1 -1
  85. package/dist/esm/q2-option-list.entry.js +353 -0
  86. package/dist/esm/q2-option.entry.js +3 -11
  87. package/dist/esm/q2-pagination.entry.js +114 -0
  88. package/dist/esm/q2-pill.entry.js +133 -0
  89. package/dist/esm/q2-radio-group.entry.js +41 -13
  90. package/dist/esm/q2-radio.entry.js +20 -3
  91. package/dist/esm/q2-section.entry.js +1 -1
  92. package/dist/esm/q2-select.entry.js +28 -11
  93. package/dist/esm/q2-stepper-pane.entry.js +1 -1
  94. package/dist/esm/q2-stepper.entry.js +2 -2
  95. package/dist/esm/q2-tab-container.entry.js +5 -1
  96. package/dist/esm/q2-tag.entry.js +90 -0
  97. package/dist/esm/q2-tecton-elements.js +1 -1
  98. package/dist/esm/q2-textarea.entry.js +1 -1
  99. package/dist/q2-tecton-elements/p-08668234.entry.js +1 -0
  100. package/dist/q2-tecton-elements/{p-fbf7c5e6.entry.js → p-0a7cff38.entry.js} +1 -1
  101. package/dist/q2-tecton-elements/p-167a19fd.entry.js +1 -0
  102. package/dist/q2-tecton-elements/{p-06fff43d.entry.js → p-2afdc922.entry.js} +1 -1
  103. package/dist/q2-tecton-elements/{p-07a5d703.entry.js → p-30bf5f44.entry.js} +1 -1
  104. package/dist/q2-tecton-elements/{p-7e030e92.entry.js → p-34415315.entry.js} +1 -1
  105. package/dist/q2-tecton-elements/p-3c6f73cb.js +1 -0
  106. package/dist/q2-tecton-elements/p-54300d2f.entry.js +1 -0
  107. package/dist/q2-tecton-elements/p-54f0d64e.entry.js +1 -0
  108. package/dist/q2-tecton-elements/p-58d95376.entry.js +1 -0
  109. package/dist/q2-tecton-elements/p-5b906cf1.entry.js +1 -0
  110. package/dist/q2-tecton-elements/p-5effd81a.entry.js +1 -0
  111. package/dist/q2-tecton-elements/p-7ce98c1a.entry.js +1 -0
  112. package/dist/q2-tecton-elements/p-91dba21f.entry.js +1 -0
  113. package/dist/q2-tecton-elements/{p-a6f8d09a.entry.js → p-9a3c37ab.entry.js} +1 -1
  114. package/dist/q2-tecton-elements/{p-75e87cca.entry.js → p-a0248299.entry.js} +1 -1
  115. package/dist/q2-tecton-elements/p-aca8302b.entry.js +1 -0
  116. package/dist/q2-tecton-elements/{p-df182f61.entry.js → p-af202624.entry.js} +1 -1
  117. package/dist/q2-tecton-elements/{p-c5e55b9f.entry.js → p-b9c2c1d3.entry.js} +1 -1
  118. package/dist/q2-tecton-elements/p-c3d68d5c.js +1 -0
  119. package/dist/q2-tecton-elements/{p-bb2e110a.entry.js → p-c5199147.entry.js} +1 -1
  120. package/dist/q2-tecton-elements/{p-843b1ee9.entry.js → p-c5e6f7fa.entry.js} +1 -1
  121. package/dist/q2-tecton-elements/{p-50967020.entry.js → p-d3058002.entry.js} +1 -1
  122. package/dist/q2-tecton-elements/p-d65aaed2.entry.js +1 -0
  123. package/dist/q2-tecton-elements/{p-9b50c3c3.entry.js → p-d9bc6494.entry.js} +1 -1
  124. package/dist/q2-tecton-elements/p-df86f160.entry.js +1 -0
  125. package/dist/q2-tecton-elements/{p-9a977ee6.entry.js → p-e38080d2.entry.js} +1 -1
  126. package/dist/q2-tecton-elements/p-e9d69ba8.entry.js +1 -0
  127. package/dist/q2-tecton-elements/p-f98dc161.entry.js +1 -0
  128. package/dist/q2-tecton-elements/{p-7e6fc65d.entry.js → p-fa9e3825.entry.js} +1 -1
  129. package/dist/q2-tecton-elements/{p-b281c349.entry.js → p-fe6407a4.entry.js} +1 -1
  130. package/dist/q2-tecton-elements/q2-tecton-elements.esm.js +1 -1
  131. package/dist/test/elements/q2-tag-test.js +151 -0
  132. package/dist/test/helpers.js +14 -3
  133. package/dist/types/components/q2-calendar/helpers.d.ts +1 -0
  134. package/dist/types/components/q2-calendar/index.d.ts +1 -0
  135. package/dist/types/components/q2-card/index.d.ts +31 -0
  136. package/dist/types/components/q2-checkbox/index.d.ts +3 -1
  137. package/dist/types/components/q2-checkbox-group/index.d.ts +1 -0
  138. package/dist/types/components/q2-input/index.d.ts +3 -0
  139. package/dist/types/components/q2-option/index.d.ts +2 -3
  140. package/dist/types/components/q2-option-list/index.d.ts +62 -0
  141. package/dist/types/components/q2-pagination/index.d.ts +30 -0
  142. package/dist/types/components/q2-pill/index.d.ts +39 -0
  143. package/dist/types/components/q2-radio/index.d.ts +4 -1
  144. package/dist/types/components/q2-radio-group/index.d.ts +5 -1
  145. package/dist/types/components/q2-select/index.d.ts +1 -0
  146. package/dist/types/components/q2-tag/index.d.ts +28 -0
  147. package/dist/types/components.d.ts +175 -1
  148. package/dist/types/utils/index.d.ts +1 -0
  149. package/dist/types/workspace/workspace/tecton-production_release_1.12.x/packages/q2-tecton-elements/.stencil/test/elements/q2-tag-test.d.ts +1 -0
  150. package/dist/types/workspace/workspace/{_production_release_1.11.0-alpha → tecton-production_release_1.12.x}/packages/q2-tecton-elements/.stencil/test/helpers.d.ts +4 -1
  151. package/package.json +2 -2
  152. package/dist/q2-tecton-elements/p-29a37091.entry.js +0 -1
  153. package/dist/q2-tecton-elements/p-37aba2a4.js +0 -1
  154. package/dist/q2-tecton-elements/p-4cd00f1a.js +0 -1
  155. package/dist/q2-tecton-elements/p-6702eb4d.entry.js +0 -1
  156. package/dist/q2-tecton-elements/p-768e3a5d.entry.js +0 -1
  157. package/dist/q2-tecton-elements/p-943c7745.entry.js +0 -1
  158. package/dist/q2-tecton-elements/p-95a73559.entry.js +0 -1
  159. package/dist/q2-tecton-elements/p-ac859fcc.entry.js +0 -1
  160. package/dist/q2-tecton-elements/p-ccbe9158.entry.js +0 -1
  161. package/dist/q2-tecton-elements/p-db6f90ac.entry.js +0 -1
  162. package/dist/q2-tecton-elements/p-fa6eea5c.entry.js +0 -1
@@ -1,4 +1,4 @@
1
- import { Component, Prop, Element, h, Listen, Event, Watch } from '@stencil/core';
1
+ import { Component, Prop, Element, h, Listen, Event, Watch, Fragment } from '@stencil/core';
2
2
  import { createGuid, isEventFromElement, loc, overrideFocus } from 'src/utils';
3
3
  export class Q2RadioGroup {
4
4
  constructor() {
@@ -7,13 +7,16 @@ export class Q2RadioGroup {
7
7
  this.hasError = false;
8
8
  this.id = `radio-group-${createGuid()}`;
9
9
  this.onMutationObserved = () => {
10
- this.valueUpdated();
10
+ this.valueUpdated(this.value);
11
11
  this.nameUpdated();
12
12
  this.disabledUpdated();
13
+ this.readonlyUpdated();
13
14
  this.tileLayoutUpdated();
14
15
  };
15
16
  this.onInnerRadioChange = (event) => {
16
17
  event.stopImmediatePropagation();
18
+ if (this.readonly)
19
+ return;
17
20
  this.change.emit({ value: event.detail.value });
18
21
  };
19
22
  }
@@ -21,17 +24,19 @@ export class Q2RadioGroup {
21
24
  return Array.from(this.hostElement.querySelectorAll('q2-radio'));
22
25
  }
23
26
  /////// LIFECYCLE HOOK ///////
27
+ componentWillLoad() {
28
+ this.onMutationObserved();
29
+ }
24
30
  componentDidLoad() {
25
31
  const observer = new MutationObserver(this.onMutationObserved);
26
32
  observer.observe(this.hostElement, { childList: true });
27
33
  this.mutationObserver = observer;
28
- this.onMutationObserved();
29
34
  overrideFocus(this.hostElement);
30
35
  }
31
36
  /////// OBSERVERS ///////
32
- valueUpdated() {
37
+ valueUpdated(newVal) {
33
38
  this.radioElements.forEach(radio => {
34
- radio.checked = this.value === radio.value;
39
+ radio.checked = newVal === radio.value;
35
40
  });
36
41
  }
37
42
  nameUpdated() {
@@ -44,6 +49,10 @@ export class Q2RadioGroup {
44
49
  radio.groupDisabled = this.disabled;
45
50
  });
46
51
  }
52
+ readonlyUpdated() {
53
+ const readonly = this.readonly;
54
+ this.radioElements.forEach(radio => (radio.groupReadonly = readonly));
55
+ }
47
56
  tileLayoutUpdated() {
48
57
  this.radioElements.forEach(radio => {
49
58
  radio.groupTileLayout = this.tilelayout;
@@ -67,11 +76,15 @@ export class Q2RadioGroup {
67
76
  const currentValue = event.target.getAttribute('value') || this.value;
68
77
  let index = this.radioElements.findIndex(el => el === event.target || el.getAttribute('value') === currentValue);
69
78
  let sign = 0;
70
- if (['ArrowLeft', 'Left', 'ArrowUp', 'Up'].includes(event.key)) {
71
- sign = -1;
72
- }
73
- else if (['ArrowRight', 'Right', 'ArrowDown', 'Down'].includes(event.key)) {
74
- sign = 1;
79
+ switch (event.key) {
80
+ case 'ArrowLeft':
81
+ case 'ArrowUp':
82
+ sign = -1;
83
+ break;
84
+ case 'ArrowRight':
85
+ case 'ArrowDown':
86
+ sign = 1;
87
+ break;
75
88
  }
76
89
  if (index === -1 || sign === 0) {
77
90
  return;
@@ -79,19 +92,31 @@ export class Q2RadioGroup {
79
92
  index += sign;
80
93
  index = sign < 0 ? Math.max(0, index) : Math.min(this.radioElements.length - 1, index);
81
94
  event.preventDefault();
82
- this.value = this.radioElements[index].value;
95
+ if (!this.readonly) {
96
+ this.value = this.radioElements[index].value;
97
+ }
83
98
  this.radioElements[index].dispatchEvent(new FocusEvent('focus'));
84
99
  }
100
+ labelDOM() {
101
+ const { label, optional, readonly } = this;
102
+ let helpText = '';
103
+ if (readonly) {
104
+ helpText = h("span", { class: "optional-tag" }, loc('tecton.element.input.readonly'));
105
+ }
106
+ else if (optional) {
107
+ helpText = h("span", { class: "optional-tag" }, loc('tecton.element.input.optional'));
108
+ }
109
+ return (h(Fragment, null,
110
+ label && loc(label),
111
+ !!helpText && h("span", { class: "optional-tag" }, helpText)));
112
+ }
85
113
  render() {
114
+ const showLabel = this.label || this.optional || this.readonly;
86
115
  return (h("div", null,
87
- this.label || this.optional ? (h("div", { class: "group-legend" },
88
- this.label && loc(this.label),
89
- this.optional ? (h("span", { class: "optional-tag" }, loc('tecton.element.input.optional'))) : (''))) : (''),
90
- h("fieldset", { class: `q2-radio-fieldset ${this.hasError ? 'has-error' : ''}`, onChange: this.onInnerRadioChange, "aria-required": `${!this.optional}` },
91
- this.label || this.optional ? (h("legend", { class: "sr-only" },
92
- this.label && loc(this.label),
93
- this.optional ? (h("span", { class: "optional-tag" }, loc('tecton.element.input.optional'))) : (''))) : (''),
94
- this.hasError ? (h("div", { class: `error-icon-container ${this.label || this.optional ? '' : 'no-label'}` },
116
+ showLabel && h("div", { class: "group-legend" }, this.labelDOM()),
117
+ h("fieldset", { class: `q2-radio-fieldset ${this.hasError ? 'has-error' : ''}`, onChange: this.onInnerRadioChange, "aria-required": `${!this.optional}`, "aria-readonly": `${this.readonly}` },
118
+ showLabel && h("legend", { class: "sr-only" }, this.labelDOM()),
119
+ this.hasError ? (h("div", { class: `error-icon-container ${!showLabel && 'no-label'}` },
95
120
  h("q2-icon", { class: "h(4) w(4) mrg-b(2)", type: "error" }))) : (''),
96
121
  this.inputDom())));
97
122
  }
@@ -203,6 +228,23 @@ export class Q2RadioGroup {
203
228
  "attribute": "optional",
204
229
  "reflect": true
205
230
  },
231
+ "readonly": {
232
+ "type": "boolean",
233
+ "mutable": false,
234
+ "complexType": {
235
+ "original": "boolean",
236
+ "resolved": "boolean",
237
+ "references": {}
238
+ },
239
+ "required": false,
240
+ "optional": false,
241
+ "docs": {
242
+ "tags": [],
243
+ "text": ""
244
+ },
245
+ "attribute": "readonly",
246
+ "reflect": true
247
+ },
206
248
  "tilelayout": {
207
249
  "type": "boolean",
208
250
  "mutable": false,
@@ -283,6 +325,9 @@ export class Q2RadioGroup {
283
325
  }, {
284
326
  "propName": "disabled",
285
327
  "methodName": "disabledUpdated"
328
+ }, {
329
+ "propName": "readonly",
330
+ "methodName": "readonlyUpdated"
286
331
  }, {
287
332
  "propName": "tilelayout",
288
333
  "methodName": "tileLayoutUpdated"
@@ -4,6 +4,7 @@ export class Q2Select {
4
4
  constructor() {
5
5
  this.selectedOptions = [];
6
6
  this.disabled = false;
7
+ this.readonly = false;
7
8
  this.multiple = false;
8
9
  this.minRows = 3;
9
10
  this.searchable = false;
@@ -11,6 +12,7 @@ export class Q2Select {
11
12
  this.optional = false;
12
13
  this.dropdownOpen = false;
13
14
  this.onlyShowingSelected = false;
15
+ this.searchText = '';
14
16
  this.hasCustomDisplay = false;
15
17
  this.inputFocused = false;
16
18
  this.scheduledAfterRender = [];
@@ -97,9 +99,10 @@ export class Q2Select {
97
99
  event.stopPropagation();
98
100
  const { activeIndex, searchable, optionElements, multiSelectHeader } = this;
99
101
  const { key, shiftKey } = event;
100
- if (multiSelectHeader &&
101
- multiSelectHeader.contains(event.target) &&
102
- [' ', 'Enter'].includes(key))
102
+ if (this.readonly ||
103
+ (multiSelectHeader &&
104
+ multiSelectHeader.contains(event.target) &&
105
+ [' ', 'Enter'].includes(key)))
103
106
  return;
104
107
  switch (key) {
105
108
  case ' ':
@@ -230,10 +233,17 @@ export class Q2Select {
230
233
  };
231
234
  this.inputInputHandler = (event) => {
232
235
  event.stopPropagation();
236
+ const inputValue = this.inputField.value;
237
+ const eventValue = event.detail.value;
238
+ const didChangeText = inputValue !== eventValue;
239
+ const shouldClearValue = !!this.value && didChangeText;
240
+ if (shouldClearValue) {
241
+ this.selectOption('');
242
+ }
233
243
  if (!this.dropdownOpen)
234
244
  this.openDropdownWithoutActiveElement();
235
- this.searchText = event.detail.value;
236
- this.input.emit({ query: event.detail.value });
245
+ this.searchText = eventValue;
246
+ this.input.emit({ query: eventValue });
237
247
  };
238
248
  this.inputFocusHandler = () => {
239
249
  this.inputFocused = true;
@@ -415,12 +425,16 @@ export class Q2Select {
415
425
  activeOption === null || activeOption === void 0 ? void 0 : activeOption.scrollIntoView({ block: 'nearest' });
416
426
  }
417
427
  openDropdownWithoutActiveElement() {
428
+ if (this.readonly)
429
+ return;
418
430
  this.activeIndex = undefined;
419
431
  this.setActiveOption();
420
432
  this.dropdownOpen = true;
421
433
  this.scheduledAfterRender.push(this.resizeIframe);
422
434
  }
423
435
  openDropdownWithActiveElement(activeIndex) {
436
+ if (this.readonly)
437
+ return;
424
438
  this.activeIndex = activeIndex;
425
439
  this.dropdownOpen = true;
426
440
  this.setActiveOption();
@@ -530,6 +544,8 @@ export class Q2Select {
530
544
  });
531
545
  }
532
546
  onHostElementChange(event) {
547
+ if (this.readonly)
548
+ return;
533
549
  if (event.target === this.hostElement && !this.hostElement.onchange) {
534
550
  if (this.multiple) {
535
551
  this.selectedOptions = event.detail.selectedOptions;
@@ -577,11 +593,12 @@ export class Q2Select {
577
593
  }, 1000);
578
594
  }
579
595
  clickHandler(event) {
580
- const target = event.target;
581
- if (target.localName !== 'q2-option' || target.disabled) {
596
+ const selected = event.target.closest('q2-option');
597
+ if (!selected ||
598
+ (selected.hasAttribute('disabled') && selected.getAttribute('disabled') !== 'false')) {
582
599
  return;
583
600
  }
584
- this.selectOption(target.value, true);
601
+ this.selectOption(selected.getAttribute('value'), true);
585
602
  }
586
603
  keydownHandler(event) {
587
604
  this.inputKeydownHandler(event);
@@ -593,7 +610,7 @@ export class Q2Select {
593
610
  this.errors.length > 0 &&
594
611
  this.errors.map(error => loc(error))) ||
595
612
  (this.invalid && ['tecton.element.select.invalid']) ||
596
- [], disabled: this.disabled, optional: this.optional, hideLabel: this.hideLabel, ariaExpanded: this.dropdownOpen, ariaOwns: "dropdown", ariaHaspopup: "listbox", role: this.searchable ? 'combobox' : null, pseudo: !this.searchable, "test-id": "toggleDropdown", "hide-messages": true, iconRight: "chevron-down", onClick: this.inputClickHandler, onInput: this.inputInputHandler, onKeyDown: this.inputKeydownHandler, onFocus: this.inputFocusHandler, onBlur: this.inputBlurHandler, onChange: this.inputChangeHandler }),
613
+ [], disabled: this.disabled, optional: this.optional, readonly: this.readonly, hideLabel: this.hideLabel, ariaExpanded: this.dropdownOpen, ariaOwns: "dropdown", ariaHaspopup: "listbox", role: this.searchable ? 'combobox' : null, pseudo: !this.searchable, "test-id": "toggleDropdown", "hide-messages": true, iconRight: "chevron-down", onClick: this.inputClickHandler, onInput: this.inputInputHandler, onKeyDown: this.inputKeydownHandler, onFocus: this.inputFocusHandler, onBlur: this.inputBlurHandler, onChange: this.inputChangeHandler }),
597
614
  h("div", { class: "custom-display-content", hidden: !this.hasCustomDisplay || !!this.searchText, onClick: this.onCustomDisplayClick },
598
615
  h("slot", { name: "q2-select-display" })),
599
616
  this.optionsDropdown()));
@@ -726,6 +743,24 @@ export class Q2Select {
726
743
  "reflect": true,
727
744
  "defaultValue": "false"
728
745
  },
746
+ "readonly": {
747
+ "type": "boolean",
748
+ "mutable": false,
749
+ "complexType": {
750
+ "original": "boolean",
751
+ "resolved": "boolean",
752
+ "references": {}
753
+ },
754
+ "required": false,
755
+ "optional": false,
756
+ "docs": {
757
+ "tags": [],
758
+ "text": ""
759
+ },
760
+ "attribute": "readonly",
761
+ "reflect": true,
762
+ "defaultValue": "false"
763
+ },
729
764
  "invalid": {
730
765
  "type": "boolean",
731
766
  "mutable": false,
@@ -136,9 +136,9 @@ button {
136
136
  .custom-display-content {
137
137
  position: absolute;
138
138
  bottom: 0;
139
- left: calc(var(--tct-scale-2, var(--app-scale-2, 10px)) + 1px);
139
+ left: calc(var-list(--tct-scale-2, --app-scale-2, 10px) + 1px);
140
140
  height: 44px;
141
- width: calc(100% - 34px - var(--tct-scale-3, var(--app-scale-3, 15px)));
141
+ width: calc(100% - 34px - var-list(--tct-scale-3, --app-scale-3, 15px));
142
142
  overflow: hidden;
143
143
  cursor: pointer;
144
144
  transition: left var(--tct-tween-2, var(--app-tween-1, 0.2s ease));
@@ -151,11 +151,11 @@ button {
151
151
 
152
152
  .is-searchable.is-focused .custom-display-content,
153
153
  .is-searchable .custom-display-content:active {
154
- left: calc(var(--tct-scale-3, var(--app-scale-3, 15px)) + 1px);
154
+ left: calc(var-list(--tct-scale-3, --app-scale-3, 15px) + 1px);
155
155
  }
156
156
 
157
157
  .has-error .custom-display-content {
158
- width: calc(100% - 68px - var(--tct-scale-3, var(--app-scale-3, 15px)));
158
+ width: calc(100% - 68px - var-list(--tct-scale-3, --app-scale-3, 15px));
159
159
  }
160
160
 
161
161
  .dropdown-open .q2-select-dropdown {
@@ -141,7 +141,7 @@ li {
141
141
  }
142
142
  .step-btn[aria-disabled], .step-btn[aria-disabled] + hr {
143
143
  --comp-bullet-font-color: var(--tct-stepper-bullet-inactive-font-color, var(--t-stepper-bullet-inactive-font-color, var(--t-text, #4d4d4d)));
144
- --comp-bullet-bg: var(--tct-stepper-bullet-inactive-bg, var(--t-stepper-bullet-inactive-bg, var(--t-gray12, #d9d9d9)));
144
+ --comp-bullet-bg: var(--tct-stepper-bullet-inactive-bg, var(--t-stepper-bullet-inactive-bg, var(--t-gray-12, #d9d9d9)));
145
145
  }
146
146
 
147
147
  .step-bubble {
@@ -171,9 +171,9 @@ li {
171
171
  }
172
172
 
173
173
  hr {
174
- width: calc(var(--comp-step-width) - var(--comp-step-gap) - var(--comp-bullet-gap) - var(--comp-bullet-size));
175
- top: calc(var(--comp-bullet-size) / 2 + var(--comp-bullet-gap));
176
- left: calc(var(--comp-step-width) * -0.5 + var(--comp-step-gap) + var(--comp-bullet-gap));
174
+ width: calc( var(--comp-step-width) - var(--comp-step-gap) - var(--comp-bullet-gap) - var(--comp-bullet-size) );
175
+ top: calc(calc(var(--comp-bullet-size) / 2) + var(--comp-bullet-gap));
176
+ left: calc(calc(var(--comp-step-width) * -0.5) + var(--comp-step-gap) + var(--comp-bullet-gap));
177
177
  border: 0;
178
178
  border-top: 1px solid var(--comp-bullet-bg);
179
179
  height: 0;
@@ -190,11 +190,11 @@ hr {
190
190
  color: var(--tct-stepper-title-color, var(--t-stepper-title-color, var(--t-text, #4d4d4d)));
191
191
  font-size: var(--tct-stepper-title-font-size, var(--t-stepper-title-font-size, var(--app-font-size-small, 12px)));
192
192
  height: 1.5em;
193
+ text-overflow: ellipsis;
194
+ overflow: hidden;
193
195
  display: -webkit-box;
194
196
  -webkit-line-clamp: 2;
195
197
  -webkit-box-orient: vertical;
196
- overflow: hidden;
197
- text-overflow: ellipsis;
198
198
  }
199
199
  [aria-selected] .step-label {
200
200
  font-weight: var(--tct-stepper-active-font-weight, var(--t-stepper-active-font-weight, 600));
@@ -206,11 +206,11 @@ hr {
206
206
  .step-description {
207
207
  color: var(--tct-stepper-description-color, var(--t-stepper-description-color, var(--t-textA, rgba(77, 77, 77, 0.77))));
208
208
  font-size: var(--tct-stepper-description-font-size, var(--t-stepper-description-font-size, var(--app-font-size-small, 12px)));
209
+ text-overflow: ellipsis;
210
+ overflow: hidden;
209
211
  display: -webkit-box;
210
212
  -webkit-line-clamp: 4;
211
213
  -webkit-box-orient: vertical;
212
- overflow: hidden;
213
- text-overflow: ellipsis;
214
214
  padding-bottom: 0.2em;
215
215
  }
216
216
 
@@ -166,6 +166,9 @@ export class Q2TabContainer {
166
166
  overrideFocus(this.hostElement);
167
167
  const index = this.tabs.findIndex(el => el.value === this.value);
168
168
  this.scheduledAfterRender.push(() => {
169
+ const hasTabs = this.tabs.length > 0;
170
+ if (!hasTabs)
171
+ return;
169
172
  const tab = this.moveFocus(Math.max(index, 0));
170
173
  this.value = tab.dataset.value;
171
174
  tab.blur();
@@ -174,6 +177,7 @@ export class Q2TabContainer {
174
177
  disconnectedCallback() {
175
178
  this.resizeObserver.disconnect();
176
179
  this.mutationObserver.disconnect();
180
+ this.resizeObserver = null;
177
181
  this.mutationObserver = null;
178
182
  }
179
183
  ///////// Observers /////////
@@ -0,0 +1,200 @@
1
+ import { Component, State, Prop, h, Listen, Element, Fragment, Event } from '@stencil/core';
2
+ import { isEventFromElement, loc, overrideFocus } from 'src/utils';
3
+ export class Q2Tag {
4
+ constructor() {
5
+ this.role = 'listitem';
6
+ /// Getters ///
7
+ /// Helpers
8
+ this.determineHasOptions = () => {
9
+ const hasOptions = !!this.hostElement.querySelectorAll('q2-option').length;
10
+ this.hasOptions = hasOptions;
11
+ };
12
+ /// Event Handlers ///
13
+ this.handleChange = event => {
14
+ event.stopPropagation();
15
+ if (!this.hasOptions)
16
+ return;
17
+ const { value } = event.detail;
18
+ this.click.emit({ value: value });
19
+ };
20
+ this.handleClick = (event) => {
21
+ event.stopPropagation();
22
+ this.optionList.toggle();
23
+ };
24
+ this.handleKeydown = (event) => {
25
+ this.optionList.handleExternalKeydown(event);
26
+ };
27
+ this.handleButtonFocusout = (event) => {
28
+ var _a;
29
+ const relatedTarget = event.relatedTarget;
30
+ if ((_a = (relatedTarget === null || relatedTarget === void 0 ? void 0 : relatedTarget.tagName) === 'Q2-OPTION') !== null && _a !== void 0 ? _a : false)
31
+ return;
32
+ this.open = false;
33
+ };
34
+ this.handleOptionListFocusout = (event) => {
35
+ const relatedTarget = event.relatedTarget;
36
+ if (relatedTarget && !(event.relatedTarget instanceof HTMLElement))
37
+ return;
38
+ if (relatedTarget && relatedTarget.closest('.btn-wrapper'))
39
+ return;
40
+ this.open = false;
41
+ };
42
+ this.handleWrapperClick = () => {
43
+ this.dropdownBtn.focus();
44
+ this.dropdownBtn.click();
45
+ };
46
+ }
47
+ /// LifeCycle Hooks ///
48
+ componentWillLoad() {
49
+ const observer = new MutationObserver(this.determineHasOptions);
50
+ observer.observe(this.hostElement, { childList: true, attributes: true });
51
+ this.mutationObserver = observer;
52
+ }
53
+ componentDidLoad() {
54
+ overrideFocus(this.hostElement);
55
+ }
56
+ disconnectedCallback() {
57
+ this.mutationObserver.disconnect();
58
+ this.mutationObserver = null;
59
+ }
60
+ /// Listeners ///
61
+ delegateFocus(event) {
62
+ if (!isEventFromElement(event, this.hostElement))
63
+ return;
64
+ if (!this.hasOptions)
65
+ return;
66
+ this.dropdownBtn.focus();
67
+ }
68
+ optionListStateEvent({ detail: { open } }) {
69
+ this.open = open;
70
+ if (!open)
71
+ this.dropdownBtn.focus();
72
+ }
73
+ /// DOM ///
74
+ render() {
75
+ const { hasOptions, open } = this;
76
+ let wrapperClassNames = ['tag-wrapper'];
77
+ if (hasOptions)
78
+ wrapperClassNames.push('has-options');
79
+ return (h(Fragment, null,
80
+ h("div", { class: wrapperClassNames.join(' '), onClick: e => e.stopPropagation() },
81
+ h("div", { class: "tag" }, this.label),
82
+ this.hasOptions && (h("div", { class: "btn-wrapper", onClick: this.handleWrapperClick },
83
+ h("button", { ref: el => (this.dropdownBtn = el), "test-id": "btn-control", onClick: this.handleClick, onKeyDown: this.handleKeydown, onFocusout: this.handleButtonFocusout, "aria-controls": "option-list", "aria-haspopup": "true", "aria-expanded": open ? 'true' : 'false', "aria-label": loc('tecton.element.tag.viewOptions') },
84
+ h("q2-icon", { type: "options" }))))),
85
+ this.hasOptions && (h("q2-option-list", { id: "option-list", ref: el => (this.optionList = el), open: this.open, onChange: this.handleChange, onFocusout: this.handleOptionListFocusout, align: "right", type: "menu", "no-select": true },
86
+ h("slot", null)))));
87
+ }
88
+ static get is() { return "q2-tag"; }
89
+ static get encapsulation() { return "shadow"; }
90
+ static get originalStyleUrls() { return {
91
+ "$": ["styles.scss"]
92
+ }; }
93
+ static get styleUrls() { return {
94
+ "$": ["styles.css"]
95
+ }; }
96
+ static get properties() { return {
97
+ "open": {
98
+ "type": "boolean",
99
+ "mutable": true,
100
+ "complexType": {
101
+ "original": "boolean",
102
+ "resolved": "boolean",
103
+ "references": {}
104
+ },
105
+ "required": false,
106
+ "optional": false,
107
+ "docs": {
108
+ "tags": [],
109
+ "text": ""
110
+ },
111
+ "attribute": "open",
112
+ "reflect": true
113
+ },
114
+ "role": {
115
+ "type": "string",
116
+ "mutable": false,
117
+ "complexType": {
118
+ "original": "string",
119
+ "resolved": "string",
120
+ "references": {}
121
+ },
122
+ "required": false,
123
+ "optional": false,
124
+ "docs": {
125
+ "tags": [],
126
+ "text": ""
127
+ },
128
+ "attribute": "role",
129
+ "reflect": true,
130
+ "defaultValue": "'listitem'"
131
+ },
132
+ "label": {
133
+ "type": "string",
134
+ "mutable": false,
135
+ "complexType": {
136
+ "original": "string",
137
+ "resolved": "string",
138
+ "references": {}
139
+ },
140
+ "required": false,
141
+ "optional": false,
142
+ "docs": {
143
+ "tags": [],
144
+ "text": ""
145
+ },
146
+ "attribute": "label",
147
+ "reflect": true
148
+ },
149
+ "theme": {
150
+ "type": "string",
151
+ "mutable": false,
152
+ "complexType": {
153
+ "original": "'primary' | 'secondary' | 'tertiary'",
154
+ "resolved": "\"primary\" | \"secondary\" | \"tertiary\"",
155
+ "references": {}
156
+ },
157
+ "required": false,
158
+ "optional": false,
159
+ "docs": {
160
+ "tags": [],
161
+ "text": ""
162
+ },
163
+ "attribute": "theme",
164
+ "reflect": true
165
+ }
166
+ }; }
167
+ static get states() { return {
168
+ "hasOptions": {}
169
+ }; }
170
+ static get events() { return [{
171
+ "method": "click",
172
+ "name": "click",
173
+ "bubbles": true,
174
+ "cancelable": true,
175
+ "composed": true,
176
+ "docs": {
177
+ "tags": [],
178
+ "text": ""
179
+ },
180
+ "complexType": {
181
+ "original": "{ value: string }",
182
+ "resolved": "{ value: string; }",
183
+ "references": {}
184
+ }
185
+ }]; }
186
+ static get elementRef() { return "hostElement"; }
187
+ static get listeners() { return [{
188
+ "name": "focus",
189
+ "method": "delegateFocus",
190
+ "target": undefined,
191
+ "capture": false,
192
+ "passive": false
193
+ }, {
194
+ "name": "optionListState",
195
+ "method": "optionListStateEvent",
196
+ "target": undefined,
197
+ "capture": false,
198
+ "passive": false
199
+ }]; }
200
+ }