Skip to content
Open
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 @@ -22,6 +22,7 @@ import {
AtomicResultBadge as LitAtomicResultBadge,
AtomicResultChildrenTemplate as LitAtomicResultChildrenTemplate,
AtomicResultHtml as LitAtomicResultHtml,
AtomicResultImage as LitAtomicResultImage,
AtomicResultList as LitAtomicResultList,
AtomicResultLocalizedText as LitAtomicResultLocalizedText,
AtomicResultMultiValueText as LitAtomicResultMultiValueText,
Expand Down Expand Up @@ -188,6 +189,12 @@ export const AtomicResultHtml = createComponent({
elementClass: LitAtomicResultHtml,
});

export const AtomicResultImage = createComponent({
tagName: 'atomic-result-image',
react: React,
elementClass: LitAtomicResultImage,
});

export const AtomicResultList = createComponent({
tagName: 'atomic-result-list',
react: React,
Expand Down

This file was deleted.

This file was deleted.

49 changes: 0 additions & 49 deletions packages/atomic/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1519,23 +1519,6 @@ export namespace Components {
*/
interface AtomicResultIcon {
}
/**
* The `atomic-result-image` component renders an image from a result field.
*/
interface AtomicResultImage {
/**
* An optional fallback image URL that will be used in case the specified image field is not available or encounters an error.
*/
"fallback"?: string;
/**
* The result field which the component should use. This will look for the field in the Result object first, then in the Result.raw object. It is important to include the necessary field in the `atomic-search-interface` component.
*/
"field": string;
/**
* The result field that contains the alt text for the image. This will look for the field in the Result object first, then in the Result.raw object If the field is not specified, or does not contain a valid value, the alt text will be set to "Image for {productName}".
*/
"imageAltField"?: string;
}
/**
* The `atomic-result-link` component automatically transforms a search result title into a clickable link that points to the original item.
*/
Expand Down Expand Up @@ -2744,15 +2727,6 @@ declare global {
prototype: HTMLAtomicResultIconElement;
new (): HTMLAtomicResultIconElement;
};
/**
* The `atomic-result-image` component renders an image from a result field.
*/
interface HTMLAtomicResultImageElement extends Components.AtomicResultImage, HTMLStencilElement {
}
var HTMLAtomicResultImageElement: {
prototype: HTMLAtomicResultImageElement;
new (): HTMLAtomicResultImageElement;
};
/**
* The `atomic-result-link` component automatically transforms a search result title into a clickable link that points to the original item.
*/
Expand Down Expand Up @@ -3141,7 +3115,6 @@ declare global {
"atomic-result-date": HTMLAtomicResultDateElement;
"atomic-result-fields-list": HTMLAtomicResultFieldsListElement;
"atomic-result-icon": HTMLAtomicResultIconElement;
"atomic-result-image": HTMLAtomicResultImageElement;
"atomic-result-link": HTMLAtomicResultLinkElement;
"atomic-result-placeholder": HTMLAtomicResultPlaceholderElement;
"atomic-result-printable-uri": HTMLAtomicResultPrintableUriElement;
Expand Down Expand Up @@ -4606,23 +4579,6 @@ declare namespace LocalJSX {
*/
interface AtomicResultIcon {
}
/**
* The `atomic-result-image` component renders an image from a result field.
*/
interface AtomicResultImage {
/**
* An optional fallback image URL that will be used in case the specified image field is not available or encounters an error.
*/
"fallback"?: string;
/**
* The result field which the component should use. This will look for the field in the Result object first, then in the Result.raw object. It is important to include the necessary field in the `atomic-search-interface` component.
*/
"field": string;
/**
* The result field that contains the alt text for the image. This will look for the field in the Result object first, then in the Result.raw object If the field is not specified, or does not contain a valid value, the alt text will be set to "Image for {productName}".
*/
"imageAltField"?: string;
}
/**
* The `atomic-result-link` component automatically transforms a search result title into a clickable link that points to the original item.
*/
Expand Down Expand Up @@ -5153,7 +5109,6 @@ declare namespace LocalJSX {
"atomic-result-date": AtomicResultDate;
"atomic-result-fields-list": AtomicResultFieldsList;
"atomic-result-icon": AtomicResultIcon;
"atomic-result-image": AtomicResultImage;
"atomic-result-link": AtomicResultLink;
"atomic-result-placeholder": AtomicResultPlaceholder;
"atomic-result-printable-uri": AtomicResultPrintableUri;
Expand Down Expand Up @@ -5401,10 +5356,6 @@ declare module "@stencil/core" {
* The component searches for a suitable icon, or outputs a generic icon if the search is unsuccessful.
*/
"atomic-result-icon": LocalJSX.AtomicResultIcon & JSXBase.HTMLAttributes<HTMLAtomicResultIconElement>;
/**
* The `atomic-result-image` component renders an image from a result field.
*/
"atomic-result-image": LocalJSX.AtomicResultImage & JSXBase.HTMLAttributes<HTMLAtomicResultImageElement>;
/**
* The `atomic-result-link` component automatically transforms a search result title into a clickable link that points to the original item.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Meta } from '@storybook/addon-docs/blocks';
import * as AtomicResultImageStories from './atomic-result-image.new.stories';
import { AtomicDocTemplate } from '../../../../storybook-utils/documentation/atomic-doc-template';

<Meta of={ AtomicResultImageStories } />

<AtomicDocTemplate
stories={ AtomicResultImageStories }
githubPath="search/atomic-result-image/atomic-result-image.ts"
tagName="atomic-result-image"
className="AtomicResultImage"
>

Use this component within `atomic-result-template` to display an image from a result field. The component handles image loading errors gracefully and supports fallback images.

For accessibility, you can specify a result field to provide custom alt text for the image using the `image-alt-field` property. If not specified, the component falls back to a default alt text based on the result title.

```html
<atomic-result-template>
<template>
<atomic-result-section-visual>
<!-- Basic usage -->
<atomic-result-image field="thumbnail"></atomic-result-image>

<!-- With fallback image -->
<atomic-result-image
field="thumbnail"
fallback="https://example.com/placeholder.png">
</atomic-result-image>

<!-- With custom alt text from a field -->
<atomic-result-image
field="thumbnail"
image-alt-field="alt_description">
</atomic-result-image>
</atomic-result-section-visual>
</template>
</atomic-result-template>
```

</AtomicDocTemplate>
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
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: response.results.slice(0, 1).map((result) => ({
...result,
raw: {
...result.raw,
thumbnail: 'https://picsum.photos/200',
alt_description: 'A beautiful placeholder image',
},
})),
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-image',
{excludeCategories: ['methods']}
);

const meta: Meta = {
component: 'atomic-result-image',
title: 'Search/Result Image',
id: 'atomic-result-image',

render: (args) => template(args),
decorators: [
resultTemplateDecorator,
resultListDecorator,
searchInterfaceDecorator,
],
parameters: {
...parameters,
msw: {
handlers: [...searchApiHarness.handlers],
},
actions: {
handles: events,
},
},
args: {
...args,
field: 'thumbnail',
},
argTypes,

play,
};

export default meta;

export const Default: Story = {};

export const WithAltTextField: Story = {
args: {
'image-alt-field': 'alt_description',
},
};

export const WithFallback: Story = {
args: {
field: 'nonexistent_field',
fallback: 'https://picsum.photos/200/200',
},
};
Loading
Loading