q2-tecton-elements 1.71.2 → 1.72.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 (265) hide show
  1. package/dist/bundle-report.json +1282 -594
  2. package/dist/cjs/click-elsewhere_3.cjs.entry.js +10 -9
  3. package/dist/cjs/{index-SpDCZABA.js → index-BY3aao8R.js} +1 -1
  4. package/dist/cjs/loader.cjs.js +1 -1
  5. package/dist/cjs/{q2-action-group_2.cjs.entry.js → q2-action-group.cjs.entry.js} +1 -89
  6. package/dist/cjs/q2-action-sheet.cjs.entry.js +1 -1
  7. package/dist/cjs/q2-badge_2.cjs.entry.js +113 -12
  8. package/dist/cjs/q2-btn_2.cjs.entry.js +2 -2
  9. package/dist/cjs/q2-calendar.cjs.entry.js +7 -5
  10. package/dist/cjs/q2-card-image.cjs.entry.js +4 -4
  11. package/dist/cjs/q2-card.cjs.entry.js +1 -1
  12. package/dist/cjs/q2-carousel-pane.cjs.entry.js +1 -1
  13. package/dist/cjs/q2-carousel.cjs.entry.js +1 -1
  14. package/dist/cjs/q2-chart-area.cjs.entry.js +1 -1
  15. package/dist/cjs/q2-chart-bar.cjs.entry.js +1 -1
  16. package/dist/cjs/q2-chart-donut.cjs.entry.js +1 -1
  17. package/dist/cjs/q2-checkbox-group.cjs.entry.js +2 -2
  18. package/dist/cjs/q2-checkbox_2.cjs.entry.js +3 -3
  19. package/dist/cjs/q2-context.cjs.entry.js +4 -3
  20. package/dist/cjs/q2-data-table.cjs.entry.js +2 -2
  21. package/dist/cjs/q2-detail.cjs.entry.js +1 -1
  22. package/dist/cjs/q2-dropdown-item.cjs.entry.js +1 -1
  23. package/dist/cjs/q2-dropdown.cjs.entry.js +3 -3
  24. package/dist/cjs/q2-editable-field.cjs.entry.js +38 -37
  25. package/dist/cjs/q2-file-picker.cjs.entry.js +60 -4
  26. package/dist/cjs/q2-icon.cjs.entry.js +1 -1
  27. package/dist/cjs/q2-item.cjs.entry.js +2 -2
  28. package/dist/cjs/q2-link_2.cjs.entry.js +1 -1
  29. package/dist/cjs/q2-loc.cjs.entry.js +1 -1
  30. package/dist/cjs/q2-message.cjs.entry.js +2 -2
  31. package/dist/cjs/q2-meter.cjs.entry.js +1 -1
  32. package/dist/cjs/q2-modal.cjs.entry.js +59 -17
  33. package/dist/cjs/q2-month-picker.cjs.entry.js +1 -1
  34. package/dist/cjs/q2-optgroup.cjs.entry.js +1 -1
  35. package/dist/cjs/q2-option.cjs.entry.js +1 -1
  36. package/dist/cjs/q2-otp.cjs.entry.js +1 -1
  37. package/dist/cjs/q2-pagination.cjs.entry.js +1 -1
  38. package/dist/cjs/q2-pill.cjs.entry.js +2 -2
  39. package/dist/cjs/q2-radio-group.cjs.entry.js +22 -4
  40. package/dist/cjs/q2-radio.cjs.entry.js +3 -3
  41. package/dist/cjs/q2-relative-time.cjs.entry.js +3 -3
  42. package/dist/cjs/q2-resize-observer.cjs.entry.js +92 -0
  43. package/dist/cjs/q2-search.cjs.entry.js +2 -2
  44. package/dist/cjs/q2-section.cjs.entry.js +7 -7
  45. package/dist/cjs/q2-select.cjs.entry.js +35 -19
  46. package/dist/cjs/q2-stepper-pane.cjs.entry.js +2 -2
  47. package/dist/cjs/q2-stepper-vertical.cjs.entry.js +2 -2
  48. package/dist/cjs/q2-stepper.cjs.entry.js +1 -1
  49. package/dist/cjs/q2-surface.cjs.entry.js +1 -1
  50. package/dist/cjs/q2-tab-container.cjs.entry.js +2 -2
  51. package/dist/cjs/q2-tab-pane.cjs.entry.js +1 -1
  52. package/dist/cjs/q2-tecton-elements.cjs.js +1 -1
  53. package/dist/cjs/q2-textarea.cjs.entry.js +1 -1
  54. package/dist/cjs/q2-toast.cjs.entry.js +1 -1
  55. package/dist/cjs/q2-tooltip.cjs.entry.js +1 -1
  56. package/dist/cjs/tecton-tab-pane.cjs.entry.js +5 -3
  57. package/dist/collection/components/q2-btn/q2-btn.css +79 -21
  58. package/dist/collection/components/q2-btn/test/q2-btn-test.vr.js +156 -3
  59. package/dist/collection/components/q2-calendar/q2-calendar.css +3 -0
  60. package/dist/collection/components/q2-calendar/q2-calendar.js +5 -3
  61. package/dist/collection/components/q2-calendar/test/q2-calendar-test.vr.js +23 -2
  62. package/dist/collection/components/q2-card/test/q2-card-test.vr.js +4 -0
  63. package/dist/collection/components/q2-card-image/q2-card-image.css +89 -134
  64. package/dist/collection/components/q2-card-image/q2-card-image.js +4 -4
  65. package/dist/collection/components/q2-card-image/test/q2-card-image-test.vr.js +4 -0
  66. package/dist/collection/components/q2-carousel/test/q2-carousel-test.vr.js +13 -0
  67. package/dist/collection/components/q2-checkbox/q2-checkbox.css +2 -2
  68. package/dist/collection/components/q2-checkbox-group/q2-checkbox-group.css +2 -0
  69. package/dist/collection/components/q2-context/q2-context.css +5 -0
  70. package/dist/collection/components/q2-context/q2-context.js +2 -1
  71. package/dist/collection/components/q2-context/test/q2-context-test.vr.js +11 -1
  72. package/dist/collection/components/q2-data-table/q2-data-table.css +3 -0
  73. package/dist/collection/components/q2-data-table/test/q2-data-table-test.vr.js +5 -0
  74. package/dist/collection/components/q2-dropdown/q2-dropdown.css +2 -0
  75. package/dist/collection/components/q2-dropdown/q2-dropdown.js +1 -1
  76. package/dist/collection/components/q2-dropdown/test/q2-dropdown-test.vr.js +30 -0
  77. package/dist/collection/components/q2-editable-field/q2-editable-field.css +2 -0
  78. package/dist/collection/components/q2-editable-field/q2-editable-field.js +38 -43
  79. package/dist/collection/components/q2-file-picker/q2-file-picker.css +27 -0
  80. package/dist/collection/components/q2-file-picker/q2-file-picker.js +98 -2
  81. package/dist/collection/components/q2-file-picker/test/q2-file-picker-test.vr.js +22 -0
  82. package/dist/collection/components/q2-input/q2-input.css +67 -1
  83. package/dist/collection/components/q2-input/q2-input.js +155 -13
  84. package/dist/collection/components/q2-input/test/q2-input-test.vr.js +35 -0
  85. package/dist/collection/components/q2-item/q2-item.css +3 -1
  86. package/dist/collection/components/q2-item/test/q2-item-test.vr.js +6 -0
  87. package/dist/collection/components/q2-message/q2-message.css +5 -5
  88. package/dist/collection/components/q2-modal/q2-modal.css +40 -3
  89. package/dist/collection/components/q2-modal/q2-modal.js +100 -16
  90. package/dist/collection/components/q2-modal/test/q2-modal-test.vr.js +25 -0
  91. package/dist/collection/components/q2-pill/q2-pill.css +2 -2
  92. package/dist/collection/components/q2-popover/q2-popover.css +3 -2
  93. package/dist/collection/components/q2-popover/q2-popover.js +8 -7
  94. package/dist/collection/components/q2-radio/q2-radio.css +158 -104
  95. package/dist/collection/components/q2-radio/q2-radio.js +1 -1
  96. package/dist/collection/components/q2-radio/test/q2-radio-test.vr.js +25 -2
  97. package/dist/collection/components/q2-radio-group/q2-radio-group.css +39 -2
  98. package/dist/collection/components/q2-radio-group/q2-radio-group.js +68 -2
  99. package/dist/collection/components/q2-radio-group/test/q2-radio-group-test.vr.js +43 -1
  100. package/dist/collection/components/q2-relative-time/q2-relative-time.js +2 -2
  101. package/dist/collection/components/q2-search/q2-search.css +2 -0
  102. package/dist/collection/components/q2-section/q2-section.css +2 -0
  103. package/dist/collection/components/q2-section/q2-section.js +6 -6
  104. package/dist/collection/components/q2-select/q2-select.css +3 -0
  105. package/dist/collection/components/q2-select/q2-select.js +37 -18
  106. package/dist/collection/components/q2-select/test/q2-select-test.vr.js +13 -0
  107. package/dist/collection/components/q2-stepper-pane/q2-stepper-pane.js +1 -1
  108. package/dist/collection/components/q2-stepper-vertical/q2-stepper-vertical.js +1 -1
  109. package/dist/collection/components/q2-surface/q2-surface.js +1 -1
  110. package/dist/collection/components/q2-tab-container/q2-tab-container.js +1 -1
  111. package/dist/collection/components/q2-tab-pane/q2-tab-pane.js +1 -1
  112. package/dist/collection/components/q2-tag/q2-tag.js +1 -1
  113. package/dist/collection/components/tecton-tab-pane/tecton-tab-pane.js +5 -3
  114. package/dist/collection/utils/index.js +1 -1
  115. package/dist/collection/utils/test/vr-helpers.js +16 -2
  116. package/dist/components/index2.js +1 -1
  117. package/dist/components/q2-btn2.js +1 -1
  118. package/dist/components/q2-calendar.js +11 -9
  119. package/dist/components/q2-card-image.js +24 -24
  120. package/dist/components/q2-checkbox-group.js +6 -6
  121. package/dist/components/q2-checkbox2.js +1 -1
  122. package/dist/components/q2-context.js +27 -26
  123. package/dist/components/q2-data-table.js +1 -1
  124. package/dist/components/q2-dropdown.js +21 -21
  125. package/dist/components/q2-editable-field.js +33 -35
  126. package/dist/components/q2-file-picker.js +70 -10
  127. package/dist/components/q2-input2.js +268 -163
  128. package/dist/components/q2-item2.js +1 -1
  129. package/dist/components/q2-message2.js +24 -24
  130. package/dist/components/q2-modal.js +96 -78
  131. package/dist/components/q2-pill.js +1 -1
  132. package/dist/components/q2-popover2.js +29 -26
  133. package/dist/components/q2-radio-group.js +70 -40
  134. package/dist/components/q2-radio.js +40 -55
  135. package/dist/components/q2-relative-time.js +5 -5
  136. package/dist/components/q2-search.js +1 -1
  137. package/dist/components/q2-section.js +33 -33
  138. package/dist/components/q2-select2.js +46 -39
  139. package/dist/components/q2-stepper-pane.js +15 -11
  140. package/dist/components/q2-stepper-vertical.js +4 -4
  141. package/dist/components/q2-surface.js +3 -3
  142. package/dist/components/q2-tab-container.js +21 -21
  143. package/dist/components/q2-tab-pane.js +2 -2
  144. package/dist/components/q2-tag2.js +5 -5
  145. package/dist/components/tecton-tab-pane.js +8 -7
  146. package/dist/esm/click-elsewhere_3.entry.js +10 -9
  147. package/dist/esm/{index-Cps4jSQM.js → index-DJw6Feh0.js} +1 -1
  148. package/dist/esm/loader.js +1 -1
  149. package/dist/esm/{q2-action-group_2.entry.js → q2-action-group.entry.js} +3 -90
  150. package/dist/esm/q2-action-sheet.entry.js +1 -1
  151. package/dist/esm/q2-badge_2.entry.js +113 -12
  152. package/dist/esm/q2-btn_2.entry.js +2 -2
  153. package/dist/esm/q2-calendar.entry.js +7 -5
  154. package/dist/esm/q2-card-image.entry.js +4 -4
  155. package/dist/esm/q2-card.entry.js +1 -1
  156. package/dist/esm/q2-carousel-pane.entry.js +1 -1
  157. package/dist/esm/q2-carousel.entry.js +1 -1
  158. package/dist/esm/q2-chart-area.entry.js +1 -1
  159. package/dist/esm/q2-chart-bar.entry.js +1 -1
  160. package/dist/esm/q2-chart-donut.entry.js +1 -1
  161. package/dist/esm/q2-checkbox-group.entry.js +2 -2
  162. package/dist/esm/q2-checkbox_2.entry.js +3 -3
  163. package/dist/esm/q2-context.entry.js +4 -3
  164. package/dist/esm/q2-data-table.entry.js +2 -2
  165. package/dist/esm/q2-detail.entry.js +1 -1
  166. package/dist/esm/q2-dropdown-item.entry.js +1 -1
  167. package/dist/esm/q2-dropdown.entry.js +3 -3
  168. package/dist/esm/q2-editable-field.entry.js +38 -37
  169. package/dist/esm/q2-file-picker.entry.js +60 -4
  170. package/dist/esm/q2-icon.entry.js +1 -1
  171. package/dist/esm/q2-item.entry.js +2 -2
  172. package/dist/esm/q2-link_2.entry.js +1 -1
  173. package/dist/esm/q2-loc.entry.js +1 -1
  174. package/dist/esm/q2-message.entry.js +2 -2
  175. package/dist/esm/q2-meter.entry.js +1 -1
  176. package/dist/esm/q2-modal.entry.js +59 -17
  177. package/dist/esm/q2-month-picker.entry.js +1 -1
  178. package/dist/esm/q2-optgroup.entry.js +1 -1
  179. package/dist/esm/q2-option.entry.js +1 -1
  180. package/dist/esm/q2-otp.entry.js +1 -1
  181. package/dist/esm/q2-pagination.entry.js +1 -1
  182. package/dist/esm/q2-pill.entry.js +2 -2
  183. package/dist/esm/q2-radio-group.entry.js +22 -4
  184. package/dist/esm/q2-radio.entry.js +3 -3
  185. package/dist/esm/q2-relative-time.entry.js +3 -3
  186. package/dist/esm/q2-resize-observer.entry.js +90 -0
  187. package/dist/esm/q2-search.entry.js +2 -2
  188. package/dist/esm/q2-section.entry.js +7 -7
  189. package/dist/esm/q2-select.entry.js +35 -19
  190. package/dist/esm/q2-stepper-pane.entry.js +2 -2
  191. package/dist/esm/q2-stepper-vertical.entry.js +2 -2
  192. package/dist/esm/q2-stepper.entry.js +1 -1
  193. package/dist/esm/q2-surface.entry.js +1 -1
  194. package/dist/esm/q2-tab-container.entry.js +2 -2
  195. package/dist/esm/q2-tab-pane.entry.js +1 -1
  196. package/dist/esm/q2-tecton-elements.js +1 -1
  197. package/dist/esm/q2-textarea.entry.js +1 -1
  198. package/dist/esm/q2-toast.entry.js +1 -1
  199. package/dist/esm/q2-tooltip.entry.js +1 -1
  200. package/dist/esm/tecton-tab-pane.entry.js +5 -3
  201. package/dist/q2-tecton-elements/click-elsewhere_3.entry.js +32 -29
  202. package/dist/q2-tecton-elements/{index-Cps4jSQM.js → index-DJw6Feh0.js} +1 -1
  203. package/dist/q2-tecton-elements/{q2-action-group_2.entry.js → q2-action-group.entry.js} +35 -113
  204. package/dist/q2-tecton-elements/q2-action-sheet.entry.js +1 -1
  205. package/dist/q2-tecton-elements/q2-badge_2.entry.js +240 -140
  206. package/dist/q2-tecton-elements/q2-btn_2.entry.js +2 -2
  207. package/dist/q2-tecton-elements/q2-calendar.entry.js +14 -12
  208. package/dist/q2-tecton-elements/q2-card-image.entry.js +9 -9
  209. package/dist/q2-tecton-elements/q2-card.entry.js +1 -1
  210. package/dist/q2-tecton-elements/q2-carousel-pane.entry.js +1 -1
  211. package/dist/q2-tecton-elements/q2-carousel.entry.js +1 -1
  212. package/dist/q2-tecton-elements/q2-chart-area.entry.js +31 -31
  213. package/dist/q2-tecton-elements/q2-chart-bar.entry.js +16 -16
  214. package/dist/q2-tecton-elements/q2-chart-donut.entry.js +6 -6
  215. package/dist/q2-tecton-elements/q2-checkbox-group.entry.js +2 -2
  216. package/dist/q2-tecton-elements/q2-checkbox_2.entry.js +7 -7
  217. package/dist/q2-tecton-elements/q2-context.entry.js +22 -21
  218. package/dist/q2-tecton-elements/q2-data-table.entry.js +34 -34
  219. package/dist/q2-tecton-elements/q2-detail.entry.js +1 -1
  220. package/dist/q2-tecton-elements/q2-dropdown-item.entry.js +1 -1
  221. package/dist/q2-tecton-elements/q2-dropdown.entry.js +15 -15
  222. package/dist/q2-tecton-elements/q2-editable-field.entry.js +38 -40
  223. package/dist/q2-tecton-elements/q2-file-picker.entry.js +61 -6
  224. package/dist/q2-tecton-elements/q2-icon.entry.js +1 -1
  225. package/dist/q2-tecton-elements/q2-item.entry.js +2 -2
  226. package/dist/q2-tecton-elements/q2-link_2.entry.js +1 -1
  227. package/dist/q2-tecton-elements/q2-loc.entry.js +1 -1
  228. package/dist/q2-tecton-elements/q2-message.entry.js +24 -24
  229. package/dist/q2-tecton-elements/q2-meter.entry.js +1 -1
  230. package/dist/q2-tecton-elements/q2-modal.entry.js +61 -45
  231. package/dist/q2-tecton-elements/q2-month-picker.entry.js +1 -1
  232. package/dist/q2-tecton-elements/q2-optgroup.entry.js +11 -11
  233. package/dist/q2-tecton-elements/q2-option.entry.js +1 -1
  234. package/dist/q2-tecton-elements/q2-otp.entry.js +1 -1
  235. package/dist/q2-tecton-elements/q2-pagination.entry.js +1 -1
  236. package/dist/q2-tecton-elements/q2-pill.entry.js +2 -2
  237. package/dist/q2-tecton-elements/q2-radio-group.entry.js +55 -34
  238. package/dist/q2-tecton-elements/q2-radio.entry.js +38 -53
  239. package/dist/q2-tecton-elements/q2-relative-time.entry.js +12 -12
  240. package/dist/q2-tecton-elements/q2-resize-observer.entry.js +81 -0
  241. package/dist/q2-tecton-elements/q2-search.entry.js +2 -2
  242. package/dist/q2-tecton-elements/q2-section.entry.js +33 -33
  243. package/dist/q2-tecton-elements/q2-select.entry.js +27 -20
  244. package/dist/q2-tecton-elements/q2-stepper-pane.entry.js +20 -16
  245. package/dist/q2-tecton-elements/q2-stepper-vertical.entry.js +5 -5
  246. package/dist/q2-tecton-elements/q2-stepper.entry.js +1 -1
  247. package/dist/q2-tecton-elements/q2-surface.entry.js +3 -3
  248. package/dist/q2-tecton-elements/q2-tab-container.entry.js +20 -20
  249. package/dist/q2-tecton-elements/q2-tab-pane.entry.js +4 -4
  250. package/dist/q2-tecton-elements/q2-tecton-elements.esm.js +1 -1
  251. package/dist/q2-tecton-elements/q2-textarea.entry.js +1 -1
  252. package/dist/q2-tecton-elements/q2-toast.entry.js +1 -1
  253. package/dist/q2-tecton-elements/q2-tooltip.entry.js +1 -1
  254. package/dist/q2-tecton-elements/tecton-tab-pane.entry.js +8 -7
  255. package/dist/types/components/q2-card-image/q2-card-image.d.ts +1 -1
  256. package/dist/types/components/q2-dropdown/test/q2-dropdown-test.vr.d.ts +1 -0
  257. package/dist/types/components/q2-editable-field/q2-editable-field.d.ts +6 -1
  258. package/dist/types/components/q2-file-picker/q2-file-picker.d.ts +20 -0
  259. package/dist/types/components/q2-input/q2-input.d.ts +28 -2
  260. package/dist/types/components/q2-modal/q2-modal.d.ts +10 -1
  261. package/dist/types/components/q2-radio-group/q2-radio-group.d.ts +14 -0
  262. package/dist/types/components/q2-select/q2-select.d.ts +8 -2
  263. package/dist/types/components.d.ts +119 -11
  264. package/dist/types/utils/test/vr-helpers.d.ts +2 -0
  265. package/package.json +3 -3
