Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const ALLOWED_LIGHT_DOM_COMPONENTS = new Set([
'src/components/insight/atomic-insight-tabs/atomic-insight-tabs.ts',
'src/components/insight/atomic-insight-result-quickview-action/atomic-insight-result-quickview-action.ts',
'src/components/insight/atomic-insight-result-attach-to-case-action/atomic-insight-result-attach-to-case-action.ts',
'src/components/insight/atomic-insight-result-action/atomic-insight-result-action.ts',

// IPX components
'src/components/ipx/atomic-ipx-tabs/atomic-ipx-tabs.ts',
Expand Down
67 changes: 0 additions & 67 deletions packages/atomic/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,13 @@
* It contains typing information for all components that exist in this project.
*/
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { Actions, InsightResultActionClickedEvent } from "./components/insight/atomic-insight-result-action/atomic-insight-result-action";
import { DateFilterRange, DateRangeRequest, ResultTemplate, ResultTemplateCondition } from "@coveo/headless";
import { RangeFacetSortCriterion as InsightRangeFacetSortCriterion } from "@coveo/headless/insight";
import { AnyBindings } from "./components/common/interface/bindings";
export { Actions, InsightResultActionClickedEvent } from "./components/insight/atomic-insight-result-action/atomic-insight-result-action";
export { DateFilterRange, DateRangeRequest, ResultTemplate, ResultTemplateCondition } from "@coveo/headless";
export { RangeFacetSortCriterion as InsightRangeFacetSortCriterion } from "@coveo/headless/insight";
export { AnyBindings } from "./components/common/interface/bindings";
export namespace Components {
interface AtomicInsightResultAction {
/**
* The type of action to perform when the result action is clicked. This will be sent along the event fired when the button is clicked.
*/
"action": Actions | string;
/**
* Specify the result action icon to display.
*/
"icon": string;
/**
* The text tooltip to show on the result action icon.
*/
"tooltip": string;
/**
* The text tooltip to show on the result action icon for some time after clicking the button.
*/
"tooltipOnClick": string;
}
interface AtomicInsightResultChildrenTemplate {
/**
* A function that must return true on results for the result template to apply. Set programmatically before initialization, not via attribute. For example, the following targets a template and sets a condition to make it apply only to results whose `title` contains `singapore`: `document.querySelector('#target-template').conditions = [(result) => /singapore/i.test(result.title)];`
Expand Down Expand Up @@ -120,32 +100,11 @@ export namespace Components {
"rangeSetter": (range: DateRangeRequest) => void;
}
}
export interface AtomicInsightResultActionCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLAtomicInsightResultActionElement;
}
export interface AtomicStencilFacetDateInputCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLAtomicStencilFacetDateInputElement;
}
declare global {
interface HTMLAtomicInsightResultActionElementEventMap {
"atomicInsightResultActionClicked": InsightResultActionClickedEvent;
}
interface HTMLAtomicInsightResultActionElement extends Components.AtomicInsightResultAction, HTMLStencilElement {
addEventListener<K extends keyof HTMLAtomicInsightResultActionElementEventMap>(type: K, listener: (this: HTMLAtomicInsightResultActionElement, ev: AtomicInsightResultActionCustomEvent<HTMLAtomicInsightResultActionElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof HTMLAtomicInsightResultActionElementEventMap>(type: K, listener: (this: HTMLAtomicInsightResultActionElement, ev: AtomicInsightResultActionCustomEvent<HTMLAtomicInsightResultActionElementEventMap[K]>) => any, options?: boolean | EventListenerOptions): void;
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
var HTMLAtomicInsightResultActionElement: {
prototype: HTMLAtomicInsightResultActionElement;
new (): HTMLAtomicInsightResultActionElement;
};
interface HTMLAtomicInsightResultChildrenTemplateElement extends Components.AtomicInsightResultChildrenTemplate, HTMLStencilElement {
}
var HTMLAtomicInsightResultChildrenTemplateElement: {
Expand Down Expand Up @@ -180,36 +139,12 @@ declare global {
new (): HTMLAtomicStencilFacetDateInputElement;
};
interface HTMLElementTagNameMap {
"atomic-insight-result-action": HTMLAtomicInsightResultActionElement;
"atomic-insight-result-children-template": HTMLAtomicInsightResultChildrenTemplateElement;
"atomic-insight-timeframe-facet": HTMLAtomicInsightTimeframeFacetElement;
"atomic-stencil-facet-date-input": HTMLAtomicStencilFacetDateInputElement;
}
}
declare namespace LocalJSX {
interface AtomicInsightResultAction {
/**
* The type of action to perform when the result action is clicked. This will be sent along the event fired when the button is clicked.
*/
"action"?: Actions | string;
/**
* Specify the result action icon to display.
*/
"icon"?: string;
/**
* @migration Stencil's
* @Event () decorator defaults to: bubbles=true, composed=true, cancelable=true. Native CustomEvent defaults to: bubbles=false, composed=false, cancelable=false. When migrating to Lit, explicitly set all three options to preserve behavior: `new CustomEvent('atomicInsightResultActionClicked', { bubbles: true, composed: true, cancelable: true, detail: ... })`
*/
"onAtomicInsightResultActionClicked"?: (event: AtomicInsightResultActionCustomEvent<InsightResultActionClickedEvent>) => void;
/**
* The text tooltip to show on the result action icon.
*/
"tooltip"?: string;
/**
* The text tooltip to show on the result action icon for some time after clicking the button.
*/
"tooltipOnClick"?: string;
}
interface AtomicInsightResultChildrenTemplate {
/**
* A function that must return true on results for the result template to apply. Set programmatically before initialization, not via attribute. For example, the following targets a template and sets a condition to make it apply only to results whose `title` contains `singapore`: `document.querySelector('#target-template').conditions = [(result) => /singapore/i.test(result.title)];`
Expand Down Expand Up @@ -299,7 +234,6 @@ declare namespace LocalJSX {
"rangeSetter": (range: DateRangeRequest) => void;
}
interface IntrinsicElements {
"atomic-insight-result-action": AtomicInsightResultAction;
"atomic-insight-result-children-template": AtomicInsightResultChildrenTemplate;
"atomic-insight-timeframe-facet": AtomicInsightTimeframeFacet;
"atomic-stencil-facet-date-input": AtomicStencilFacetDateInput;
Expand All @@ -309,7 +243,6 @@ export { LocalJSX as JSX };
declare module "@stencil/core" {
export namespace JSX {
interface IntrinsicElements {
"atomic-insight-result-action": LocalJSX.AtomicInsightResultAction & JSXBase.HTMLAttributes<HTMLAtomicInsightResultActionElement>;
"atomic-insight-result-children-template": LocalJSX.AtomicInsightResultChildrenTemplate & JSXBase.HTMLAttributes<HTMLAtomicInsightResultChildrenTemplateElement>;
"atomic-insight-timeframe-facet": LocalJSX.AtomicInsightTimeframeFacet & JSXBase.HTMLAttributes<HTMLAtomicInsightTimeframeFacetElement>;
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { Meta } from '@storybook/addon-docs/blocks';
import * as AtomicInsightResultActionStories from './atomic-insight-result-action.new.stories';
import { AtomicDocTemplate } from '@/storybook-utils/documentation/atomic-doc-template';

<Meta of={AtomicInsightResultActionStories} />

<AtomicDocTemplate
stories={AtomicInsightResultActionStories}
defaultStory="Default"
githubPath="insight/atomic-insight-result-action/atomic-insight-result-action.ts"
tagName="atomic-insight-result-action"
className="AtomicInsightResultAction"
>

Place this component directly inside `atomic-result-section-actions` for always-visible actions, or inside an `atomic-insight-result-action-bar` for actions that appear on hover.

### Always visible

```html
<atomic-insight-result-template>
<template>
<atomic-result-section-actions>
<atomic-insight-result-action
action="copyToClipboard"
tooltip="Copy"
tooltip-on-click="Copied!"
></atomic-insight-result-action>
</atomic-result-section-actions>
</template>
</atomic-insight-result-template>
```

### Visible on hover

```html
<atomic-insight-result-template>
<template>
<atomic-result-section-actions>
<atomic-insight-result-action-bar>
<atomic-insight-result-action
action="copyToClipboard"
tooltip="Copy"
tooltip-on-click="Copied!"
></atomic-insight-result-action>
</atomic-insight-result-action-bar>
</atomic-result-section-actions>
</template>
</atomic-insight-result-template>
```

## Available actions

The component supports the following built-in action types, each with a default icon:

| Action | Description | Default Icon |
|--------|-------------|--------------|
| `copyToClipboard` | Copies the result's click URI to the clipboard | Copy icon |
| `attachToCase` | Attaches the result to a case | Attach icon |
| `quickview` | Opens a quickview of the result | Preview icon |
| `postToFeed` | Posts the result to a feed | Share icon |
| `sendAsEmail` | Sends the result as an email | Email icon |

## Handling events

Listen for the `atomicInsightResultActionClicked` event to implement custom logic:

```javascript
document.addEventListener('atomicInsightResultActionClicked', (event) => {
const { action, result } = event.detail;

switch (action) {
case 'copyToClipboard':
// The component automatically copies to clipboard,
// but you can add additional logic here
console.log('Copied:', result.clickUri);
break;
case 'attachToCase':
// Implement your attach-to-case logic
break;
case 'quickview':
// Implement your quickview logic
break;
case 'postToFeed':
// Implement your post-to-feed logic
break;
case 'sendAsEmail':
// Implement your send-as-email logic
break;
default:
// Handle custom actions
console.log('Custom action:', action);
}
});
```

## Custom icons

You can provide a custom SVG icon using the `icon` property:

```html
<atomic-insight-result-action
action="customAction"
tooltip="Custom action"
icon="<svg>...</svg>"
></atomic-insight-result-action>
```

</AtomicDocTemplate>
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import type {Meta, StoryObj as Story} from '@storybook/web-components-vite';
import {html} from 'lit';
import {MockInsightApi} from '@/storybook-utils/api/insight/mock';
import {parameters} from '@/storybook-utils/common/common-meta-parameters';
import {wrapInInsightInterface} from '@/storybook-utils/insight/insight-interface-wrapper';
import {wrapInInsightLayout} from '@/storybook-utils/insight/insight-layout-wrapper';
import {wrapInInsightResultList} from '@/storybook-utils/insight/insight-result-list-wrapper';
import {wrapInInsightResultTemplate} from '@/storybook-utils/insight/insight-result-template-wrapper';

const insightApiHarness = new MockInsightApi();

const {decorator: insightInterfaceDecorator, play} = wrapInInsightInterface(
{},
false,
false
);
const {decorator: insightLayoutDecorator} = wrapInInsightLayout(false);
const {decorator: insightResultListDecorator} = wrapInInsightResultList(
'list',
false
);
const {decorator: insightResultTemplateDecorator} =
wrapInInsightResultTemplate(false);

const meta: Meta = {
component: 'atomic-insight-result-action',
title: 'Insight/Result Action',
id: 'atomic-insight-result-action',
render: (args) => html`
<atomic-result-section-actions id="code-root">
<atomic-insight-result-action
action=${args.action}
tooltip=${args.tooltip}
tooltip-on-click=${args.tooltipOnClick}
icon=${args.icon}
></atomic-insight-result-action>
</atomic-result-section-actions>
`,
args: {
action: 'copyToClipboard',
tooltip: 'Copy to clipboard',
tooltipOnClick: 'Copied!',
icon: '',
},
argTypes: {
action: {
control: 'select',
options: [
'copyToClipboard',
'attachToCase',
'quickview',
'postToFeed',
'sendAsEmail',
],
description: 'The type of action to perform when clicked',
},
tooltip: {
control: 'text',
description: 'The text tooltip to show on the result action icon',
},
tooltipOnClick: {
control: 'text',
description: 'The text tooltip to show after clicking the button',
},
icon: {
control: 'text',
description:
'Custom SVG icon to display. If not provided, uses a default icon based on the action type.',
},
},
decorators: [
(story) => html`
<atomic-result-section-title>
<atomic-result-link></atomic-result-link>
</atomic-result-section-title>
<atomic-result-section-excerpt>
<atomic-result-text field="excerpt"></atomic-result-text>
</atomic-result-section-excerpt>
${story()}
`,
insightResultTemplateDecorator,
insightResultListDecorator,
insightLayoutDecorator,
insightInterfaceDecorator,
],
parameters: {
...parameters,
msw: {
handlers: [...insightApiHarness.handlers],
},
},
play,
};

export default meta;

export const Default: Story = {};

export const InActionBar: Story = {
render: (args) => html`
<atomic-result-section-actions id="code-root">
<atomic-insight-result-action-bar>
<atomic-insight-result-action
action=${args.action}
tooltip=${args.tooltip}
tooltip-on-click=${args.tooltipOnClick}
icon=${args.icon}
></atomic-insight-result-action>
</atomic-insight-result-action-bar>
</atomic-result-section-actions>
`,
};

This file was deleted.

Loading