@brandsync/wc 0.0.5 → 0.0.7
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.
- package/custom-elements.json +207 -1
- package/dist/brandsync-wc/brandsync-wc.esm.js +1 -1
- package/dist/brandsync-wc/p-5a0fe72e.entry.js +1 -0
- package/dist/brandsync-wc/{p-300eea85.entry.js → p-6abdfaf0.entry.js} +1 -1
- package/dist/brandsync-wc/{p-27288299.entry.js → p-76eca100.entry.js} +1 -1
- package/dist/brandsync-wc/{p-0ded3be8.entry.js → p-a12d0a60.entry.js} +1 -1
- package/dist/brandsync-wc/p-bfd09c98.entry.js +1 -0
- package/dist/brandsync-wc/p-c63d16e1.entry.js +1 -0
- package/dist/brandsync-wc/{p-b24c455f.entry.js → p-dd0fea0e.entry.js} +1 -1
- package/dist/brandsync-wc/{p-cdbad27a.entry.js → p-f5f443e2.entry.js} +1 -1
- package/dist/brandsync-wc/{p-1dc6d7f5.entry.js → p-f88d9a6e.entry.js} +1 -1
- package/dist/cjs/brandsync-wc.cjs.js +1 -1
- package/dist/cjs/bs-ai-thinking.cjs.entry.js +34 -0
- package/dist/cjs/bs-button-skeleton.cjs.entry.js +1 -1
- package/dist/cjs/bs-chatbot-header.cjs.entry.js +2 -2
- package/dist/cjs/bs-chatbot-response-action.cjs.entry.js +1 -1
- package/dist/cjs/bs-chatbot-suggestion-button.cjs.entry.js +25 -0
- package/dist/cjs/bs-input.cjs.entry.js +2 -2
- package/dist/cjs/bs-menu-item.cjs.entry.js +1 -1
- package/dist/cjs/bs-menu.cjs.entry.js +1 -1
- package/dist/cjs/bs-tooltip.cjs.entry.js +24 -0
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +4 -1
- package/dist/collection/components/bs-ai-thinking/bs-ai-thinking.cmp.test.js +28 -0
- package/dist/collection/components/bs-ai-thinking/bs-ai-thinking.css +60 -0
- package/dist/collection/components/bs-ai-thinking/bs-ai-thinking.js +72 -0
- package/dist/collection/components/bs-ai-thinking/bs-ai-thinking.stories.js +21 -0
- package/dist/collection/components/bs-ai-thinking/genie-mark-icon.js +14 -0
- package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.js +1 -1
- package/dist/collection/components/bs-chatbot-header/bs-chatbot-header.css +33 -0
- package/dist/collection/components/bs-chatbot-header/bs-chatbot-header.js +9 -1
- package/dist/collection/components/bs-chatbot-response-action/bs-chatbot-response-action.js +1 -1
- package/dist/collection/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.cmp.test.js +24 -0
- package/dist/collection/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.css +57 -0
- package/dist/collection/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.js +104 -0
- package/dist/collection/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.stories.js +30 -0
- package/dist/collection/components/bs-input/bs-input.js +2 -2
- package/dist/collection/components/bs-menu/bs-menu.js +1 -1
- package/dist/collection/components/bs-menu-item/bs-menu-item.js +1 -1
- package/dist/collection/components/bs-tooltip/bs-tooltip.cmp.test.js +16 -0
- package/dist/collection/components/bs-tooltip/bs-tooltip.css +45 -0
- package/dist/collection/components/bs-tooltip/bs-tooltip.js +83 -0
- package/dist/collection/components/bs-tooltip/bs-tooltip.stories.js +26 -0
- package/dist/components/bs-ai-thinking.d.ts +11 -0
- package/dist/components/bs-ai-thinking.js +1 -0
- package/dist/components/bs-button-skeleton.js +1 -1
- package/dist/components/bs-chatbot-header.js +1 -1
- package/dist/components/bs-chatbot-response-action.js +1 -1
- package/dist/components/bs-chatbot-suggestion-button.d.ts +11 -0
- package/dist/components/bs-chatbot-suggestion-button.js +1 -0
- package/dist/components/bs-input.js +1 -1
- package/dist/components/bs-menu-item.js +1 -1
- package/dist/components/bs-menu.js +1 -1
- package/dist/components/bs-tooltip.d.ts +11 -0
- package/dist/components/bs-tooltip.js +1 -0
- package/dist/components/p-CoC4LQCI.js +1 -0
- package/dist/esm/brandsync-wc.js +1 -1
- package/dist/esm/bs-ai-thinking.entry.js +32 -0
- package/dist/esm/bs-button-skeleton.entry.js +1 -1
- package/dist/esm/bs-chatbot-header.entry.js +2 -2
- package/dist/esm/bs-chatbot-response-action.entry.js +1 -1
- package/dist/esm/bs-chatbot-suggestion-button.entry.js +23 -0
- package/dist/esm/bs-input.entry.js +2 -2
- package/dist/esm/bs-menu-item.entry.js +1 -1
- package/dist/esm/bs-menu.entry.js +1 -1
- package/dist/esm/bs-tooltip.entry.js +22 -0
- package/dist/esm/loader.js +1 -1
- package/dist/types/components/bs-ai-thinking/bs-ai-thinking.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-ai-thinking/bs-ai-thinking.d.ts +32 -0
- package/dist/types/components/bs-ai-thinking/bs-ai-thinking.stories.d.ts +10 -0
- package/dist/types/components/bs-ai-thinking/genie-mark-icon.d.ts +1 -0
- package/dist/types/components/bs-chatbot-header/bs-chatbot-header.d.ts +8 -0
- package/dist/types/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.d.ts +46 -0
- package/dist/types/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.stories.d.ts +10 -0
- package/dist/types/components/bs-tooltip/bs-tooltip.cmp.test.d.ts +1 -0
- package/dist/types/components/bs-tooltip/bs-tooltip.d.ts +44 -0
- package/dist/types/components/bs-tooltip/bs-tooltip.stories.d.ts +9 -0
- package/dist/types/components.d.ts +441 -0
- package/package.json +2 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-CVh-sqA_.js');
|
|
4
|
+
|
|
5
|
+
const bsChatbotSuggestionButtonCss = () => `:host{display:inline-block;--bs-chatbot-suggestion-button-radius:var(--bs-border-radius-full);--bs-chatbot-suggestion-button-border-color:var(--bs-border-primary);--bs-chatbot-suggestion-button-bg-default:var(--bs-color-primary-container);--bs-chatbot-suggestion-button-bg-hover:var(--bs-color-primary-container-hover);--bs-chatbot-suggestion-button-bg-pressed:var(--bs-brand-200);--bs-chatbot-suggestion-button-bg-focus:var(--bs-color-primary-container-hover);--bs-chatbot-suggestion-button-text-default:var(--bs-text-action);--bs-chatbot-suggestion-button-text-hover:var(--bs-text-action-hover);--bs-chatbot-suggestion-button-focus-ring-color:var(--bs-border-primary-focus)}.bs-chatbot-suggestion-button{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;height:40px;min-width:80px;padding:var(--bs-spacing-100) var(--bs-spacing-200);border:var(--bs-border-width-thin) solid var(--bs-chatbot-suggestion-button-border-color);border-radius:var(--bs-chatbot-suggestion-button-radius);background:var(--bs-chatbot-suggestion-button-bg-default);color:var(--bs-chatbot-suggestion-button-text-default);font-family:inherit;font-size:var(--bs-font-size-md);line-height:calc(var(--bs-line-height-body-md) * 1px);text-align:center;cursor:pointer;transition:background-color var(--bs-duration-fast) var(--bs-easing-standard)}.bs-chatbot-suggestion-button:hover:not(:disabled){background:var(--bs-chatbot-suggestion-button-bg-hover);color:var(--bs-chatbot-suggestion-button-text-hover)}.bs-chatbot-suggestion-button:active:not(:disabled){background:var(--bs-chatbot-suggestion-button-bg-pressed);color:var(--bs-chatbot-suggestion-button-text-hover)}.bs-chatbot-suggestion-button:focus-visible{background:var(--bs-chatbot-suggestion-button-bg-focus);color:var(--bs-chatbot-suggestion-button-text-hover);outline:var(--bs-border-width-medium) solid var(--bs-chatbot-suggestion-button-focus-ring-color);outline-offset:3px}.bs-chatbot-suggestion-button:disabled{opacity:var(--bs-opacity-disabled);cursor:not-allowed}`;
|
|
6
|
+
|
|
7
|
+
const BsChatbotSuggestionButton = class {
|
|
8
|
+
constructor(hostRef) {
|
|
9
|
+
index.registerInstance(this, hostRef);
|
|
10
|
+
this.bsSelect = index.createEvent(this, "bsSelect");
|
|
11
|
+
}
|
|
12
|
+
/** Disables the button and applies a reduced-opacity treatment. */
|
|
13
|
+
disabled = false;
|
|
14
|
+
/** Fires when the button is clicked. */
|
|
15
|
+
bsSelect;
|
|
16
|
+
onClick = () => {
|
|
17
|
+
this.bsSelect.emit();
|
|
18
|
+
};
|
|
19
|
+
render() {
|
|
20
|
+
return (index.h("button", { key: 'fc87dab75d560ce5f6612c2bf61875d574eddd1f', type: "button", part: "button", class: "bs-chatbot-suggestion-button", disabled: this.disabled, onClick: this.onClick }, index.h("slot", { key: '27ae5b010dcac9ebbb3924c72299cbb5a067ce6b' })));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
BsChatbotSuggestionButton.style = bsChatbotSuggestionButtonCss();
|
|
24
|
+
|
|
25
|
+
exports.bs_chatbot_suggestion_button = BsChatbotSuggestionButton;
|
|
@@ -30,10 +30,10 @@ const BsInput = class {
|
|
|
30
30
|
this.bsChange.emit(value);
|
|
31
31
|
};
|
|
32
32
|
render() {
|
|
33
|
-
return (index.h("div", { key: '
|
|
33
|
+
return (index.h("div", { key: '2c6b38b4594ccde2536515fcd252831bacb6aaeb', class: `bs-input ${this.error ? 'bs-input--error' : ''}` }, this.label && (
|
|
34
34
|
// "control" is a fixed id, not a generated one -- safe because Shadow DOM scopes ids
|
|
35
35
|
// to this instance's own shadow root, so it can never collide with another bs-input.
|
|
36
|
-
index.h("label", { key: '
|
|
36
|
+
index.h("label", { key: '9df0fae013470d8a77b0cc6288c8178b1ac62e0d', part: "label", class: "bs-input__label", htmlFor: "control" }, this.label)), index.h("input", { key: 'a6ddc857d33c4e51a4c64b422a7df5b6261f5180', id: "control", part: "control", class: "bs-input__control", type: this.type, value: this.value, placeholder: this.placeholder, disabled: this.disabled, "aria-describedby": this.error || this.description ? 'description-or-error' : undefined, "aria-invalid": this.error ? 'true' : undefined, onInput: this.onInput, onChange: this.onChange }), this.error ? (index.h("span", { id: "description-or-error", part: "error", class: "bs-input__error" }, this.error)) : this.description ? (index.h("span", { id: "description-or-error", part: "description", class: "bs-input__description" }, this.description)) : null));
|
|
37
37
|
}
|
|
38
38
|
static get delegatesFocus() { return true; }
|
|
39
39
|
};
|
|
@@ -21,7 +21,7 @@ const BsMenuItem = class {
|
|
|
21
21
|
this.bsSelect.emit();
|
|
22
22
|
};
|
|
23
23
|
render() {
|
|
24
|
-
return (index.h("button", { key: '
|
|
24
|
+
return (index.h("button", { key: '6083688b1903b514b0ed6a95a7ee2e64766a94f1', type: "button", part: "item", role: "menuitem", class: "bs-menu-item", onClick: this.onClick }, index.h("span", { key: '65f3df1d22c0e44ed77073de68ce36631b80a31e', part: "icon", class: `bs-menu-item__icon ${this.hasIcon ? 'bs-menu-item__icon--has-content' : ''}` }, index.h("slot", { key: 'a41d500967d857cc5e326194c422992aeab74055', name: "icon", onSlotchange: this.onIconSlotchange })), index.h("span", { key: 'ab17fb6fd7014b7ec74a2eb93de300812a610136', part: "label", class: "bs-menu-item__label" }, index.h("slot", { key: '9b41e86d17fecd71cfe0ff1e5c735aaa143a8d12' }))));
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
27
|
BsMenuItem.style = bsMenuItemCss();
|
|
@@ -9,7 +9,7 @@ const BsMenu = class {
|
|
|
9
9
|
index.registerInstance(this, hostRef);
|
|
10
10
|
}
|
|
11
11
|
render() {
|
|
12
|
-
return (index.h("div", { key: '
|
|
12
|
+
return (index.h("div", { key: 'a48826382a6a13a5047cb893e29fc2f09749b280', part: "list", class: "bs-menu", role: "menu" }, index.h("slot", { key: 'cb4e1eb5988a95f016dc61f698d1c6aadf2d3467' })));
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
15
|
BsMenu.style = bsMenuCss();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-CVh-sqA_.js');
|
|
4
|
+
|
|
5
|
+
const bsTooltipCss = () => `:host{display:inline-block;--bs-tooltip-bg:var(--bs-surface-inverse);--bs-tooltip-color:var(--bs-text-inverse);--bs-tooltip-radius:var(--bs-border-radius-50);--bs-tooltip-padding-x:var(--bs-spacing-200);--bs-tooltip-padding-y:var(--bs-spacing-100);--bs-tooltip-max-width:200px;--bs-tooltip-shadow:-1px 4px 8px rgba(0, 0, 0, 0.08);--bs-tooltip-font-size:var(--bs-font-size-sm);--bs-tooltip-line-height:var(--bs-line-height-body-sm)}.bs-tooltip{position:relative;display:inline-block}.bs-tooltip__bubble{box-sizing:border-box;max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);background:var(--bs-tooltip-bg);color:var(--bs-tooltip-color);border-radius:var(--bs-tooltip-radius);box-shadow:var(--bs-tooltip-shadow);font-family:inherit;font-size:var(--bs-tooltip-font-size);line-height:calc(var(--bs-tooltip-line-height) * 1px)}.bs-tooltip__arrow{position:absolute;top:-6px;left:50%;transform:translateX(-50%);width:8px;height:8px;background:var(--bs-tooltip-bg);clip-path:polygon(50% 0, 0% 100%, 100% 100%)}`;
|
|
6
|
+
|
|
7
|
+
const BsTooltip = class {
|
|
8
|
+
constructor(hostRef) {
|
|
9
|
+
index.registerInstance(this, hostRef);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Which edge of the bubble the arrow points from, and therefore which side of a trigger the
|
|
13
|
+
* bubble should be placed on. `'top'` is the only value implemented -- it is the only variant
|
|
14
|
+
* confirmed from the Figma "EG Tooltip" component (arrow at the top of the bubble, pointing
|
|
15
|
+
* up). Bottom/left/right variants aren't implemented pending further Figma design confirmation.
|
|
16
|
+
*/
|
|
17
|
+
placement = 'top';
|
|
18
|
+
render() {
|
|
19
|
+
return (index.h("div", { key: '784b59f0a817e4756e7954588cd5e42a52508262', class: "bs-tooltip" }, index.h("span", { key: 'b564933fb13a90ab5482c4fde14c99b7431216e5', part: "arrow", class: "bs-tooltip__arrow" }), index.h("div", { key: 'ffb9c4d052d7b8ce618ec825d3989b6311c90c03', part: "bubble", class: "bs-tooltip__bubble" }, index.h("slot", { key: 'cb6cdfe74feb87b23b90da251aa08e76f3bcf0ff' }))));
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
BsTooltip.style = bsTooltipCss();
|
|
23
|
+
|
|
24
|
+
exports.bs_tooltip = BsTooltip;
|
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -5,7 +5,7 @@ var index = require('./index-CVh-sqA_.js');
|
|
|
5
5
|
const defineCustomElements = async (win, options) => {
|
|
6
6
|
if (typeof window === 'undefined') return undefined;
|
|
7
7
|
await index.globalScripts();
|
|
8
|
-
return index.bootstrapLazy([["bs-badge.cjs",[[769,"bs-badge",{"variant":[1]}]]],["bs-button.cjs",[[785,"bs-button",{"variant":[1],"size":[1],"disabled":[4],"type":[1],"ariaLabel":[1,"aria-label"],"hasIcon":[32],"hasEndIcon":[32],"hasLabel":[32]}]]],["bs-button-skeleton.cjs",[[513,"bs-button-skeleton",{"size":[1]}]]],["bs-card.cjs",[[769,"bs-card",{"surface":[1]}]]],["bs-chatbot-
|
|
8
|
+
return index.bootstrapLazy([["bs-chatbot-header.cjs",[[769,"bs-chatbot-header",{"heading":[1],"expanded":[1540]}]]],["bs-ai-thinking.cjs",[[513,"bs-ai-thinking",{"label":[1]}]]],["bs-badge.cjs",[[769,"bs-badge",{"variant":[1]}]]],["bs-button.cjs",[[785,"bs-button",{"variant":[1],"size":[1],"disabled":[4],"type":[1],"ariaLabel":[1,"aria-label"],"hasIcon":[32],"hasEndIcon":[32],"hasLabel":[32]}]]],["bs-button-skeleton.cjs",[[513,"bs-button-skeleton",{"size":[1]}]]],["bs-card.cjs",[[769,"bs-card",{"surface":[1]}]]],["bs-chatbot-response-action.cjs",[[769,"bs-chatbot-response-action",{"sourcesCount":[2,"sources-count"],"menuOpen":[1540,"menu-open"]},[[4,"click","onDocumentClick"],[4,"keydown","onKeydown"]]]]],["bs-chatbot-suggestion-button.cjs",[[769,"bs-chatbot-suggestion-button",{"disabled":[4]}]]],["bs-composer.cjs",[[785,"bs-composer",{"variant":[1],"placeholder":[1],"value":[1],"state":[1],"ariaLabel":[1,"aria-label"]}]]],["bs-data-table.cjs",[[513,"bs-data-table",{"columns":[16],"rows":[16],"sortColumn":[1,"sort-column"],"sortDirection":[1,"sort-direction"],"selectable":[4],"cellRenderer":[16],"selectedIds":[32]}]]],["bs-input.cjs",[[529,"bs-input",{"value":[1],"type":[1],"label":[1],"placeholder":[1],"description":[1],"error":[1],"disabled":[4]}]]],["bs-menu.cjs",[[257,"bs-menu"]]],["bs-menu-item.cjs",[[769,"bs-menu-item",{"hasIcon":[32]}]]],["bs-modal.cjs",[[769,"bs-modal",{"open":[1540],"heading":[1],"size":[1],"hasFooter":[32]},[[4,"keydown","onKeydown"],[4,"focusin","onFocusIn"]]]]],["bs-tooltip.cjs",[[769,"bs-tooltip",{"placement":[1]}]]]], options);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
exports.setNonce = index.setNonce;
|
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
"components/bs-composer/bs-composer.js",
|
|
7
7
|
"components/bs-data-table/bs-data-table.js",
|
|
8
8
|
"components/bs-modal/bs-modal.js",
|
|
9
|
+
"components/bs-ai-thinking/bs-ai-thinking.js",
|
|
9
10
|
"components/bs-button-skeleton/bs-button-skeleton.js",
|
|
10
11
|
"components/bs-chatbot-header/bs-chatbot-header.js",
|
|
11
12
|
"components/bs-chatbot-response-action/bs-chatbot-response-action.js",
|
|
13
|
+
"components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.js",
|
|
12
14
|
"components/bs-input/bs-input.js",
|
|
13
15
|
"components/bs-menu/bs-menu.js",
|
|
14
|
-
"components/bs-menu-item/bs-menu-item.js"
|
|
16
|
+
"components/bs-menu-item/bs-menu-item.js",
|
|
17
|
+
"components/bs-tooltip/bs-tooltip.js"
|
|
15
18
|
],
|
|
16
19
|
"mixins": [],
|
|
17
20
|
"compiler": {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { render, h, describe, it, expect } from "@stencil/vitest";
|
|
2
|
+
describe('bs-ai-thinking', () => {
|
|
3
|
+
it('renders the default label with icon and label parts', async () => {
|
|
4
|
+
const { root } = await render(h("bs-ai-thinking", null));
|
|
5
|
+
expect(root).toHaveTextContent('Thinking');
|
|
6
|
+
const icon = root.shadowRoot.querySelector('[part="icon"]');
|
|
7
|
+
const label = root.shadowRoot.querySelector('[part="label"]');
|
|
8
|
+
expect(icon).not.toBeNull();
|
|
9
|
+
expect(icon.tagName).toBe('IMG');
|
|
10
|
+
expect(label).not.toBeNull();
|
|
11
|
+
});
|
|
12
|
+
it('renders a custom label', async () => {
|
|
13
|
+
const { root } = await render(h("bs-ai-thinking", { label: "Retrieving" }));
|
|
14
|
+
expect(root).toHaveTextContent('Retrieving');
|
|
15
|
+
});
|
|
16
|
+
it('exposes an accessible status region', async () => {
|
|
17
|
+
const { root } = await render(h("bs-ai-thinking", { label: "Searching" }));
|
|
18
|
+
const status = root.shadowRoot.querySelector('[role="status"]');
|
|
19
|
+
expect(status).not.toBeNull();
|
|
20
|
+
expect(status.getAttribute('aria-live')).toBe('polite');
|
|
21
|
+
});
|
|
22
|
+
it('marks the icon as decorative', async () => {
|
|
23
|
+
const { root } = await render(h("bs-ai-thinking", null));
|
|
24
|
+
const icon = root.shadowRoot.querySelector('[part="icon"]');
|
|
25
|
+
expect(icon.getAttribute('alt')).toBe('');
|
|
26
|
+
expect(icon.getAttribute('aria-hidden')).toBe('true');
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
--bs-ai-thinking-gap: var(--bs-spacing-100);
|
|
4
|
+
--bs-ai-thinking-icon-size: 24px;
|
|
5
|
+
--bs-ai-thinking-text: var(--bs-text-muted);
|
|
6
|
+
--bs-ai-thinking-font-size: var(--bs-font-size-md);
|
|
7
|
+
--bs-ai-thinking-line-height: var(--bs-line-height-body-md);
|
|
8
|
+
/* Figma's keyframe track for this label runs over exactly 2s -- no --bs-duration-* token
|
|
9
|
+
* reaches that high (the longest, --bs-duration-slower, is 500ms), so this is aliased directly
|
|
10
|
+
* to the literal value, same precedent as bs-tooltip's --bs-tooltip-shadow. */
|
|
11
|
+
--bs-ai-thinking-cycle-duration: 2s;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.bs-ai-thinking {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
gap: var(--bs-ai-thinking-gap);
|
|
18
|
+
font-family: inherit;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.bs-ai-thinking__icon {
|
|
22
|
+
display: block;
|
|
23
|
+
width: var(--bs-ai-thinking-icon-size);
|
|
24
|
+
height: var(--bs-ai-thinking-icon-size);
|
|
25
|
+
flex-shrink: 0;
|
|
26
|
+
object-fit: contain;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.bs-ai-thinking__label {
|
|
30
|
+
color: var(--bs-ai-thinking-text);
|
|
31
|
+
font-size: var(--bs-ai-thinking-font-size);
|
|
32
|
+
line-height: calc(var(--bs-ai-thinking-line-height) * 1px);
|
|
33
|
+
animation: bs-ai-thinking-pulse var(--bs-ai-thinking-cycle-duration) linear infinite;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Reproduces Figma's exact keyframe track for this node (hold hidden briefly, ease in with the
|
|
37
|
+
* source's own cubic-bezier, hold visible, then reset) -- a breathing pulse, not an invented
|
|
38
|
+
* shimmer sweep. */
|
|
39
|
+
@keyframes bs-ai-thinking-pulse {
|
|
40
|
+
0% {
|
|
41
|
+
opacity: 0;
|
|
42
|
+
}
|
|
43
|
+
8.175% {
|
|
44
|
+
animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
|
|
45
|
+
opacity: 0;
|
|
46
|
+
}
|
|
47
|
+
80.546% {
|
|
48
|
+
opacity: 1;
|
|
49
|
+
}
|
|
50
|
+
100% {
|
|
51
|
+
opacity: 1;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@media (prefers-reduced-motion: reduce) {
|
|
56
|
+
.bs-ai-thinking__label {
|
|
57
|
+
animation: none;
|
|
58
|
+
opacity: 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { h } from "@stencil/core";
|
|
2
|
+
import { GENIE_MARK_ICON } from "./genie-mark-icon";
|
|
3
|
+
/**
|
|
4
|
+
* A small inline status indicator for Genie AI surfaces: the colorful Genie mark next to a label
|
|
5
|
+
* (e.g. "Retrieving", "Thinking", "Searching") whose text pulses in a slow breathing loop while
|
|
6
|
+
* an operation is in progress.
|
|
7
|
+
*
|
|
8
|
+
* ## When to use
|
|
9
|
+
* - Inline in a Genie AI chat transcript to show what the assistant is currently doing while a
|
|
10
|
+
* response is being generated (retrieving context, searching, thinking).
|
|
11
|
+
*
|
|
12
|
+
* ## When not to use
|
|
13
|
+
* - A blocking/full-panel loading state -- this is a small inline indicator, not a spinner overlay.
|
|
14
|
+
*
|
|
15
|
+
* The label's pulse animation reproduces Figma's exact keyframe track (a plain opacity
|
|
16
|
+
* fade-in/hold/reset with the source's own cubic-bezier easing) rather than an invented
|
|
17
|
+
* shimmer-sweep -- the source design only specifies this one animation.
|
|
18
|
+
*
|
|
19
|
+
* @part icon - The Genie mark icon.
|
|
20
|
+
* @part label - The status label text.
|
|
21
|
+
* @prop --bs-ai-thinking-gap - Gap between icon and label. Aliased to `--bs-spacing-100`.
|
|
22
|
+
* @prop --bs-ai-thinking-icon-size - Width/height of the icon.
|
|
23
|
+
* @prop --bs-ai-thinking-text - Label color. Aliased to `--bs-text-muted`.
|
|
24
|
+
* @prop --bs-ai-thinking-font-size - Label font size. Aliased to `--bs-font-size-md`.
|
|
25
|
+
* @prop --bs-ai-thinking-line-height - Label line height. Aliased to `--bs-line-height-body-md`.
|
|
26
|
+
* @prop --bs-ai-thinking-cycle-duration - Duration of one pulse loop. Figma specifies exactly 2s,
|
|
27
|
+
* longer than any `--bs-duration-*` token (max `--bs-duration-slower` is 500ms), so this is
|
|
28
|
+
* aliased directly to the literal value.
|
|
29
|
+
*/
|
|
30
|
+
export class BsAiThinking {
|
|
31
|
+
/** The status text shown next to the icon, e.g. "Retrieving", "Thinking", "Searching". */
|
|
32
|
+
label = 'Thinking';
|
|
33
|
+
render() {
|
|
34
|
+
return (h("div", { key: '5efb57ce1f0d5bcaed2c0ea963566be5f153e983', class: "bs-ai-thinking", role: "status", "aria-live": "polite" }, h("img", { key: '24e00c0d94ad448cd0f9b08f42baf0208e70baa5', part: "icon", class: "bs-ai-thinking__icon", src: GENIE_MARK_ICON, alt: "", "aria-hidden": "true" }), h("span", { key: '8d207d2c9f7752c853fa85991564d4dd0f547b4c', part: "label", class: "bs-ai-thinking__label" }, this.label)));
|
|
35
|
+
}
|
|
36
|
+
static get is() { return "bs-ai-thinking"; }
|
|
37
|
+
static get encapsulation() { return "shadow"; }
|
|
38
|
+
static get originalStyleUrls() {
|
|
39
|
+
return {
|
|
40
|
+
"$": ["bs-ai-thinking.css"]
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
static get styleUrls() {
|
|
44
|
+
return {
|
|
45
|
+
"$": ["bs-ai-thinking.css"]
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
static get properties() {
|
|
49
|
+
return {
|
|
50
|
+
"label": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"mutable": false,
|
|
53
|
+
"complexType": {
|
|
54
|
+
"original": "string",
|
|
55
|
+
"resolved": "string",
|
|
56
|
+
"references": {}
|
|
57
|
+
},
|
|
58
|
+
"required": false,
|
|
59
|
+
"optional": false,
|
|
60
|
+
"docs": {
|
|
61
|
+
"tags": [],
|
|
62
|
+
"text": "The status text shown next to the icon, e.g. \"Retrieving\", \"Thinking\", \"Searching\"."
|
|
63
|
+
},
|
|
64
|
+
"getter": false,
|
|
65
|
+
"setter": false,
|
|
66
|
+
"reflect": false,
|
|
67
|
+
"attribute": "label",
|
|
68
|
+
"defaultValue": "'Thinking'"
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import { componentDescription, propDescription } from "../../stories-utils";
|
|
3
|
+
const meta = {
|
|
4
|
+
title: 'Genie AI Components/bs-ai-thinking',
|
|
5
|
+
parameters: { docs: { description: { component: componentDescription('bs-ai-thinking') } } },
|
|
6
|
+
render: args => html ` <bs-ai-thinking label=${args.label}></bs-ai-thinking> `,
|
|
7
|
+
argTypes: {
|
|
8
|
+
label: { control: 'text', description: propDescription('bs-ai-thinking', 'label') },
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
label: 'Retrieving',
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export default meta;
|
|
15
|
+
export const Default = {};
|
|
16
|
+
export const Thinking = {
|
|
17
|
+
args: { label: 'Thinking' },
|
|
18
|
+
};
|
|
19
|
+
export const Searching = {
|
|
20
|
+
args: { label: 'Searching' },
|
|
21
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Genie brand mark (icon only, no wordmark), exported directly from Figma (node 156:1185,
|
|
2
|
+
// 'Retrieving' -- see bs-ai-thinking.tsx) and inlined as a base64 PNG data URI. This is a
|
|
3
|
+
// raster (not vector) export because the source uses gradient-mesh/image-masked fills that
|
|
4
|
+
// don't reduce to plain SVG paths (same reason bs-chatbot-header's genie-logo.ts embeds its own
|
|
5
|
+
// icon fill as a raster pattern) -- rendering it as a real exported image is required by the
|
|
6
|
+
// design-fidelity rule (never redraw a multi-color gradient mark as flat CSS shapes).
|
|
7
|
+
//
|
|
8
|
+
// Figma's own PNG export came back with an opaque white background baked in (the canvas instance
|
|
9
|
+
// sits on a white container frame), which showed as a visible white square in dark mode. The
|
|
10
|
+
// background was removed by de-matting against that known white backdrop (recovering true alpha
|
|
11
|
+
// + unpremultiplied color per pixel, not a flat white-key which leaves halos on the antialiased
|
|
12
|
+
// edges) before encoding -- see git history for the one-off script if this asset is ever
|
|
13
|
+
// re-exported from a design update.
|
|
14
|
+
export const GENIE_MARK_ICON = 'data:image/png;base64,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';
|
|
@@ -25,7 +25,7 @@ export class BsButtonSkeleton {
|
|
|
25
25
|
/** Sizing scale, matching the `bs-button` size it stands in for. */
|
|
26
26
|
size = 'md';
|
|
27
27
|
render() {
|
|
28
|
-
return h("span", { key: '
|
|
28
|
+
return h("span", { key: '34febfe9aa1e20130b62b7884e766cd5285848d7', part: "container", class: `bs-button-skeleton bs-button-skeleton--${this.size}`, role: "status", "aria-label": "Loading" });
|
|
29
29
|
}
|
|
30
30
|
static get is() { return "bs-button-skeleton"; }
|
|
31
31
|
static get encapsulation() { return "shadow"; }
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
--bs-chatbot-header-padding-bottom: var(--bs-spacing-100);
|
|
7
7
|
--bs-chatbot-header-padding-x: var(--bs-margin-fluid);
|
|
8
8
|
--bs-chatbot-header-gap: var(--bs-navigation-header-gap);
|
|
9
|
+
--bs-chatbot-header-actions-gap: var(--bs-spacing-100);
|
|
9
10
|
--bs-chatbot-header-button-size: var(--bs-spacing-600);
|
|
10
11
|
--bs-chatbot-header-button-radius: var(--bs-border-radius-100);
|
|
11
12
|
--bs-chatbot-header-button-hover: var(--bs-color-neutral-container);
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
.bs-chatbot-header__actions {
|
|
42
43
|
display: flex;
|
|
43
44
|
align-items: center;
|
|
45
|
+
gap: var(--bs-chatbot-header-actions-gap);
|
|
44
46
|
flex-shrink: 0;
|
|
45
47
|
}
|
|
46
48
|
|
|
@@ -79,3 +81,34 @@
|
|
|
79
81
|
.bs-chatbot-header__button:active {
|
|
80
82
|
background: var(--bs-chatbot-header-button-pressed);
|
|
81
83
|
}
|
|
84
|
+
|
|
85
|
+
.bs-chatbot-header__tooltip-wrapper {
|
|
86
|
+
position: relative;
|
|
87
|
+
display: inline-flex;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.bs-chatbot-header__tooltip {
|
|
91
|
+
position: absolute;
|
|
92
|
+
top: 100%;
|
|
93
|
+
left: 50%;
|
|
94
|
+
transform: translateX(-50%);
|
|
95
|
+
margin-top: var(--bs-spacing-100);
|
|
96
|
+
opacity: 0;
|
|
97
|
+
visibility: hidden;
|
|
98
|
+
pointer-events: none;
|
|
99
|
+
/* Hides immediately (no delay) but waits --bs-duration-slow before showing, so the tooltip
|
|
100
|
+
* doesn't flash in on every incidental pointer pass-over -- standard tooltip UX, and this
|
|
101
|
+
* duration token already collapses to 0ms under prefers-reduced-motion (see tokens.css), so
|
|
102
|
+
* no separate reduced-motion handling is needed here. */
|
|
103
|
+
transition: opacity var(--bs-duration-fast) var(--bs-easing-standard);
|
|
104
|
+
transition-delay: 0s;
|
|
105
|
+
white-space: nowrap;
|
|
106
|
+
z-index: 1;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.bs-chatbot-header__tooltip-wrapper:hover .bs-chatbot-header__tooltip,
|
|
110
|
+
.bs-chatbot-header__tooltip-wrapper:focus-within .bs-chatbot-header__tooltip {
|
|
111
|
+
opacity: 1;
|
|
112
|
+
visibility: visible;
|
|
113
|
+
transition-delay: var(--bs-duration-slow);
|
|
114
|
+
}
|
|
@@ -11,6 +11,13 @@ import { GENIE_LOGO_SVG } from "./genie-logo";
|
|
|
11
11
|
* - A generic app/page header — this component's layout and actions are purpose-built for the
|
|
12
12
|
* Genie chat panel, not a general navigation bar.
|
|
13
13
|
*
|
|
14
|
+
* Each action button shows a `bs-tooltip` (placement="top", i.e. positioned below the button with
|
|
15
|
+
* its arrow pointing up toward it -- fits naturally since this header sits at the top of a panel)
|
|
16
|
+
* on hover/focus, driven by plain CSS (`:hover`/`:focus-within` on a wrapper, no extra JS state).
|
|
17
|
+
* The tooltip is `aria-hidden` since it's a purely visual reinforcement of each button's existing
|
|
18
|
+
* `aria-label` -- screen readers already get the accessible name from the button itself, so the
|
|
19
|
+
* tooltip doesn't need to be (and shouldn't be) announced a second time.
|
|
20
|
+
*
|
|
14
21
|
* @slot new-chat-icon - Overrides the default "New chat" button icon.
|
|
15
22
|
* @slot history-icon - Overrides the default "History" button icon.
|
|
16
23
|
* @slot expand-icon - Overrides the default "Expand"/"Collapse" button icon (rendered regardless of `expanded` -- there is no separate confirmed "collapsed" glyph in the design, so swap it yourself via this slot if you need one).
|
|
@@ -26,6 +33,7 @@ import { GENIE_LOGO_SVG } from "./genie-logo";
|
|
|
26
33
|
* @prop --bs-chatbot-header-padding-bottom - Aliased to `--bs-spacing-100`.
|
|
27
34
|
* @prop --bs-chatbot-header-padding-x - Aliased to `--bs-margin-fluid`.
|
|
28
35
|
* @prop --bs-chatbot-header-gap - Gap between the logo and the button group. Aliased to `--bs-navigation-header-gap`.
|
|
36
|
+
* @prop --bs-chatbot-header-actions-gap - Gap between the individual action buttons. Aliased to `--bs-spacing-100`.
|
|
29
37
|
* @prop --bs-chatbot-header-button-size - Width/height of each icon button. Aliased to `--bs-spacing-600`.
|
|
30
38
|
* @prop --bs-chatbot-header-button-radius - Corner radius of each icon button. Aliased to `--bs-border-radius-100`.
|
|
31
39
|
* @prop --bs-chatbot-header-button-hover - Icon button background on hover. Aliased to `--bs-color-neutral-container`.
|
|
@@ -66,7 +74,7 @@ export class BsChatbotHeader {
|
|
|
66
74
|
this.bsClose.emit();
|
|
67
75
|
};
|
|
68
76
|
render() {
|
|
69
|
-
return (h("div", { key: '
|
|
77
|
+
return (h("div", { key: '9ae798e8d79c992933228383823d3160dc660f90', class: "bs-chatbot-header", role: "banner", "aria-label": this.heading }, h("div", { key: 'c80243df90e7ed74cea0679b94c139fc6bba8cc5', part: "logo", class: "bs-chatbot-header__logo", role: "img", "aria-label": this.heading, innerHTML: GENIE_LOGO_SVG }), h("div", { key: 'ebcfc959d4d7c606866870f1f107c4fc771d25b1', class: "bs-chatbot-header__actions" }, h("span", { key: '153e84f8e63faf67c180338da94e86d2b28da945', class: "bs-chatbot-header__tooltip-wrapper" }, h("button", { key: '76b48c5dcaf482dfbafacf8125a5c2908bbc27c3', type: "button", part: "new-chat", class: "bs-chatbot-header__button", "aria-label": "New chat", onClick: this.onNewChatClick }, h("slot", { key: 'b09177f97df5a1ddb20374d260858f0ae3afea12', name: "new-chat-icon" }, h(NewChatIcon, { key: 'a1907a4fd8730c83af15ad7dbf8ec1d784fac88d' }))), h("bs-tooltip", { key: '77b453884b760bf4687b26adbb06f6220c49dbca', class: "bs-chatbot-header__tooltip", placement: "top", "aria-hidden": "true" }, "New chat")), h("span", { key: '8b775f74bd28efa4b812f959658cae97ffce085f', class: "bs-chatbot-header__tooltip-wrapper" }, h("button", { key: '1a8c279aa94175b2d90654aa4d3c959273147a7c', type: "button", part: "history", class: "bs-chatbot-header__button", "aria-label": "History", onClick: this.onHistoryClick }, h("slot", { key: '8660d04481d3d846731e83b23c865e2bab1cbea7', name: "history-icon" }, h(HistoryIcon, { key: 'a34ed34be60fbc2869b34480342007aa59700177' }))), h("bs-tooltip", { key: '7ba408053f7b0e88330720d3dff4f188f233f46a', class: "bs-chatbot-header__tooltip", placement: "top", "aria-hidden": "true" }, "History")), h("span", { key: '4b4d24319a9b5b2085c8180748f72bfcc532a942', class: "bs-chatbot-header__tooltip-wrapper" }, h("button", { key: 'b9055bd0344465df6afb40aad28ea9565865751e', type: "button", part: "expand", class: "bs-chatbot-header__button", "aria-label": this.expanded ? 'Collapse' : 'Expand', "aria-pressed": this.expanded ? 'true' : 'false', onClick: this.onExpandClick }, h("slot", { key: '460b3c1d20f2a48945df6385e3ebf7f54577881e', name: "expand-icon" }, h(ExpandIcon, { key: '890b772fff27703a7d3da00ff4ad5f2844714075' }))), h("bs-tooltip", { key: 'b43756a31171e14b70bc80574741b28b4dad2c98', class: "bs-chatbot-header__tooltip", placement: "top", "aria-hidden": "true" }, this.expanded ? 'Collapse' : 'Expand')), h("span", { key: '2023c06216607d6205ec3a0a13d2b06a10babae5', class: "bs-chatbot-header__tooltip-wrapper" }, h("button", { key: '1bdc7a342af4b6b37121edb9a93c30ba659d95bf', type: "button", part: "close", class: "bs-chatbot-header__button", "aria-label": "Close", onClick: this.onCloseClick }, h("slot", { key: '1c47b5499cf15ca73aa8a9dab792bf72c441ff38', name: "close-icon" }, h(CloseIcon, { key: '2ce1bad2bca776187e238647c02e3cc4b68018de' }))), h("bs-tooltip", { key: 'd7a3016e6eab564ab0cd9f5ab1d79be2b6408c17', class: "bs-chatbot-header__tooltip", placement: "top", "aria-hidden": "true" }, "Close")))));
|
|
70
78
|
}
|
|
71
79
|
static get is() { return "bs-chatbot-header"; }
|
|
72
80
|
static get encapsulation() { return "shadow"; }
|
|
@@ -105,7 +105,7 @@ export class BsChatbotResponseAction {
|
|
|
105
105
|
};
|
|
106
106
|
render() {
|
|
107
107
|
const hasSources = !!this.sourcesCount && this.sourcesCount > 0;
|
|
108
|
-
return (h("div", { key: '
|
|
108
|
+
return (h("div", { key: 'd372000276bedcf0bd64015d955a4ed4ff1c83cc', class: "bs-chatbot-response-action" }, h("button", { key: '6fff591650e4f6114a653ff37bfebe100d4874b7', type: "button", part: "like", class: "bs-chatbot-response-action__button", "aria-label": "Like", onClick: this.onLikeClick }, h("slot", { key: 'e92d29243291141fd63120b4bc6a5024f1908066', name: "like-icon" }, h(ThumbsUpIcon, { key: 'd1a7e8d922f5e712e48e19c6176fdb60ac511240' }))), h("button", { key: '7115ff6c49c5388440f0fe8a352ddd4459a5f8ed', type: "button", part: "dislike", class: "bs-chatbot-response-action__button", "aria-label": "Dislike", onClick: this.onDislikeClick }, h("slot", { key: 'd3642d52b90cbd3f6c60d8b8ead3d14fab29f531', name: "dislike-icon" }, h(ThumbsDownIcon, { key: '8cff196faabd164cf023bfa8bac02f3455885261' }))), h("button", { key: 'd32e2ebce71ab91327d7ad7406ae581b2ff98443', type: "button", part: "copy", class: "bs-chatbot-response-action__button", "aria-label": "Copy", onClick: this.onCopyClick }, h("slot", { key: '1c0459f9fb78202d41e5bf7b3bf5a11ac9c00ecd', name: "copy-icon" }, h(CopyIcon, { key: 'b3d8e9f3cb2125c26967156f046ce3caf44ab8b1' }))), h("button", { key: 'c14f8a2580018edac6b16c82be5b339c7a4033af', type: "button", part: "regenerate", class: "bs-chatbot-response-action__button", "aria-label": "Regenerate", onClick: this.onRegenerateClick }, h("slot", { key: 'cf67332b681da43a7a305909e14a16bf6a3ca962', name: "regenerate-icon" }, h(RegenerateIcon, { key: '76b5b9c39624007532b2c2b7f20554f12cd8eee4' }))), h("div", { key: 'b62694c42bf23484362e188b6b74559810fce693', class: "bs-chatbot-response-action__menu-wrapper" }, h("button", { key: '36715b97f529bfc9c064020d434d0210a3674e52', type: "button", part: "menu", class: "bs-chatbot-response-action__button", "aria-label": "More options", "aria-haspopup": "menu", "aria-expanded": this.menuOpen ? 'true' : 'false', onClick: this.onMenuClick }, h("slot", { key: 'f11d837af777a04cc9031921f92b57e139758f2c', name: "menu-icon" }, h(MenuIcon, { key: '3c0c0a70edcf1e8c817a121fce315b8a747ee8e4' }))), this.menuOpen && (h("div", { key: '5a4848466caecf26ce3797b14609932e76ca653d', class: "bs-chatbot-response-action__menu-popup" }, h("slot", { key: 'f79ac9bcde08eadd0a904223f6f13c9850066827', name: "menu" })))), hasSources && (h("button", { key: 'ef9663bbbb7f74482743177bdfa8053575c3330e', type: "button", part: "sources", class: "bs-chatbot-response-action__sources", onClick: this.onSourcesClick }, h("slot", { key: 'f848fd2b5e545d186a7f337c2d0fe0f300c567f7', name: "sources-icon" }, h(SourcesIcon, { key: '7a8be099bcf97209b30c1b941b1f13691d9c07d3' })), h("span", { key: 'e91be28b3d36b1cc3a91c17218ca5ea77938f887', class: "bs-chatbot-response-action__sources-label" }, this.sourcesCount, " ", this.sourcesCount === 1 ? 'source' : 'sources')))));
|
|
109
109
|
}
|
|
110
110
|
static get is() { return "bs-chatbot-response-action"; }
|
|
111
111
|
static get encapsulation() { return "shadow"; }
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { render, h, describe, it, expect } from "@stencil/vitest";
|
|
2
|
+
describe('bs-chatbot-suggestion-button', () => {
|
|
3
|
+
it('renders the default slot label content and the button part', async () => {
|
|
4
|
+
const { root } = await render(h("bs-chatbot-suggestion-button", null, "How can I help you?"));
|
|
5
|
+
expect(root).toHaveTextContent('How can I help you?');
|
|
6
|
+
const button = root.shadowRoot.querySelector('[part="button"]');
|
|
7
|
+
expect(button).not.toBeNull();
|
|
8
|
+
expect(button.tagName).toBe('BUTTON');
|
|
9
|
+
});
|
|
10
|
+
it('emits bsSelect exactly once on a normal click', async () => {
|
|
11
|
+
const { root, spyOnEvent } = await render(h("bs-chatbot-suggestion-button", null, "Suggestion"));
|
|
12
|
+
const selectSpy = spyOnEvent('bsSelect');
|
|
13
|
+
root.shadowRoot.querySelector('[part="button"]').click();
|
|
14
|
+
expect(selectSpy).toHaveReceivedEventTimes(1);
|
|
15
|
+
});
|
|
16
|
+
it('applies the native disabled attribute and does not fire bsSelect on click when disabled', async () => {
|
|
17
|
+
const { root, spyOnEvent } = await render(h("bs-chatbot-suggestion-button", { disabled: true }, "Suggestion"));
|
|
18
|
+
const selectSpy = spyOnEvent('bsSelect');
|
|
19
|
+
const button = root.shadowRoot.querySelector('[part="button"]');
|
|
20
|
+
expect(button.disabled).toBe(true);
|
|
21
|
+
button.click();
|
|
22
|
+
expect(selectSpy.length).toBe(0);
|
|
23
|
+
});
|
|
24
|
+
});
|
package/dist/collection/components/bs-chatbot-suggestion-button/bs-chatbot-suggestion-button.css
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-block;
|
|
3
|
+
--bs-chatbot-suggestion-button-radius: var(--bs-border-radius-full);
|
|
4
|
+
--bs-chatbot-suggestion-button-border-color: var(--bs-border-primary);
|
|
5
|
+
--bs-chatbot-suggestion-button-bg-default: var(--bs-color-primary-container);
|
|
6
|
+
--bs-chatbot-suggestion-button-bg-hover: var(--bs-color-primary-container-hover);
|
|
7
|
+
/* No pre-built semantic "container-pressed" token matches this tonal button's lighter pressed
|
|
8
|
+
* shade progression (50 -> 100 -> 200) -- alias the primitive directly, same precedent
|
|
9
|
+
* documented in bs-button.css for its subtle/outlined/success/warning/info variants. */
|
|
10
|
+
--bs-chatbot-suggestion-button-bg-pressed: var(--bs-brand-200);
|
|
11
|
+
--bs-chatbot-suggestion-button-bg-focus: var(--bs-color-primary-container-hover);
|
|
12
|
+
--bs-chatbot-suggestion-button-text-default: var(--bs-text-action);
|
|
13
|
+
--bs-chatbot-suggestion-button-text-hover: var(--bs-text-action-hover);
|
|
14
|
+
--bs-chatbot-suggestion-button-focus-ring-color: var(--bs-border-primary-focus);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.bs-chatbot-suggestion-button {
|
|
18
|
+
box-sizing: border-box;
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
height: 40px;
|
|
23
|
+
min-width: 80px;
|
|
24
|
+
padding: var(--bs-spacing-100) var(--bs-spacing-200);
|
|
25
|
+
border: var(--bs-border-width-thin) solid var(--bs-chatbot-suggestion-button-border-color);
|
|
26
|
+
border-radius: var(--bs-chatbot-suggestion-button-radius);
|
|
27
|
+
background: var(--bs-chatbot-suggestion-button-bg-default);
|
|
28
|
+
color: var(--bs-chatbot-suggestion-button-text-default);
|
|
29
|
+
font-family: inherit;
|
|
30
|
+
font-size: var(--bs-font-size-md);
|
|
31
|
+
line-height: calc(var(--bs-line-height-body-md) * 1px);
|
|
32
|
+
text-align: center;
|
|
33
|
+
cursor: pointer;
|
|
34
|
+
transition: background-color var(--bs-duration-fast) var(--bs-easing-standard);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.bs-chatbot-suggestion-button:hover:not(:disabled) {
|
|
38
|
+
background: var(--bs-chatbot-suggestion-button-bg-hover);
|
|
39
|
+
color: var(--bs-chatbot-suggestion-button-text-hover);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.bs-chatbot-suggestion-button:active:not(:disabled) {
|
|
43
|
+
background: var(--bs-chatbot-suggestion-button-bg-pressed);
|
|
44
|
+
color: var(--bs-chatbot-suggestion-button-text-hover);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.bs-chatbot-suggestion-button:focus-visible {
|
|
48
|
+
background: var(--bs-chatbot-suggestion-button-bg-focus);
|
|
49
|
+
color: var(--bs-chatbot-suggestion-button-text-hover);
|
|
50
|
+
outline: var(--bs-border-width-medium) solid var(--bs-chatbot-suggestion-button-focus-ring-color);
|
|
51
|
+
outline-offset: 3px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.bs-chatbot-suggestion-button:disabled {
|
|
55
|
+
opacity: var(--bs-opacity-disabled);
|
|
56
|
+
cursor: not-allowed;
|
|
57
|
+
}
|