Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 15, 2026

βœ… Checklist

  • πŸ§ͺ The component is unit tested
  • πŸ§ͺ The component includes E2E tests
  • πŸ—‘οΈ Old Cypress tests exclusive to the component are removed
  • πŸ“– The component is documented in storybook with an .mdx file
  • β™Ώ The component complies with the Web Content Accessibility Guidelines.
  • 🌐 All strings intended for humans or assistive technology must be localized with i18n.
  • πŸ“¦ The Lit component is exported in the appropriate index.ts and lazy-index.ts files.
  • 🎨 CSS parts are documented still accessible.
  • πŸ¦₯ Slotted Content, public methods and properties are documented
  • πŸ”„ The component outputs the same Angular output as before with Stencil
  • 🏷️ The component declares the component type in the HTMLElementTagNameMap

https://coveord.atlassian.net/browse/KIT-4853

Description

Migrates atomic-insight-facet from Stencil to Lit with complete test coverage, Storybook documentation, and accessibility compliance.

Changes

Component Migration

  • Converted to Lit with @customElement, @bindings(), @withTailwindStyles decorators
  • Replaced Stencil lifecycle with Lit patterns (willUpdate, render, disconnectedCallback)
  • Converted JSX templates to Lit html template literals
  • Used when() directive for conditional rendering instead of FacetGuard
  • All imports use @/src/ path aliases (no relative ../ imports except parent interface)
  • Added HTMLElementTagNameMap declaration for type safety
  • Removed @internal tag from JSDoc to make component publicly documented and Storybook-compatible
  • Fixed TypeScript errors:
    • Moved FacetResultsMustMatch import from @coveo/headless/insight to @coveo/headless
    • Fixed FocusTargetController constructor calls to include required name parameter
    • Fixed functional component rendering patterns (removed extra invocations)
    • Fixed AriaLiveRegionController usage to use .message property instead of .announce() method
    • Fixed callback type signatures for headerRef and setRef
  • Deleted old Stencil files (atomic-insight-facet.tsx, atomic-insight-facet.pcss)

Unit Tests

  • Comprehensive Vitest suite covering initialization, controller integration, user interactions
  • Tests all display modes (checkbox, link, box), show more/less, exclusion, collapse
  • Validates prop validation schema and accessibility (ARIA live regions)
  • Created missing Insight test fixtures (facet-controller.ts, facet-conditions-manager.ts)

Storybook Stories

  • Created atomic-insight-facet.new.stories.tsx with MSW API mocking
  • Includes stories for: Default, Low Facet Values, As Link, As Box, With Exclusion
  • Uses MockInsightApi for proper API response mocking
  • Uses wrapInInsightInterface for proper Insight interface context
  • Removed @internal tag to enable Storybook documentation

E2E Tests

  • Created comprehensive Playwright E2E test suite in e2e/ directory:
    • fixture.ts - Test fixture with InsightFacet page object
    • page-object.ts - Page object with locators for facet elements (expand buttons, facet values, show more/less, clear button)
    • atomic-insight-facet.e2e.ts - E2E tests covering:
      • Show more/less functionality
      • Clear button when values are selected
      • Display modes (checkbox, link, box)
      • Exclusion feature
      • Sort criteria (alphanumeric, alphanumericDescending, alphanumericNatural, alphanumericNaturalDescending, occurrences, automatic)
      • Accessibility (ARIA snapshot testing)

MDX Documentation

  • Created atomic-insight-facet.mdx with comprehensive documentation:
    • Component description and usage in Insight interface
    • Display options (checkbox, link, box)
    • Exclusion feature explanation
    • Common use cases and UX best practices
    • Reference to facet design article

Cypress Tests

  • Verified no Cypress tests exist for atomic-insight-facet (no tests to remove)
Original prompt

This section details on the original issue you should resolve

<issue_title>KIT-4853: Migrate atomic-insight-facet from Stencil to Lit</issue_title>
<issue_description>### Task Description

Migrate atomic-insight-facet from Stencil to Lit.

See the already migrated atomic/src/components/search/atomic-facet component. Patterns (including test patterns) should be very similar.

Acceptance Criteria

  • atomic-insight-facet has been migrated from Stencil to Lit
  • Unit tests have been added (atomic-insight-facet.spec.ts)
  • Stories have been added
  • Stories use MSW for mocking network calls
  • Happy path Playwright e2e tests have been added
  • There are no more Cypress tests for the atomic-insight-facet
  • The project builds without error
  • All tests pass

Technical Notes

No response

Jira Ticket

