Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/atomic-react/src/components/search/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
AtomicRecsInterface as LitAtomicRecsInterface,
AtomicResult as LitAtomicResult,
AtomicResultBadge as LitAtomicResultBadge,
AtomicResultChildren as LitAtomicResultChildren,
AtomicResultChildrenTemplate as LitAtomicResultChildrenTemplate,
AtomicResultHtml as LitAtomicResultHtml,
AtomicResultList as LitAtomicResultList,
Expand Down Expand Up @@ -150,6 +151,12 @@ export const AtomicResultBadge = createComponent({
elementClass: LitAtomicResultBadge,
});

export const AtomicResultChildren = createComponent({
tagName: 'atomic-result-children',
react: React,
elementClass: LitAtomicResultChildren,
});

export const AtomicResultChildrenTemplate = createComponent({
tagName: 'atomic-result-children-template',
react: React,
Expand Down
1 change: 1 addition & 0 deletions packages/atomic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
"cypress-axe": "1.6.0",
"cypress-repeat": "catalog:",
"cypress-split": "1.5.0",
"fs-extra": "11.3.2",
"handlebars": "4.7.8",
"html-loader-jest": "0.2.1",
"jest": "catalog:",
Expand Down
57 changes: 0 additions & 57 deletions packages/atomic/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1509,25 +1509,6 @@ export namespace Components {
*/
"collapseFacetsAfter": number;
}
/**
* The `atomic-result-children` component is responsible for displaying child results by applying one or more child result templates.
* Includes two slots, "before-children" and "after-children", which allow for rendering content before and after the list of children,
* only when children exist.
*/
interface AtomicResultChildren {
/**
* The expected size of the image displayed in the children results.
*/
"imageSize"?: ItemDisplayImageSize;
/**
* Whether to inherit templates defined in a parent atomic-result-children. Only works for the second level of child nesting.
*/
"inheritTemplates": boolean;
/**
* The non-localized copy for an empty result state. An empty string will result in the component being hidden.
*/
"noResultText": string;
}
/**
* The `atomic-result-date` component renders the value of a date result field.
*/
Expand Down Expand Up @@ -2850,17 +2831,6 @@ declare global {
prototype: HTMLAtomicRefineToggleElement;
new (): HTMLAtomicRefineToggleElement;
};
/**
* The `atomic-result-children` component is responsible for displaying child results by applying one or more child result templates.
* Includes two slots, "before-children" and "after-children", which allow for rendering content before and after the list of children,
* only when children exist.
*/
interface HTMLAtomicResultChildrenElement extends Components.AtomicResultChildren, HTMLStencilElement {
}
var HTMLAtomicResultChildrenElement: {
prototype: HTMLAtomicResultChildrenElement;
new (): HTMLAtomicResultChildrenElement;
};
/**
* The `atomic-result-date` component renders the value of a date result field.
*/
Expand Down Expand Up @@ -3342,7 +3312,6 @@ declare global {
"atomic-recs-result-template": HTMLAtomicRecsResultTemplateElement;
"atomic-refine-modal": HTMLAtomicRefineModalElement;
"atomic-refine-toggle": HTMLAtomicRefineToggleElement;
"atomic-result-children": HTMLAtomicResultChildrenElement;
"atomic-result-date": HTMLAtomicResultDateElement;
"atomic-result-fields-list": HTMLAtomicResultFieldsListElement;
"atomic-result-icon": HTMLAtomicResultIconElement;
Expand Down Expand Up @@ -4806,25 +4775,6 @@ declare namespace LocalJSX {
*/
"collapseFacetsAfter"?: number;
}
/**
* The `atomic-result-children` component is responsible for displaying child results by applying one or more child result templates.
* Includes two slots, "before-children" and "after-children", which allow for rendering content before and after the list of children,
* only when children exist.
*/
interface AtomicResultChildren {
/**
* The expected size of the image displayed in the children results.
*/
"imageSize"?: ItemDisplayImageSize;
/**
* Whether to inherit templates defined in a parent atomic-result-children. Only works for the second level of child nesting.
*/
"inheritTemplates"?: boolean;
/**
* The non-localized copy for an empty result state. An empty string will result in the component being hidden.
*/
"noResultText"?: string;
}
/**
* The `atomic-result-date` component renders the value of a date result field.
*/
Expand Down Expand Up @@ -5472,7 +5422,6 @@ declare namespace LocalJSX {
"atomic-recs-result-template": AtomicRecsResultTemplate;
"atomic-refine-modal": AtomicRefineModal;
"atomic-refine-toggle": AtomicRefineToggle;
"atomic-result-children": AtomicResultChildren;
"atomic-result-date": AtomicResultDate;
"atomic-result-fields-list": AtomicResultFieldsList;
"atomic-result-icon": AtomicResultIcon;
Expand Down Expand Up @@ -5730,12 +5679,6 @@ declare module "@stencil/core" {
* When this component is added to the `atomic-search-interface`, an `atomic-refine-modal` component is automatically created.
*/
"atomic-refine-toggle": LocalJSX.AtomicRefineToggle & JSXBase.HTMLAttributes<HTMLAtomicRefineToggleElement>;
/**
* The `atomic-result-children` component is responsible for displaying child results by applying one or more child result templates.
* Includes two slots, "before-children" and "after-children", which allow for rendering content before and after the list of children,
* only when children exist.
*/
"atomic-result-children": LocalJSX.AtomicResultChildren & JSXBase.HTMLAttributes<HTMLAtomicResultChildrenElement>;
/**
* The `atomic-result-date` component renders the value of a date result field.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type {FoldedResultList, FoldedResultListState} from '@coveo/headless';
import type {LitElement, ReactiveController, ReactiveControllerHost} from 'lit';
import {buildCustomEvent} from '@/src/utils/event-utils';

const foldedItemListContextEventName = 'atomic/resolveFoldedResultList';

/**
* A reactive controller that manages folded item list context from parent components.
* Handles fetching FoldedResultList via custom events.
*/
export class FoldedItemListContextController implements ReactiveController {
private host: ReactiveControllerHost & LitElement;
private _foldedItemList: FoldedResultList | null = null;
private _unsubscribe: (() => void) | null = null;

constructor(host: ReactiveControllerHost & LitElement) {
this.host = host;
host.addController(this);
}

get foldedItemList(): FoldedResultList | null {
return this._foldedItemList;
}

get state(): FoldedResultListState | null {
return this._foldedItemList?.state ?? null;
}

hostConnected(): void {
this._resolveFoldedItemListContext();
}

hostDisconnected(): void {
this._unsubscribe?.();
this._unsubscribe = null;
}

private _resolveFoldedItemListContext(): void {
const event = buildCustomEvent(
foldedItemListContextEventName,
(foldedItemList: FoldedResultList) => {
this._foldedItemList = foldedItemList;
this._unsubscribe = foldedItemList.subscribe(() => {
this.host.requestUpdate();
});
this.host.requestUpdate();
}
);

const canceled = this.host.dispatchEvent(event);
if (canceled) {
this._foldedItemList = null;
}
}
}

type FoldedItemListContextEventHandler = (
foldedItemList: FoldedResultList
) => void;
export type FoldedItemListContextEvent =
CustomEvent<FoldedItemListContextEventHandler>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Meta } from '@storybook/addon-docs/blocks';
import * as AtomicResultChildrenStories from './atomic-result-children.new.stories';
import { AtomicDocTemplate } from '../../../../storybook-utils/documentation/atomic-doc-template';

<Meta of={ AtomicResultChildrenStories } />

<AtomicDocTemplate
stories={ AtomicResultChildrenStories }
githubPath="search/result-lists/atomic-result-children/atomic-result-children.ts"
tagName="atomic-result-children"
className="AtomicResultChildren"
>

// TODO: Add usage instructions here.

// * See atomic-product-link.mdx for typical template component.
// * See atomic-commerce-pager.mdx for typical non-template component.

</AtomicDocTemplate>
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import type {Meta, StoryObj as Story} from '@storybook/web-components-vite';
import {getStorybookHelpers} from '@wc-toolkit/storybook-helpers';
import {MockSearchApi} from '@/storybook-utils/api/search/mock';
import {parameters} from '@/storybook-utils/common/common-meta-parameters';
import {wrapInResultList} from '@/storybook-utils/search/result-list-wrapper';
import {wrapInResultTemplate} from '@/storybook-utils/search/result-template-wrapper';
import {wrapInSearchInterface} from '@/storybook-utils/search/search-interface-wrapper';

const searchApiHarness = new MockSearchApi();
searchApiHarness.searchEndpoint.mock((response) => ({
...response,
results: [
{
title: 'Animals',
excerpt: 'Collection of animals',
clickUri: 'https://example.com/animals',
uniqueId: 'animals-parent',
childResults: [
{
title: 'Cats',
excerpt: 'Cat species',
clickUri: 'https://example.com/cats',
uniqueId: 'cats-child',
raw: {
foldingcollection: 'Animals',
foldingchild: ['cats'],
foldingparent: 'animals',
},
},
{
title: 'Dogs',
excerpt: 'Dog species',
clickUri: 'https://example.com/dogs',
uniqueId: 'dogs-child',
raw: {
foldingcollection: 'Animals',
foldingchild: ['dogs'],
foldingparent: 'animals',
},
},
],
totalNumberOfChildResults: 2,
raw: {
foldingcollection: 'Animals',
foldingchild: ['animals'],
},
},
],
totalCount: 1,
totalCountFiltered: 1,
}));

const {decorator: searchInterfaceDecorator, play} = wrapInSearchInterface({
includeCodeRoot: false,
});
const {decorator: resultListDecorator} = wrapInResultList('list', false);
const {decorator: resultTemplateDecorator} = wrapInResultTemplate();

const {events, args, argTypes, template} = getStorybookHelpers(
'atomic-result-children',
{excludeCategories: ['methods']}
);

const meta: Meta = {
component: 'atomic-result-children',
title: 'Search/Result Children',
id: 'atomic-result-children',
render: (args) => template(args),
decorators: [
resultTemplateDecorator,
resultListDecorator,
searchInterfaceDecorator,
],
parameters: {
...parameters,
msw: {
handlers: [...searchApiHarness.handlers],
},
actions: {
handles: events,
},
},
args,
argTypes,
play,
};

export default meta;

export const Default: Story = {};
Loading
Loading