@brandsync/wc 0.0.10 → 0.0.12

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 (300) hide show
  1. package/custom-elements.json +3584 -508
  2. package/dist/brandsync-wc/brandsync-wc.css +20 -0
  3. package/dist/brandsync-wc/brandsync-wc.esm.js +1 -1
  4. package/dist/brandsync-wc/{p-b1e1b2d6.entry.js → p-09aa03d1.entry.js} +1 -1
  5. package/dist/brandsync-wc/p-0eee5477.entry.js +1 -0
  6. package/dist/brandsync-wc/p-0fa017ce.entry.js +1 -0
  7. package/dist/brandsync-wc/p-12ec9e92.entry.js +1 -0
  8. package/dist/brandsync-wc/{p-3dacae70.entry.js → p-1900f6ce.entry.js} +1 -1
  9. package/dist/brandsync-wc/{p-575ce905.entry.js → p-1adc59be.entry.js} +1 -1
  10. package/dist/brandsync-wc/p-1c6fa697.entry.js +1 -0
  11. package/dist/brandsync-wc/{p-dd747a12.entry.js → p-1cf715aa.entry.js} +1 -1
  12. package/dist/brandsync-wc/{p-8a78d6ea.entry.js → p-20dbc6a1.entry.js} +1 -1
  13. package/dist/brandsync-wc/{p-a34f460d.entry.js → p-23457a21.entry.js} +1 -1
  14. package/dist/brandsync-wc/p-266f5dde.entry.js +1 -0
  15. package/dist/brandsync-wc/p-2a65aabb.entry.js +1 -0
  16. package/dist/brandsync-wc/{p-8d12ed96.entry.js → p-2c51d738.entry.js} +1 -1
  17. package/dist/brandsync-wc/p-3b31f7c7.entry.js +1 -0
  18. package/dist/brandsync-wc/p-46ddc8e1.entry.js +1 -0
  19. package/dist/brandsync-wc/p-56c66448.entry.js +1 -0
  20. package/dist/brandsync-wc/{p-18af02df.entry.js → p-57fdbb76.entry.js} +1 -1
  21. package/dist/brandsync-wc/{p-7776b57b.entry.js → p-64e2a7d7.entry.js} +1 -1
  22. package/dist/brandsync-wc/{p-805644e4.entry.js → p-6e854e92.entry.js} +1 -1
  23. package/dist/brandsync-wc/p-72a33f88.entry.js +1 -0
  24. package/dist/brandsync-wc/p-8049f9f2.entry.js +1 -0
  25. package/dist/brandsync-wc/{p-d682675e.entry.js → p-88a0abee.entry.js} +1 -1
  26. package/dist/brandsync-wc/p-8b662ee3.entry.js +1 -0
  27. package/dist/brandsync-wc/{p-94ed898a.entry.js → p-8ded1eb6.entry.js} +1 -1
  28. package/dist/brandsync-wc/{p-nLORuTUY.js → p-DST5-cTx.js} +2 -2
  29. package/dist/brandsync-wc/p-a5b15061.entry.js +1 -0
  30. package/dist/brandsync-wc/{p-30a0e168.entry.js → p-aba300a9.entry.js} +1 -1
  31. package/dist/brandsync-wc/p-b24a980b.entry.js +1 -0
  32. package/dist/brandsync-wc/{p-96f374be.entry.js → p-b289450a.entry.js} +1 -1
  33. package/dist/brandsync-wc/{p-880ea3f8.entry.js → p-b8a2f882.entry.js} +1 -1
  34. package/dist/brandsync-wc/p-c320b6b4.entry.js +1 -0
  35. package/dist/brandsync-wc/{p-1515498e.entry.js → p-d4e3ca77.entry.js} +1 -1
  36. package/dist/brandsync-wc/{p-ce0914a7.entry.js → p-dd09d335.entry.js} +1 -1
  37. package/dist/brandsync-wc/p-ef8522b5.entry.js +1 -0
  38. package/dist/brandsync-wc/p-f04db1b0.entry.js +1 -0
  39. package/dist/cjs/brandsync-wc.cjs.js +2 -2
  40. package/dist/cjs/bs-ai-disclaimer.cjs.entry.js +3 -2
  41. package/dist/cjs/bs-ai-greeting.cjs.entry.js +2 -2
  42. package/dist/cjs/bs-ai-thinking.cjs.entry.js +2 -2
  43. package/dist/cjs/bs-attachment-list.cjs.entry.js +2 -2
  44. package/dist/cjs/bs-attachment.cjs.entry.js +3 -3
  45. package/dist/cjs/bs-badge.cjs.entry.js +1 -1
  46. package/dist/cjs/bs-button-skeleton.cjs.entry.js +2 -2
  47. package/dist/cjs/bs-button.cjs.entry.js +3 -3
  48. package/dist/cjs/bs-card.cjs.entry.js +1 -1
  49. package/dist/cjs/bs-chatbot-feedback.cjs.entry.js +2 -2
  50. package/dist/cjs/bs-chatbot-header.cjs.entry.js +2 -2
  51. package/dist/cjs/bs-chatbot-response-action.cjs.entry.js +2 -2
  52. package/dist/cjs/bs-chatbot-sources-drawer.cjs.entry.js +2 -2
  53. package/dist/cjs/bs-chatbot-suggestion-button.cjs.entry.js +2 -2
  54. package/dist/cjs/bs-checkbox.cjs.entry.js +94 -0
  55. package/dist/cjs/bs-composer-status-banner.cjs.entry.js +14 -2
  56. package/dist/cjs/bs-composer.cjs.entry.js +37 -4
  57. package/dist/cjs/bs-data-table.cjs.entry.js +3 -3
  58. package/dist/cjs/bs-icon-button.cjs.entry.js +40 -0
  59. package/dist/cjs/bs-inline-tab.cjs.entry.js +69 -0
  60. package/dist/cjs/bs-input.cjs.entry.js +3 -3
  61. package/dist/cjs/bs-logo.cjs.entry.js +165 -0
  62. package/dist/cjs/bs-menu_2.cjs.entry.js +3 -3
  63. package/dist/cjs/bs-modal.cjs.entry.js +1 -1
  64. package/dist/cjs/bs-navigation-drawer-item.cjs.entry.js +104 -0
  65. package/dist/cjs/bs-navigation-drawer.cjs.entry.js +81 -0
  66. package/dist/cjs/bs-navigation-header.cjs.entry.js +44 -0
  67. package/dist/cjs/bs-radio.cjs.entry.js +49 -0
  68. package/dist/cjs/bs-slider.cjs.entry.js +191 -0
  69. package/dist/cjs/bs-source-link.cjs.entry.js +3 -3
  70. package/dist/cjs/bs-switch.cjs.entry.js +57 -0
  71. package/dist/cjs/bs-tab.cjs.entry.js +80 -0
  72. package/dist/cjs/bs-tabs.cjs.entry.js +39 -0
  73. package/dist/cjs/bs-tooltip.cjs.entry.js +2 -2
  74. package/dist/cjs/{index-CVh-sqA_.js → index-B3sdhEGk.js} +74 -2
  75. package/dist/cjs/loader.cjs.js +2 -2
  76. package/dist/collection/collection-manifest.json +14 -2
  77. package/dist/collection/components/bs-ai-chatbot/bs-ai-chatbot.stories.js +26 -11
  78. package/dist/collection/components/bs-ai-disclaimer/bs-ai-disclaimer.js +2 -1
  79. package/dist/collection/components/bs-ai-greeting/bs-ai-greeting.js +1 -1
  80. package/dist/collection/components/bs-ai-thinking/bs-ai-thinking.js +1 -1
  81. package/dist/collection/components/bs-attachment/bs-attachment.css +12 -33
  82. package/dist/collection/components/bs-attachment/bs-attachment.js +4 -10
  83. package/dist/collection/components/bs-attachment-list/bs-attachment-list.js +1 -1
  84. package/dist/collection/components/bs-button/{bs-button.cmp.test.js → bs-button/bs-button.cmp.test.js} +26 -0
  85. package/dist/collection/components/bs-button/{bs-button.css → bs-button/bs-button.css} +57 -6
  86. package/dist/collection/components/bs-button/{bs-button.js → bs-button/bs-button.js} +10 -5
  87. package/dist/collection/components/bs-button/{bs-button.stories.js → bs-button/bs-button.stories.js} +2 -27
  88. package/dist/collection/components/bs-button/bs-icon-button/bs-icon-button.cmp.test.js +83 -0
  89. package/dist/collection/components/bs-button/bs-icon-button/bs-icon-button.css +346 -0
  90. package/dist/collection/components/bs-button/bs-icon-button/bs-icon-button.js +185 -0
  91. package/dist/collection/components/bs-button/bs-icon-button/bs-icon-button.stories.js +74 -0
  92. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.js +3 -3
  93. package/dist/collection/components/bs-chatbot-feedback/bs-chatbot-feedback.js +1 -1
  94. package/dist/collection/components/bs-chatbot-header/bs-chatbot-header.js +1 -1
  95. package/dist/collection/components/bs-chatbot-response-action/bs-chatbot-response-action.js +1 -1
  96. package/dist/collection/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.js +1 -1
  97. package/dist/collection/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.js +1 -1
  98. package/dist/collection/components/bs-checkbox/bs-checkbox.cmp.test.js +117 -0
  99. package/dist/collection/components/bs-checkbox/bs-checkbox.css +199 -0
  100. package/dist/collection/components/bs-checkbox/bs-checkbox.js +265 -0
  101. package/dist/collection/components/bs-checkbox/bs-checkbox.stories.js +65 -0
  102. package/dist/collection/components/bs-composer/bs-composer.cmp.test.js +48 -7
  103. package/dist/collection/components/bs-composer/bs-composer.css +15 -0
  104. package/dist/collection/components/bs-composer/bs-composer.js +38 -4
  105. package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.cmp.test.js +47 -1
  106. package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.js +20 -1
  107. package/dist/collection/components/bs-data-table/bs-data-table.js +2 -2
  108. package/dist/collection/components/bs-input/bs-input.js +2 -2
  109. package/dist/collection/components/bs-logo/brandsync-logo-full-dark.js +44 -0
  110. package/dist/collection/components/bs-logo/brandsync-logo-full-light.js +40 -0
  111. package/dist/collection/components/bs-logo/brandsync-logo-mark.js +17 -0
  112. package/dist/collection/components/bs-logo/bs-logo.cmp.test.js +113 -0
  113. package/dist/collection/components/bs-logo/bs-logo.css +79 -0
  114. package/dist/collection/components/bs-logo/bs-logo.js +193 -0
  115. package/dist/collection/components/bs-logo/bs-logo.stories.js +69 -0
  116. package/dist/collection/components/bs-menu/bs-menu.js +1 -1
  117. package/dist/collection/components/bs-menu-item/bs-menu-item.js +1 -1
  118. package/dist/collection/components/bs-radio/bs-radio.cmp.test.js +76 -0
  119. package/dist/collection/components/bs-radio/bs-radio.css +164 -0
  120. package/dist/collection/components/bs-radio/bs-radio.js +170 -0
  121. package/dist/collection/components/bs-radio/bs-radio.stories.js +56 -0
  122. package/dist/collection/components/bs-slider/bs-slider.cmp.test.js +139 -0
  123. package/dist/collection/components/bs-slider/bs-slider.css +409 -0
  124. package/dist/collection/components/bs-slider/bs-slider.js +499 -0
  125. package/dist/collection/components/bs-slider/bs-slider.stories.js +70 -0
  126. package/dist/collection/components/bs-source-link/bs-source-link.js +2 -2
  127. package/dist/collection/components/bs-switch/bs-switch.cmp.test.js +71 -0
  128. package/dist/collection/components/bs-switch/bs-switch.css +196 -0
  129. package/dist/collection/components/bs-switch/bs-switch.js +185 -0
  130. package/dist/collection/components/bs-switch/bs-switch.stories.js +60 -0
  131. package/dist/collection/components/bs-tab/bs-inline-tab/bs-inline-tab.cmp.test.js +104 -0
  132. package/dist/collection/components/bs-tab/bs-inline-tab/bs-inline-tab.css +163 -0
  133. package/dist/collection/components/bs-tab/bs-inline-tab/bs-inline-tab.js +192 -0
  134. package/dist/collection/components/bs-tab/bs-inline-tab/bs-inline-tab.stories.js +95 -0
  135. package/dist/collection/components/bs-tab/bs-tab/bs-tab.cmp.test.js +120 -0
  136. package/dist/collection/components/bs-tab/bs-tab/bs-tab.css +216 -0
  137. package/dist/collection/components/bs-tab/bs-tab/bs-tab.js +232 -0
  138. package/dist/collection/components/bs-tab/bs-tab/bs-tab.stories.js +138 -0
  139. package/dist/collection/components/bs-tab/bs-tabs/bs-tabs.cmp.test.js +61 -0
  140. package/dist/collection/components/bs-tab/bs-tabs/bs-tabs.css +39 -0
  141. package/dist/collection/components/bs-tab/bs-tabs/bs-tabs.js +133 -0
  142. package/dist/collection/components/bs-tab/bs-tabs/bs-tabs.stories.js +39 -0
  143. package/dist/collection/components/bs-tooltip/bs-tooltip.js +1 -1
  144. package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.cmp.test.js +131 -0
  145. package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.css +257 -0
  146. package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.js +253 -0
  147. package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.stories.js +202 -0
  148. package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.cmp.test.js +172 -0
  149. package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.css +325 -0
  150. package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.js +314 -0
  151. package/dist/collection/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.stories.js +78 -0
  152. package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.cmp.test.js +77 -0
  153. package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.css +106 -0
  154. package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.js +188 -0
  155. package/dist/collection/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.stories.js +189 -0
  156. package/dist/components/bs-ai-disclaimer.js +1 -1
  157. package/dist/components/bs-ai-greeting.js +1 -1
  158. package/dist/components/bs-ai-thinking.js +1 -1
  159. package/dist/components/bs-attachment-list.js +1 -1
  160. package/dist/components/bs-attachment.js +1 -1
  161. package/dist/components/bs-badge.js +1 -1
  162. package/dist/components/bs-button-skeleton.js +1 -1
  163. package/dist/components/bs-button.js +1 -1
  164. package/dist/components/bs-card.js +1 -1
  165. package/dist/components/bs-chatbot-feedback.js +1 -1
  166. package/dist/components/bs-chatbot-header.js +1 -1
  167. package/dist/components/bs-chatbot-response-action.js +1 -1
  168. package/dist/components/bs-chatbot-sources-drawer.js +1 -1
  169. package/dist/components/bs-chatbot-suggestion-button.js +1 -1
  170. package/dist/components/bs-checkbox.d.ts +11 -0
  171. package/dist/components/bs-checkbox.js +1 -0
  172. package/dist/components/bs-composer-status-banner.js +1 -1
  173. package/dist/components/bs-composer.js +1 -1
  174. package/dist/components/bs-data-table.js +1 -1
  175. package/dist/components/bs-icon-button.d.ts +11 -0
  176. package/dist/components/bs-icon-button.js +1 -0
  177. package/dist/components/bs-inline-tab.d.ts +11 -0
  178. package/dist/components/bs-inline-tab.js +1 -0
  179. package/dist/components/bs-input.js +1 -1
  180. package/dist/components/bs-logo.d.ts +11 -0
  181. package/dist/components/bs-logo.js +1 -0
  182. package/dist/components/bs-menu-item.js +1 -1
  183. package/dist/components/bs-menu.js +1 -1
  184. package/dist/components/bs-modal.js +1 -1
  185. package/dist/components/bs-navigation-drawer-item.d.ts +11 -0
  186. package/dist/components/bs-navigation-drawer-item.js +1 -0
  187. package/dist/components/bs-navigation-drawer.d.ts +11 -0
  188. package/dist/components/bs-navigation-drawer.js +1 -0
  189. package/dist/components/bs-navigation-header.d.ts +11 -0
  190. package/dist/components/bs-navigation-header.js +1 -0
  191. package/dist/components/bs-radio.d.ts +11 -0
  192. package/dist/components/bs-radio.js +1 -0
  193. package/dist/components/bs-slider.d.ts +11 -0
  194. package/dist/components/bs-slider.js +1 -0
  195. package/dist/components/bs-source-link.js +1 -1
  196. package/dist/components/bs-switch.d.ts +11 -0
  197. package/dist/components/bs-switch.js +1 -0
  198. package/dist/components/bs-tab.d.ts +11 -0
  199. package/dist/components/bs-tab.js +1 -0
  200. package/dist/components/bs-tabs.d.ts +11 -0
  201. package/dist/components/bs-tabs.js +1 -0
  202. package/dist/components/bs-tooltip.js +1 -1
  203. package/dist/components/index.js +1 -1
  204. package/dist/components/p-BAOJc0V0.js +1 -0
  205. package/dist/components/{p-BpvhHQSw.js → p-Be1Pfcnm.js} +1 -1
  206. package/dist/components/{p-Cz2nfz2j.js → p-BqYyMGrB.js} +1 -1
  207. package/dist/components/p-CaWqTQBZ.js +1 -0
  208. package/dist/components/{p-DndQiCMP.js → p-DivZLd6i.js} +1 -1
  209. package/dist/components/{p-DHbUF0g6.js → p-xfx69LQx.js} +1 -1
  210. package/dist/esm/brandsync-wc.js +3 -3
  211. package/dist/esm/bs-ai-disclaimer.entry.js +3 -2
  212. package/dist/esm/bs-ai-greeting.entry.js +2 -2
  213. package/dist/esm/bs-ai-thinking.entry.js +2 -2
  214. package/dist/esm/bs-attachment-list.entry.js +2 -2
  215. package/dist/esm/bs-attachment.entry.js +3 -3
  216. package/dist/esm/bs-badge.entry.js +1 -1
  217. package/dist/esm/bs-button-skeleton.entry.js +2 -2
  218. package/dist/esm/bs-button.entry.js +3 -3
  219. package/dist/esm/bs-card.entry.js +1 -1
  220. package/dist/esm/bs-chatbot-feedback.entry.js +2 -2
  221. package/dist/esm/bs-chatbot-header.entry.js +2 -2
  222. package/dist/esm/bs-chatbot-response-action.entry.js +2 -2
  223. package/dist/esm/bs-chatbot-sources-drawer.entry.js +2 -2
  224. package/dist/esm/bs-chatbot-suggestion-button.entry.js +2 -2
  225. package/dist/esm/bs-checkbox.entry.js +92 -0
  226. package/dist/esm/bs-composer-status-banner.entry.js +14 -2
  227. package/dist/esm/bs-composer.entry.js +37 -4
  228. package/dist/esm/bs-data-table.entry.js +3 -3
  229. package/dist/esm/bs-icon-button.entry.js +38 -0
  230. package/dist/esm/bs-inline-tab.entry.js +67 -0
  231. package/dist/esm/bs-input.entry.js +3 -3
  232. package/dist/esm/bs-logo.entry.js +163 -0
  233. package/dist/esm/bs-menu_2.entry.js +3 -3
  234. package/dist/esm/bs-modal.entry.js +1 -1
  235. package/dist/esm/bs-navigation-drawer-item.entry.js +102 -0
  236. package/dist/esm/bs-navigation-drawer.entry.js +79 -0
  237. package/dist/esm/bs-navigation-header.entry.js +42 -0
  238. package/dist/esm/bs-radio.entry.js +47 -0
  239. package/dist/esm/bs-slider.entry.js +189 -0
  240. package/dist/esm/bs-source-link.entry.js +3 -3
  241. package/dist/esm/bs-switch.entry.js +55 -0
  242. package/dist/esm/bs-tab.entry.js +78 -0
  243. package/dist/esm/bs-tabs.entry.js +37 -0
  244. package/dist/esm/bs-tooltip.entry.js +2 -2
  245. package/dist/esm/{index-nLORuTUY.js → index-DST5-cTx.js} +74 -2
  246. package/dist/esm/loader.js +3 -3
  247. package/dist/types/components/bs-attachment/bs-attachment.d.ts +3 -9
  248. package/dist/types/components/bs-button/{bs-button.d.ts → bs-button/bs-button.d.ts} +5 -0
  249. package/dist/types/components/bs-button/{bs-button.stories.d.ts → bs-button/bs-button.stories.d.ts} +0 -2
  250. package/dist/types/components/bs-button/bs-icon-button/bs-icon-button.cmp.test.d.ts +1 -0
  251. package/dist/types/components/bs-button/bs-icon-button/bs-icon-button.d.ts +51 -0
  252. package/dist/types/components/bs-button/bs-icon-button/bs-icon-button.stories.d.ts +16 -0
  253. package/dist/types/components/bs-button-skeleton/bs-button-skeleton.d.ts +1 -1
  254. package/dist/types/components/bs-button-skeleton/bs-button-skeleton.stories.d.ts +1 -1
  255. package/dist/types/components/bs-checkbox/bs-checkbox.cmp.test.d.ts +1 -0
  256. package/dist/types/components/bs-checkbox/bs-checkbox.d.ts +64 -0
  257. package/dist/types/components/bs-checkbox/bs-checkbox.stories.d.ts +23 -0
  258. package/dist/types/components/bs-composer/bs-composer.d.ts +26 -2
  259. package/dist/types/components/bs-composer-status-banner/bs-composer-status-banner.d.ts +14 -0
  260. package/dist/types/components/bs-logo/brandsync-logo-full-dark.d.ts +1 -0
  261. package/dist/types/components/bs-logo/brandsync-logo-full-light.d.ts +1 -0
  262. package/dist/types/components/bs-logo/brandsync-logo-mark.d.ts +1 -0
  263. package/dist/types/components/bs-logo/bs-logo.cmp.test.d.ts +1 -0
  264. package/dist/types/components/bs-logo/bs-logo.d.ts +73 -0
  265. package/dist/types/components/bs-logo/bs-logo.stories.d.ts +17 -0
  266. package/dist/types/components/bs-radio/bs-radio.cmp.test.d.ts +1 -0
  267. package/dist/types/components/bs-radio/bs-radio.d.ts +45 -0
  268. package/dist/types/components/bs-radio/bs-radio.stories.d.ts +16 -0
  269. package/dist/types/components/bs-slider/bs-slider.cmp.test.d.ts +1 -0
  270. package/dist/types/components/bs-slider/bs-slider.d.ts +109 -0
  271. package/dist/types/components/bs-slider/bs-slider.stories.d.ts +24 -0
  272. package/dist/types/components/bs-switch/bs-switch.cmp.test.d.ts +1 -0
  273. package/dist/types/components/bs-switch/bs-switch.d.ts +45 -0
  274. package/dist/types/components/bs-switch/bs-switch.stories.d.ts +17 -0
  275. package/dist/types/components/bs-tab/bs-inline-tab/bs-inline-tab.cmp.test.d.ts +1 -0
  276. package/dist/types/components/bs-tab/bs-inline-tab/bs-inline-tab.d.ts +65 -0
  277. package/dist/types/components/bs-tab/bs-inline-tab/bs-inline-tab.stories.d.ts +22 -0
  278. package/dist/types/components/bs-tab/bs-tab/bs-tab.cmp.test.d.ts +1 -0
  279. package/dist/types/components/bs-tab/bs-tab/bs-tab.d.ts +74 -0
  280. package/dist/types/components/bs-tab/bs-tab/bs-tab.stories.d.ts +30 -0
  281. package/dist/types/components/bs-tab/bs-tabs/bs-tabs.cmp.test.d.ts +1 -0
  282. package/dist/types/components/bs-tab/bs-tabs/bs-tabs.d.ts +45 -0
  283. package/dist/types/components/bs-tab/bs-tabs/bs-tabs.stories.d.ts +13 -0
  284. package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.cmp.test.d.ts +1 -0
  285. package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.d.ts +96 -0
  286. package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer/bs-navigation-drawer.stories.d.ts +16 -0
  287. package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.cmp.test.d.ts +1 -0
  288. package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.d.ts +103 -0
  289. package/dist/types/components/ui-shell/bs-navigation-drawer/bs-navigation-drawer-item/bs-navigation-drawer-item.stories.d.ts +20 -0
  290. package/dist/types/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.cmp.test.d.ts +1 -0
  291. package/dist/types/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.d.ts +60 -0
  292. package/dist/types/components/ui-shell/bs-navigation-header/bs-navigation-header/bs-navigation-header.stories.d.ts +21 -0
  293. package/dist/types/components.d.ts +1973 -49
  294. package/package.json +1 -1
  295. package/dist/brandsync-wc/p-0d64ea40.entry.js +0 -1
  296. package/dist/brandsync-wc/p-16a54578.entry.js +0 -1
  297. package/dist/brandsync-wc/p-bc72439a.entry.js +0 -1
  298. package/dist/brandsync-wc/p-dad4a92c.entry.js +0 -1
  299. package/dist/brandsync-wc/p-eb4d87f0.entry.js +0 -1
  300. /package/dist/types/components/bs-button/{bs-button.cmp.test.d.ts → bs-button/bs-button.cmp.test.d.ts} +0 -0