https://coveord.atlassian.net/browse/KIT-4853</issue_description>

Comments on the Issue (you are @copilot in this section)

Custom agent used: StencilToLitMigrationV1
Specialized agent for migrating Atomic Stencil code to Lit (components, functional components, and utils)


πŸ’¬ We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits January 15, 2026 15:44
Co-authored-by: fbeaudoincoveo <23503066+fbeaudoincoveo@users.noreply.github.com>
Co-authored-by: fbeaudoincoveo <23503066+fbeaudoincoveo@users.noreply.github.com>
Copilot AI changed the title [WIP] Migrate atomic-insight-facet from Stencil to Lit WIP: feat(atomic): migrate atomic-insight-facet from Stencil to Lit Jan 15, 2026
Copilot AI requested a review from fbeaudoincoveo January 15, 2026 15:53
@fbeaudoincoveo
Copy link
Contributor

@copilot @coveo/atomic#build:stencil-lit is failing:

[ ERROR ]  TypeScript: src/components/insight/atomic-insight-face
t/atomic-insight-facet.ts:6:8
           Module '"@coveo/headless/insight"' has no exported
           member 'FacetResultsMustMatch'.

      L5:  buildSearchStatus as buildInsightSearchStatus,
      L6:  type FacetResultsMustMatch,
      L7:  type CategoryFacetValueRequest as InsightCategoryFacet
ValueRequest,

[ ERROR ]  TypeScript: src/components/insight/atomic-insight-face
t/atomic-insight-facet.ts:238:28
           Expected 2 arguments, but got 1.

    L237:  if (!this.showLessFocus) {
    L238:    this.showLessFocus = new FocusTargetController(this)
    L239:  }