@@ -42,11 +42,38 @@ const VARIANTS = [
42
42
  html: `<q2-radio-group label="Hidden" name="g1" hide-label>${RADIOS}</q2-radio-group>`,
43
43
  states: ['resting'],
44
44
  },
45
+ {
46
+ name: 'horizontal',
47
+ html: `<q2-radio-group label="Group" name="g1" orientation="horizontal">${RADIOS}</q2-radio-group>`,
48
+ states: ['resting'],
49
+ },
50
+ {
51
+ name: 'horizontal-centered',
52
+ html: `<q2-radio-group label="Group" name="g1" orientation="horizontal" style="--tct-radio-group-horizontal-gap: 20px; --tct-radio-group-justify-content: center">${RADIOS}</q2-radio-group>`,
53
+ states: ['resting'],
54
+ },
55
+ {
56
+ name: 'horizontal-mobile',
57
+ html: `<q2-radio-group label="Group" name="g1" orientation="horizontal">${RADIOS}</q2-radio-group>`,
58
+ states: ['resting'],
59
+ viewport: { width: 375, height: 600 },
60
+ },
61
+ {
62
+ name: 'vertical-with-separators',
63
+ html: `<q2-radio-group label="Group" name="g1" style="--tct-radio-group-separator-width: 4px; --tct-radio-min-height: 48px">${RADIOS}</q2-radio-group>`,
64
+ states: ['resting'],
65
+ },
45
66
  {
46
67
  name: 'tile-layout',
47
- html: `<q2-radio-group label="Group" name="g1" tile-layout>${RADIOS}</q2-radio-group>`,
68
+ html: `<q2-radio-group label="Group" name="g1" tile-layout value="2">${RADIOS}</q2-radio-group>`,
48
69
  states: ['resting', 'hover', 'focus'],
49
70
  },