@@ -0,0 +1,265 @@
1
+ import { h } from "@stencil/core";
2
+ /**
3
+ * A single checkbox with its label, for a binary choice or one item within a group of independent
4
+ * choices.
5
+ *
6
+ * ## When to use
7
+ * - A single standalone binary setting (e.g. "Remember me", "I agree to the terms").
8
+ * - One item within a set of independent, non-exclusive choices (a checkbox group/list).
9
+ * - `indeterminate` for a "select all" checkbox representing a partially-selected group.
10
+ *
11
+ * ## When not to use
12
+ * - A single mutually-exclusive choice from a set -- use a radio group instead.
13
+ * - An on/off setting that takes effect immediately (no explicit form submission) -- use `bs-switch`.
14
+ *
15
+ * @slot - Default slot: the label text.
16
+ * @part box - The visual checkbox square.
17
+ * @part icon - The check/minus icon shown inside the box when `checked` or `indeterminate`.
18
+ * @part label - The label text wrapper.
19
+ */
20
+ // Note: this component's CSS Custom Properties (--bs-checkbox-*) are documented via @prop comments
21
+ // in bs-checkbox.css, not here -- Stencil's docs generator only parses @prop out of CSS file
22
+ // comments, not the class-level JSDoc (see bs-input.tsx's equivalent note).
23
+ export class BsCheckbox {
24
+ el;
25
+ inputEl;
26
+ /** Sizing scale. Controls the box's width/height and border width; corner radius is constant
27
+ * across all sizes. */
28
+ size = 'lg';
29
+ /** Whether the checkbox is checked. Mutable so clicking the label/input toggles it directly.
30
+ * When `indeterminate` is also true, `indeterminate` wins visually (shows the minus icon)
31
+ * regardless of this value -- same as native checkboxes. */
32
+ checked = false;
33
+ /** Whether the checkbox is in the indeterminate ("partially selected") state -- shows a minus
34
+ * icon instead of a check, and takes visual precedence over `checked`. Unlike `checked`, native
35
+ * checkboxes have no `indeterminate` HTML attribute; it can only be set as a JS property on the
36
+ * element. This `@Prop` still works as an attribute for the *host* (`<bs-checkbox>`) since that's
37
+ * this component's own reflected state, not the native control's -- the native `<input>` inside
38
+ * has its `.indeterminate` property set imperatively in `componentDidLoad`/`componentDidUpdate`. */
39
+ indeterminate = false;
40
+ /** Disables the checkbox: sets the native `disabled` attribute, suppresses hover/focus styling,
41
+ * and prevents toggling. */
42
+ disabled = false;
43
+ /** Applies the error border/label-color treatment. This component's spec has no error message
44
+ * text of its own (unlike `bs-input`'s `error: string`), so it's a plain boolean. */
45
+ error = false;
46
+ /**
47
+ * Accessible name for the checkbox. Required whenever the default (label) slot is empty (e.g. a
48
+ * bare "select row" checkbox in a table) -- without it, the internal native `<input>` has no
49
+ * accessible name at all. Setting `aria-label` directly on the `<bs-checkbox>` host does NOT
50
+ * work for this: that attribute stays on the light-DOM host and is never forwarded into the
51
+ * shadow DOM by the browser, so the actual focusable element (the native `<input>` inside) stays
52
+ * nameless. This prop exists specifically to bridge that gap -- same pattern as `bs-button`'s and
53
+ * `bs-tab`'s identical `ariaLabel` prop, both of which explicitly bind it onto their own internal
54
+ * focusable element for the same reason.
55
+ */
56
+ ariaLabel = null;
57
+ /** Emitted when the checked state changes via user interaction, with the new `checked` value. */
58
+ bsChange;
59
+ /** Keeps the native input's `.indeterminate` JS property in sync -- this can't be expressed as a
60
+ * JSX attribute in Stencil, it must be set imperatively on the element. */
61
+ onIndeterminateChange() {
62
+ if (this.inputEl) {
63
+ this.inputEl.indeterminate = this.indeterminate;
64
+ }
65
+ }
66
+ componentDidLoad() {
67
+ if (this.inputEl) {
68
+ this.inputEl.indeterminate = this.indeterminate;
69
+ }
70
+ }
71
+ componentDidUpdate() {
72
+ if (this.inputEl) {
73
+ this.inputEl.indeterminate = this.indeterminate;
74
+ }
75
+ }
76
+ onChange = (ev) => {
77
+ const checked = ev.target.checked;
78
+ this.checked = checked;
79
+ // Clicking a native checkbox always clears indeterminate, regardless of what it was before --
80
+ // match that here so the visual state (icon) tracks the real native behavior.
81
+ this.indeterminate = false;
82
+ this.bsChange.emit(checked);
83
+ };
84
+ render() {
85
+ const showIcon = this.checked || this.indeterminate;
86
+ const boxClasses = [
87
+ 'bs-checkbox__box',
88
+ `bs-checkbox__box--${this.size}`,
89
+ showIcon ? 'bs-checkbox__box--selected' : '',
90
+ this.disabled ? 'bs-checkbox__box--disabled' : '',
91
+ this.error ? 'bs-checkbox__box--error' : '',
92
+ ]
93
+ .filter(Boolean)
94
+ .join(' ');
95
+ return (h("label", { key: '04fb1da55eb6a0e91fd705db9217f5e2c0992f89', class: `bs-checkbox ${this.disabled ? 'bs-checkbox--disabled' : ''}` }, h("input", { key: '06b83f45f7dfe52cd81eab603742d04d74135c7a', ref: el => (this.inputEl = el), class: "bs-checkbox__input", type: "checkbox", checked: this.checked, disabled: this.disabled, "aria-checked": this.indeterminate ? 'mixed' : String(this.checked), "aria-label": this.ariaLabel, onChange: this.onChange }), h("span", { key: 'a8a8b45074eef7cfcb5f579eff0fb7b27b71d25a', part: "box", class: boxClasses }, showIcon && (h("svg", { key: '78cf717b4cd7fbf8c56a76788a22c8aecf7fcc28', part: "icon", class: "bs-checkbox__icon", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true" }, this.indeterminate ? (h("path", { d: "M3 8H13", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round" })) : (h("path", { d: "M3 8.5L6.2 11.5L13 4.5", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }))))), h("span", { key: '2d78205d8091c89ac3a6d07cbb74b6d6a9c09971', part: "label", class: "bs-checkbox__label" }, h("slot", { key: '7da0c6d1f84b788b242b95b11d78e566f482b48c' }))));
96
+ }
97
+ static get is() { return "bs-checkbox"; }
98
+ static get encapsulation() { return "shadow"; }
99
+ static get delegatesFocus() { return true; }
100
+ static get originalStyleUrls() {
101
+ return {
102
+ "$": ["bs-checkbox.css"]
103
+ };
104
+ }
105
+ static get styleUrls() {
106
+ return {
107
+ "$": ["bs-checkbox.css"]
108
+ };
109
+ }
110
+ static get properties() {
111
+ return {
112
+ "size": {
113
+ "type": "string",
114
+ "mutable": false,
115
+ "complexType": {
116
+ "original": "BsCheckboxSize",
117
+ "resolved": "\"lg\" | \"md\" | \"sm\"",
118
+ "references": {
119
+ "BsCheckboxSize": {
120
+ "location": "local",
121
+ "path": "/Users/vivka/brandsync-web-components/src/components/bs-checkbox/bs-checkbox.tsx",
122
+ "id": "src/components/bs-checkbox/bs-checkbox.tsx::BsCheckboxSize"
123
+ }
124
+ }
125
+ },
126
+ "required": false,
127
+ "optional": false,
128
+ "docs": {
129
+ "tags": [],
130
+ "text": "Sizing scale. Controls the box's width/height and border width; corner radius is constant\nacross all sizes."
131
+ },
132
+ "getter": false,
133
+ "setter": false,
134
+ "reflect": false,
135
+ "attribute": "size",
136
+ "defaultValue": "'lg'"
137
+ },
138
+ "checked": {
139
+ "type": "boolean",
140
+ "mutable": true,
141
+ "complexType": {
142
+ "original": "boolean",
143
+ "resolved": "boolean",
144
+ "references": {}
145
+ },
146
+ "required": false,
147
+ "optional": false,
148
+ "docs": {
149
+ "tags": [],
150
+ "text": "Whether the checkbox is checked. Mutable so clicking the label/input toggles it directly.\nWhen `indeterminate` is also true, `indeterminate` wins visually (shows the minus icon)\nregardless of this value -- same as native checkboxes."
151
+ },
152
+ "getter": false,
153
+ "setter": false,
154
+ "reflect": true,
155
+ "attribute": "checked",
156
+ "defaultValue": "false"
157
+ },
158
+ "indeterminate": {
159
+ "type": "boolean",
160
+ "mutable": true,
161
+ "complexType": {
162
+ "original": "boolean",
163
+ "resolved": "boolean",
164
+ "references": {}
165
+ },
166
+ "required": false,
167
+ "optional": false,
168
+ "docs": {
169
+ "tags": [],
170
+ "text": "Whether the checkbox is in the indeterminate (\"partially selected\") state -- shows a minus\nicon instead of a check, and takes visual precedence over `checked`. Unlike `checked`, native\ncheckboxes have no `indeterminate` HTML attribute; it can only be set as a JS property on the\nelement. This `@Prop` still works as an attribute for the *host* (`<bs-checkbox>`) since that's\nthis component's own reflected state, not the native control's -- the native `<input>` inside\nhas its `.indeterminate` property set imperatively in `componentDidLoad`/`componentDidUpdate`."
171
+ },
172
+ "getter": false,
173
+ "setter": false,
174
+ "reflect": true,
175
+ "attribute": "indeterminate",
176
+ "defaultValue": "false"
177
+ },
178
+ "disabled": {
179
+ "type": "boolean",
180
+ "mutable": false,
181
+ "complexType": {
182
+ "original": "boolean",
183
+ "resolved": "boolean",
184
+ "references": {}
185
+ },
186
+ "required": false,
187
+ "optional": false,
188
+ "docs": {
189
+ "tags": [],
190
+ "text": "Disables the checkbox: sets the native `disabled` attribute, suppresses hover/focus styling,\nand prevents toggling."
191
+ },
192
+ "getter": false,
193
+ "setter": false,
194
+ "reflect": false,
195
+ "attribute": "disabled",
196
+ "defaultValue": "false"
197
+ },
198
+ "error": {
199
+ "type": "boolean",
200
+ "mutable": false,
201
+ "complexType": {
202
+ "original": "boolean",
203
+ "resolved": "boolean",
204
+ "references": {}
205
+ },
206
+ "required": false,
207
+ "optional": false,
208
+ "docs": {
209
+ "tags": [],
210
+ "text": "Applies the error border/label-color treatment. This component's spec has no error message\ntext of its own (unlike `bs-input`'s `error: string`), so it's a plain boolean."
211
+ },
212
+ "getter": false,
213
+ "setter": false,
214
+ "reflect": false,
215
+ "attribute": "error",
216
+ "defaultValue": "false"
217
+ },
218
+ "ariaLabel": {
219
+ "type": "string",
220
+ "mutable": false,
221
+ "complexType": {
222
+ "original": "string | null",
223
+ "resolved": "string",
224
+ "references": {}
225
+ },
226
+ "required": false,
227
+ "optional": false,
228
+ "docs": {
229
+ "tags": [],
230
+ "text": "Accessible name for the checkbox. Required whenever the default (label) slot is empty (e.g. a\nbare \"select row\" checkbox in a table) -- without it, the internal native `<input>` has no\naccessible name at all. Setting `aria-label` directly on the `<bs-checkbox>` host does NOT\nwork for this: that attribute stays on the light-DOM host and is never forwarded into the\nshadow DOM by the browser, so the actual focusable element (the native `<input>` inside) stays\nnameless. This prop exists specifically to bridge that gap -- same pattern as `bs-button`'s and\n`bs-tab`'s identical `ariaLabel` prop, both of which explicitly bind it onto their own internal\nfocusable element for the same reason."
231
+ },
232
+ "getter": false,
233
+ "setter": false,
234
+ "reflect": false,
235
+ "attribute": "aria-label",
236
+ "defaultValue": "null"
237
+ }
238
+ };
239
+ }
240
+ static get events() {
241
+ return [{
242
+ "method": "bsChange",
243
+ "name": "bsChange",
244
+ "bubbles": true,
245
+ "cancelable": true,
246
+ "composed": true,
247
+ "docs": {
248
+ "tags": [],
249
+ "text": "Emitted when the checked state changes via user interaction, with the new `checked` value."
250
+ },
251
+ "complexType": {
252
+ "original": "boolean",
253
+ "resolved": "boolean",
254
+ "references": {}
255
+ }
256
+ }];
257
+ }
258
+ static get elementRef() { return "el"; }
259
+ static get watchers() {
260
+ return [{
261
+ "propName": "indeterminate",
262
+ "methodName": "onIndeterminateChange"
263
+ }];
264
+ }
265
+ }
@@ -0,0 +1,65 @@
1
+ import { html } from "lit";
2
+ import { componentDescription, propDescription } from "../../stories-utils";
3
+ const sizes = ['sm', 'md', 'lg'];
4
+ const meta = {
5
+ title: 'Components/bs-checkbox',
6
+ parameters: { docs: { description: { component: componentDescription('bs-checkbox') } } },
7
+ render: args => html `
8
+ <bs-checkbox
9
+ size=${args.size}
10
+ ?checked=${args.checked}
11
+ .indeterminate=${args.indeterminate}
12
+ ?disabled=${args.disabled}
13
+ ?error=${args.error}
14
+ >
15
+ ${args.label}
16
+ </bs-checkbox>
17
+ `,
18
+ argTypes: {
19
+ size: { control: 'select', options: sizes, description: propDescription('bs-checkbox', 'size') },
20
+ checked: { control: 'boolean', description: propDescription('bs-checkbox', 'checked') },
21
+ indeterminate: { control: 'boolean', description: propDescription('bs-checkbox', 'indeterminate') },
22
+ disabled: { control: 'boolean', description: propDescription('bs-checkbox', 'disabled') },
23
+ error: { control: 'boolean', description: propDescription('bs-checkbox', 'error') },
24
+ label: { control: 'text' },
25
+ },
26
+ args: {
27
+ size: 'lg',
28
+ checked: false,
29
+ indeterminate: false,
30
+ disabled: false,
31
+ error: false,
32
+ label: 'Accept terms and conditions',
33
+ },
34
+ };
35
+ export default meta;
36
+ export const Default = {};
37
+ export const Checked = {
38
+ args: { checked: true },
39
+ };
40
+ export const Indeterminate = {
41
+ args: { indeterminate: true },
42
+ };
43
+ export const Disabled = {
44
+ args: { disabled: true },
45
+ };
46
+ export const DisabledChecked = {
47
+ name: 'Disabled + checked',
48
+ args: { disabled: true, checked: true },
49
+ };
50
+ export const Error = {
51
+ args: { error: true },
52
+ };
53
+ export const ErrorChecked = {
54
+ name: 'Error + checked',
55
+ args: { error: true, checked: true },
56
+ };
57
+ export const Small = {
58
+ args: { size: 'sm', checked: true },
59
+ };
60
+ export const Medium = {
61
+ args: { size: 'md', checked: true },
62
+ };
63
+ export const Large = {
64
+ args: { size: 'lg', checked: true },
65
+ };
@@ -2,7 +2,7 @@ import { render, h, describe, it, expect } from "@stencil/vitest";
2
2
  describe('bs-composer', () => {
3
3
  it('renders with idle state defaults: ai variant placeholder, enabled mic/action buttons', async () => {
4
4
  const { root } = await render(h("bs-composer", null));
5
- const input = root.shadowRoot.querySelector('input');
5
+ const input = root.shadowRoot.querySelector('textarea');
6
6
  expect(input).toEqualAttribute('placeholder', 'Ask Genie something...');
7
7
  expect(input).not.toHaveAttribute('disabled');
8
8
  const mic = root.shadowRoot.querySelector('[part="mic"]');
@@ -13,22 +13,22 @@ describe('bs-composer', () => {
13
13
  });
14
14
  it('uses the human variant default placeholder', async () => {
15
15
  const { root } = await render(h("bs-composer", { variant: "human" }));
16
- const input = root.shadowRoot.querySelector('input');
16
+ const input = root.shadowRoot.querySelector('textarea');
17
17
  expect(input).toEqualAttribute('placeholder', 'Message your support agent...');
18
18
  });
19
19
  it('overrides the variant default placeholder when placeholder is set', async () => {
20
20
  const { root } = await render(h("bs-composer", { variant: "ai", placeholder: "Custom prompt" }));
21
- const input = root.shadowRoot.querySelector('input');
21
+ const input = root.shadowRoot.querySelector('textarea');
22
22
  expect(input).toEqualAttribute('placeholder', 'Custom prompt');
23
23
  });
24
24
  it('reflects the value prop to the native input', async () => {
25
25
  const { root } = await render(h("bs-composer", { value: "hello there" }));
26
- const input = root.shadowRoot.querySelector('input');
26
+ const input = root.shadowRoot.querySelector('textarea');
27
27
  expect(input.value).toBe('hello there');
28
28
  });
29
29
  it('sets aria-label on the input from the ariaLabel prop', async () => {
30
30
  const { root } = await render(h("bs-composer", { ariaLabel: "Message" }));
31
- const input = root.shadowRoot.querySelector('input');
31
+ const input = root.shadowRoot.querySelector('textarea');
32
32
  expect(input).toEqualAttribute('aria-label', 'Message');
33
33
  });
34
34
  it('renders consumer-supplied content in the actions-end slot, after the primary action button', async () => {
@@ -59,12 +59,53 @@ describe('bs-composer', () => {
59
59
  it('emits bsInput with the current value as the user types', async () => {
60
60
  const { root, spyOnEvent } = await render(h("bs-composer", null));
61
61
  const spy = spyOnEvent('bsInput');
62
- const input = root.shadowRoot.querySelector('input');
62
+ const input = root.shadowRoot.querySelector('textarea');
63
63
  input.value = 'a';
64
64
  input.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
65
65
  expect(spy).toHaveReceivedEventTimes(1);
66
66
  expect(spy).toHaveReceivedEventDetail('a');
67
67
  });
68
+ describe('auto-grow', () => {
69
+ it('grows taller as multi-line content is typed', async () => {
70
+ const { root } = await render(h("bs-composer", null));
71
+ const textarea = root.shadowRoot.querySelector('textarea');
72
+ const oneLineHeight = textarea.getBoundingClientRect().height;
73
+ textarea.value = 'line one\nline two\nline three';
74
+ textarea.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
75
+ const threeLineHeight = textarea.getBoundingClientRect().height;
76
+ expect(threeLineHeight).toBeGreaterThan(oneLineHeight);
77
+ });
78
+ it('caps growth at --bs-composer-input-max-lines and scrolls internally beyond that', async () => {
79
+ const { root } = await render(h("bs-composer", null));
80
+ const textarea = root.shadowRoot.querySelector('textarea');
81
+ const lineHeight = textarea.getBoundingClientRect().height;
82
+ const fifteenLines = Array.from({ length: 15 }, (_, i) => `line ${i}`).join('\n');
83
+ textarea.value = fifteenLines;
84
+ textarea.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
85
+ const cappedHeight = textarea.getBoundingClientRect().height;
86
+ // 10 lines' worth of height, not 15 -- the default max-lines is 10 (see bs-composer.css).
87
+ expect(cappedHeight).toBeCloseTo(lineHeight * 10, 0);
88
+ expect(textarea.scrollHeight).toBeGreaterThan(textarea.clientHeight);
89
+ });
90
+ it('resizes to fit an initial multi-line value prop, not just user typing', async () => {
91
+ // Measure each render's height before the other render() call runs -- a second render() in
92
+ // the same test can detach the first instance from the layout tree, which would make its
93
+ // getBoundingClientRect() report 0 rather than its real (but by-then-detached) height.
94
+ const single = await render(h("bs-composer", { value: "one line" }));
95
+ const singleLineHeight = single.root.shadowRoot.querySelector('textarea').getBoundingClientRect().height;
96
+ const multi = await render(h("bs-composer", { value: 'line one\nline two\nline three' }));
97
+ const multiLineHeight = multi.root.shadowRoot.querySelector('textarea').getBoundingClientRect().height;
98
+ expect(multiLineHeight).toBeGreaterThan(singleLineHeight);
99
+ });
100
+ it('re-runs the resize when the value prop is updated programmatically (not via typing)', async () => {
101
+ const { root, setProps, waitForChanges } = await render(h("bs-composer", { value: "one line" }));
102
+ const textarea = root.shadowRoot.querySelector('textarea');
103
+ const oneLineHeight = textarea.getBoundingClientRect().height;
104
+ await setProps({ value: 'line one\nline two\nline three\nline four' });
105
+ await waitForChanges();
106
+ expect(textarea.getBoundingClientRect().height).toBeGreaterThan(oneLineHeight);
107
+ });
108
+ });
68
109
  it('emits bsAttach when the attach button is clicked', async () => {
69
110
  const { root, spyOnEvent } = await render(h("bs-composer", null));
70
111
  const spy = spyOnEvent('bsAttach');
@@ -107,7 +148,7 @@ describe('bs-composer', () => {
107
148
  describe('state="disabled"', () => {
108
149
  it('natively disables both the mic and action buttons and the text input', async () => {
109
150
  const { root } = await render(h("bs-composer", { state: "disabled" }));
110
- expect(root.shadowRoot.querySelector('input')).toHaveAttribute('disabled');
151
+ expect(root.shadowRoot.querySelector('textarea')).toHaveAttribute('disabled');
111
152
  expect(root.shadowRoot.querySelector('[part="mic"]')).toHaveAttribute('disabled');
112
153
  expect(root.shadowRoot.querySelector('[part="action"]')).toHaveAttribute('disabled');
113
154
  });
@@ -22,6 +22,8 @@
22
22
  --bs-composer-subtle-pressed: var(--bs-color-neutral-container-pressed);
23
23
 
24
24
  --bs-composer-waveform-color: var(--bs-border-default);
25
+
26
+ --bs-composer-input-max-lines: 10;
25
27
  }
26
28
 
27
29
  .bs-composer {
@@ -62,12 +64,25 @@
62
64
  .bs-composer__input {
63
65
  flex: 1;
64
66
  min-width: 0;
67
+ box-sizing: border-box;
68
+ /* Browsers apply their own default padding to <textarea> (Chromium: 2px) -- zero it out so the
69
+ auto-grow height math (line-height * number of lines) isn't thrown off by unaccounted-for
70
+ padding. */
71
+ padding: 0;
65
72
  border: none;
66
73
  outline: none;
74
+ resize: none;
67
75
  background: transparent;
68
76
  color: var(--bs-input-text);
69
77
  font-family: inherit;
70
78
  font-size: var(--bs-font-size-md);
79
+ /* Explicit, not the textarea's default line-height -- the auto-grow max-height below is computed
80
+ in terms of this exact value times --bs-composer-input-max-lines, so it has to be pinned down. */
81
+ line-height: calc(var(--bs-line-height-body-md) * 1px);
82
+ /* Grows with content (see bs-composer.tsx's resizeInput) up to this many lines' worth of height,
83
+ then scrolls internally instead of growing the whole composer further. */
84
+ max-height: calc(var(--bs-composer-input-max-lines) * var(--bs-line-height-body-md) * 1px);
85
+ overflow-y: auto;
71
86
  }
72
87
 
73
88
  .bs-composer__input::placeholder {
@@ -37,7 +37,7 @@ const WAVEFORM_BAR_HEIGHTS = [
37
37
  * roughly match `--bs-composer-button-size` to align visually.
38
38
  * @part attachments - The wrapper around the `attachments` slot.
39
39
  * @part attach - The "+" attach button.
40
- * @part input - The native text `<input>`.
40
+ * @part input - The native text `<textarea>`.
41
41
  * @part mic - The secondary icon button (microphone, or the stop-recording square while `state="recording"`).
42
42
  * @part action - The primary circular action button (send, stop, or confirm depending on `state`).
43
43
  * @prop --bs-composer-radius - Corner radius of the container. Aliased to `--bs-border-radius-150`.
@@ -57,9 +57,11 @@ const WAVEFORM_BAR_HEIGHTS = [
57
57
  * @prop --bs-composer-mic-icon-disabled - Aliased to `--bs-icon-disabled`.
58
58
  * @prop --bs-composer-subtle-hover - Background of the attach/mic buttons on hover (subtle-button treatment, same as `bs-button`'s `subtle` variant). Aliased to `--bs-color-neutral-container`.
59
59
  * @prop --bs-composer-subtle-pressed - Background of the attach/mic buttons when pressed. Aliased to `--bs-color-neutral-container-pressed`.
60
+ * @prop --bs-composer-input-max-lines - How many lines the text field grows to before scrolling internally instead of growing further. Aliased to `10`.
60
61
  */
61
62
  export class BsComposer {
62
63
  el;
64
+ inputEl;
63
65
  /**
64
66
  * Which flavor of composer this is: changes the *default* placeholder text (set `placeholder`
65
67
  * directly to override it) and, per the Figma design, renders the container border dashed
@@ -70,7 +72,12 @@ export class BsComposer {
70
72
  /** Overrides the variant's default placeholder. */
71
73
  placeholder;
72
74
  /** Current text value. Native `input` events don't cross the Shadow DOM boundary, so this
73
- * component re-dispatches them as a `bsInput` custom event instead. */
75
+ * component re-dispatches them as a `bsInput` custom event instead.
76
+ *
77
+ * The field is a `<textarea>` (not a single-line `<input>`) that grows with its content, up to
78
+ * `--bs-composer-input-max-lines` (10 by default) -- beyond that it scrolls internally instead
79
+ * of growing further. Setting `value` as a prop (not just typing) also re-triggers the resize,
80
+ * so e.g. programmatically clearing the field after submit correctly shrinks it back down. */
74
81
  value = '';
75
82
  /**
76
83
  * Which of the four mutually-exclusive composer states to render: `idle` (send, enabled),
@@ -107,11 +114,38 @@ export class BsComposer {
107
114
  componentWillLoad() {
108
115
  this.hasAttachments = Array.from(this.el.childNodes).some(node => node.nodeType === Node.ELEMENT_NODE && node.getAttribute('slot') === 'attachments');
109
116
  }
117
+ componentDidLoad() {
118
+ this.resizeInput();
119
+ }
120
+ /** Re-runs the auto-grow calculation after every re-render -- notably including a `value` prop
121
+ * change from the outside (e.g. a consumer clearing the field after submit, or pre-filling it),
122
+ * not just while the user is typing. This has to be `componentDidUpdate`, not a `@Watch('value')`
123
+ * callback: `@Watch` fires as soon as the prop is reassigned, which is BEFORE Stencil's next
124
+ * render actually pushes the new value into the textarea's DOM `.value` -- reading `scrollHeight`
125
+ * at that point still reflects the OLD content, so the resize would silently no-op. */
126
+ componentDidUpdate() {
127
+ this.resizeInput();
128
+ }
129
+ /**
130
+ * Grows the textarea to fit its content, up to `--bs-composer-input-max-lines` worth of height
131
+ * (CSS `max-height` clamps the visual result and `overflow-y: auto` takes over beyond that --
132
+ * see bs-composer.css). Resetting `height` to `auto` first is required before reading
133
+ * `scrollHeight`, otherwise a shrinking edit (e.g. deleting a line) would never shrink the
134
+ * textarea back down -- `scrollHeight` only ever reports the larger of "current height" and
135
+ * "content height" if the height isn't cleared first.
136
+ */
137
+ resizeInput() {
138
+ if (!this.inputEl)
139
+ return;
140
+ this.inputEl.style.height = 'auto';
141
+ this.inputEl.style.height = `${this.inputEl.scrollHeight}px`;
142
+ }
110
143
  onAttachmentsSlotchange = (ev) => {
111
144
  this.hasAttachments = ev.target.assignedNodes().length > 0;
112
145
  };
113
146
  onInput = (ev) => {
114
147
  const value = ev.target.value;
148
+ this.resizeInput();
115
149
  this.bsInput.emit(value);
116
150
  };
117
151
  onAttachClick = () => {
@@ -149,7 +183,7 @@ export class BsComposer {
149
183
  const placeholder = this.placeholder ?? DEFAULT_PLACEHOLDERS[this.variant];
150
184
  const disabled = this.state === 'disabled';
151
185
  const recording = this.state === 'recording';
152
- return (h("div", { key: '5b367f64f2cfe04d7815b52d6abc3baebf46453e', class: `bs-composer bs-composer--${this.state} bs-composer--${this.variant}` }, h("div", { key: 'f1e7dbeb16e8f2cd0b4e2345f6c5fc03bcc5177c', part: "attachments", class: `bs-composer__attachments-row ${this.hasAttachments ? 'bs-composer__attachments-row--visible' : ''}` }, h("slot", { key: '6e59f2f3857c81a132c5873d9a32dbed27eb2c02', name: "attachments", onSlotchange: this.onAttachmentsSlotchange })), h("div", { key: '79a0a03a7f66b654f5ab8379447cf00459c7a6c3', class: "bs-composer__text-row" }, h("input", { key: 'b9560af8433d186fdadd5b05368290d077c5e8ce', part: "input", class: "bs-composer__input", type: "text", value: this.value, placeholder: placeholder, disabled: disabled, "aria-label": this.ariaLabel, onInput: this.onInput })), h("div", { key: '5b9a8edd0412e1a86efd33afae37fb73559a89f6', class: "bs-composer__controls-row" }, h("button", { key: '5c405e009e9f61902ca6623e09efa238e71737a3', type: "button", part: "attach", class: "bs-composer__attach", "aria-label": "Attach", onClick: this.onAttachClick }, h(PlusIcon, { key: '5832b29579d3c8c855237f286366944aeb6553f6' })), recording ? (h("span", { class: "bs-composer__waveform", "aria-hidden": "true" }, WAVEFORM_BAR_HEIGHTS.map(height => (h("span", { class: "bs-composer__waveform-bar", style: { '--bs-composer-bar-height': `${height}px` } }))))) : (h("span", { class: "bs-composer__spacer" })), h("button", { key: 'b4006fe5d452d02d0093d1dba0b65e6f33e5a65b', type: "button", part: "mic", class: `bs-composer__mic ${recording ? 'bs-composer__mic--recording' : ''}`, "aria-label": recording ? 'Stop recording' : 'Start voice input', disabled: disabled, onClick: this.onMicClick }, recording ? h(StopIcon, null) : h(MicIcon, null)), h("button", { key: 'b647f1dd0c40dc795b96da5cad695300b0c9dfd3', type: "button", part: "action", class: `bs-composer__action bs-composer__action--${this.state}`, "aria-label": this.actionLabel(), disabled: disabled, onClick: this.onActionClick }, this.renderActionIcon()), h("slot", { key: '2c78b5641091024925e84ca1a779ac1fc37fc0ae', name: "actions-end" }))));
186
+ return (h("div", { key: '4d6ea6241693e45065388f34f9fe2c141eb6379f', class: `bs-composer bs-composer--${this.state} bs-composer--${this.variant}` }, h("div", { key: '952853cd4a36c5dc6057186825432616c5c99b38', part: "attachments", class: `bs-composer__attachments-row ${this.hasAttachments ? 'bs-composer__attachments-row--visible' : ''}` }, h("slot", { key: '65311f5b1f1b8fd1e6c9f33741a53c94bbe292b0', name: "attachments", onSlotchange: this.onAttachmentsSlotchange })), h("div", { key: '8699568430ff2140b0869a004a253e6c01e1984f', class: "bs-composer__text-row" }, h("textarea", { key: '5505815f7bb6ff19191ffea375fcd7fb856371fd', ref: el => (this.inputEl = el), part: "input", class: "bs-composer__input", rows: 1, value: this.value, placeholder: placeholder, disabled: disabled, "aria-label": this.ariaLabel, onInput: this.onInput })), h("div", { key: 'fd65f7928117afd583e3f1e2372cbb66305a530e', class: "bs-composer__controls-row" }, h("button", { key: '4e691d7ca567a4ece45601f47836d1ac7c5e2a1d', type: "button", part: "attach", class: "bs-composer__attach", "aria-label": "Attach", onClick: this.onAttachClick }, h(PlusIcon, { key: 'e363bbfcd346090dbceafd20d893af0903952223' })), recording ? (h("span", { class: "bs-composer__waveform", "aria-hidden": "true" }, WAVEFORM_BAR_HEIGHTS.map(height => (h("span", { class: "bs-composer__waveform-bar", style: { '--bs-composer-bar-height': `${height}px` } }))))) : (h("span", { class: "bs-composer__spacer" })), h("button", { key: 'e0f113e189ec7ded494c7ef7cf91fe3e13df01bc', type: "button", part: "mic", class: `bs-composer__mic ${recording ? 'bs-composer__mic--recording' : ''}`, "aria-label": recording ? 'Stop recording' : 'Start voice input', disabled: disabled, onClick: this.onMicClick }, recording ? h(StopIcon, null) : h(MicIcon, null)), h("button", { key: '3603219c2c3781a9e2894142313f84dfa52c21ed', type: "button", part: "action", class: `bs-composer__action bs-composer__action--${this.state}`, "aria-label": this.actionLabel(), disabled: disabled, onClick: this.onActionClick }, this.renderActionIcon()), h("slot", { key: '3d143aa3f254310dba537c19a6ac4c40205a405d', name: "actions-end" }))));
153
187
  }
154
188
  static get is() { return "bs-composer"; }
155
189
  static get encapsulation() { return "shadow"; }
@@ -223,7 +257,7 @@ export class BsComposer {
223
257
  "optional": false,
224
258
  "docs": {
225
259
  "tags": [],
226
- "text": "Current text value. Native `input` events don't cross the Shadow DOM boundary, so this\ncomponent re-dispatches them as a `bsInput` custom event instead."
260
+ "text": "Current text value. Native `input` events don't cross the Shadow DOM boundary, so this\ncomponent re-dispatches them as a `bsInput` custom event instead.\n\nThe field is a `<textarea>` (not a single-line `<input>`) that grows with its content, up to\n`--bs-composer-input-max-lines` (10 by default) -- beyond that it scrolls internally instead\nof growing further. Setting `value` as a prop (not just typing) also re-triggers the resize,\nso e.g. programmatically clearing the field after submit correctly shrinks it back down."
227
261
  },
228
262
  "getter": false,
229
263
  "setter": false,
@@ -1,10 +1,56 @@
1
1
  import { render, h, describe, it, expect } from "@stencil/vitest";
2
2
  describe('bs-composer-status-banner', () => {
3
- it('renders the message and a default clock icon', async () => {
3
+ it('renders the message and a default icon', async () => {
4
4
  const { root } = await render(h("bs-composer-status-banner", { message: "Something went wrong" }));
5
5
  expect(root).toHaveTextContent('Something went wrong');
6
6
  expect(root.shadowRoot.querySelector('[part="icon"] svg')).not.toBeNull();
7
7
  });
8
+ describe('accessibility', () => {
9
+ it('sets role="alert" for type="error" (the default)', async () => {
10
+ const { root } = await render(h("bs-composer-status-banner", null));
11
+ expect(root.shadowRoot.querySelector('.bs-composer-status-banner')).toEqualAttribute('role', 'alert');
12
+ });
13
+ it('sets role="alert" for type="warning"', async () => {
14
+ const { root } = await render(h("bs-composer-status-banner", { type: "warning" }));
15
+ expect(root.shadowRoot.querySelector('.bs-composer-status-banner')).toEqualAttribute('role', 'alert');
16
+ });
17
+ it('sets role="status" for type="info"', async () => {
18
+ const { root } = await render(h("bs-composer-status-banner", { type: "info" }));
19
+ expect(root.shadowRoot.querySelector('.bs-composer-status-banner')).toEqualAttribute('role', 'status');
20
+ });
21
+ it('sets role="status" for type="neutral"', async () => {
22
+ const { root } = await render(h("bs-composer-status-banner", { type: "neutral" }));
23
+ expect(root.shadowRoot.querySelector('.bs-composer-status-banner')).toEqualAttribute('role', 'status');
24
+ });
25
+ });
26
+ describe('default icon per type', () => {
27
+ it('shows the warning-triangle icon for type="error"', async () => {
28
+ const { root } = await render(h("bs-composer-status-banner", { type: "error" }));
29
+ const svg = root.shadowRoot.querySelector('[part="icon"] svg');
30
+ expect(svg.querySelector('circle[r="0.75"]')).not.toBeNull();
31
+ });
32
+ it('shows the warning-triangle icon for type="warning"', async () => {
33
+ const { root } = await render(h("bs-composer-status-banner", { type: "warning" }));
34
+ const svg = root.shadowRoot.querySelector('[part="icon"] svg');
35
+ expect(svg.querySelector('circle[r="0.75"]')).not.toBeNull();
36
+ });
37
+ it('shows the clock icon for type="info"', async () => {
38
+ const { root } = await render(h("bs-composer-status-banner", { type: "info" }));
39
+ const svg = root.shadowRoot.querySelector('[part="icon"] svg');
40
+ expect(svg.querySelector('circle[r="7.25"]')).not.toBeNull();
41
+ });
42
+ it('shows the clock icon for type="neutral"', async () => {
43
+ const { root } = await render(h("bs-composer-status-banner", { type: "neutral" }));
44
+ const svg = root.shadowRoot.querySelector('[part="icon"] svg');
45
+ expect(svg.querySelector('circle[r="7.25"]')).not.toBeNull();
46
+ });
47
+ it('a slotted icon still overrides the type-based default', async () => {
48
+ const { root } = await render(h("bs-composer-status-banner", { type: "error" }, h("svg", { slot: "icon", class: "custom-icon" })));
49
+ const slot = root.shadowRoot.querySelector('slot[name="icon"]');
50
+ expect(slot.assignedElements()).toHaveLength(1);
51
+ expect(slot.assignedElements()[0]).toHaveClass('custom-icon');
52
+ });
53
+ });
8
54
  it('does not render the icon when showIcon is false', async () => {
9
55
  const { root } = await render(h("bs-composer-status-banner", { showIcon: false }));
10
56
  expect(root.shadowRoot.querySelector('[part="icon"]')).toBeNull();