@brandsync/wc 0.0.8 → 0.0.10

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 (200) hide show
  1. package/custom-elements.json +1821 -342
  2. package/dist/brandsync-wc/brandsync-wc.esm.js +1 -1
  3. package/dist/brandsync-wc/p-0d64ea40.entry.js +1 -0
  4. package/dist/brandsync-wc/{p-c63d16e1.entry.js → p-1515498e.entry.js} +1 -1
  5. package/dist/brandsync-wc/p-16a54578.entry.js +1 -0
  6. package/dist/brandsync-wc/p-18af02df.entry.js +1 -0
  7. package/dist/brandsync-wc/p-30a0e168.entry.js +1 -0
  8. package/dist/brandsync-wc/p-3dacae70.entry.js +1 -0
  9. package/dist/brandsync-wc/p-575ce905.entry.js +1 -0
  10. package/dist/brandsync-wc/{p-dd0fea0e.entry.js → p-7776b57b.entry.js} +1 -1
  11. package/dist/brandsync-wc/{p-260bd201.entry.js → p-805644e4.entry.js} +1 -1
  12. package/dist/brandsync-wc/{p-f88d9a6e.entry.js → p-8a78d6ea.entry.js} +1 -1
  13. package/dist/brandsync-wc/p-8d12ed96.entry.js +1 -0
  14. package/dist/brandsync-wc/p-94ed898a.entry.js +1 -0
  15. package/dist/brandsync-wc/{p-9e5d2211.entry.js → p-96f374be.entry.js} +1 -1
  16. package/dist/brandsync-wc/{p-ab5cc7af.entry.js → p-a34f460d.entry.js} +1 -1
  17. package/dist/brandsync-wc/p-b1e1b2d6.entry.js +1 -0
  18. package/dist/brandsync-wc/p-bc72439a.entry.js +1 -0
  19. package/dist/brandsync-wc/{p-76eca100.entry.js → p-ce0914a7.entry.js} +1 -1
  20. package/dist/brandsync-wc/{p-5a0fe72e.entry.js → p-d682675e.entry.js} +1 -1
  21. package/dist/brandsync-wc/p-dad4a92c.entry.js +1 -0
  22. package/dist/brandsync-wc/{p-cfc3421b.entry.js → p-dd747a12.entry.js} +1 -1
  23. package/dist/brandsync-wc/{p-2742ecef.entry.js → p-eb4d87f0.entry.js} +1 -1
  24. package/dist/cjs/brandsync-wc.cjs.js +1 -1
  25. package/dist/cjs/bs-ai-disclaimer.cjs.entry.js +17 -0
  26. package/dist/cjs/bs-ai-greeting.cjs.entry.js +24 -0
  27. package/dist/cjs/bs-ai-thinking.cjs.entry.js +1 -1
  28. package/dist/cjs/bs-attachment-list.cjs.entry.js +47 -0
  29. package/dist/cjs/bs-attachment.cjs.entry.js +46 -0
  30. package/dist/cjs/bs-badge.cjs.entry.js +1 -1
  31. package/dist/cjs/bs-button-skeleton.cjs.entry.js +1 -1
  32. package/dist/cjs/bs-button.cjs.entry.js +1 -1
  33. package/dist/cjs/bs-card.cjs.entry.js +1 -1
  34. package/dist/cjs/bs-chatbot-feedback.cjs.entry.js +94 -0
  35. package/dist/cjs/bs-chatbot-header.cjs.entry.js +1 -1
  36. package/dist/cjs/bs-chatbot-response-action.cjs.entry.js +1 -1
  37. package/dist/cjs/bs-chatbot-sources-drawer.cjs.entry.js +38 -0
  38. package/dist/cjs/bs-chatbot-suggestion-button.cjs.entry.js +1 -1
  39. package/dist/cjs/bs-composer-status-banner.cjs.entry.js +43 -0
  40. package/dist/cjs/bs-composer.cjs.entry.js +16 -2
  41. package/dist/cjs/bs-data-table.cjs.entry.js +2 -2
  42. package/dist/cjs/bs-input.cjs.entry.js +270 -4
  43. package/dist/cjs/bs-menu_2.cjs.entry.js +47 -0
  44. package/dist/cjs/bs-source-link.cjs.entry.js +39 -0
  45. package/dist/cjs/bs-tooltip.cjs.entry.js +1 -1
  46. package/dist/cjs/loader.cjs.js +1 -1
  47. package/dist/collection/collection-manifest.json +8 -0
  48. package/dist/collection/components/bs-ai-chatbot/bs-ai-chatbot.stories.js +180 -0
  49. package/dist/collection/components/bs-ai-disclaimer/bs-ai-disclaimer.cmp.test.js +14 -0
  50. package/dist/collection/components/bs-ai-disclaimer/bs-ai-disclaimer.css +27 -0
  51. package/dist/collection/components/bs-ai-disclaimer/bs-ai-disclaimer.js +41 -0
  52. package/dist/collection/components/bs-ai-disclaimer/bs-ai-disclaimer.stories.js +15 -0
  53. package/dist/collection/components/bs-ai-greeting/bs-ai-greeting.cmp.test.js +22 -0
  54. package/dist/collection/components/bs-ai-greeting/bs-ai-greeting.css +53 -0
  55. package/dist/collection/components/bs-ai-greeting/bs-ai-greeting.js +103 -0
  56. package/dist/collection/components/bs-ai-greeting/bs-ai-greeting.stories.js +23 -0
  57. package/dist/collection/components/bs-ai-thinking/bs-ai-thinking.js +1 -1
  58. package/dist/collection/components/bs-attachment/bs-attachment.cmp.test.js +41 -0
  59. package/dist/collection/components/bs-attachment/bs-attachment.css +184 -0
  60. package/dist/collection/components/bs-attachment/bs-attachment.js +230 -0
  61. package/dist/collection/components/bs-attachment/bs-attachment.stories.js +58 -0
  62. package/dist/collection/components/bs-attachment-list/bs-attachment-list.cmp.test.js +28 -0
  63. package/dist/collection/components/bs-attachment-list/bs-attachment-list.css +56 -0
  64. package/dist/collection/components/bs-attachment-list/bs-attachment-list.js +105 -0
  65. package/dist/collection/components/bs-attachment-list/bs-attachment-list.stories.js +47 -0
  66. package/dist/collection/components/bs-badge/bs-badge.js +1 -1
  67. package/dist/collection/components/bs-button/bs-button.js +1 -1
  68. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.js +1 -1
  69. package/dist/collection/components/bs-card/bs-card.js +1 -1
  70. package/dist/collection/components/bs-chatbot-feedback/bs-chatbot-feedback.cmp.test.js +73 -0
  71. package/dist/collection/components/bs-chatbot-feedback/bs-chatbot-feedback.css +253 -0
  72. package/dist/collection/components/bs-chatbot-feedback/bs-chatbot-feedback.js +324 -0
  73. package/dist/collection/components/bs-chatbot-feedback/bs-chatbot-feedback.stories.js +54 -0
  74. package/dist/collection/components/bs-chatbot-header/bs-chatbot-header.js +1 -1
  75. package/dist/collection/components/bs-chatbot-response-action/bs-chatbot-response-action.js +1 -1
  76. package/dist/collection/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.cmp.test.js +34 -0
  77. package/dist/collection/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.css +106 -0
  78. package/dist/collection/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.js +142 -0
  79. package/dist/collection/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.stories.js +44 -0
  80. package/dist/collection/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.js +1 -1
  81. package/dist/collection/components/bs-composer/bs-composer.cmp.test.js +12 -0
  82. package/dist/collection/components/bs-composer/bs-composer.css +10 -0
  83. package/dist/collection/components/bs-composer/bs-composer.js +25 -1
  84. package/dist/collection/components/bs-composer/bs-composer.stories.js +13 -0
  85. package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.cmp.test.js +42 -0
  86. package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.css +173 -0
  87. package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.js +270 -0
  88. package/dist/collection/components/bs-composer-status-banner/bs-composer-status-banner.stories.js +75 -0
  89. package/dist/collection/components/bs-data-table/bs-data-table.js +2 -2
  90. package/dist/collection/components/bs-input/bs-input.cmp.test.js +296 -0
  91. package/dist/collection/components/bs-input/bs-input.css +333 -23
  92. package/dist/collection/components/bs-input/bs-input.js +647 -11
  93. package/dist/collection/components/bs-input/bs-input.stories.js +128 -1
  94. package/dist/collection/components/bs-menu/bs-menu.js +1 -1
  95. package/dist/collection/components/bs-menu-item/bs-menu-item.cmp.test.js +18 -0
  96. package/dist/collection/components/bs-menu-item/bs-menu-item.css +19 -1
  97. package/dist/collection/components/bs-menu-item/bs-menu-item.js +34 -2
  98. package/dist/collection/components/bs-menu-item/bs-menu-item.stories.js +3 -0
  99. package/dist/collection/components/bs-source-link/bs-source-link.cmp.test.js +42 -0
  100. package/dist/collection/components/bs-source-link/bs-source-link.css +114 -0
  101. package/dist/collection/components/bs-source-link/bs-source-link.js +192 -0
  102. package/dist/collection/components/bs-source-link/bs-source-link.stories.js +33 -0
  103. package/dist/collection/components/bs-tooltip/bs-tooltip.js +1 -1
  104. package/dist/components/bs-ai-disclaimer.d.ts +11 -0
  105. package/dist/components/bs-ai-disclaimer.js +1 -0
  106. package/dist/components/bs-ai-greeting.d.ts +11 -0
  107. package/dist/components/bs-ai-greeting.js +1 -0
  108. package/dist/components/bs-ai-thinking.js +1 -1
  109. package/dist/components/bs-attachment-list.d.ts +11 -0
  110. package/dist/components/bs-attachment-list.js +1 -0
  111. package/dist/components/bs-attachment.d.ts +11 -0
  112. package/dist/components/bs-attachment.js +1 -0
  113. package/dist/components/bs-badge.js +1 -1
  114. package/dist/components/bs-button-skeleton.js +1 -1
  115. package/dist/components/bs-button.js +1 -1
  116. package/dist/components/bs-card.js +1 -1
  117. package/dist/components/bs-chatbot-feedback.d.ts +11 -0
  118. package/dist/components/bs-chatbot-feedback.js +1 -0
  119. package/dist/components/bs-chatbot-header.js +1 -1
  120. package/dist/components/bs-chatbot-response-action.js +1 -1
  121. package/dist/components/bs-chatbot-sources-drawer.d.ts +11 -0
  122. package/dist/components/bs-chatbot-sources-drawer.js +1 -0
  123. package/dist/components/bs-chatbot-suggestion-button.js +1 -1
  124. package/dist/components/bs-composer-status-banner.d.ts +11 -0
  125. package/dist/components/bs-composer-status-banner.js +1 -0
  126. package/dist/components/bs-composer.js +1 -1
  127. package/dist/components/bs-data-table.js +1 -1
  128. package/dist/components/bs-input.js +1 -1
  129. package/dist/components/bs-menu-item.js +1 -1
  130. package/dist/components/bs-menu.js +1 -1
  131. package/dist/components/bs-source-link.d.ts +11 -0
  132. package/dist/components/bs-source-link.js +1 -0
  133. package/dist/components/bs-tooltip.js +1 -1
  134. package/dist/components/{p-CoC4LQCI.js → p-Cz2nfz2j.js} +1 -1
  135. package/dist/components/p-DHbUF0g6.js +1 -0
  136. package/dist/components/p-DndQiCMP.js +1 -0
  137. package/dist/esm/brandsync-wc.js +1 -1
  138. package/dist/esm/bs-ai-disclaimer.entry.js +15 -0
  139. package/dist/esm/bs-ai-greeting.entry.js +22 -0
  140. package/dist/esm/bs-ai-thinking.entry.js +1 -1
  141. package/dist/esm/bs-attachment-list.entry.js +45 -0
  142. package/dist/esm/bs-attachment.entry.js +44 -0
  143. package/dist/esm/bs-badge.entry.js +1 -1
  144. package/dist/esm/bs-button-skeleton.entry.js +1 -1
  145. package/dist/esm/bs-button.entry.js +1 -1
  146. package/dist/esm/bs-card.entry.js +1 -1
  147. package/dist/esm/bs-chatbot-feedback.entry.js +92 -0
  148. package/dist/esm/bs-chatbot-header.entry.js +1 -1
  149. package/dist/esm/bs-chatbot-response-action.entry.js +1 -1
  150. package/dist/esm/bs-chatbot-sources-drawer.entry.js +36 -0
  151. package/dist/esm/bs-chatbot-suggestion-button.entry.js +1 -1
  152. package/dist/esm/bs-composer-status-banner.entry.js +41 -0
  153. package/dist/esm/bs-composer.entry.js +17 -3
  154. package/dist/esm/bs-data-table.entry.js +2 -2
  155. package/dist/esm/bs-input.entry.js +271 -5
  156. package/dist/esm/bs-menu_2.entry.js +44 -0
  157. package/dist/esm/bs-source-link.entry.js +37 -0
  158. package/dist/esm/bs-tooltip.entry.js +1 -1
  159. package/dist/esm/loader.js +1 -1
  160. package/dist/types/components/bs-ai-chatbot/bs-ai-chatbot.stories.d.ts +18 -0
  161. package/dist/types/components/bs-ai-disclaimer/bs-ai-disclaimer.cmp.test.d.ts +1 -0
  162. package/dist/types/components/bs-ai-disclaimer/bs-ai-disclaimer.d.ts +26 -0
  163. package/dist/types/components/bs-ai-disclaimer/bs-ai-disclaimer.stories.d.ts +8 -0
  164. package/dist/types/components/bs-ai-greeting/bs-ai-greeting.cmp.test.d.ts +1 -0
  165. package/dist/types/components/bs-ai-greeting/bs-ai-greeting.d.ts +42 -0
  166. package/dist/types/components/bs-ai-greeting/bs-ai-greeting.stories.d.ts +10 -0
  167. package/dist/types/components/bs-attachment/bs-attachment.cmp.test.d.ts +1 -0
  168. package/dist/types/components/bs-attachment/bs-attachment.d.ts +59 -0
  169. package/dist/types/components/bs-attachment/bs-attachment.stories.d.ts +17 -0
  170. package/dist/types/components/bs-attachment-list/bs-attachment-list.cmp.test.d.ts +1 -0
  171. package/dist/types/components/bs-attachment-list/bs-attachment-list.d.ts +42 -0
  172. package/dist/types/components/bs-attachment-list/bs-attachment-list.stories.d.ts +10 -0
  173. package/dist/types/components/bs-chatbot-feedback/bs-chatbot-feedback.cmp.test.d.ts +1 -0
  174. package/dist/types/components/bs-chatbot-feedback/bs-chatbot-feedback.d.ts +90 -0
  175. package/dist/types/components/bs-chatbot-feedback/bs-chatbot-feedback.stories.d.ts +16 -0
  176. package/dist/types/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.cmp.test.d.ts +1 -0
  177. package/dist/types/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.d.ts +54 -0
  178. package/dist/types/components/bs-chatbot-sources-drawer/bs-chatbot-sources-drawer.stories.d.ts +10 -0
  179. package/dist/types/components/bs-composer/bs-composer.d.ts +14 -0
  180. package/dist/types/components/bs-composer/bs-composer.stories.d.ts +1 -0
  181. package/dist/types/components/bs-composer-status-banner/bs-composer-status-banner.cmp.test.d.ts +1 -0
  182. package/dist/types/components/bs-composer-status-banner/bs-composer-status-banner.d.ts +88 -0
  183. package/dist/types/components/bs-composer-status-banner/bs-composer-status-banner.stories.d.ts +20 -0
  184. package/dist/types/components/bs-input/bs-input.d.ts +139 -6
  185. package/dist/types/components/bs-input/bs-input.stories.d.ts +19 -0
  186. package/dist/types/components/bs-menu-item/bs-menu-item.d.ts +7 -1
  187. package/dist/types/components/bs-menu-item/bs-menu-item.stories.d.ts +1 -0
  188. package/dist/types/components/bs-source-link/bs-source-link.cmp.test.d.ts +1 -0
  189. package/dist/types/components/bs-source-link/bs-source-link.d.ts +51 -0
  190. package/dist/types/components/bs-source-link/bs-source-link.stories.d.ts +13 -0
  191. package/dist/types/components.d.ts +1776 -24
  192. package/package.json +1 -1
  193. package/dist/brandsync-wc/p-6abdfaf0.entry.js +0 -1
  194. package/dist/brandsync-wc/p-6c1fa4da.entry.js +0 -1
  195. package/dist/brandsync-wc/p-a12d0a60.entry.js +0 -1
  196. package/dist/brandsync-wc/p-f5f443e2.entry.js +0 -1
  197. package/dist/cjs/bs-menu-item.cjs.entry.js +0 -29
  198. package/dist/cjs/bs-menu.cjs.entry.js +0 -17
  199. package/dist/esm/bs-menu-item.entry.js +0 -27
  200. package/dist/esm/bs-menu.entry.js +0 -15