71
+ {
72
+ name: 'tile-layout-focus-last',
73
+ html: `<q2-radio-group label="Group" name="g1" tile-layout value="2">${RADIOS}</q2-radio-group>`,
74
+ states: ['focus'],
75
+ focusSteps: 2,
76
+ },
50
77
  {
51
78
  name: 'tile-layout-left',
52
79
  html: `<q2-radio-group label="Group" name="g1" tile-layout tile-alignment="left">${RADIOS}</q2-radio-group>`,
@@ -63,15 +90,24 @@ const VARIANTS = [
63
90
  states: ['resting'],
64
91
  },
65
92
  ];
93
+ const waitForRadioGroup = async (page) => {
94
+ await page.locator('q2-radio-group[stencil-hydrated]').waitFor();
95
+ await expect(page.locator('q2-radio[stencil-hydrated]')).toHaveCount(3);
96
+ await page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))));
97
+ };
66
98
  const restingCase = (variant, theme) => {
67
99
  test(`q2-radio-group--${variant.name}--resting — ${theme}`, async ({ page }) => {
100
+ if (variant.viewport)
101
+ await page.setViewportSize(variant.viewport);
68
102
  await setupPage(page, variant.html, { theme });
103
+ await waitForRadioGroup(page);
69
104
  await expect(page).toHaveScreenshot(`q2-radio-group--${variant.name}--resting--${theme}.png`);
70
105
  });
71
106
  };
