@brandsync/wc 0.0.1

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 (134) hide show
  1. package/LICENSE +21 -0
  2. package/custom-elements.json +1138 -0
  3. package/dist/brandsync-wc/brandsync-wc.css +1730 -0
  4. package/dist/brandsync-wc/brandsync-wc.esm.js +1 -0
  5. package/dist/brandsync-wc/brandsync-wc.esm.js.map +1 -0
  6. package/dist/brandsync-wc/index-Cqxk7LcP.js.map +1 -0
  7. package/dist/brandsync-wc/index.esm.js +1 -0
  8. package/dist/brandsync-wc/index.esm.js.map +1 -0
  9. package/dist/brandsync-wc/p-042ad15a.entry.js +1 -0
  10. package/dist/brandsync-wc/p-2c4df28d.entry.js +1 -0
  11. package/dist/brandsync-wc/p-3134f5f5.entry.js +1 -0
  12. package/dist/brandsync-wc/p-5739acaf.entry.js +1 -0
  13. package/dist/brandsync-wc/p-BOj_41o9.js +3 -0
  14. package/dist/brandsync-wc/p-c2cc0d6f.entry.js +1 -0
  15. package/dist/brandsync-wc/p-da11e421.entry.js +1 -0
  16. package/dist/brandsync-wc/p-db3934d2.entry.js +1 -0
  17. package/dist/brandsync-wc/p-e38a9744.entry.js +1 -0
  18. package/dist/cjs/brandsync-wc.cjs.js +24 -0
  19. package/dist/cjs/bs-badge.cjs.entry.js +19 -0
  20. package/dist/cjs/bs-button-skeleton.cjs.entry.js +19 -0
  21. package/dist/cjs/bs-button.cjs.entry.js +88 -0
  22. package/dist/cjs/bs-card.cjs.entry.js +20 -0
  23. package/dist/cjs/bs-composer.cjs.entry.js +116 -0
  24. package/dist/cjs/bs-data-table.cjs.entry.js +62 -0
  25. package/dist/cjs/bs-input.cjs.entry.js +42 -0
  26. package/dist/cjs/bs-modal.cjs.entry.js +69 -0
  27. package/dist/cjs/index-nyOcuVbF.js +1710 -0
  28. package/dist/cjs/index.cjs.js +7 -0
  29. package/dist/cjs/loader.cjs.js +12 -0
  30. package/dist/collection/collection-manifest.json +20 -0
  31. package/dist/collection/components/bs-badge/bs-badge.cmp.test.js +30 -0
  32. package/dist/collection/components/bs-badge/bs-badge.css +55 -0
  33. package/dist/collection/components/bs-badge/bs-badge.js +64 -0
  34. package/dist/collection/components/bs-badge/bs-badge.stories.js +75 -0
  35. package/dist/collection/components/bs-button/bs-button.cmp.test.js +81 -0
  36. package/dist/collection/components/bs-button/bs-button.css +247 -0
  37. package/dist/collection/components/bs-button/bs-button.js +242 -0
  38. package/dist/collection/components/bs-button/bs-button.stories.js +145 -0
  39. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.cmp.test.js +18 -0
  40. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.css +46 -0
  41. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.js +73 -0
  42. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.stories.js +25 -0
  43. package/dist/collection/components/bs-card/bs-card.cmp.test.js +42 -0
  44. package/dist/collection/components/bs-card/bs-card.css +31 -0
  45. package/dist/collection/components/bs-card/bs-card.js +70 -0
  46. package/dist/collection/components/bs-card/bs-card.stories.js +27 -0
  47. package/dist/collection/components/bs-composer/bs-composer.cmp.test.js +132 -0
  48. package/dist/collection/components/bs-composer/bs-composer.css +185 -0
  49. package/dist/collection/components/bs-composer/bs-composer.js +353 -0
  50. package/dist/collection/components/bs-composer/bs-composer.stories.js +66 -0
  51. package/dist/collection/components/bs-data-table/bs-data-table.css +56 -0
  52. package/dist/collection/components/bs-data-table/bs-data-table.js +259 -0
  53. package/dist/collection/components/bs-data-table/bs-data-table.stories.js +55 -0
  54. package/dist/collection/components/bs-input/bs-input.cmp.test.js +101 -0
  55. package/dist/collection/components/bs-input/bs-input.css +64 -0
  56. package/dist/collection/components/bs-input/bs-input.js +230 -0
  57. package/dist/collection/components/bs-input/bs-input.stories.js +40 -0
  58. package/dist/collection/components/bs-modal/bs-modal.cmp.test.js +112 -0
  59. package/dist/collection/components/bs-modal/bs-modal.css +66 -0
  60. package/dist/collection/components/bs-modal/bs-modal.js +198 -0
  61. package/dist/collection/components/bs-modal/bs-modal.stories.js +38 -0
  62. package/dist/collection/index.js +10 -0
  63. package/dist/collection/stories-utils.js +25 -0
  64. package/dist/collection/utils/utils.js +3 -0
  65. package/dist/collection/utils/utils.unit.test.js +16 -0
  66. package/dist/components/bs-badge.d.ts +11 -0
  67. package/dist/components/bs-badge.js +1 -0
  68. package/dist/components/bs-button-skeleton.d.ts +11 -0
  69. package/dist/components/bs-button-skeleton.js +1 -0
  70. package/dist/components/bs-button.d.ts +11 -0
  71. package/dist/components/bs-button.js +1 -0
  72. package/dist/components/bs-card.d.ts +11 -0
  73. package/dist/components/bs-card.js +1 -0
  74. package/dist/components/bs-composer.d.ts +11 -0
  75. package/dist/components/bs-composer.js +1 -0
  76. package/dist/components/bs-data-table.d.ts +11 -0
  77. package/dist/components/bs-data-table.js +1 -0
  78. package/dist/components/bs-input.d.ts +11 -0
  79. package/dist/components/bs-input.js +1 -0
  80. package/dist/components/bs-modal.d.ts +11 -0
  81. package/dist/components/bs-modal.js +1 -0
  82. package/dist/components/index.d.ts +35 -0
  83. package/dist/components/index.js +1 -0
  84. package/dist/components/p-Cu4gTknX.js +1 -0
  85. package/dist/esm/brandsync-wc.js +20 -0
  86. package/dist/esm/bs-badge.entry.js +17 -0
  87. package/dist/esm/bs-button-skeleton.entry.js +17 -0
  88. package/dist/esm/bs-button.entry.js +86 -0
  89. package/dist/esm/bs-card.entry.js +18 -0
  90. package/dist/esm/bs-composer.entry.js +114 -0
  91. package/dist/esm/bs-data-table.entry.js +60 -0
  92. package/dist/esm/bs-input.entry.js +40 -0
  93. package/dist/esm/bs-modal.entry.js +67 -0
  94. package/dist/esm/index-BOj_41o9.js +1701 -0
  95. package/dist/esm/index.js +5 -0
  96. package/dist/esm/loader.js +10 -0
  97. package/dist/index.cjs.js +1 -0
  98. package/dist/index.js +1 -0
  99. package/dist/types/components/bs-badge/bs-badge.cmp.test.d.ts +1 -0
  100. package/dist/types/components/bs-badge/bs-badge.d.ts +20 -0
  101. package/dist/types/components/bs-badge/bs-badge.stories.d.ts +19 -0
  102. package/dist/types/components/bs-button/bs-button.cmp.test.d.ts +1 -0
  103. package/dist/types/components/bs-button/bs-button.d.ts +84 -0
  104. package/dist/types/components/bs-button/bs-button.stories.d.ts +29 -0
  105. package/dist/types/components/bs-button-skeleton/bs-button-skeleton.cmp.test.d.ts +1 -0
  106. package/dist/types/components/bs-button-skeleton/bs-button-skeleton.d.ts +28 -0
  107. package/dist/types/components/bs-button-skeleton/bs-button-skeleton.stories.d.ts +10 -0
  108. package/dist/types/components/bs-card/bs-card.cmp.test.d.ts +1 -0
  109. package/dist/types/components/bs-card/bs-card.d.ts +26 -0
  110. package/dist/types/components/bs-card/bs-card.stories.d.ts +10 -0
  111. package/dist/types/components/bs-composer/bs-composer.cmp.test.d.ts +1 -0
  112. package/dist/types/components/bs-composer/bs-composer.d.ts +83 -0
  113. package/dist/types/components/bs-composer/bs-composer.stories.d.ts +17 -0
  114. package/dist/types/components/bs-data-table/bs-data-table.d.ts +55 -0
  115. package/dist/types/components/bs-data-table/bs-data-table.stories.d.ts +7 -0
  116. package/dist/types/components/bs-input/bs-input.cmp.test.d.ts +1 -0
  117. package/dist/types/components/bs-input/bs-input.d.ts +33 -0
  118. package/dist/types/components/bs-input/bs-input.stories.d.ts +15 -0
  119. package/dist/types/components/bs-modal/bs-modal.cmp.test.d.ts +1 -0
  120. package/dist/types/components/bs-modal/bs-modal.d.ts +45 -0
  121. package/dist/types/components/bs-modal/bs-modal.stories.d.ts +9 -0
  122. package/dist/types/components.d.ts +962 -0
  123. package/dist/types/index.d.ts +11 -0
  124. package/dist/types/stencil-public-runtime.d.ts +1872 -0
  125. package/dist/types/stories-utils.d.ts +8 -0
  126. package/dist/types/utils/utils.d.ts +1 -0
  127. package/dist/types/utils/utils.unit.test.d.ts +1 -0
  128. package/loader/cdn.js +1 -0
  129. package/loader/index.cjs.js +1 -0
  130. package/loader/index.d.ts +24 -0
  131. package/loader/index.es2017.js +1 -0
  132. package/loader/index.js +2 -0
  133. package/package.json +67 -0
  134. package/readme.md +48 -0