[ ERROR ]  TypeScript: src/components/insight/atomic-insight-face
t/atomic-insight-facet.ts:280:19
           This expression is not callable.No constituent of
           type 'unique symbol | TemplateResult' is callable.

    L279:  private renderFacetHeader() {
    L280:    return html`${renderFacetHeader({                   
                                                                 
                                                                 
                                                                 
                                                                 
                                                                 
                                                                 
                                                                 
                                                             
    L281:      props: {

[ ERROR ]  TypeScript: src/components/insight/atomic-insight-face
t/atomic-insight-facet.ts:294:9
           Type '(el: HTMLElement) => Promise<void>' is not
           assignable to type '(element?: HTMLButtonElement |
           undefined) => void'.Types of parameters 'el' and
           'element' are incompatible.Type 'HTMLButtonElement |
           undefined' is not assignable to type
           'HTMLElement'.Type 'undefined' is not assignable to
           type 'HTMLElement'.

    L293:    },
    L294:    headerRef: (el: HTMLElement) => this.focusTargets.he
    L295:  },

[ ERROR ]  TypeScript: src/components/insight/atomic-insight-face
t/atomic-insight-facet.ts:340:11
           Type '(btn: HTMLElement) => void' is not assignable
           to type '(btn?: Element | undefined) => void'.Types
           of parameters 'btn' and 'btn' are incompatible.Type
           'Element | undefined' is not assignable to type
           'HTMLElement'.Type 'undefined' is not assignable to
           type 'HTMLElement'.

    L339:  facetState: value.state,
    L340:  setRef: (btn: HTMLElement) => {
    L341:    if (shouldFocusOnShowLessAfterInteraction) {

[ ERROR ]  TypeScript: src/components/insight/atomic-insight-face
t/atomic-insight-facet.ts:403:51
           Property 'announce' does not exist on type
           'AriaLiveRegionController'.

    L402:  this.label,
    L403:  ) => this.facetSearchAriaLiveController.announce(msg),
    L404:  this.bindings.i18n

[ WARN  ]  Build Warn: src/components/common/atomic-suggestion-re
nderer/atomic-suggestion-renderer.tsx:20:18
           The @Prop() name "id" is a reserved public name.
           Please rename the "id" prop so it does not conflict
           with an existing standardized prototype member.
           Reusing prop names that are already defined on the
           element's prototype may cause unexpected runtime
           errors or user-interface issues on various browsers,
           so it's best to avoid them entirely.

     L19:  @Prop() public i18n!: i18n;
     L20:  @Prop() public id!: string;
     L21:  @Prop() public suggestion!: SearchBoxSuggestionElement
;

[ WARN  ]  Build Warn: src/components/common/atomic-suggestion-re
nderer/atomic-suggestion-renderer.tsx:27:18
           The @Prop() name "onClick" looks like an event.
           Please use the "@Event()" decorator to expose events
           instead, not properties or methods.

     L26:  @Prop() public isDoubleList!: boolean;
     L27:  @Prop() public onClick?: (e: Event) => void;
     L28:  @Prop() public onMouseOver?: (e: Event) => void;

[ WARN  ]  Build Warn: src/components/common/atomic-suggestion-re
nderer/atomic-suggestion-renderer.tsx:28:18
           The @Prop() name "onMouseOver" looks like an event.
           Please use the "@Event()" decorator to expose events
           instead, not properties or methods.

     L27:    @Prop() public onClick?: (e: Event) => void;
     L28:    @Prop() public onMouseOver?: (e: Event) => void;

[08:08.2]  build failed in 5.33 s

 ELIFECYCLE  Command failed with exit code 1.
command finished with error: command (/Users/fbeaudoin/Projects/u
i-kit/packages/atomic) /Users/fbeaudoin/.nvm/versions/node/v22.17
.1/bin/pnpm run build:stencil-lit exited (1)
└─ @coveo/atomic#build:stencil-lit ──
@coveo/atomic#build:stencil-lit: command (/Users/fbeaudoin/Projects/ui-kit/packages/atomic) /Users/fbeaudoin/.nvm/versions/node/v22.17.1/bin/pnpm run build:stencil-lit exited (1)

 Tasks:    21 successful, 22 total
Cached:    20 cached, 22 total
  Time:    8.804s 
Failed:    @coveo/atomic#build:stencil-lit

There are several ts errors in atomic-insight-facet.ts.

Also atomic-insight-facet.tsx has not been deleted, nor has atomic-insight-facet.pcss. This should be done. For the pcss file, double check to ensure that the static styles property in the migrated component is fully equivalent.

Once the old files have been deleted, and the necessary adjustments have been made to make the build pass, continue to the next step (creating Storybook stories).

…tomic-insight-facet

Co-authored-by: fbeaudoincoveo <23503066+fbeaudoincoveo@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 15, 2026

@copilot @coveo/atomic#build:stencil-lit is failing:

Fixed in commit 37b563e:

TypeScript errors fixed:

  • Moved FacetResultsMustMatch import from @coveo/headless/insight to @coveo/headless
  • Fixed FocusTargetController constructor calls to include required name parameter
  • Fixed renderFacetHeader call (removed extra () invocation)
  • Fixed AriaLiveRegionController usage to use .message property instead of .announce() method
  • Fixed callback signatures for headerRef and setRef to match expected types

Old files deleted:

  • Removed atomic-insight-facet.tsx (Stencil component)
  • Removed atomic-insight-facet.pcss (styles now in Lit component's static styles)

The build now passes successfully. Proceeding to create Storybook stories next.

… mocking

Co-authored-by: fbeaudoincoveo <23503066+fbeaudoincoveo@users.noreply.github.com>
@fbeaudoincoveo fbeaudoincoveo changed the title WIP: feat(atomic): migrate atomic-insight-facet from Stencil to Lit refactor(atomic): migrate atomic-insight-facet from Stencil to Lit Jan 20, 2026
@fbeaudoincoveo fbeaudoincoveo changed the title refactor(atomic): migrate atomic-insight-facet from Stencil to Lit WIP refactor(atomic): migrate atomic-insight-facet from Stencil to Lit Jan 20, 2026
@fbeaudoincoveo fbeaudoincoveo changed the title WIP refactor(atomic): migrate atomic-insight-facet from Stencil to Lit WIP: refactor(atomic): migrate atomic-insight-facet from Stencil to Lit Jan 20, 2026
@fbeaudoincoveo fbeaudoincoveo deployed to Prerelease (CDN) January 20, 2026 20:24 — with GitHub Actions Active
@fbeaudoincoveo fbeaudoincoveo marked this pull request as ready for review January 20, 2026 21:13
@fbeaudoincoveo fbeaudoincoveo requested review from a team as code owners January 20, 2026 21:13
@fbeaudoincoveo fbeaudoincoveo requested review from Copilot, louis-bompart and y-lakhdar and removed request for Copilot January 20, 2026 21:13
* - `allValues`: A result will match if all corresponding facet values are selected.
*/
@property({type: String, reflect: true, attribute: 'results-must-match'})
resultsMustMatch: FacetResultsMustMatch = 'atLeastOneValue';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this prop is entirely unused at the moment, but it was in the original Stencil component so I didn't remove it.

However, given the fact that insight components are more or less "internal", we could consider removing iat entirely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

KIT-4853: Migrate atomic-insight-facet from Stencil to Lit

2 participants