From 7b6b5936fcebe095826163c713fae449796d99b9 Mon Sep 17 00:00:00 2001 From: loookashow Date: Mon, 27 Jul 2026 18:31:31 +0200 Subject: [PATCH] fix(core): hide ask affordance in plain search mode --- .changeset/plain-mode-hides-ask.md | 11 ++++++++ packages/core/custom-elements.json | 4 +-- .../core/loquix-search-dialog.test.ts | 26 +++++++++++++++++++ .../core/loquix-search-input.test.ts | 13 ++++++++++ .../components/core/loquix-search-input.ts | 5 +++- .../core/loquix-search-panel.test.ts | 24 +++++++++++++++++ 6 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 .changeset/plain-mode-hides-ask.md diff --git a/.changeset/plain-mode-hides-ask.md b/.changeset/plain-mode-hides-ask.md new file mode 100644 index 0000000..2ef590e --- /dev/null +++ b/.changeset/plain-mode-hides-ask.md @@ -0,0 +1,11 @@ +--- +'@loquix/core': patch +--- + +Fix `loquix-search-input` rendering the "Ask AI" button in `mode="plain"`. + +`show-ask-affordance` used to win over `mode`, so the plain-mode surfaces of +`loquix-search-dialog` and `loquix-search-panel` — which both set the attribute +on their inner input unconditionally — still showed the button, and clicking it +dispatched a `loquix-search-ask` event the host never opted into. Plain mode now +suppresses the affordance regardless of `show-ask-affordance`. diff --git a/packages/core/custom-elements.json b/packages/core/custom-elements.json index 6ad47a6..b2e294b 100644 --- a/packages/core/custom-elements.json +++ b/packages/core/custom-elements.json @@ -12567,7 +12567,7 @@ "text": "boolean" }, "default": "false", - "description": "Force the smart affordance to be visible.", + "description": "Force the smart affordance to be visible. Ignored when `mode` is `plain`.", "attribute": "show-ask-affordance" }, { @@ -12800,7 +12800,7 @@ "text": "boolean" }, "default": "false", - "description": "Force the smart affordance to be visible.", + "description": "Force the smart affordance to be visible. Ignored when `mode` is `plain`.", "fieldName": "showAskAffordance" }, { diff --git a/packages/core/src/components/core/loquix-search-dialog.test.ts b/packages/core/src/components/core/loquix-search-dialog.test.ts index 338d5c2..c618fa4 100644 --- a/packages/core/src/components/core/loquix-search-dialog.test.ts +++ b/packages/core/src/components/core/loquix-search-dialog.test.ts @@ -1,4 +1,5 @@ import { expect, fixture, html } from '@open-wc/testing'; +import type { LitElement } from 'lit'; import { waitForEvent } from '../../test-utils.js'; import './define-search-dialog.js'; import type { LoquixSearchDialog } from './loquix-search-dialog.js'; @@ -310,6 +311,31 @@ describe('loquix-search-dialog', () => { expect(answer.getAttribute('state')).to.equal('generating'); }); + it('shows the Ask AI affordance on the dialog input by default', async () => { + const el = await fixture( + html``, + ); + await el.updateComplete; + + const dialogInput = el.shadowRoot!.querySelector('.dialog-input') as LitElement; + await dialogInput.updateComplete; + + expect(dialogInput.shadowRoot!.querySelector('[part~="ask-button"]')).to.exist; + }); + + it('does not show the Ask AI affordance on the dialog input in plain mode', async () => { + const el = await fixture( + html``, + ); + await el.updateComplete; + + const dialogInput = el.shadowRoot!.querySelector('.dialog-input') as LitElement; + await dialogInput.updateComplete; + + const ask = dialogInput.shadowRoot!.querySelector('[part~="ask-button"]'); + expect(ask === null, 'ask button must not render in plain mode').to.be.true; + }); + it('syncs value from the dialog input change event', async () => { const el = await fixture( html``, diff --git a/packages/core/src/components/core/loquix-search-input.test.ts b/packages/core/src/components/core/loquix-search-input.test.ts index d32cbee..1e28c41 100644 --- a/packages/core/src/components/core/loquix-search-input.test.ts +++ b/packages/core/src/components/core/loquix-search-input.test.ts @@ -78,6 +78,19 @@ describe('loquix-search-input', () => { expect(ask!.querySelector('svg')).to.equal(null); }); + it('does not show Ask AI affordance in plain mode even when forced', async () => { + const el = await fixture( + html``, + ); + await el.updateComplete; + const ask = getShadowPart(el, 'ask-button'); + expect(ask === null, 'ask button must not render in plain mode').to.be.true; + }); + it('hides inline kbd when Ask AI affordance is visible by default', async () => { const el = await fixture( html` { expect(answer.getAttribute('state')).to.equal('generating'); }); + it('shows the Ask AI affordance on the inline input by default', async () => { + const el = await fixture(html``); + await el.updateComplete; + + const input = el.shadowRoot!.querySelector('loquix-search-input[part="input"]') as LitElement; + await input.updateComplete; + + expect(input.shadowRoot!.querySelector('[part~="ask-button"]')).to.exist; + }); + + it('does not show the Ask AI affordance on the inline input in plain mode', async () => { + const el = await fixture( + html``, + ); + await el.updateComplete; + + const input = el.shadowRoot!.querySelector('loquix-search-input[part="input"]') as LitElement; + await input.updateComplete; + + const ask = input.shadowRoot!.querySelector('[part~="ask-button"]'); + expect(ask === null, 'ask button must not render in plain mode').to.be.true; + }); + it('syncs value from the input change event', async () => { const el = await fixture( html``,