@@ -0,0 +1,353 @@
1
+ import { h } from "@stencil/core";
2
+ const DEFAULT_PLACEHOLDERS = {
3
+ ai: 'Ask Genie something...',
4
+ human: 'Message your support agent...',
5
+ };
6
+ // Static (non-animated) placeholder audio-level bar heights in px, sampled from the Figma
7
+ // "Audio Waveform" reference (60 bars, 2.5px wide, 3px gap) -- a real analyzer would drive these
8
+ // from actual audio input, this just reproduces the designed look.
9
+ const WAVEFORM_BAR_HEIGHTS = [
10
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 18, 14, 34, 22, 22, 10, 28, 18, 12, 24, 6, 20, 30, 14, 8, 26, 16,
11
+ 32, 10, 22, 18, 12, 28, 8, 20, 14, 24, 10, 16, 30, 12, 22, 6, 18, 26, 8, 14, 32, 20, 10, 24, 6,
12
+ ];
13
+ /**
14
+ * A chat composer input for Genie AI-style conversational interfaces: a text field
15
+ * plus an attach button, a mic/voice-recording toggle, and a single primary action button whose
16
+ * icon and behavior change with `state` (send, stop generating, or confirm a voice recording).
17
+ *
18
+ * ## When to use
19
+ * - The message-entry bar for an AI chat/assistant or human support conversation.
20
+ *
21
+ * ## When not to use
22
+ * - A general-purpose text field — use `bs-input` instead; this component's layout and states are
23
+ * purpose-built for a chat composer, not a generic form field.
24
+ *
25
+ * @part attach - The "+" attach button.
26
+ * @part input - The native text `<input>`.
27
+ * @part mic - The secondary icon button (microphone, or the stop-recording square while `state="recording"`).
28
+ * @part action - The primary circular action button (send, stop, or confirm depending on `state`).
29
+ * @prop --bs-composer-radius - Corner radius of the container. Aliased to `--bs-border-radius-150`.
30
+ * @prop --bs-composer-button-radius - Corner radius of the attach/mic/action buttons. Aliased to `--bs-border-radius-100`.
31
+ * @prop --bs-composer-button-size - Width/height of the attach/mic/action buttons. Aliased to `--bs-spacing-600`.
32
+ * @prop --bs-composer-bg - Background of the pill container. Aliased to `--bs-input-bg-default`.
33
+ * @prop --bs-composer-border - Border color of the pill container. Aliased to `--bs-input-border-default`.
34
+ * @prop --bs-composer-border-focus - Border color when the text field has focus. Aliased to `--bs-input-border-focus`.
35
+ * @prop --bs-composer-action-bg - Background of the primary action button. Aliased to `--bs-color-primary-default`.
36
+ * @prop --bs-composer-action-bg-hover - Aliased to `--bs-color-primary-hover`.
37
+ * @prop --bs-composer-action-bg-pressed - Aliased to `--bs-color-primary-pressed`.
38
+ * @prop --bs-composer-action-bg-disabled - Aliased to `--bs-surface-action-disabled`.
39
+ * @prop --bs-composer-action-icon - Icon color on the primary action button. Aliased to `--bs-text-on-action`.
40
+ * @prop --bs-composer-action-icon-disabled - Aliased to `--bs-text-on-disabled`.
41
+ * @prop --bs-composer-attach-icon - Icon color of the attach button. Aliased to `--bs-icon-default`.
42
+ * @prop --bs-composer-mic-icon - Icon color of the mic/stop-recording button. Aliased to `--bs-icon-default`.
43
+ * @prop --bs-composer-mic-icon-disabled - Aliased to `--bs-icon-disabled`.
44
+ * @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`.
45
+ * @prop --bs-composer-subtle-pressed - Background of the attach/mic buttons when pressed. Aliased to `--bs-color-neutral-container-pressed`.
46
+ */
47
+ export class BsComposer {
48
+ /**
49
+ * Which flavor of composer this is: changes the *default* placeholder text (set `placeholder`
50
+ * directly to override it) and, per the Figma design, renders the container border dashed
51
+ * instead of solid for `'human'` -- a deliberate visual cue distinguishing a human-support
52
+ * composer from the AI one, not a layout/token difference.
53
+ */
54
+ variant = 'ai';
55
+ /** Overrides the variant's default placeholder. */
56
+ placeholder;
57
+ /** Current text value. Native `input` events don't cross the Shadow DOM boundary, so this
58
+ * component re-dispatches them as a `bsInput` custom event instead. */
59
+ value = '';
60
+ /**
61
+ * Which of the four mutually-exclusive composer states to render: `idle` (send, enabled),
62
+ * `generating` (stop, while the AI is responding), `disabled` (send, but not interactive), or
63
+ * `recording` (voice input in progress -- shows a waveform and a confirm action).
64
+ */
65
+ state = 'idle';
66
+ /**
67
+ * Accessible name for the text field. This component has no visible `<label>` (chat composers
68
+ * don't show one in the design), so `ariaLabel` is the only way a consumer gives the textbox an
69
+ * accessible name -- set it in every real usage.
70
+ */
71
+ ariaLabel = null;
72
+ /** Fires on every keystroke in the text field, with the current value. */
73
+ bsInput;
74
+ /** Fires when the primary action button is clicked while `state="idle"`. */
75
+ bsSubmit;
76
+ /** Fires when the primary action button is clicked while `state="generating"`. */
77
+ bsStop;
78
+ /** Fires when the primary action button is clicked while `state="recording"`. */
79
+ bsVoiceConfirm;
80
+ /** Fires when the "+" attach button is clicked. */
81
+ bsAttach;
82
+ /** Fires when the mic/stop-recording button is clicked. The consumer decides what that means
83
+ * (e.g. start recording when idle/generating, or stop recording when `state="recording"`). */
84
+ bsMicToggle;
85
+ onInput = (ev) => {
86
+ const value = ev.target.value;
87
+ this.bsInput.emit(value);
88
+ };
89
+ onAttachClick = () => {
90
+ this.bsAttach.emit();
91
+ };
92
+ onMicClick = () => {
93
+ this.bsMicToggle.emit();
94
+ };
95
+ onActionClick = () => {
96
+ if (this.state === 'idle') {
97
+ this.bsSubmit.emit();
98
+ }
99
+ else if (this.state === 'generating') {
100
+ this.bsStop.emit();
101
+ }
102
+ else if (this.state === 'recording') {
103
+ this.bsVoiceConfirm.emit();
104
+ }
105
+ };
106
+ actionLabel() {
107
+ if (this.state === 'generating')
108
+ return 'Stop';
109
+ if (this.state === 'recording')
110
+ return 'Confirm';
111
+ return 'Send';
112
+ }
113
+ renderActionIcon() {
114
+ if (this.state === 'generating')
115
+ return h(StopIcon, null);
116
+ if (this.state === 'recording')
117
+ return h(CheckIcon, null);
118
+ return h(SendIcon, null);
119
+ }
120
+ render() {
121
+ const placeholder = this.placeholder ?? DEFAULT_PLACEHOLDERS[this.variant];
122
+ const disabled = this.state === 'disabled';
123
+ const recording = this.state === 'recording';
124
+ return (h("div", { key: '785b4da8ddb23f4762ac7ea379b3ecdaa9584f40', class: `bs-composer bs-composer--${this.state} bs-composer--${this.variant}` }, h("div", { key: '5b470cc47221f93ce9852ebaeaf9a35d740d5df1', class: "bs-composer__text-row" }, h("input", { key: '3f4093d98bc0a0ba8440da9fec1d5cb2e302b746', 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: '21103c8d6ac108e705487f670aeb4aaf89d45981', class: "bs-composer__controls-row" }, h("button", { key: '570ef86150f5b0072008fb0215ed1f0affac7af4', type: "button", part: "attach", class: "bs-composer__attach", "aria-label": "Attach", onClick: this.onAttachClick }, h(PlusIcon, { key: 'ea030569c8b5d2bafaae3ecfe29b956a54921f34' })), 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: '1906485b13395c9c730f7091176dab4e81ecbcb9', 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: '3486957673a3bbf7c3dbac41fd5c19e8dbb6258a', type: "button", part: "action", class: `bs-composer__action bs-composer__action--${this.state}`, "aria-label": this.actionLabel(), disabled: disabled, onClick: this.onActionClick }, this.renderActionIcon()))));
125
+ }
126
+ static get is() { return "bs-composer"; }
127
+ static get encapsulation() { return "shadow"; }
128
+ static get delegatesFocus() { return true; }
129
+ static get originalStyleUrls() {
130
+ return {
131
+ "$": ["bs-composer.css"]
132
+ };
133
+ }
134
+ static get styleUrls() {
135
+ return {
136
+ "$": ["bs-composer.css"]
137
+ };
138
+ }
139
+ static get properties() {
140
+ return {
141
+ "variant": {
142
+ "type": "string",
143
+ "mutable": false,
144
+ "complexType": {
145
+ "original": "BsComposerVariant",
146
+ "resolved": "\"ai\" | \"human\"",
147
+ "references": {
148
+ "BsComposerVariant": {
149
+ "location": "local",
150
+ "path": "/Users/vivka/brandsync-web-components/src/components/bs-composer/bs-composer.tsx",
151
+ "id": "src/components/bs-composer/bs-composer.tsx::BsComposerVariant"
152
+ }
153
+ }
154
+ },
155
+ "required": false,
156
+ "optional": false,
157
+ "docs": {
158
+ "tags": [],
159
+ "text": "Which flavor of composer this is: changes the *default* placeholder text (set `placeholder`\ndirectly to override it) and, per the Figma design, renders the container border dashed\ninstead of solid for `'human'` -- a deliberate visual cue distinguishing a human-support\ncomposer from the AI one, not a layout/token difference."
160
+ },
161
+ "getter": false,
162
+ "setter": false,
163
+ "reflect": false,
164
+ "attribute": "variant",
165
+ "defaultValue": "'ai'"
166
+ },
167
+ "placeholder": {
168
+ "type": "string",
169
+ "mutable": false,
170
+ "complexType": {
171
+ "original": "string",
172
+ "resolved": "string",
173
+ "references": {}
174
+ },
175
+ "required": false,
176
+ "optional": true,
177
+ "docs": {
178
+ "tags": [],
179
+ "text": "Overrides the variant's default placeholder."
180
+ },
181
+ "getter": false,
182
+ "setter": false,
183
+ "reflect": false,
184
+ "attribute": "placeholder"
185
+ },
186
+ "value": {
187
+ "type": "string",
188
+ "mutable": false,
189
+ "complexType": {
190
+ "original": "string",
191
+ "resolved": "string",
192
+ "references": {}
193
+ },
194
+ "required": false,
195
+ "optional": false,
196
+ "docs": {
197
+ "tags": [],
198
+ "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."
199
+ },
200
+ "getter": false,
201
+ "setter": false,
202
+ "reflect": false,
203
+ "attribute": "value",
204
+ "defaultValue": "''"
205
+ },
206
+ "state": {
207
+ "type": "string",
208
+ "mutable": false,
209
+ "complexType": {
210
+ "original": "BsComposerState",
211
+ "resolved": "\"disabled\" | \"generating\" | \"idle\" | \"recording\"",
212
+ "references": {
213
+ "BsComposerState": {
214
+ "location": "local",
215
+ "path": "/Users/vivka/brandsync-web-components/src/components/bs-composer/bs-composer.tsx",
216
+ "id": "src/components/bs-composer/bs-composer.tsx::BsComposerState"
217
+ }
218
+ }
219
+ },
220
+ "required": false,
221
+ "optional": false,
222
+ "docs": {
223
+ "tags": [],
224
+ "text": "Which of the four mutually-exclusive composer states to render: `idle` (send, enabled),\n`generating` (stop, while the AI is responding), `disabled` (send, but not interactive), or\n`recording` (voice input in progress -- shows a waveform and a confirm action)."
225
+ },
226
+ "getter": false,
227
+ "setter": false,
228
+ "reflect": false,
229
+ "attribute": "state",
230
+ "defaultValue": "'idle'"
231
+ },
232
+ "ariaLabel": {
233
+ "type": "string",
234
+ "mutable": false,
235
+ "complexType": {
236
+ "original": "string | null",
237
+ "resolved": "string",
238
+ "references": {}
239
+ },
240
+ "required": false,
241
+ "optional": false,
242
+ "docs": {
243
+ "tags": [],
244
+ "text": "Accessible name for the text field. This component has no visible `<label>` (chat composers\ndon't show one in the design), so `ariaLabel` is the only way a consumer gives the textbox an\naccessible name -- set it in every real usage."
245
+ },
246
+ "getter": false,
247
+ "setter": false,
248
+ "reflect": false,
249
+ "attribute": "aria-label",
250
+ "defaultValue": "null"
251
+ }
252
+ };
253
+ }
254
+ static get events() {
255
+ return [{
256
+ "method": "bsInput",
257
+ "name": "bsInput",
258
+ "bubbles": true,
259
+ "cancelable": true,
260
+ "composed": true,
261
+ "docs": {
262
+ "tags": [],
263
+ "text": "Fires on every keystroke in the text field, with the current value."
264
+ },
265
+ "complexType": {
266
+ "original": "string",
267
+ "resolved": "string",
268
+ "references": {}
269
+ }
270
+ }, {
271
+ "method": "bsSubmit",
272
+ "name": "bsSubmit",
273
+ "bubbles": true,
274
+ "cancelable": true,
275
+ "composed": true,
276
+ "docs": {
277
+ "tags": [],
278
+ "text": "Fires when the primary action button is clicked while `state=\"idle\"`."
279
+ },
280
+ "complexType": {
281
+ "original": "void",
282
+ "resolved": "void",
283
+ "references": {}
284
+ }
285
+ }, {
286
+ "method": "bsStop",
287
+ "name": "bsStop",
288
+ "bubbles": true,
289
+ "cancelable": true,
290
+ "composed": true,
291
+ "docs": {
292
+ "tags": [],
293
+ "text": "Fires when the primary action button is clicked while `state=\"generating\"`."
294
+ },
295
+ "complexType": {
296
+ "original": "void",
297
+ "resolved": "void",
298
+ "references": {}
299
+ }
300
+ }, {
301
+ "method": "bsVoiceConfirm",
302
+ "name": "bsVoiceConfirm",
303
+ "bubbles": true,
304
+ "cancelable": true,
305
+ "composed": true,
306
+ "docs": {
307
+ "tags": [],
308
+ "text": "Fires when the primary action button is clicked while `state=\"recording\"`."
309
+ },
310
+ "complexType": {
311
+ "original": "void",
312
+ "resolved": "void",
313
+ "references": {}
314
+ }
315
+ }, {
316
+ "method": "bsAttach",
317
+ "name": "bsAttach",
318
+ "bubbles": true,
319
+ "cancelable": true,
320
+ "composed": true,
321
+ "docs": {
322
+ "tags": [],
323
+ "text": "Fires when the \"+\" attach button is clicked."
324
+ },
325
+ "complexType": {
326
+ "original": "void",
327
+ "resolved": "void",
328
+ "references": {}
329
+ }
330
+ }, {
331
+ "method": "bsMicToggle",
332
+ "name": "bsMicToggle",
333
+ "bubbles": true,
334
+ "cancelable": true,
335
+ "composed": true,
336
+ "docs": {
337
+ "tags": [],
338
+ "text": "Fires when the mic/stop-recording button is clicked. The consumer decides what that means\n(e.g. start recording when idle/generating, or stop recording when `state=\"recording\"`)."
339
+ },
340
+ "complexType": {
341
+ "original": "void",
342
+ "resolved": "void",
343
+ "references": {}
344
+ }
345
+ }];
346
+ }
347
+ }
348
+ 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" })));
349
+ 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" })));
350
+ // Exact "PaperPlaneRight" path from the Figma design (node 45:95), not a hand-drawn approximation.
351
+ const SendIcon = () => (h("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M13.5 12H7.5", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { d: "M4.54594 20.745C4.4932 20.889 4.48589 21.0457 4.52499 21.1941C4.56409 21.3424 4.64771 21.4751 4.76459 21.5744C4.88147 21.6737 5.02599 21.7348 5.17866 21.7494C5.33133 21.7641 5.48482 21.7315 5.61844 21.6562L21.3684 12.6478C21.4857 12.583 21.5834 12.4879 21.6514 12.3725C21.7195 12.2571 21.7553 12.1255 21.7553 11.9916C21.7553 11.8576 21.7195 11.7261 21.6514 11.6107C21.5834 11.4952 21.4857 11.4002 21.3684 11.3353L5.61844 2.34937C5.48523 2.27487 5.33245 2.24278 5.18052 2.2574C5.02859 2.27201 4.88474 2.33264 4.76817 2.43117C4.65161 2.5297 4.56788 2.66145 4.52817 2.80882C4.48846 2.9562 4.49466 3.11218 4.54594 3.25594L7.5 12L4.54594 20.745Z", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" })));
352
+ const StopIcon = () => (h("svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("rect", { x: "6", y: "6", width: "8", height: "8", rx: "1.5", fill: "currentColor" })));
353
+ const CheckIcon = () => (h("svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M4.5 10.5L8 14L15.5 6", stroke: "currentColor", "stroke-width": "1.75", "stroke-linecap": "round", "stroke-linejoin": "round" })));
@@ -0,0 +1,66 @@
1
+ import { html } from "lit";
2
+ import { componentDescription, propDescription } from "../../stories-utils";
3
+ const variants = ['ai', 'human'];
4
+ const states = ['idle', 'generating', 'disabled', 'recording'];
5
+ const meta = {
6
+ title: 'Genie AI Components/bs-composer',
7
+ parameters: { docs: { description: { component: componentDescription('bs-composer') } } },
8
+ render: args => html `
9
+ <bs-composer
10
+ variant=${args.variant}
11
+ state=${args.state}
12
+ value=${args.value}
13
+ placeholder=${args.placeholder}
14
+ aria-label="Message"
15
+ ></bs-composer>
16
+ `,
17
+ argTypes: {
18
+ variant: { control: 'select', options: variants, description: propDescription('bs-composer', 'variant') },
19
+ state: { control: 'select', options: states, description: propDescription('bs-composer', 'state') },
20
+ value: { control: 'text', description: propDescription('bs-composer', 'value') },
21
+ placeholder: { control: 'text', description: propDescription('bs-composer', 'placeholder') },
22
+ },
23
+ args: {
24
+ variant: 'ai',
25
+ state: 'idle',
26
+ value: '',
27
+ placeholder: '',
28
+ },
29
+ };
30
+ export default meta;
31
+ export const Default = {};
32
+ export const Human = {
33
+ args: { variant: 'human' },
34
+ };
35
+ export const Generating = {
36
+ args: { state: 'generating', value: 'Summarize this thread for me' },
37
+ };
38
+ export const Disabled = {
39
+ args: { state: 'disabled' },
40
+ };
41
+ export const Recording = {
42
+ args: { state: 'recording', value: 'Here is what I have so far' },
43
+ };
44
+ export const AllStates = {
45
+ name: 'All variants × states',
46
+ render: () => html `
47
+ <div style="display:flex; flex-direction:column; gap:24px; max-width: 420px;">
48
+ ${variants.map(variant => html `
49
+ <div style="display:flex; flex-direction:column; gap:12px;">
50
+ <h4 style="margin:0; font-family: sans-serif; text-transform: capitalize;">${variant}</h4>
51
+ ${states.map(state => html `
52
+ <div>
53
+ <div style="font-size: 12px; font-family: monospace; color: #888; margin-bottom: 4px;">${state}</div>
54
+ <bs-composer
55
+ variant=${variant}
56
+ state=${state}
57
+ value=${state === 'recording' ? 'Here is what I have so far' : ''}
58
+ aria-label="Message"
59
+ ></bs-composer>
60
+ </div>
61
+ `)}
62
+ </div>
63
+ `)}
64
+ </div>
65
+ `,
66
+ };
@@ -0,0 +1,56 @@
1
+ :host {
2
+ display: block;
3
+ }
4
+
5
+ .bs-data-table {
6
+ width: 100%;
7
+ border-collapse: collapse;
8
+ font-family: inherit;
9
+ font-size: var(--bs-font-size-sm);
10
+ color: var(--bs-text-default);
11
+ }
12
+
13
+ .bs-data-table__header-cell {
14
+ text-align: left;
15
+ padding: var(--bs-spacing-200) var(--bs-spacing-300);
16
+ border-bottom: 1px solid var(--bs-border-default);
17
+ font-weight: var(--bs-font-weight-semibold);
18
+ color: var(--bs-text-secondary);
19
+ white-space: nowrap;
20
+ }
21
+
22
+ .bs-data-table__sort-button {
23
+ display: inline-flex;
24
+ align-items: center;
25
+ border: none;
26
+ background: none;
27
+ padding: 0;
28
+ font: inherit;
29
+ color: inherit;
30
+ cursor: pointer;
31
+ user-select: none;
32
+ }
33
+
34
+ .bs-data-table__sort-button:focus-visible {
35
+ outline: 2px solid var(--bs-border-neutral-focus);
36
+ outline-offset: 2px;
37
+ }
38
+
39
+ .bs-data-table__sort-indicator {
40
+ color: var(--bs-text-action);
41
+ }
42
+
43
+ .bs-data-table__row:hover {
44
+ background: var(--bs-surface-hover);
45
+ }
46
+
47
+ .bs-data-table__cell {
48
+ padding: var(--bs-spacing-200) var(--bs-spacing-300);
49
+ border-bottom: 1px solid var(--bs-border-default);
50
+ }
51
+
52
+ .bs-data-table__select-col {
53
+ width: var(--bs-spacing-500);
54
+ padding: var(--bs-spacing-200) var(--bs-spacing-300);
55
+ border-bottom: 1px solid var(--bs-border-default);
56
+ }