Skip to content
Merged
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
8 changes: 6 additions & 2 deletions .github/prompts/migrate-stencil-to-lit.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,14 @@ export class AtomicIcon

**Conversion:** `../` β†’ `@/src/` + full path from `src/` directory. Keep `./` (same-dir) imports.

**Exception - SVG imports:** SVG files (icons, assets) **cannot** use path aliases. Always use relative paths for `.svg` imports.

**Examples:**
```typescript
'../../../utils/initialization-utils' β†’ '@/src/utils/initialization-utils'
'../../common/query-error/details' β†’ '@/src/components/common/query-error/details'
'./local-helper' β†’ './local-helper' // βœ… Same-dir OK
'../../../assets/icons/arrow.svg' β†’ '../../../assets/icons/arrow.svg' // βœ… SVG must use relative path
```

**Verify after migration:** `grep -E "from '\.\./|from \"\.\\./" atomic-{name}.ts` β†’ zero matches
Expand Down Expand Up @@ -307,15 +310,16 @@ import {renderButton} from '../../../common/button';
import {bindings} from '../../../../decorators/bindings';
```

**βœ… All imports use path aliases:**
**βœ… All imports use path aliases (except SVG):**

```typescript
import {renderButton} from '@/src/components/common/button';
import {bindings} from '@/src/decorators/bindings';
import {localHelper} from './local-helper'; // Same-dir OK
import ArrowIcon from '../../../assets/icons/arrow.svg'; // SVG must use relative path
```

Verify: `grep -E "from '\.\./|from \"\.\\./" atomic-{name}.ts` β†’ zero matches
Verify: `grep -E "from '\.\./|from \"\.\\./" atomic-{name}.ts` β†’ only SVG imports should match

**❌ Including empty styles:**

Expand Down
7 changes: 7 additions & 0 deletions packages/atomic-react/src/components/commerce/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
AtomicComponentError as LitAtomicComponentError,
AtomicFocusTrap as LitAtomicFocusTrap,
AtomicIcon as LitAtomicIcon,
AtomicInsightEditToggle as LitAtomicInsightEditToggle,
AtomicInsightFullSearchButton as LitAtomicInsightFullSearchButton,
AtomicInsightGenerateAnswerButton as LitAtomicInsightGenerateAnswerButton,
AtomicInsightInterface as LitAtomicInsightInterface,
Expand Down Expand Up @@ -243,6 +244,12 @@ export const AtomicIcon = createComponent({
elementClass: LitAtomicIcon,
});

export const AtomicInsightEditToggle = createComponent({
tagName: 'atomic-insight-edit-toggle',
react: React,
elementClass: LitAtomicInsightEditToggle,
});

export const AtomicInsightFullSearchButton = createComponent({
tagName: 'atomic-insight-full-search-button',
react: React,
Expand Down
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 @@ -18,6 +18,7 @@ import {
AtomicGeneratedAnswer as LitAtomicGeneratedAnswer,
AtomicHtml as LitAtomicHtml,
AtomicIcon as LitAtomicIcon,
AtomicInsightEditToggle as LitAtomicInsightEditToggle,
AtomicInsightFullSearchButton as LitAtomicInsightFullSearchButton,
AtomicInsightGenerateAnswerButton as LitAtomicInsightGenerateAnswerButton,
AtomicInsightInterface as LitAtomicInsightInterface,
Expand Down Expand Up @@ -202,6 +203,12 @@ export const AtomicIcon = createComponent({
elementClass: LitAtomicIcon,
});

export const AtomicInsightEditToggle = createComponent({
tagName: 'atomic-insight-edit-toggle',
react: React,
elementClass: LitAtomicInsightEditToggle,
});

export const AtomicInsightFullSearchButton = createComponent({
tagName: 'atomic-insight-full-search-button',
react: React,
Expand Down
4 changes: 3 additions & 1 deletion packages/atomic/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ const svgTransform: PluginImpl = () => {
const svgContent = readFileSync(
resolve(dirname(id), importPath),
'utf8'
).replace(/'/g, "\\'");
)
.replace(/\r?\n/g, '')
.replace(/'/g, "\\'");
return `const ${importName} = '${svgContent}';`;
}
);
Expand Down
17 changes: 0 additions & 17 deletions packages/atomic/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ export namespace Components {
*/
"isOpen": boolean;
}
interface AtomicInsightEditToggle {
"clickCallback": () => void;
"tooltip": string;
}
interface AtomicInsightFacet {
/**
* Whether to display the facet values as checkboxes (multiple selection), links (single selection) or boxes (multiple selection). Possible values are 'checkbox', 'link', and 'box'.
Expand Down Expand Up @@ -1070,12 +1066,6 @@ declare global {
prototype: HTMLAtomicGeneratedAnswerFeedbackModalElement;
new (): HTMLAtomicGeneratedAnswerFeedbackModalElement;
};
interface HTMLAtomicInsightEditToggleElement extends Components.AtomicInsightEditToggle, HTMLStencilElement {
}
var HTMLAtomicInsightEditToggleElement: {
prototype: HTMLAtomicInsightEditToggleElement;
new (): HTMLAtomicInsightEditToggleElement;
};
interface HTMLAtomicInsightFacetElement extends Components.AtomicInsightFacet, HTMLStencilElement {
}
var HTMLAtomicInsightFacetElement: {
Expand Down Expand Up @@ -1579,7 +1569,6 @@ declare global {
interface HTMLElementTagNameMap {
"atomic-citation": HTMLAtomicCitationElement;
"atomic-generated-answer-feedback-modal": HTMLAtomicGeneratedAnswerFeedbackModalElement;
"atomic-insight-edit-toggle": HTMLAtomicInsightEditToggleElement;
"atomic-insight-facet": HTMLAtomicInsightFacetElement;
"atomic-insight-folded-result-list": HTMLAtomicInsightFoldedResultListElement;
"atomic-insight-generated-answer": HTMLAtomicInsightGeneratedAnswerElement;
Expand Down Expand Up @@ -1676,10 +1665,6 @@ declare namespace LocalJSX {
"isOpen"?: boolean;
"onFeedbackSent"?: (event: AtomicGeneratedAnswerFeedbackModalCustomEvent<any>) => void;
}
interface AtomicInsightEditToggle {
"clickCallback"?: () => void;
"tooltip"?: string;
}
interface AtomicInsightFacet {
/**
* Whether to display the facet values as checkboxes (multiple selection), links (single selection) or boxes (multiple selection). Possible values are 'checkbox', 'link', and 'box'.
Expand Down Expand Up @@ -2565,7 +2550,6 @@ declare namespace LocalJSX {
interface IntrinsicElements {
"atomic-citation": AtomicCitation;
"atomic-generated-answer-feedback-modal": AtomicGeneratedAnswerFeedbackModal;
"atomic-insight-edit-toggle": AtomicInsightEditToggle;
"atomic-insight-facet": AtomicInsightFacet;
"atomic-insight-folded-result-list": AtomicInsightFoldedResultList;
"atomic-insight-generated-answer": AtomicInsightGeneratedAnswer;
Expand Down Expand Up @@ -2629,7 +2613,6 @@ declare module "@stencil/core" {
* Internal component, only to use through `atomic-generated-answer` or `atomic-insight-generated-answer`
*/
"atomic-generated-answer-feedback-modal": LocalJSX.AtomicGeneratedAnswerFeedbackModal & JSXBase.HTMLAttributes<HTMLAtomicGeneratedAnswerFeedbackModalElement>;
"atomic-insight-edit-toggle": LocalJSX.AtomicInsightEditToggle & JSXBase.HTMLAttributes<HTMLAtomicInsightEditToggleElement>;
"atomic-insight-facet": LocalJSX.AtomicInsightFacet & JSXBase.HTMLAttributes<HTMLAtomicInsightFacetElement>;
"atomic-insight-folded-result-list": LocalJSX.AtomicInsightFoldedResultList & JSXBase.HTMLAttributes<HTMLAtomicInsightFoldedResultListElement>;
"atomic-insight-generated-answer": LocalJSX.AtomicInsightGeneratedAnswer & JSXBase.HTMLAttributes<HTMLAtomicInsightGeneratedAnswerElement>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Meta } from '@storybook/addon-docs/blocks';
import * as AtomicInsightEditToggleStories from './atomic-insight-edit-toggle.new.stories';
import { AtomicDocTemplate } from '@/storybook-utils/documentation/atomic-doc-template';

<Meta of={AtomicInsightEditToggleStories} />

<AtomicDocTemplate
stories={AtomicInsightEditToggleStories}
githubPath="insight/atomic-insight-edit-toggle/atomic-insight-edit-toggle.ts"
tagName="atomic-insight-edit-toggle"
className="AtomicInsightEditToggle"
>

The `atomic-insight-edit-toggle` component provides an edit button for insight interfaces. This is an internal component typically used within other Insight components to provide editing functionality.

The component can be configured with a callback function and optional tooltip.

## Styling

The component uses the following part attributes for styling:

- `insight-edit-toggle-container`: The container wrapper
- `insight-edit-toggle-button`: The button element
- `insight-edit-toggle-icon`: The edit icon

</AtomicDocTemplate>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type {Meta, StoryObj as Story} from '@storybook/web-components-vite';
import {getStorybookHelpers} from '@wc-toolkit/storybook-helpers';
import {parameters} from '@/storybook-utils/common/common-meta-parameters';
import {wrapInInsightInterface} from '@/storybook-utils/insight/insight-interface-wrapper';

const {decorator, play} = wrapInInsightInterface();
const {events, args, argTypes, template} = getStorybookHelpers(
'atomic-insight-edit-toggle',
{excludeCategories: ['methods']}
);

const meta: Meta = {
component: 'atomic-insight-edit-toggle',
title: 'Insight/Edit Toggle',
id: 'atomic-insight-edit-toggle',
render: (args) => template(args),
decorators: [decorator],
parameters: {
...parameters,
actions: {
handles: events,
},
},
args,
argTypes,
play,
};

export default meta;

export const Default: Story = {};

export const WithTooltip: Story = {
name: 'With tooltip',
args: {
tooltip: 'Click to edit this item',
},
};

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {html} from 'lit';
import {describe, expect, it, vi} from 'vitest';
import {page} from 'vitest/browser';
import {fixture} from '@/vitest-utils/testing-helpers/fixture';
import './atomic-insight-edit-toggle';
import type {AtomicInsightEditToggle} from './atomic-insight-edit-toggle';

describe('atomic-insight-edit-toggle', () => {
const renderComponent = async ({
clickCallback = vi.fn(),
tooltip = '',
} = {}) => {
const element = await fixture<AtomicInsightEditToggle>(html`
<atomic-insight-edit-toggle
.clickCallback=${clickCallback}
.tooltip=${tooltip}
></atomic-insight-edit-toggle>
`);

const button = page.getByRole('button', {name: 'Edit'});

return {
element,
button,
};
};

it('should render the edit button', async () => {
const {button} = await renderComponent();
await expect.element(button).toBeInTheDocument();
});

it('should call clickCallback when button is clicked', async () => {
const clickCallback = vi.fn();
const {button} = await renderComponent({clickCallback});

await button.click();

expect(clickCallback).toHaveBeenCalledOnce();
});

it('should apply tooltip to button', async () => {
const tooltip = 'Edit this item';
const {button} = await renderComponent({tooltip});

await expect.element(button).toHaveAttribute('title', tooltip);
});

it('should have correct aria-label', async () => {
const {button} = await renderComponent();
await expect.element(button).toHaveAttribute('aria-label', 'Edit');
});

it('should render with default empty tooltip', async () => {
const {button} = await renderComponent();
await expect.element(button).toHaveAttribute('title', '');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {html, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import {renderIconButton} from '@/src/components/common/icon-button';
import {withTailwindStyles} from '@/src/decorators/with-tailwind-styles';
import EditIcon from '../../../images/edit.svg';

/**
* The `atomic-insight-edit-toggle` component provides an edit button for insight interfaces.
*
* @part insight-edit-toggle-container - The container element wrapping the edit toggle icon button.
* @part insight-edit-toggle-button - The edit button element.
* @part insight-edit-toggle-icon - The edit icon element displayed inside the button.
*/
@customElement('atomic-insight-edit-toggle')
@withTailwindStyles
export class AtomicInsightEditToggle extends LitElement {
/**
* The callback function to be executed when the button is clicked.
*/
@property({type: Function}) public clickCallback: () => void = () => {};

/**
* The tooltip text to display on hover.
*/
@property({type: String}) public tooltip = '';

protected render() {
return html`${renderIconButton({
props: {
partPrefix: 'insight-edit-toggle',
style: 'outline-neutral',
icon: EditIcon,
ariaLabel: 'Edit',
onClick: this.clickCallback,
title: this.tooltip,
},
})}`;
}
}

declare global {
interface HTMLElementTagNameMap {
'atomic-insight-edit-toggle': AtomicInsightEditToggle;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {expect, test} from './fixture';

test.describe('edit toggle', () => {
test.beforeEach(async ({editToggle}) => {
await editToggle.load();
});

test('should display the edit toggle button', async ({editToggle}) => {
await expect(editToggle.editButton).toBeVisible();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {test as base} from '@playwright/test';
import {EditTogglePageObject} from './page-object';

type AtomicInsightEditToggleE2EFixtures = {
editToggle: EditTogglePageObject;
};

export const test = base.extend<AtomicInsightEditToggleE2EFixtures>({
editToggle: async ({page}, use) => {
await use(new EditTogglePageObject(page));
},
});

export {expect} from '@playwright/test';
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type {Page} from '@playwright/test';
import {BasePageObject} from '@/playwright-utils/lit-base-page-object';

export class EditTogglePageObject extends BasePageObject {
constructor(page: Page) {
super(page, 'atomic-insight-edit-toggle');
}

get editButton() {
return this.page.getByRole('button', {name: 'Edit'});
}
}
1 change: 1 addition & 0 deletions packages/atomic/src/components/insight/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Auto-generated file
export {AtomicInsightEditToggle} from './atomic-insight-edit-toggle/atomic-insight-edit-toggle.js';
export {AtomicInsightFullSearchButton} from './atomic-insight-full-search-button/atomic-insight-full-search-button.js';
export {AtomicInsightGenerateAnswerButton} from './atomic-insight-generate-answer-button/atomic-insight-generate-answer-button.js';
export {AtomicInsightInterface} from './atomic-insight-interface/atomic-insight-interface.js';
Expand Down
Loading
Loading