72
107
  const hoverCase = (variant, theme) => {
73
108
  test(`q2-radio-group--${variant.name}--hover — ${theme}`, async ({ page }) => {
74
109
  await setupPage(page, variant.html, { theme });
110
+ await waitForRadioGroup(page);
75
111
  // Hover the first radio (a tile when tile-layout is active).
76
112
  await page.locator('q2-radio').first().hover();
77
113
  await expect(page).toHaveScreenshot(`q2-radio-group--${variant.name}--hover--${theme}.png`);
@@ -79,8 +115,13 @@ const hoverCase = (variant, theme) => {
79
115
  };
80
116
  const focusCase = (variant, theme) => {
81
117
  test(`q2-radio-group--${variant.name}--focus — ${theme}`, async ({ page }) => {
118
+ var _a;
82
119
  await setupPage(page, variant.html, { theme });
120
+ await waitForRadioGroup(page);
83
121
  await page.keyboard.press('Tab');
122
+ for (let step = 0; step < ((_a = variant.focusSteps) !== null && _a !== void 0 ? _a : 0); step++) {
123
+ await page.keyboard.press('ArrowRight');
124
+ }
84
125
  await expect(page).toHaveScreenshot(`q2-radio-group--${variant.name}--focus--${theme}.png`);
85
126
  });
86
127
  };
@@ -102,6 +143,7 @@ test.describe(`q2-radio-group — scaled font size × themes`, () => {
102
143
  for (const theme of THEMES) {
103
144
  test(`q2-radio-group--optional--resting--${FONT_SCALE_SUFFIX} — ${theme}`, async ({ page }) => {
104
145
  await setupPage(page, OPTIONAL_VARIANT.html, { theme, fontSizePx: FONT_SCALE_PX });
146
+ await waitForRadioGroup(page);
105
147
  await expect(page).toHaveScreenshot(`q2-radio-group--optional--resting--${FONT_SCALE_SUFFIX}--${theme}.png`);
106
148
  });
107
149
  }
@@ -74,7 +74,7 @@ export class Q2RelativeTime {
74
74
  return;
75
75
  }
76
76
  const message = intlFormatDistance(new Date(dateObject), new Date(baseDateObject), {
77
- locale,
77
+ locale: locale || document.documentElement.lang || 'en-US',
78
78
  localeMatcher: 'best fit',
79
79
  numeric: handleNumeric,
80
80
  style: messageFormat,
@@ -153,7 +153,7 @@ export class Q2RelativeTime {
153
153
  // #region Render Methods
154
154
  render() {
155
155
  const { shouldShow, displayedMessage } = this;
156
- return h(Fragment, { key: '48a6ad8165ea3380500edb280142a47e0a7a6848' }, shouldShow ? h("time", { dateTime: displayedMessage }, displayedMessage) : null);
156
+ return h(Fragment, { key: '7bcf2e8d9cb391ea43664b9cf01ec6d474a1743e' }, shouldShow ? h("time", { dateTime: displayedMessage }, displayedMessage) : null);
157
157
  }
158
158
  static get is() { return "q2-relative-time"; }
159
159
  static get encapsulation() { return "shadow"; }
@@ -147,6 +147,7 @@ button {
147
147
  }
148
148
 
149
149
  /**
150
+ * @prop --tct-search-icon-size: (<length>) Controls the size of search input icons, including slotted icons and clear.
150
151
  * @prop --tct-search-margin?: (<length-percentage>+) Controls the margin of the component host as a shorthand. Overrides --tct-search-margin-top and --tct-search-margin-bottom when set.
151
152
  * @prop --tct-search-margin-top: (<length-percentage>) Controls the top margin of the component host.
152
153
  * @prop --tct-search-margin-bottom: (<length-percentage>) Controls the bottom margin of the component host.
@@ -187,6 +188,7 @@ button {
187
188
  }
188
189
 
189
190
  .q2-search-input {
191
+ --tct-input-icon-size: var(--tct-search-icon-size, var(--const-px-18, 18px));
190
192
  margin: 0;
191
193
  --tct-input-min-height: var(--tct-search-input-min-height, initial);
192
194
  --tct-input-max-height: var(--tct-search-input-max-height, none);
@@ -104,6 +104,7 @@ button {
104
104
  * @prop --tct-section-header-min-height: (<length>) Controls the minimum height of the section header when a header is present.
105
105
  * @prop --tct-section-title-margin?: (<length-percentage>+) Controls the optional outer margin of the section title.
106
106
  * @prop --tct-section-title-font-size: (<length-percentage>) Controls the font size of the section title.
107
+ * @prop --tct-section-icon-size: (<length>) Controls the size of the section expand/collapse icon.
107
108
  * @prop --tct-section-title-font-weight: (<number>) Controls the font weight of the section title.
108
109
  * @prop --tct-section-title-text-transform?: (<custom-ident>) Controls the optional text transform of the section title.
109
110
  * @prop --tct-section-title-letter-spacing?: (<length>) Controls the optional letter spacing of the section title.
@@ -182,6 +183,7 @@ header.has-header {
182
183
  }
183
184
 
184
185
  q2-icon {
186
+ --tct-icon-size: var(--tct-section-icon-size, var(--const-px-18, 18px));
185
187
  transition: transform var(--comp-tween);
186
188
  }
187
189
  :host(:not([expanded])) q2-icon, :host([expanded=false]) q2-icon {
@@ -1,5 +1,5 @@
1
1
  import { h, } from "@stencil/core";
2
- import { isEventFromElement, loc, nextPaint, overrideFocus, resizeIframe } from "../../utils/index";
2
+ import { hasSlotContent, isEventFromElement, loc, nextPaint, overrideFocus, resizeIframe } from "../../utils/index";
3
3
  import mirrorEmit from "../../utils/mirror-emit";
4
4
  /**
5
5
  * @name Section
@@ -40,9 +40,9 @@ export class Q2Section {
40
40
  });
41
41
  };
42
42
  this.onHeaderSlotChange = () => {
43
- const hasSlotContent = !!this.hostElement.querySelector('[slot="q2-section-header"]');
44
- if (this.hasYieldedHeader !== hasSlotContent) {
45
- this.hasYieldedHeader = !!hasSlotContent;
43
+ const hasHeader = hasSlotContent(this.hostElement, 'q2-section-header');
44
+ if (this.hasYieldedHeader !== hasHeader) {
45
+ this.hasYieldedHeader = hasHeader;
46
46
  }
47
47
  };
48
48
  this.onTransitionEnd = () => {
@@ -186,9 +186,9 @@ export class Q2Section {
186
186
  wrapperClasses.push('is-transitioning');
187
187
  }
188
188
  const showDefaultHeader = !this.hasYieldedHeader && !!this.label;
189
- return (h("section", { key: '5dbed551d8571ef48b81fe7fc40b0c56db2d685a', class: "wrapper" }, h("header", { key: 'dfc3bc20a49856a2fcdee6b5cae1626e32ff5416', class: hasHeader ? 'has-header' : '' }, h("div", { key: 'b9073b701f1006f8048cac33b4cae9e44888c8e2', class: "header-content", id: this.titleId, onClick: this.collapsible && this.onHeaderClick }, showDefaultHeader && h("h2", { key: 'd701205c1808c6eaf2b7f3739c7488d934cf1cc0', class: "title" }, loc(this.label)), h("div", { key: '5428fcecafd6e84a884783c0cc1223cb91160f69', ref: el => (this.headerSlotWrapper = el), class: "header-slot-wrapper" }, h("slot", { key: 'f7d873afc6f319c259e11db10e7cf2d3010ca3c6', ref: (el) => (this.headerSlot = el), name: "q2-section-header" }))), this.collapsible && !this.noCollapseIcon && (h("q2-btn", { key: '6143342070b00156a36db039dee5e19a1a6cbe2f', label: loc(this.label || 'tecton.element.section.defaultToggleLabel'), ariaExpanded: `${!!this.expanded}`, ariaControls: this.contentId, "test-id": "toggleButton", "hide-label": true, onClick: this.onHeaderClick }, h("q2-icon", { key: '297304e09f1b60c2a3e4d8146ff7b75f14d64e5c', type: "chevron-up" })))), h("div", { key: '3a78d8a8ffde28f5e006fd988f6d01463758c4c1', class: wrapperClasses.join(' '), id: this.contentId, "aria-labelledby": this.titleId, role: "region", onTransitionEnd: this.onTransitionEnd, style: this.collapsible && {
189
+ return (h("section", { key: '1614590b2058a69ebaee5a59455ec5c8bfa30bde', class: "wrapper" }, h("header", { key: 'e52e3037b59ac3443e812299114850dd6ed8810b', class: hasHeader ? 'has-header' : '' }, h("div", { key: '2066c8ff48cb4c6445068207533b3b6b808e9dd7', class: "header-content", id: this.titleId, onClick: this.collapsible && this.onHeaderClick }, showDefaultHeader && h("h2", { key: 'a159d8b6bc29e10711b603aef2ce6c1419f4b7ae', class: "title" }, loc(this.label)), h("div", { key: '829f24123711551a6e3792cb66a2759386d6bec8', ref: el => (this.headerSlotWrapper = el), class: "header-slot-wrapper" }, h("slot", { key: '22c2518c55bf5f6160917beea8ab2c523bf76169', ref: (el) => (this.headerSlot = el), name: "q2-section-header" }))), this.collapsible && !this.noCollapseIcon && (h("q2-btn", { key: '950c09ccfad31453393a52cd21321338d53ac03b', label: loc(this.label || 'tecton.element.section.defaultToggleLabel'), ariaExpanded: `${!!this.expanded}`, ariaControls: this.contentId, "test-id": "toggleButton", "hide-label": true, onClick: this.onHeaderClick }, h("q2-icon", { key: 'a962ea4f0f5c0ba761d3c3eafd31a16f0338c8da', type: "chevron-up" })))), h("div", { key: '45a1762386b7bf88fcaa50c18c1ac059b93d2e59', class: wrapperClasses.join(' '), id: this.contentId, "aria-labelledby": this.titleId, role: "region", onTransitionEnd: this.onTransitionEnd, style: this.collapsible && {
190
190
  height: this.contentHeight,
191
- } }, h("div", { key: '0c7019101641ae7d05772a9ec4e8c16ca40e1112', ref: el => (this.contentContainer = el), class: "content", tabindex: "-1" }, h("slot", { key: '49a17e0cd8279255eec0dc2d7344dc0fa260dc46', ref: (el) => (this.contentSlot = el) })))));
191
+ } }, h("div", { key: '80508c39608fa4bf3d6f1911ff592f04e5115014', ref: el => (this.contentContainer = el), class: "content", tabindex: "-1" }, h("slot", { key: 'c88062ea0a59b62143e22c8492a8d06826a27a83', ref: (el) => (this.contentSlot = el) })))));
192
192
  }
193
193
  static get is() { return "q2-section"; }
194
194
  static get encapsulation() { return "shadow"; }
@@ -147,6 +147,7 @@ button {
147
147
  }
148
148
 
149
149
  /**
150
+ * @prop --tct-select-icon-size: (<length>) Controls the size of the select chevron and clear icons.
150
151
  * @prop --tct-select-margin: (<length-percentage>+) Controls the outer margin of the select host.
151
152
  * @prop --tct-select-margin-top: (<length-percentage>) Controls the top margin of the select host when --tct-select-margin is not set.
152
153
  * @prop --tct-select-margin-bottom: (<length-percentage>) Controls the bottom margin of the select host when --tct-select-margin is not set.
@@ -176,6 +177,8 @@ button {
176
177
 
177
178
  .q2-select-input {
178
179
  margin: 0;
180
+ letter-spacing: inherit;
181
+ --tct-input-icon-size: var(--tct-select-icon-size, var(--const-px-18, 18px));
179
182
  --tct-input-min-height: var(--tct-select-input-min-height, var(--t-select-input-min-height));
180
183
  --tct-input-max-height: var(--tct-select-input-max-height, var(--t-select-input-max-height, none));
181
184
  }
@@ -17,6 +17,7 @@ export class Q2Select {
17
17
  this.guid = createGuid();
18
18
  this.isOrientationUpdate = false;
19
19
  this.lastTouchWasInPopover = false;
20
+ this.removingSelectedDisplay = false;
20
21
  this.scheduledAfterRender = [];
21
22
  // #endregion
22
23
  // #region State Properties
@@ -75,7 +76,12 @@ export class Q2Select {
75
76
  * Takes priority over `optional` if both are `true`.
76
77
  */
77
78
  this.readonly = false;
78
- /** Enables search functionality. */
79
+ /**
80
+ * Enables search functionality.
81
+ * @warning
82
+ * `searchable` is not compatible with the `hoist` prop. The action sheet workflow used when `hoist` is `true` does not support in-list search filtering.
83
+ * If both are set, `searchable` has no effect while the action sheet is active.
84
+ */
79
85
  this.searchable = false;
80
86
  /**
81
87
  * Each item in this array should correspond to the value of a `q2-option` element.
@@ -183,9 +189,6 @@ export class Q2Select {
183
189
  this.inputInputHandler = (event) => {
184
190
  event.stopPropagation();
185
191
  const eventValue = event.detail.value;
186
- const shouldClearValue = !!this.value;
187
- if (shouldClearValue)
188
- this.clearValue();
189
192
  if (!this.open)
190
193
  this.openDropdownWithoutActiveElement();
191
194
  this.prioritizeSearch = true;
@@ -202,6 +205,8 @@ export class Q2Select {
202
205
  return;
203
206
  // slots are incompatible with action sheet
204
207
  if (shouldShowActionSheet(this, event) && !hasSlot) {
208
+ event.preventDefault();
209
+ event.stopPropagation();
205
210
  return this.executeActionSheet(event);
206
211
  }
207
212
  const keysForOptionListToHandle = [
@@ -274,16 +279,16 @@ export class Q2Select {
274
279
  this.open = open;
275
280
  };
276
281
  this.onSelectedDisplayClick = (event) => {
282
+ var _a, _b;
277
283
  // Stop click from bubbling to q2-input's onClick (which would toggle the dropdown)
278
284
  event.stopPropagation();
279
285
  if (this.open) {
280
- this.focusInput();
286
+ (_a = this.innerInputField) === null || _a === void 0 ? void 0 : _a.focus();
281
287
  return;
282
288
  }
289
+ (_b = this.innerInputField) === null || _b === void 0 ? void 0 : _b.focus();
283
290
  this.prioritizeSearch = this.searchable;
284
- this.clearSelectedDisplay();
285
291
  this.openDropdownWithoutActiveElement();
286
- this.focusInput();
287
292
  };
288
293
  this.onSelectedDisplayMousedown = (event) => {
289
294
  // Prevent focus shift away from the hidden input
@@ -374,20 +379,27 @@ export class Q2Select {
374
379
  }
375
380
  }
376
381
  delegateFocus(event) {
377
- var _a;
382
+ var _a, _b;
378
383
  // Always delegate focus from host to inner input (fixes programmatic focus)
379
384
  if (isEventFromElement(event, this.hostElement)) {
380
385
  (_a = this.innerInputField) === null || _a === void 0 ? void 0 : _a.focus();
381
386
  }
382
- // Manage display state for searchable selects (preserves existing behavior)
383
- const fromHost = isRelatedTargetWithinHost(event, this.hostElement);
384
- this.prioritizeSearch = fromHost && this.searchable;
387
+ const fromOutside = isRelatedTargetWithinHost(event, this.hostElement);
388
+ const hasRobustSelectedDisplay = !!this.selectedDisplaySlot ||
389
+ (this.multilineOptions && !!this.firstSelectedOptionElement && !this.firstSelectedOptionElement.display);
390
+ this.prioritizeSearch = fromOutside && this.searchable && (this.multiple || hasRobustSelectedDisplay);
385
391
  if (this.prioritizeSearch) {
386
392
  this.clearSelectedDisplay();
387
393
  }
394
+ else if (fromOutside && this.searchable && !!this.value) {
395
+ (_b = this.innerInputField) === null || _b === void 0 ? void 0 : _b.select();
396
+ }
388
397
  }
389
398
  handleFocusout(event) {
390
399
  var _a;
400
+ // Removing the robust display while opening search can emit a focusout without a destination.
401
+ if (!event.relatedTarget && (this.removingSelectedDisplay || (this.open && this.prioritizeSearch)))
402
+ return;
391
403
  const relatedTarget = event.relatedTarget;
392
404
  const isLeavingHost = !((_a = this.popoverElement) === null || _a === void 0 ? void 0 : _a.contains(relatedTarget)) && !this.hostElement.contains(relatedTarget);
393
405
  if (isLeavingHost)
@@ -509,14 +521,14 @@ export class Q2Select {
509
521
  return;
510
522
  this.optionElements.forEach(element => (element.multiline = newValue));
511
523
  }
512
- openChanged(isOpen) {
524
+ openChanged(isOpen, wasOpen) {
513
525
  if (isOpen) {
514
526
  this.addTouchEventListeners();
515
527
  }
516
528
  else {
517
529
  this.removeTouchEventListeners();
518
- // Reset prioritizeSearch when dropdown closes to ensure selected display can be restored
519
- this.prioritizeSearch = false;
530
+ if (wasOpen)
531
+ this.prioritizeSearch = false;
520
532
  }
521
533
  this.scheduledAfterRender.push(async () => {
522
534
  await waitForNextPaint();
@@ -722,7 +734,9 @@ export class Q2Select {
722
734
  if (slot) {
723
735
  slot.removeEventListener('mousedown', this.onSelectedDisplayMousedown);
724
736
  slot.removeEventListener('click', this.onSelectedDisplayClick);
737
+ this.removingSelectedDisplay = true;
725
738
  slot.remove();
739
+ setTimeout(() => (this.removingSelectedDisplay = false), 0);
726
740
  }
727
741
  }
728
742
  clearValue() {
@@ -813,13 +827,15 @@ export class Q2Select {
813
827
  return (h("q2-popover", { ref: el => (this.popoverElement = el), controlElement: this.innerInputContainer, open: this.open, "max-height": this.popoverMaxHeight, minHeight: this.popoverMinHeight, direction: this.popDirection, mode: this.popoverMode || undefined, block: true }, h("div", { class: "popover-content" }, h("q2-option-list", { onPopoverState: this.onPopoverState, ref: el => (this.optionList = el), type: "listbox", id: "option-list", "show-selected": this.showSelected, label: this.listLabel, multiple: this.multiple, selectedOptions: this.structuredSelectedOptions, onChange: e => e.stopPropagation(), onTctChange: this.onOptionListChange }, h("slot", null)), h("div", { class: "popover-top-container", ref: el => (this.popoverTopContainer = el), hidden: !this.multiple && !this.hasPopoverTop, tabindex: "-1" }, h("slot", { name: "popover-top" }), this.multiple && this.renderVisibilityToggle())), h("div", { class: "popover-bottom-container", hidden: !this.hasPopoverBottom, tabindex: "-1" }, h("slot", { name: "popover-bottom" }))));
814
828
  }
815
829
  renderSelectField() {
816
- var _a;
830
+ var _a, _b;
817
831
  return (h(Fragment, null, h("div", { "aria-live": "polite", "aria-atomic": "true", role: "status", class: "sr" }, this.statusMessage), h("q2-input", { ref: el => (this.inputField = el), class: "q2-select-input", label: (this.label && loc(this.label)) || '', value: this.selectedDisplay, clearable: (!this.disabled && this.clearable && (!!this.value || !!((_a = this.selectedOptions) === null || _a === void 0 ? void 0 : _a.length))) ||
818
832
  undefined, errors: (Array.isArray(this.errors) &&
819
833
  this.errors.length > 0 &&
820
834
  this.errors.map(error => loc(error))) ||
821
835
  (this.invalid && ['tecton.element.select.invalid']) ||
822
- [], disabled: this.disabled, optional: this.optional, readonly: !!this.readonly, placeholder: this.placeholder || undefined, hideLabel: this.hideLabel, valid: this.valid, ariaExpanded: `${this.open}`, ariaControls: "option-list", ariaHaspopup: "listbox", "test-id": "toggleDropdown", "hide-messages": true, iconRight: "chevron-down", onClick: this.inputClickHandler, onInput: e => e.stopImmediatePropagation(), onTctInput: this.inputInputHandler, onKeyDown: this.inputKeydownHandler, onFocus: this.inputFocusHandler, onBlur: this.inputBlurHandler, onChange: e => e.stopPropagation(), onTctChange: this.inputChangeHandler, badgeValue: this.badgeValue, badgeTheme: this.inputFocused ? 'primary' : undefined, _role: "combobox", _preventEntry: !this.searchable }, this.renderCustomDisplay()), h("div", { class: "custom-display-content", hidden: !this.hasCustomDisplay || !!this.searchText, onClick: this.onCustomDisplayClick }, h("slot", { name: "q2-select-display" })), this.renderOptionsDropdown()));
836
+ [], disabled: this.disabled, optional: this.optional, readonly: !!this.readonly, placeholder: this.placeholder || undefined, hideLabel: this.hideLabel, valid: this.valid, ariaExpanded: `${this.open}`, ariaControls: "option-list", ariaHaspopup: "listbox", "test-id": "toggleDropdown", "hide-messages": true, iconRight: "chevron-down", onClick: this.inputClickHandler, onInput: e => e.stopImmediatePropagation(), onTctInput: this.inputInputHandler, onKeyDown: this.inputKeydownHandler, onFocus: this.inputFocusHandler, onBlur: this.inputBlurHandler, onChange: e => e.stopPropagation(), onTctChange: this.inputChangeHandler, badgeValue: this.badgeValue, badgeTheme: this.inputFocused ? 'primary' : undefined, _ariaDescription: this.multiple && ((_b = this.selectedOptions) === null || _b === void 0 ? void 0 : _b.length)
837
+ ? loc('tecton.element.select.selectionCount', [this.selectedOptions.length])
838
+ : undefined, _role: "combobox", _preventEntry: !this.searchable }, this.renderCustomDisplay()), h("div", { class: "custom-display-content", hidden: !this.hasCustomDisplay || !!this.searchText, onClick: this.onCustomDisplayClick }, h("slot", { name: "q2-select-display" })), this.renderOptionsDropdown()));
823
839
  }
824
840
  renderVisibilityToggle() {
825
841
  var _a, _b;
@@ -830,7 +846,7 @@ export class Q2Select {
830
846
  ]), checked: showSelected, "test-id": "selectedOptionsButton", onClick: this.showSelectedOptions, onKeyDown: this.visibilityToggleKeyDown }), h("label", { htmlFor: "selected" }, loc('tecton.element.select.multiHeader.selected', [selectedOptionsCount]))))));
831
847
  }
832
848
  render() {
833
- return (h("click-elsewhere", { key: 'edb9951db5493781ee1f5da0ed5f6c03aff107e9', class: this.wrapperClasses, role: "presentation", onChange: this.clickedElsewhere }, this.renderSelectField()));
849
+ return (h("click-elsewhere", { key: '5c9a6d681aedcebfbadd6b1249f7bcd96c27809c', class: this.wrapperClasses, role: "presentation", onChange: this.clickedElsewhere }, this.renderSelectField()));
834
850
  }
835
851
  static get is() { return "q2-select"; }
836
852
  static get encapsulation() { return "shadow"; }
@@ -1233,7 +1249,10 @@ export class Q2Select {
1233
1249
  "required": false,
1234
1250
  "optional": false,
1235
1251
  "docs": {
1236
- "tags": [],
1252
+ "tags": [{
1253
+ "name": "warning",
1254
+ "text": "`searchable` is not compatible with the `hoist` prop. The action sheet workflow used when `hoist` is `true` does not support in-list search filtering.\nIf both are set, `searchable` has no effect while the action sheet is active."
1255
+ }],
1237
1256
  "text": "Enables search functionality."
1238
1257
  },
1239
1258
  "getter": false,
@@ -18,6 +18,19 @@ const VARIANTS = [
18
18
  html: `<q2-select label="My select" placeholder="Select an option">${OPTIONS}</q2-select>`,
19
19
  states: ['resting', 'focus', 'expanded-option-hover', 'expanded-option-focus'],
20
20
  },
21
+ {
22
+ name: 'letter-spacing-override',
23
+ html: `<style>
24
+ q2-select {
25
+ --tct-input-label-letter-spacing: initial;
26
+ letter-spacing: 0.12em !important;
27
+ }
28
+ </style>
29
+ <div style="width: 220px">
30
+ <q2-select label="Account funding source selection" placeholder="Select an option">${OPTIONS}</q2-select>
31
+ </div>`,
32
+ states: ['resting'],
33
+ },
21
34
  {
22
35
  name: 'multiple',
23
36
  html: `<q2-select label="My select" placeholder="Select an option" multiple>${OPTIONS}</q2-select>`,
@@ -73,7 +73,7 @@ export class Q2StepperPane {
73
73
  // #region Render Methods
74
74
  render() {
75
75
  const { label, isActive } = this;
76
- return (h(Host, { key: '7acf643f717380c37eb25334534afbca81ac8ab6', role: "listitem" }, h(Fragment, { key: '0241a9ad68973eea81c961070d6171dab3241f79' }, h("div", { key: '25e9a406b8c0672eec836920706d44ed53906e1d', "aria-label": label && loc(label), tabindex: "0", hidden: !isActive && !(this.isChildActive && this.showWithChildren) }, h("slot", { key: '00f456ab21d2ecf58946de5df397bb3c81c2a749' })), h("div", { key: 'bdac4c2caf9b9bf5a6280258475afa552e578e7e', hidden: true }, h("slot", { key: '2ede75ad70c10eda1f8c6de4556bccc9c66e8b97', name: "label", onSlotchange: () => this.contentChange.emit() }), h("slot", { key: '990f2d44a0f9cb0437b63f3570a94874752a94da', name: "description", onSlotchange: () => this.contentChange.emit() })), h("slot", { key: '1f12d65608f73a3737abb7f987cab300ec1c9856', name: "children" }))));
76
+ return (h(Host, { key: '7acf643f717380c37eb25334534afbca81ac8ab6', role: "listitem" }, h(Fragment, { key: '0241a9ad68973eea81c961070d6171dab3241f79' }, h("div", { key: '6678cb4a7e65a3a4341ff552682c1011c588108b', role: "group", "aria-labelledby": "pane-label", tabindex: "0", hidden: !isActive && !(this.isChildActive && this.showWithChildren) }, h("slot", { key: '0f8d339f894bdaa55bd5bdf94b1220da7a083dde' })), h("div", { key: '51e3934ad791e45486360ab8c6509b68e3a15d9d', hidden: true }, h("span", { key: '96fe08c826d87f86559fe2dbb586914b4065eb40', id: "pane-label" }, h("slot", { key: 'b4cab1594ae047f032fbaa67f75167e31cc4cdf7', name: "label", onSlotchange: () => this.contentChange.emit() }, label && loc(label))), h("slot", { key: '473cf6b9bc3ef5995d11e46502db1321d59baa5e', name: "description", onSlotchange: () => this.contentChange.emit() })), h("slot", { key: '76cb24680ed1ec8a49956f888accf3fd07da7fa0', name: "children" }))));
77
77
  }
78
78
  static get is() { return "q2-stepper-pane"; }
79
79
  static get encapsulation() { return "shadow"; }
@@ -325,7 +325,7 @@ export class Q2StepperVertical {
325
325
  return (h("li", { role: "presentation" }, h("button", { class: stepClasses.join(' '), type: "button", "aria-labelledby": labelledBy, "aria-describedBy": descriptionId, "aria-label": btnLabel, "aria-selected": `${isCurrentStep}`, "aria-expanded": !!pane.children.length ? `${isExpanded}` : null, id: id, "aria-disabled": isLocked ? 'true' : null, role: "tab", tabIndex: isCurrentStep ? 0 : -1, onKeyDown: ev => !isLocked && this.onStepKeyDown(ev, id), onClick: ev => !isPaneDisabled && !isLocked && this.onStepClick(ev, id) }, label && (h(Fragment, null, h("span", { class: "sr-only", id: positionId }, positionLabel), h("span", { class: "sr-only", id: statusId }, statusLabel))), statusIcon ? (h("div", { class: "step-icon" }, h("q2-icon", { "aria-hidden": "true", type: statusIcon }))) : (h("div", { class: "step-bubble" }, stepNumber)), label && (h("div", null, h("div", { class: "step-label", id: labelId, innerHTML: sanitizeHTMLString(stepLabel) }), description && (h("div", { class: "step-description", id: descriptionId, innerHTML: sanitizeHTMLString(description) }))))), this.renderSpacer(pane, isExpanded, isLastStep)));
326
326
  }
327
327
  render() {
328
- return (h(Fragment, { key: 'eab8d8816aebfb5aa104a17b75dc0e8b4ed4ce68' }, h("ul", { key: 'f155624641313e8375e6ee448fed150ae0c62cf1', role: "tablist" }, this.structuredPanes.map((pane, index) => this.renderStepBtn(pane, index))), h("div", { key: '1ff078e00dcb1e4c861bc691ccc31ec5c1436fac', role: "list" }, h("slot", { key: 'adf07ae0725ccc7c1ce149052f2325e6bfc01677' }))));
328
+ return (h(Fragment, { key: '9d40414e7b510493b0236568c4d6231eeacdbd80' }, h("ul", { key: 'b3a444833439d59be874a2bf04833f8df0ff107f', role: "tablist" }, this.structuredPanes.map((pane, index) => this.renderStepBtn(pane, index))), h("div", { key: '34f3841d0eb0c5fe96670ac3d5e87244682ace74', role: "list" }, h("slot", { key: 'e224e413162cb28eab4ec0e8b51367ed3b83fa0b' }))));
329
329
  }
330
330
  static get is() { return "q2-stepper-vertical"; }
331
331
  static get encapsulation() { return "shadow"; }
@@ -84,7 +84,7 @@ export class Q2Surface {
84
84
  // #endregion
85
85
  // #region Render Methods
86
86
  render() {
87
- return (h(Host, { key: '992667ac1d625dff77a01d06d058865f99d8d190' }, h("div", { key: 'd58162c346c58a2cc21a4334c08b6cc4a53ed2e0', class: "container", role: this.clickable ? 'button' : undefined, tabIndex: this.clickable ? 0 : undefined }, h("slot", { key: 'b70930390799484c71da93d1f801ecc681d168c6' }))));
87
+ return (h(Host, { key: '8dd96991bc74e2157dc256f21eb4953eaeffdd46' }, h("div", { key: 'a5b315fd3e6dd999cd704b3fd2c9de5ffb139033', class: "container", role: this.clickable ? 'button' : undefined, tabIndex: this.clickable ? 0 : undefined }, h("slot", { key: '4897bfe06a95bf14eddf2bb964bf4a27ed96798a' }))));
88
88
  }
89
89
  static get is() { return "q2-surface"; }
90
90
  static get encapsulation() { return "shadow"; }
@@ -335,7 +335,7 @@ export class Q2TabContainer {
335
335
  }
336
336
  render() {
337
337
  const isVertical = this.computedOrientation === 'vertical';
338
- return (h(Fragment, { key: '710b889bd81a28f6ba7c0deb43abe49a269baec4' }, h("div", { key: '444efee6412d2440c99bd1e9b123fe385f2453a5', class: "tab-container" }, this.scrollEnabled && (h(Fragment, { key: '56c9916fb99dd3434a8305721d03e85c0f5fb370' }, h("div", { key: 'c506eb6690b60194b50171ad5139cc65b4fabedd', class: "gradient-left", hidden: !this.showScrollBack }), h("div", { key: '7af01eb18190e0af6fb80364fb73dcf6145d979d', class: "gradient-right", hidden: !this.showScrollForward }), h("q2-btn", { key: '8cb5f49e48c119d32b196e3ecc7e8a018acc7aa0', class: "btn-left", hidden: !this.showScrollBack, onTctClick: () => this.onScrollBtnClick('back') }, h("q2-icon", { key: '65f3caea2251c7ce96861718df064f230ec6e02e', type: isVertical ? 'chevron-up' : 'chevron-left', label: isVertical ? 'scroll up' : 'scroll left' })), h("q2-btn", { key: '07b833fe0e6b3030255374e4dd323fc99379a293', class: "btn-right", hidden: !this.showScrollForward, onTctClick: () => this.onScrollBtnClick('forward') }, h("q2-icon", { key: 'e446b55822239e657ab10c50694a9756ec8b030b', type: isVertical ? 'chevron-down' : 'chevron-right', label: isVertical ? 'scroll down' : 'scroll right' })))), h("ul", { key: '20d4f371b80b2515b762e80b88574938783e9252', onScroll: this.checkScrollState, ref: el => (this.listElement = el), class: this.noPrint ? 'no-print' : null, role: "tablist", "aria-orientation": this.computedOrientation }, this.tabs.map((tab, index) => this.renderTab(tab, index)))), h("div", { key: '9eaba5d408629dc548a9c57428b801293f642172', class: "tab-content" }, h("slot", { key: '811737fa0e22c994299c9164a6401209e6ecf418', onSlotchange: () => this.onSlotChange() }))));
338
+ return (h(Fragment, { key: '684e234955e0d7f9b929a1e80e323ba62db4d066' }, h("div", { key: '92ea060ada2cc956817f4eb9cb97d0f110c5032a', class: "tab-container" }, this.scrollEnabled && (h(Fragment, { key: 'b43a4ff0510de5adfefde8f5184ab5f3f1d95563' }, h("div", { key: '3daed974f567574741534b4c39c6fa0ddb1c7f58', class: "gradient-left", hidden: !this.showScrollBack }), h("div", { key: '36266d6970a75fff03e538c12951a530220b2756', class: "gradient-right", hidden: !this.showScrollForward }), h("q2-btn", { key: '7c5b35fee0bbd981520f55fe99fc53143be7376c', class: "btn-left", hidden: !this.showScrollBack, onTctClick: () => this.onScrollBtnClick('back') }, h("q2-icon", { key: '0759d5d77d603074acc21bd9a29e4db50f0474a2', type: isVertical ? 'chevron-up' : 'chevron-left', label: isVertical ? 'scroll up' : 'scroll left' })), h("q2-btn", { key: '419c43832886d9aae9b63eba545ffb8122f862b6', class: "btn-right", hidden: !this.showScrollForward, onTctClick: () => this.onScrollBtnClick('forward') }, h("q2-icon", { key: '4148a86411c5859b0253da31439ff90ad78490b3', type: isVertical ? 'chevron-down' : 'chevron-right', label: isVertical ? 'scroll down' : 'scroll right' })))), h("ul", { key: 'fdd72d9ba1d932497b5d7cd9e14d926fe1e92f72', onScroll: this.checkScrollState, ref: el => (this.listElement = el), class: this.noPrint ? 'no-print' : null, role: "tablist", "aria-orientation": this.computedOrientation }, this.tabs.map((tab, index) => this.renderTab(tab, index)))), h("div", { key: 'e9d90030fcc43f17a43aa2e4a306e3489b4c4110', class: "tab-content" }, h("slot", { key: '130ddf5f14ec801e09471b9cf4ab080e4bf5fc27', onSlotchange: () => this.onSlotChange() }))));
339
339
  }
340
340
  static get is() { return "q2-tab-container"; }
341
341
  static get encapsulation() { return "shadow"; }
@@ -19,7 +19,7 @@ export class Q2TabPane {
19
19
  // #endregion
20
20
  // #region Render Methods
21
21
  render() {
22
- return (h("div", { key: '1957cbeca0ca1f0b5f840701286ebeb6b69565ce', id: `tab-pane-${this.guid}-${this.index}`, class: `tab-pane${this.selected ? '' : ' hidden'}`, role: "tabpanel", tabindex: "-1", "aria-hidden": `${!this.selected}`, "aria-labelledby": `tab-${this.guid}-${this.index}` }, h("slot", { key: '6772ac75d219ebc30209907468a9fb801cd5db0d' })));
22
+ return (h("div", { key: '2ff20db182ab3bf252df52bbcb7be2b39893d17c', id: `tab-pane-${this.guid}-${this.index}`, class: `tab-pane${this.selected ? '' : ' hidden'}`, role: "tabpanel", tabindex: "-1", "aria-hidden": `${!this.selected}`, "aria-labelledby": `tab-${this.guid}-${this.index}` }, h("slot", { key: '871922c3065609934e6a6a8c62000c84551a612a' })));
23
23
  }
24
24
  static get is() { return "q2-tab-pane"; }
25
25
  static get encapsulation() { return "shadow"; }
@@ -194,7 +194,7 @@ export class Q2Tag {
194
194
  if (this.optionCount)
195
195
  wrapperClassNames.push('has-options');
196
196
  const shouldShowOptions = this.optionCount > 0;
197
- return (h(Host, { key: 'b7b199109ef756942f6cf76aff904a21ba406998' }, h("click-elsewhere", { key: 'f4a5ec911c582d480e5d7d91638d681ba6c054c8', onChange: this.onClickElsewhere }, shouldShowOptions ? (h(Fragment, null, h("button", { class: "tag-wrapper", ref: el => (this.dropdownBtn = el), "test-id": "btn-control", type: "button", role: "combobox", onClick: this.handleClick, onKeyDown: this.handleKeydown, onFocusout: this.handleButtonFocusout, "aria-controls": "option-list", "aria-expanded": open ? 'true' : 'false', "aria-describedby": "option-description", "aria-label": loc(this.label) }, h("div", { class: wrapperClassNames.join(' ') }, loc(this.label)), h("q2-icon", { type: "options" })), this.renderHiddenElement())) : (h("div", { class: "tag-wrapper", onClick: e => e.stopPropagation() }, h("div", { class: wrapperClassNames.join(' ') }, h("slot", { name: "decorator" }), loc(this.label)))), shouldShowOptions && (h("q2-popover", { key: '046a9aae077ed9800b081ce70aa5d03f0d919cff', ref: el => (this.popoverElement = el), controlElement: this.dropdownBtn, open: this.open, maxHeight: this.popoverMaxHeight, minHeight: this.popoverMinHeight, direction: this.popoverDirection, align: this.popoverAlignment }, h("q2-option-list", { key: '63899f97a13db69ed8776214ca6670e825663c5a', id: "option-list", ref: el => (this.optionList = el), onChange: this.handleChange, type: "menu", align: "right", label: loc('tecton.element.optionList.label', [this.optionListLabel]), "no-select": true }, h("slot", { key: '40fa7c27a8b27ae2c5f894bbe1ae6e51ab1b55f0' })))))));
197
+ return (h(Host, { key: 'da6dc23ff4f250b18242a49db02eccc16210b043' }, h("click-elsewhere", { key: 'ee1da442ffd5aa53e55ae95f95b3ac51e2f5c71e', onChange: this.onClickElsewhere }, shouldShowOptions ? (h(Fragment, null, h("button", { class: "tag-wrapper", ref: el => (this.dropdownBtn = el), "test-id": "btn-control", type: "button", role: "combobox", onClick: this.handleClick, onKeyDown: this.handleKeydown, onFocusout: this.handleButtonFocusout, "aria-controls": "option-list", "aria-expanded": open ? 'true' : 'false', "aria-describedby": "option-description", "aria-label": loc(this.label) }, h("div", { class: wrapperClassNames.join(' ') }, loc(this.label)), h("q2-icon", { type: "options" })), this.renderHiddenElement())) : (h("div", { class: "tag-wrapper", onClick: e => e.stopPropagation() }, h("div", { class: wrapperClassNames.join(' ') }, h("slot", { name: "decorator" }), loc(this.label)))), shouldShowOptions && (h("q2-popover", { key: '578989b60b19f6f5e01c1cbc49a83e87fc74c5a9', ref: el => (this.popoverElement = el), controlElement: this.dropdownBtn, open: this.open, maxHeight: this.popoverMaxHeight, minHeight: this.popoverMinHeight, direction: this.popoverDirection, align: this.popoverAlignment }, h("q2-option-list", { key: 'd21abcd1fe11241e14b4f411d9559c12c139c18a', id: "option-list", ref: el => (this.optionList = el), onChange: this.handleChange, type: "menu", align: "right", label: loc('tecton.element.optionList.label', [this.optionListLabel]), "no-select": true }, h("slot", { key: 'd46ec7dad47e40cec883205d6fb2424abcdd1038' })))))));
198
198
  }
199
199
  static get is() { return "q2-tag"; }
200
200
  static get encapsulation() { return "shadow"; }
@@ -17,7 +17,9 @@ export class TectonTabPane {
17
17
  const loadingWrapper = this.hostElement.shadowRoot.querySelector('.loading-wrapper');
18
18
  /* istanbul ignore next */
19
19
  if (loadingWrapper) {
20
- loadingWrapper.style.minHeight = this.minHeight;
20
+ if (loadingWrapper.querySelector('.q2-row')) {
21
+ loadingWrapper.style.minHeight = this.minHeight;
22
+ }
21
23
  loadingWrapper.hidden = !this.selected;
22
24
  }
23
25
  }
@@ -49,9 +51,9 @@ export class TectonTabPane {
49
51
  // #endregion
50
52
  // #region Render Methods
51
53
  render() {
52
- return (h("div", { key: '68c7250777ec0c700107df4997634d4aee8f8e91', id: `tab-pane-${this.guid}-${this.index}`, class: `tab-pane${this.selected ? '' : ' hidden'}`, role: "tabpanel", tabindex: "-1", "aria-hidden": `${!this.selected}`, "aria-labelledby": `tab-${this.guid}-${this.index}` }, this.selected && this.provided !== undefined && !this.provided && (h("div", { key: '7b8c74b691fc1c599766900125e09afe79e53859' }, h("slot", { key: 'bbf7c58bef21ab334059655e958e976b9bdf327e', name: "loading-wrapper" }), h("iframe", { key: '6a262f757dd78294fcf49242b337b02c13842ee8', hidden: true, name: this.moduleId, scrolling: "no", src: this.showForm && this.authPayload.length ? '' : this.url || '', "data-module-id": this.moduleId, style: this.minHeight ? { minHeight: this.minHeight } : null, onLoad: this.onIFrameLoad, title: this.iframeTitle, allow: "geolocation; camera" }), this._showForm && this.authPayload ? (h("form", { hidden: true, method: "post", action: this.url, target: this.moduleId, encType: "multipart/form-data" }, this.authPayload.map(element => {
54
+ return (h("div", { key: '6c0524ab1981900cc7a37803fd9426c6397049c4', id: `tab-pane-${this.guid}-${this.index}`, class: `tab-pane${this.selected ? '' : ' hidden'}`, role: "tabpanel", tabindex: "-1", "aria-hidden": `${!this.selected}`, "aria-labelledby": `tab-${this.guid}-${this.index}` }, this.selected && this.provided !== undefined && !this.provided && (h("div", { key: '10cc2712e1ccefa6a9bb3b657830636da4d81980' }, h("slot", { key: 'cde7112d4035c6f118e9c50b0fe5d9d91c70ee7d', name: "loading-wrapper" }), h("iframe", { key: '851972991feb3b8f6c7f569e92ff2e624d94e221', hidden: true, name: this.moduleId, scrolling: "no", src: this.showForm && this.authPayload.length ? '' : this.url || '', "data-module-id": this.moduleId, style: this.minHeight ? { minHeight: this.minHeight } : null, onLoad: this.onIFrameLoad, title: this.iframeTitle, allow: "geolocation; camera" }), this._showForm && this.authPayload ? (h("form", { hidden: true, method: "post", action: this.url, target: this.moduleId, encType: "multipart/form-data" }, this.authPayload.map(element => {
53
55
  return (h("input", { type: "hidden", value: element.value, name: element.key }));
54
- }))) : (''))), h("div", { key: 'd9be64623c99011b7f30256d0abfaeab23f72c00', class: "slot-wrapper", hidden: this.selected && this.provided !== undefined && !this.provided }, h("slot", { key: 'a1a3a9772b2875c7d4ab510e9014d99b6e036ad3' }))));
56
+ }))) : (''))), h("div", { key: '741c6f2c89dc15493f165428929f589425aa4d75', class: "slot-wrapper", hidden: this.selected && this.provided !== undefined && !this.provided }, h("slot", { key: '17100ec2dc0ea2d1e27628d36e9e6e1139f293a9' }))));
55
57
  }
56
58
  static get is() { return "tecton-tab-pane"; }
57
59
  static get encapsulation() { return "shadow"; }
@@ -244,7 +244,7 @@ export function renderLabel(target) {
244
244
  return (h("label", { htmlFor: target.inputId, class: labelClasses.join(' ') }, h("slot", { name: "label" }, label ? loc(label) : undefined, helpText)));
245
245
  }
246
246
  export function hasSlotContent(target, slotName) {
247
- return target.querySelector(`[slot="${slotName}"]`) !== null;
247
+ return Array.from(target.children).some(child => child.getAttribute('slot') === slotName);
248
248
  }
249
249
  export function handleAriaLabel(target) {
250
250
  const { ariaLabel } = target;
@@ -40,6 +40,7 @@ const getDefaultEnStrings = () => {
40
40
  const BASE_THEME_CSS_CONTENT = readFileSync(join(__dirname, '../../../', BASE_THEME_CSS), 'utf8');
41
41
  const UTILITIES_CSS_CONTENT = readFileSync(join(__dirname, '../../../', UTILITIES_CSS), 'utf8');
42
42
  export const setupPage = async (page, content, options = {}) => {
43
+ var _a;
43
44
  // Bootstrap localization BEFORE setContent so that any Stencil class-field initializers
44
45
  // that call loc() (e.g., q2-select's `listLabel: string = loc('tecton.element.select.listLabel')`)
45
46
  // see the shim during hydration. addInitScript runs on every new document before any page script.
@@ -92,15 +93,24 @@ export const setupPage = async (page, content, options = {}) => {
92
93
  };
93
94
  }, mergedStrings);
94
95
  }
95
- await page.setContent(content);
96
+ // Inject --t-prefers-motion before any element is parsed so the @container style()
97
+ // query in host.scss matches from the very first component render, preventing the
98
+ // race where Stencil's microtask-scheduled render fires before the CSS variable is
99
+ // set and 0.4s transitions start at full speed.
100
+ const motion = (_a = options.motion) !== null && _a !== void 0 ? _a : 'reduced';
101
+ await page.setContent(`<style>body{--t-prefers-motion:"${motion}"!important}</style>${content}`);
96
102
  // `data-tecton-module` gates the rules in q2-tecton-utilities.css (focus rings,
97
103
  // normalize, etc.). Match the preview page's <body data-tecton-module>.
98
- await page.evaluate(() => document.body.setAttribute('data-tecton-module', ''));
104
+ await page.evaluate(() => {
105
+ document.body.setAttribute('data-tecton-module', '');
106
+ });
99
107
  // Mirror q2-tecton-sdk's insertDefaultThemeTag: prepend theme + utilities to
100
108
  // <head> so they sit BEFORE the component-injected <style> tags Stencil emits.
101
109
  // addStyleTag would append, placing utilities last in the cascade — its
102
110
  // [data-tecton-module] *:focus-visible rule ties on specificity with component
103
111
  // focus rules, so document order decides, and appending makes utilities win.
112
+ // These arrive after Stencil's first render (evaluate runs in a new browser task),
113
+ // but the re-render is fast and the cascade position is what matters.
104
114
  await page.evaluate(({ baseTheme, utilities }) => {
105
115
  const head = document.head;
106
116
  const firstChild = head.firstChild;
@@ -121,4 +131,8 @@ export const setupPage = async (page, content, options = {}) => {
121
131
  });
122
132
  }
123
133
  await page.locator('[stencil-hydrated]').first().waitFor();
134
+ // Two rAFs after hydration: frame 1 lets microtask-batched nested renders finish
135
+ // (q2-btn inside q2-input/q2-calendar, q2-pill inside q2-list); frame 2 ensures
136
+ // the layout from those nested renders is committed before the screenshot.
137
+ await page.evaluate(() => new Promise(r => requestAnimationFrame(() => requestAnimationFrame(() => r()))));
124
138
  };
@@ -170,7 +170,7 @@ function renderLabel(n) {
170
170
  }
171
171
 
172
172
  function hasSlotContent(e, n) {
173
- return null !== e.querySelector(`[slot="${n}"]`);
173
+ return Array.from(e.children).some((e => e.getAttribute("slot") === n));
174
174
  }
175
175
 
176
176
  function handleAriaLabel(e) {