@@ -0,0 +1,142 @@
1
+ import { h } from "@stencil/core";
2
+ /**
3
+ * The "Sources" panel shown alongside a Genie AI chat response -- a header with a title, a count
4
+ * badge, and a collapse chevron, above a stack of `bs-source-link` citation rows.
5
+ *
6
+ * ## When to use
7
+ * - Displaying the documents/sources a Genie response cited, typically opened from a "view
8
+ * sources" action on a `bs-chatbot-response-action` bar.
9
+ *
10
+ * ## When not to use
11
+ * - A generic list container -- this component's header (title + count + collapse) is
12
+ * purpose-built for the sources use case.
13
+ *
14
+ * @slot - One or more `bs-source-link` rows.
15
+ * @slot collapse-icon - Overrides the default collapse chevron icon.
16
+ * @part heading - The "Sources" title text.
17
+ * @part count - The count badge next to the title.
18
+ * @part collapse - The collapse chevron button.
19
+ * @part list - The scrollable container of slotted `bs-source-link` rows.
20
+ * @prop --bs-chatbot-sources-drawer-bg - Background of the whole panel. Aliased to `--bs-surface-raised`.
21
+ * @prop --bs-chatbot-sources-drawer-header-shadow - Drop shadow under the header, separating it
22
+ * from the scrolled list. Aliased to `--bs-shadow-xs`.
23
+ * @prop --bs-chatbot-sources-drawer-header-padding-x - Aliased to `--bs-spacing-200`.
24
+ * @prop --bs-chatbot-sources-drawer-header-padding-top - Aliased to `--bs-spacing-150`.
25
+ * @prop --bs-chatbot-sources-drawer-header-padding-bottom - Aliased to `--bs-spacing-100`.
26
+ * @prop --bs-chatbot-sources-drawer-heading-color - Aliased to `--bs-text-default`.
27
+ * @prop --bs-chatbot-sources-drawer-count-bg - Count badge background. Aliased to
28
+ * `--bs-badge-bg-neutral-container`.
29
+ * @prop --bs-chatbot-sources-drawer-count-color - Count badge text color. Aliased to
30
+ * `--bs-badge-text-neutral`.
31
+ * @prop --bs-chatbot-sources-drawer-collapse-hover - Collapse button background on hover. Aliased
32
+ * to `--bs-surface-hover`.
33
+ * @prop --bs-chatbot-sources-drawer-section-gap - Gap between the header and the list. Aliased to
34
+ * `--bs-spacing-200`.
35
+ * @prop --bs-chatbot-sources-drawer-list-padding - Horizontal/bottom padding of the list. Aliased
36
+ * to `--bs-spacing-200`.
37
+ * @prop --bs-chatbot-sources-drawer-list-gap - Gap between rows. Aliased to `--bs-spacing-50`.
38
+ */
39
+ export class BsChatbotSourcesDrawer {
40
+ el;
41
+ /** The panel title. */
42
+ heading = 'Sources';
43
+ /**
44
+ * Overrides the auto-detected count badge. By default the badge reflects the number of slotted
45
+ * `bs-source-link` children, so most consumers don't need to set this.
46
+ */
47
+ count;
48
+ /** Fires when the collapse chevron is clicked. The consuming app owns actually hiding the panel. */
49
+ bsCollapse;
50
+ slottedCount = 0;
51
+ onSlotchange = (event) => {
52
+ const slot = event.target;
53
+ this.slottedCount = slot.assignedElements().filter(el => el.tagName.toLowerCase() === 'bs-source-link').length;
54
+ };
55
+ onCollapseClick = () => {
56
+ this.bsCollapse.emit();
57
+ };
58
+ render() {
59
+ const displayCount = this.count ?? this.slottedCount;
60
+ return (h("div", { key: '54cb56455b630d5ed30dd2a925728f2803143b17', class: "bs-chatbot-sources-drawer", role: "region", "aria-label": this.heading }, h("div", { key: 'd24eabd0ac2c36ec4033a9b5c361aa32225fa78a', class: "bs-chatbot-sources-drawer__header" }, h("div", { key: '0bec3fb848552496e1884b4731c5e1964570c70d', class: "bs-chatbot-sources-drawer__title-group" }, h("h2", { key: '955389bd4f3ba1950c9af404e5880a6837298384', part: "heading", class: "bs-chatbot-sources-drawer__heading" }, this.heading), displayCount > 0 && (h("span", { key: '40d83288bbd257504ef814247c7bd4664df9e169', part: "count", class: "bs-chatbot-sources-drawer__count" }, displayCount))), h("button", { key: '56a15c64faea80790387d4918843c806b684268b', type: "button", part: "collapse", class: "bs-chatbot-sources-drawer__collapse", "aria-label": "Collapse sources", onClick: this.onCollapseClick }, h("slot", { key: 'c321f53482f0265357a6a29fc40e0ff3766f0b74', name: "collapse-icon" }, h(CaretRightIcon, { key: 'c3d4c17bebd2611b27c3e7f87d359e4b46c41d4f' })))), h("div", { key: 'd6c4b8e3660f765112f0c33dd72021af118332d9', part: "list", class: "bs-chatbot-sources-drawer__list" }, h("slot", { key: '19759a01d921ed2517cbca2b01ea53741a207b8b', onSlotchange: this.onSlotchange }))));
61
+ }
62
+ static get is() { return "bs-chatbot-sources-drawer"; }
63
+ static get encapsulation() { return "shadow"; }
64
+ static get originalStyleUrls() {
65
+ return {
66
+ "$": ["bs-chatbot-sources-drawer.css"]
67
+ };
68
+ }
69
+ static get styleUrls() {
70
+ return {
71
+ "$": ["bs-chatbot-sources-drawer.css"]
72
+ };
73
+ }
74
+ static get properties() {
75
+ return {
76
+ "heading": {
77
+ "type": "string",
78
+ "mutable": false,
79
+ "complexType": {
80
+ "original": "string",
81
+ "resolved": "string",
82
+ "references": {}
83
+ },
84
+ "required": false,
85
+ "optional": false,
86
+ "docs": {
87
+ "tags": [],
88
+ "text": "The panel title."
89
+ },
90
+ "getter": false,
91
+ "setter": false,
92
+ "reflect": false,
93
+ "attribute": "heading",
94
+ "defaultValue": "'Sources'"
95
+ },
96
+ "count": {
97
+ "type": "number",
98
+ "mutable": false,
99
+ "complexType": {
100
+ "original": "number",
101
+ "resolved": "number",
102
+ "references": {}
103
+ },
104
+ "required": false,
105
+ "optional": true,
106
+ "docs": {
107
+ "tags": [],
108
+ "text": "Overrides the auto-detected count badge. By default the badge reflects the number of slotted\n`bs-source-link` children, so most consumers don't need to set this."
109
+ },
110
+ "getter": false,
111
+ "setter": false,
112
+ "reflect": false,
113
+ "attribute": "count"
114
+ }
115
+ };
116
+ }
117
+ static get states() {
118
+ return {
119
+ "slottedCount": {}
120
+ };
121
+ }
122
+ static get events() {
123
+ return [{
124
+ "method": "bsCollapse",
125
+ "name": "bsCollapse",
126
+ "bubbles": true,
127
+ "cancelable": true,
128
+ "composed": true,
129
+ "docs": {
130
+ "tags": [],
131
+ "text": "Fires when the collapse chevron is clicked. The consuming app owns actually hiding the panel."
132
+ },
133
+ "complexType": {
134
+ "original": "void",
135
+ "resolved": "void",
136
+ "references": {}
137
+ }
138
+ }];
139
+ }
140
+ static get elementRef() { return "el"; }
141
+ }
142
+ const CaretRightIcon = () => (h("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M7.5 4.375L13.125 10L7.5 15.625", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" })));
@@ -0,0 +1,44 @@
1
+ import { html } from "lit";
2
+ import { componentDescription, propDescription } from "../../stories-utils";
3
+ const SAMPLE_SOURCES = html `
4
+ <bs-source-link file-name="Employee Handbook 2026" source-name="HoltePortalen" version="v3.2"></bs-source-link>
5
+ <bs-source-link file-name="Payroll Processing Guide" source-name="WorkdayHQ" version="v2.4"></bs-source-link>
6
+ <bs-source-link file-name="Benefits & Leave Policy" source-name="PeopleOps Wiki" version="v1.8"></bs-source-link>
7
+ `;
8
+ const meta = {
9
+ title: 'Genie AI Components/bs-chatbot-sources-drawer',
10
+ parameters: { docs: { description: { component: componentDescription('bs-chatbot-sources-drawer') } } },
11
+ render: args => html `
12
+ <div style="max-width: 380px; height: 400px; border: 1px solid var(--bs-border-default); border-radius: var(--bs-border-radius-150); overflow: hidden;">
13
+ <bs-chatbot-sources-drawer heading=${args.heading}>${SAMPLE_SOURCES}</bs-chatbot-sources-drawer>
14
+ </div>
15
+ `,
16
+ argTypes: {
17
+ heading: { control: 'text', description: propDescription('bs-chatbot-sources-drawer', 'heading') },
18
+ },
19
+ args: {
20
+ heading: 'Sources',
21
+ },
22
+ };
23
+ export default meta;
24
+ export const Default = {};
25
+ export const Empty = {
26
+ render: args => html `
27
+ <div style="max-width: 380px; height: 200px; border: 1px solid var(--bs-border-default); border-radius: var(--bs-border-radius-150); overflow: hidden;">
28
+ <bs-chatbot-sources-drawer heading=${args.heading}></bs-chatbot-sources-drawer>
29
+ </div>
30
+ `,
31
+ };
32
+ export const ManySources = {
33
+ name: 'Many sources (scrollable)',
34
+ render: args => html `
35
+ <div style="max-width: 380px; height: 300px; border: 1px solid var(--bs-border-default); border-radius: var(--bs-border-radius-150); overflow: hidden;">
36
+ <bs-chatbot-sources-drawer heading=${args.heading}>
37
+ ${SAMPLE_SOURCES}
38
+ <bs-source-link file-name="Onboarding Checklist" source-name="HoltePortalen" version="v1.0"></bs-source-link>
39
+ <bs-source-link file-name="IT Security Policy" source-name="WorkdayHQ" version="v4.1"></bs-source-link>
40
+ <bs-source-link file-name="Remote Work Guidelines" source-name="PeopleOps Wiki" version="v2.0"></bs-source-link>
41
+ </bs-chatbot-sources-drawer>
42
+ </div>
43
+ `,
44
+ };
@@ -45,7 +45,7 @@ export class BsChatbotSuggestionButton {
45
45
  this.bsSelect.emit();
46
46
  };
47
47
  render() {
48
- return (h("button", { key: 'fc87dab75d560ce5f6612c2bf61875d574eddd1f', type: "button", part: "button", class: "bs-chatbot-suggestion-button", disabled: this.disabled, onClick: this.onClick }, h("slot", { key: '27ae5b010dcac9ebbb3924c72299cbb5a067ce6b' })));
48
+ return (h("button", { key: '2a5213dc81a29dd68f99717b93e6f5396db5c5da', type: "button", part: "button", class: "bs-chatbot-suggestion-button", disabled: this.disabled, onClick: this.onClick }, h("slot", { key: '28b5ac8ddcdab80fb377a897dc1af62257473385' })));
49
49
  }
50
50
  static get is() { return "bs-chatbot-suggestion-button"; }
51
51
  static get encapsulation() { return "shadow"; }
@@ -44,6 +44,18 @@ describe('bs-composer', () => {
44
44
  const actionIndex = children.findIndex(el => el.getAttribute('part') === 'action');
45
45
  expect(slotIndex).toBeGreaterThan(actionIndex);
46
46
  });
47
+ it('does not show the attachments row when nothing is slotted into it', async () => {
48
+ const { root } = await render(h("bs-composer", null));
49
+ const row = root.shadowRoot.querySelector('[part="attachments"]');
50
+ expect(row.className).not.toContain('bs-composer__attachments-row--visible');
51
+ });
52
+ it('shows the attachments row and renders slotted content when something is assigned to it', async () => {
53
+ const { root } = await render(h("bs-composer", null, h("div", { slot: "attachments" }, "attachments here")));
54
+ const row = root.shadowRoot.querySelector('[part="attachments"]');
55
+ expect(row.className).toContain('bs-composer__attachments-row--visible');
56
+ const slot = root.shadowRoot.querySelector('slot[name="attachments"]');
57
+ expect(slot.assignedElements()).toHaveLength(1);
58
+ });
47
59
  it('emits bsInput with the current value as the user types', async () => {
48
60
  const { root, spyOnEvent } = await render(h("bs-composer", null));
49
61
  const spy = spyOnEvent('bsInput');
@@ -42,6 +42,16 @@
42
42
  border-color: var(--bs-composer-border-focus);
43
43
  }
44
44
 
45
+ .bs-composer__attachments-row {
46
+ display: none;
47
+ }
48
+
49
+ /* No padding of its own -- slotted content (e.g. bs-attachment-list) already supplies its own
50
+ * inset, matching how the `actions-end` slot also imposes no spacing on what's slotted into it. */
51
+ .bs-composer__attachments-row--visible {
52
+ display: block;
53
+ }
54
+
45
55
  .bs-composer__text-row {
46
56
  display: flex;
47
57
  align-items: center;
@@ -28,10 +28,14 @@ const WAVEFORM_BAR_HEIGHTS = [
28
28
  * useful for e.g. focusing the composer after a parent view mounts, without reaching into its
29
29
  * shadow root.
30
30
  *
31
+ * @slot attachments - A `bs-attachment-list` (or other content) rendered inside the composer's own
32
+ * bordered container, above the text field -- only takes up space/padding when it has assigned
33
+ * content, so leaving it empty renders identically to not having the slot at all.
31
34
  * @slot actions-end - Extra consumer-supplied controls appended after the primary action button
32
35
  * in the controls row (e.g. a product-specific "Tools" button). Slotted content is placed
33
36
  * inline in the same flex row as attach/mic/action, so a slotted element should size itself to
34
37
  * roughly match `--bs-composer-button-size` to align visually.
38
+ * @part attachments - The wrapper around the `attachments` slot.
35
39
  * @part attach - The "+" attach button.
36
40
  * @part input - The native text `<input>`.
37
41
  * @part mic - The secondary icon button (microphone, or the stop-recording square while `state="recording"`).
@@ -55,6 +59,7 @@ const WAVEFORM_BAR_HEIGHTS = [
55
59
  * @prop --bs-composer-subtle-pressed - Background of the attach/mic buttons when pressed. Aliased to `--bs-color-neutral-container-pressed`.
56
60
  */
57
61
  export class BsComposer {
62
+ el;
58
63
  /**
59
64
  * Which flavor of composer this is: changes the *default* placeholder text (set `placeholder`
60
65
  * directly to override it) and, per the Figma design, renders the container border dashed
@@ -79,6 +84,10 @@ export class BsComposer {
79
84
  * accessible name -- set it in every real usage.
80
85
  */
81
86
  ariaLabel = null;
87
+ /** Tracks whether the `attachments` slot has assigned content, so the row above the text field
88
+ * (padding, border) only takes up space when a consumer has actually put something there --
89
+ * same reasoning/pattern as `hasIcon`/`hasLabel` in `bs-attachment`. */
90
+ hasAttachments = false;
82
91
  /** Fires on every keystroke in the text field, with the current value. */
83
92
  bsInput;
84
93
  /** Fires when the primary action button is clicked while `state="idle"`. */
@@ -92,6 +101,15 @@ export class BsComposer {
92
101
  /** Fires when the mic/stop-recording button is clicked. The consumer decides what that means
93
102
  * (e.g. start recording when idle/generating, or stop recording when `state="recording"`). */
94
103
  bsMicToggle;
104
+ /** Computes the initial `hasAttachments` state directly from the host's light DOM children,
105
+ * before first render -- same reasoning as `bs-attachment`'s `componentWillLoad`: `slotchange`
106
+ * alone never fires for a slot that starts out empty and stays that way. */
107
+ componentWillLoad() {
108
+ this.hasAttachments = Array.from(this.el.childNodes).some(node => node.nodeType === Node.ELEMENT_NODE && node.getAttribute('slot') === 'attachments');
109
+ }
110
+ onAttachmentsSlotchange = (ev) => {
111
+ this.hasAttachments = ev.target.assignedNodes().length > 0;
112
+ };
95
113
  onInput = (ev) => {
96
114
  const value = ev.target.value;
97
115
  this.bsInput.emit(value);
@@ -131,7 +149,7 @@ export class BsComposer {
131
149
  const placeholder = this.placeholder ?? DEFAULT_PLACEHOLDERS[this.variant];
132
150
  const disabled = this.state === 'disabled';
133
151
  const recording = this.state === 'recording';
134
- return (h("div", { key: '04c250520759948faa89bd625646a62c79cc6cee', class: `bs-composer bs-composer--${this.state} bs-composer--${this.variant}` }, h("div", { key: '8d5d99b90141d3dbeff1b31851cbbb5eaae3d920', class: "bs-composer__text-row" }, h("input", { key: '4eb1ef1b51a41de86da466c8a2c9ea93a7746b43', 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: '8a733762c56ae3f4de7f2af1d89fb05d521b1d17', class: "bs-composer__controls-row" }, h("button", { key: 'b4cd13546ec447f2650a02f43dc2fc0b6d65c8ef', type: "button", part: "attach", class: "bs-composer__attach", "aria-label": "Attach", onClick: this.onAttachClick }, h(PlusIcon, { key: 'af8da06a2550d5c37d3737b145ad70c006e1ce66' })), 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: '18b81bf7dd6057c3954566cd12994bb8589ff4ee', 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: 'a1cf9435fa7dc8e52db7ae148e07fde06971f27c', 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: '6779413b48314161a75ec75be273e72fe4d622c3', name: "actions-end" }))));
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" }))));
135
153
  }
136
154
  static get is() { return "bs-composer"; }
137
155
  static get encapsulation() { return "shadow"; }
@@ -261,6 +279,11 @@ export class BsComposer {
261
279
  }
262
280
  };
263
281
  }
282
+ static get states() {
283
+ return {
284
+ "hasAttachments": {}
285
+ };
286
+ }
264
287
  static get events() {
265
288
  return [{
266
289
  "method": "bsInput",
@@ -354,6 +377,7 @@ export class BsComposer {
354
377
  }
355
378
  }];
356
379
  }
380
+ static get elementRef() { return "el"; }
357
381
  }
358
382
  const PlusIcon = () => (h("svg", { viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M8 2.5V13.5M2.5 8H13.5", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round" })));
359
383
  const MicIcon = () => (h("svg", { viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M8 9.5C9.10457 9.5 10 8.60457 10 7.5V3.5C10 2.39543 9.10457 1.5 8 1.5C6.89543 1.5 6 2.39543 6 3.5V7.5C6 8.60457 6.89543 9.5 8 9.5Z", stroke: "currentColor", "stroke-width": "1.4" }), h("path", { d: "M3.5 7V7.5C3.5 9.98528 5.51472 12 8 12C10.4853 12 12.5 9.98528 12.5 7.5V7", stroke: "currentColor", "stroke-width": "1.4", "stroke-linecap": "round" }), h("path", { d: "M8 12V14.5", stroke: "currentColor", "stroke-width": "1.4", "stroke-linecap": "round" })));
@@ -41,6 +41,19 @@ export const Disabled = {
41
41
  export const Recording = {
42
42
  args: { state: 'recording', value: 'Here is what I have so far' },
43
43
  };
44
+ export const WithAttachments = {
45
+ name: 'With attachments',
46
+ render: () => html `
47
+ <div style="max-width: 420px;">
48
+ <bs-composer aria-label="Message">
49
+ <bs-attachment-list slot="attachments">
50
+ <bs-attachment type="image" image-src="https://images.unsplash.com/photo-1512917774080-9991f1c4c750?w=200&h=200&fit=crop"></bs-attachment>
51
+ <bs-attachment type="pdf" file-name="Dummy-pdf-in-here"></bs-attachment>
52
+ </bs-attachment-list>
53
+ </bs-composer>
54
+ </div>
55
+ `,
56
+ };
44
57
  export const AllStates = {
45
58
  name: 'All variants × states',
46
59
  render: () => html `
@@ -0,0 +1,42 @@
1
+ import { render, h, describe, it, expect } from "@stencil/vitest";
2
+ describe('bs-composer-status-banner', () => {
3
+ it('renders the message and a default clock icon', async () => {
4
+ const { root } = await render(h("bs-composer-status-banner", { message: "Something went wrong" }));
5
+ expect(root).toHaveTextContent('Something went wrong');
6
+ expect(root.shadowRoot.querySelector('[part="icon"] svg')).not.toBeNull();
7
+ });
8
+ it('does not render the icon when showIcon is false', async () => {
9
+ const { root } = await render(h("bs-composer-status-banner", { showIcon: false }));
10
+ expect(root.shadowRoot.querySelector('[part="icon"]')).toBeNull();
11
+ });
12
+ it('applies the type-specific class', async () => {
13
+ const { root } = await render(h("bs-composer-status-banner", { type: "warning" }));
14
+ expect(root.shadowRoot.querySelector('.bs-composer-status-banner').className).toContain('bs-composer-status-banner--warning');
15
+ });
16
+ it('does not render the action button by default', async () => {
17
+ const { root } = await render(h("bs-composer-status-banner", null));
18
+ expect(root.shadowRoot.querySelector('[part="action"]')).toBeNull();
19
+ });
20
+ it('renders the action button with actionLabel when showButton is true', async () => {
21
+ const { root } = await render(h("bs-composer-status-banner", { showButton: true, actionLabel: "Retry" }));
22
+ const action = root.shadowRoot.querySelector('[part="action"]');
23
+ expect(action).not.toBeNull();
24
+ expect(action).toHaveTextContent('Retry');
25
+ });
26
+ it('emits bsAction when the action button is clicked', async () => {
27
+ const { root, spyOnEvent } = await render(h("bs-composer-status-banner", { showButton: true }));
28
+ const actionSpy = spyOnEvent('bsAction');
29
+ root.shadowRoot.querySelector('[part="action"]').click();
30
+ expect(actionSpy).toHaveReceivedEventTimes(1);
31
+ });
32
+ it('does not render the close button when allowClose is false', async () => {
33
+ const { root } = await render(h("bs-composer-status-banner", { allowClose: false }));
34
+ expect(root.shadowRoot.querySelector('[part="close"]')).toBeNull();
35
+ });
36
+ it('emits bsClose when the close button is clicked', async () => {
37
+ const { root, spyOnEvent } = await render(h("bs-composer-status-banner", null));
38
+ const closeSpy = spyOnEvent('bsClose');
39
+ root.shadowRoot.querySelector('[part="close"]').click();
40
+ expect(closeSpy).toHaveReceivedEventTimes(1);
41
+ });
42
+ });
@@ -0,0 +1,173 @@
1
+ :host {
2
+ display: block;
3
+ --bs-composer-status-banner-radius: var(--bs-border-radius-150);
4
+ --bs-composer-status-banner-padding-x: var(--bs-spacing-150);
5
+ --bs-composer-status-banner-padding-top: var(--bs-spacing-100);
6
+ --bs-composer-status-banner-padding-bottom: var(--bs-spacing-200);
7
+ --bs-composer-status-banner-gap: var(--bs-spacing-100);
8
+ --bs-composer-status-banner-icon-gap: var(--bs-spacing-75);
9
+
10
+ --bs-composer-status-banner-error-bg: var(--bs-color-error-container);
11
+ --bs-composer-status-banner-error-text: var(--bs-text-error);
12
+ --bs-composer-status-banner-error-action-bg: var(--bs-color-error-default);
13
+ --bs-composer-status-banner-error-action-bg-hover: var(--bs-color-error-hover);
14
+
15
+ --bs-composer-status-banner-info-bg: var(--bs-color-info-container);
16
+ --bs-composer-status-banner-info-text: var(--bs-text-info);
17
+ --bs-composer-status-banner-info-action-bg: var(--bs-color-info-default);
18
+ --bs-composer-status-banner-info-action-bg-hover: var(--bs-color-info-hover);
19
+
20
+ --bs-composer-status-banner-neutral-bg: var(--bs-color-neutral-container);
21
+ --bs-composer-status-banner-neutral-text: var(--bs-text-default);
22
+ --bs-composer-status-banner-neutral-action-bg: var(--bs-color-neutral-container);
23
+ --bs-composer-status-banner-neutral-action-bg-hover: var(--bs-color-neutral-container-hover);
24
+ --bs-composer-status-banner-neutral-action-border: var(--bs-border-neutral-container);
25
+
26
+ --bs-composer-status-banner-warning-bg: var(--bs-color-warning-container);
27
+ --bs-composer-status-banner-warning-text: var(--bs-text-warning);
28
+ --bs-composer-status-banner-warning-action-bg: var(--bs-color-warning-default);
29
+ --bs-composer-status-banner-warning-action-bg-hover: var(--bs-color-warning-hover);
30
+
31
+ --bs-composer-status-banner-close-hover-bg: var(--bs-color-neutral-container-hover);
32
+ }
33
+
34
+ .bs-composer-status-banner {
35
+ box-sizing: border-box;
36
+ display: flex;
37
+ align-items: center;
38
+ gap: var(--bs-composer-status-banner-gap);
39
+ padding: var(--bs-composer-status-banner-padding-top) var(--bs-composer-status-banner-padding-x) var(--bs-composer-status-banner-padding-bottom);
40
+ border-radius: var(--bs-composer-status-banner-radius) var(--bs-composer-status-banner-radius) 0 0;
41
+ font-family: inherit;
42
+ }
43
+
44
+ .bs-composer-status-banner--error {
45
+ background: var(--bs-composer-status-banner-error-bg);
46
+ color: var(--bs-composer-status-banner-error-text);
47
+ }
48
+
49
+ .bs-composer-status-banner--info {
50
+ background: var(--bs-composer-status-banner-info-bg);
51
+ color: var(--bs-composer-status-banner-info-text);
52
+ }
53
+
54
+ .bs-composer-status-banner--neutral {
55
+ background: var(--bs-composer-status-banner-neutral-bg);
56
+ color: var(--bs-composer-status-banner-neutral-text);
57
+ }
58
+
59
+ .bs-composer-status-banner--warning {
60
+ background: var(--bs-composer-status-banner-warning-bg);
61
+ color: var(--bs-composer-status-banner-warning-text);
62
+ }
63
+
64
+ .bs-composer-status-banner__message-group {
65
+ box-sizing: border-box;
66
+ display: flex;
67
+ align-items: center;
68
+ flex: 1 0 0;
69
+ min-width: 0;
70
+ gap: var(--bs-composer-status-banner-icon-gap);
71
+ }
72
+
73
+ .bs-composer-status-banner__icon {
74
+ display: inline-flex;
75
+ flex-shrink: 0;
76
+ width: 20px;
77
+ height: 20px;
78
+ }
79
+
80
+ .bs-composer-status-banner__icon ::slotted(*) {
81
+ display: block;
82
+ width: 100%;
83
+ height: 100%;
84
+ }
85
+
86
+ .bs-composer-status-banner__message {
87
+ margin: 0;
88
+ flex: 1 0 0;
89
+ min-width: 0;
90
+ font-size: var(--bs-font-size-md);
91
+ line-height: calc(var(--bs-line-height-body-md) * 1px);
92
+ word-break: break-word;
93
+ }
94
+
95
+ .bs-composer-status-banner__action {
96
+ box-sizing: border-box;
97
+ flex-shrink: 0;
98
+ height: 32px;
99
+ padding: 0 var(--bs-spacing-150);
100
+ border: none;
101
+ border-radius: var(--bs-border-radius-100);
102
+ color: var(--bs-text-on-action);
103
+ font-family: inherit;
104
+ font-size: var(--bs-font-size-sm);
105
+ font-weight: var(--bs-font-weight-medium);
106
+ line-height: calc(var(--bs-line-height-body-sm) * 1px);
107
+ cursor: pointer;
108
+ transition: background-color var(--bs-duration-fast) var(--bs-easing-standard);
109
+ }
110
+
111
+ .bs-composer-status-banner--error .bs-composer-status-banner__action {
112
+ background: var(--bs-composer-status-banner-error-action-bg);
113
+ }
114
+ .bs-composer-status-banner--error .bs-composer-status-banner__action:hover {
115
+ background: var(--bs-composer-status-banner-error-action-bg-hover);
116
+ }
117
+
118
+ .bs-composer-status-banner--info .bs-composer-status-banner__action {
119
+ background: var(--bs-composer-status-banner-info-action-bg);
120
+ }
121
+ .bs-composer-status-banner--info .bs-composer-status-banner__action:hover {
122
+ background: var(--bs-composer-status-banner-info-action-bg-hover);
123
+ }
124
+
125
+ .bs-composer-status-banner--warning .bs-composer-status-banner__action {
126
+ background: var(--bs-composer-status-banner-warning-action-bg);
127
+ }
128
+ .bs-composer-status-banner--warning .bs-composer-status-banner__action:hover {
129
+ background: var(--bs-composer-status-banner-warning-action-bg-hover);
130
+ }
131
+
132
+ /* The only variant whose action button is outlined (container bg + visible border) instead of a
133
+ * solid semantic color -- there's no strong "neutral action" brand color to fill it with. */
134
+ .bs-composer-status-banner--neutral .bs-composer-status-banner__action {
135
+ background: var(--bs-composer-status-banner-neutral-action-bg);
136
+ border: var(--bs-border-width-thin) solid var(--bs-composer-status-banner-neutral-action-border);
137
+ color: var(--bs-text-default);
138
+ }
139
+ .bs-composer-status-banner--neutral .bs-composer-status-banner__action:hover {
140
+ background: var(--bs-composer-status-banner-neutral-action-bg-hover);
141
+ }
142
+
143
+ .bs-composer-status-banner__close {
144
+ box-sizing: border-box;
145
+ display: inline-flex;
146
+ flex-shrink: 0;
147
+ align-items: center;
148
+ justify-content: center;
149
+ width: 32px;
150
+ height: 32px;
151
+ padding: 0;
152
+ background: transparent;
153
+ border: none;
154
+ border-radius: var(--bs-border-radius-100);
155
+ color: inherit;
156
+ cursor: pointer;
157
+ transition: background-color var(--bs-duration-fast) var(--bs-easing-standard);
158
+ }
159
+
160
+ .bs-composer-status-banner__close:hover {
161
+ background: var(--bs-composer-status-banner-close-hover-bg);
162
+ }
163
+
164
+ .bs-composer-status-banner__close svg {
165
+ width: 20px;
166
+ height: 20px;
167
+ }
168
+
169
+ .bs-composer-status-banner__close:focus-visible,
170
+ .bs-composer-status-banner__action:focus-visible {
171
+ outline: 2px solid var(--bs-border-neutral-focus);
172
+ outline-offset: 1px;
173
+ }