Skip to content

Commit 871ded9

Browse files
Copiloty-lakhdardeveloper-experience-bot[bot]
authored
feat(atomic): migrate atomic-sort-expression from Stencil to Lit (#6653)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: y-lakhdar <12199712+y-lakhdar@users.noreply.github.com> Co-authored-by: ylakhdar <ylakhdar@coveo.com> Co-authored-by: developer-experience-bot[bot] <91079284+developer-experience-bot[bot]@users.noreply.github.com>
1 parent 296d09a commit 871ded9

File tree

9 files changed

+466
-87
lines changed

9 files changed

+466
-87
lines changed

packages/atomic-react/src/components/search/components.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
AtomicSearchLayout as LitAtomicSearchLayout,
4646
AtomicSegmentedFacetScrollable as LitAtomicSegmentedFacetScrollable,
4747
AtomicSortDropdown as LitAtomicSortDropdown,
48+
AtomicSortExpression as LitAtomicSortExpression,
4849
AtomicTab as LitAtomicTab,
4950
AtomicText as LitAtomicText,
5051
} from '@coveo/atomic/components';
@@ -327,6 +328,12 @@ export const AtomicSortDropdown = createComponent({
327328
elementClass: LitAtomicSortDropdown,
328329
});
329330

331+
export const AtomicSortExpression = createComponent({
332+
tagName: 'atomic-sort-expression',
333+
react: React,
334+
elementClass: LitAtomicSortExpression,
335+
});
336+
330337
export const AtomicTab = createComponent({
331338
tagName: 'atomic-tab',
332339
react: React,

packages/atomic/src/components.d.ts

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,27 +1781,6 @@ export namespace Components {
17811781
*/
17821782
"snippetStyle"?: string;
17831783
}
1784-
/**
1785-
* The `atomic-sort-expression` component defines a sort expression. This component must be inside an `atomic-sort-dropdown` component.
1786-
*/
1787-
interface AtomicSortExpression {
1788-
/**
1789-
* One or more sort criteria that the end user can select or toggle between. The available sort criteria are: * `relevancy` * `date ascending`/`date descending` * `qre` * `<FIELD> ascending`/`<FIELD> descending`, where you replace `<FIELD>` with the name of a sortable field in your index (`criteria="size ascending"`). You can specify multiple sort criteria to be used in the same request by separating them with a comma (`criteria="size ascending, date ascending"`). You can specify a list of comma-separated sort criteria which will be applied sequentially. For example, if there's a tie on the 1st criterion, the API uses the 2nd criterion to break the tie. However, this only works when combining: * a relevancy criterion followed by one or more field or date criteria. * a qre criterion followed by one or more field or date criteria. * two or more field criteria (`<FIELD>` descending, `<FIELD>` descending). * a single date criterion and one or more field criteria in any order (`<FIELD>` descending, date ascending). Examples: * `relevancy`, `<FIELD> descending` * `qre`, `<FIELD> ascending` * `date descending`, `<FIELD> descending`, `<FIELD> ascending`
1790-
*/
1791-
"expression": string;
1792-
/**
1793-
* The non-localized label to display for this expression.
1794-
*/
1795-
"label": string;
1796-
/**
1797-
* The tabs on which the sort expression must not be displayed. This property should not be used at the same time as `tabs-included`. Set this property as a stringified JSON array, for example: ```html <atomic-sort-expression tabs-excluded='["tabIDA", "tabIDB"]'></atomic-sort-expression> ``` If you don't set this property, the sort expression can be displayed on any tab. Otherwise, the sort expression won't be displayed on any of the specified tabs.
1798-
*/
1799-
"tabsExcluded": string[] | string;
1800-
/**
1801-
* The tabs on which the sort expression can be displayed. This property should not be used at the same time as `tabs-excluded`. Set this property as a stringified JSON array, for example: ```html <atomic-sort-expression tabs-included='["tabIDA", "tabIDB"]'></atomic-sort-expression snippet> ``` If you don't set this property, the sort expression can be displayed on any tab. Otherwise, the sort expression can only be displayed on the specified tabs.
1802-
*/
1803-
"tabsIncluded": string[] | string;
1804-
}
18051784
/**
18061785
* @deprecated Use `atomic-facet-date-input` instead. This component is meant to be used with Stencil components only.
18071786
* Internal component made to be integrated in a TimeframeFacet.
@@ -2939,15 +2918,6 @@ declare global {
29392918
prototype: HTMLAtomicSmartSnippetSuggestionsElement;
29402919
new (): HTMLAtomicSmartSnippetSuggestionsElement;
29412920
};
2942-
/**
2943-
* The `atomic-sort-expression` component defines a sort expression. This component must be inside an `atomic-sort-dropdown` component.
2944-
*/
2945-
interface HTMLAtomicSortExpressionElement extends Components.AtomicSortExpression, HTMLStencilElement {
2946-
}
2947-
var HTMLAtomicSortExpressionElement: {
2948-
prototype: HTMLAtomicSortExpressionElement;
2949-
new (): HTMLAtomicSortExpressionElement;
2950-
};
29512921
interface HTMLAtomicStencilFacetDateInputElementEventMap {
29522922
"atomic/dateInputApply": any;
29532923
}
@@ -3130,7 +3100,6 @@ declare global {
31303100
"atomic-smart-snippet-feedback-modal": HTMLAtomicSmartSnippetFeedbackModalElement;
31313101
"atomic-smart-snippet-source": HTMLAtomicSmartSnippetSourceElement;
31323102
"atomic-smart-snippet-suggestions": HTMLAtomicSmartSnippetSuggestionsElement;
3133-
"atomic-sort-expression": HTMLAtomicSortExpressionElement;
31343103
"atomic-stencil-facet-date-input": HTMLAtomicStencilFacetDateInputElement;
31353104
"atomic-suggestion-renderer": HTMLAtomicSuggestionRendererElement;
31363105
"atomic-tab-bar": HTMLAtomicTabBarElement;
@@ -4858,27 +4827,6 @@ declare namespace LocalJSX {
48584827
*/
48594828
"snippetStyle"?: string;
48604829
}
4861-
/**
4862-
* The `atomic-sort-expression` component defines a sort expression. This component must be inside an `atomic-sort-dropdown` component.
4863-
*/
4864-
interface AtomicSortExpression {
4865-
/**
4866-
* One or more sort criteria that the end user can select or toggle between. The available sort criteria are: * `relevancy` * `date ascending`/`date descending` * `qre` * `<FIELD> ascending`/`<FIELD> descending`, where you replace `<FIELD>` with the name of a sortable field in your index (`criteria="size ascending"`). You can specify multiple sort criteria to be used in the same request by separating them with a comma (`criteria="size ascending, date ascending"`). You can specify a list of comma-separated sort criteria which will be applied sequentially. For example, if there's a tie on the 1st criterion, the API uses the 2nd criterion to break the tie. However, this only works when combining: * a relevancy criterion followed by one or more field or date criteria. * a qre criterion followed by one or more field or date criteria. * two or more field criteria (`<FIELD>` descending, `<FIELD>` descending). * a single date criterion and one or more field criteria in any order (`<FIELD>` descending, date ascending). Examples: * `relevancy`, `<FIELD> descending` * `qre`, `<FIELD> ascending` * `date descending`, `<FIELD> descending`, `<FIELD> ascending`
4867-
*/
4868-
"expression": string;
4869-
/**
4870-
* The non-localized label to display for this expression.
4871-
*/
4872-
"label": string;
4873-
/**
4874-
* The tabs on which the sort expression must not be displayed. This property should not be used at the same time as `tabs-included`. Set this property as a stringified JSON array, for example: ```html <atomic-sort-expression tabs-excluded='["tabIDA", "tabIDB"]'></atomic-sort-expression> ``` If you don't set this property, the sort expression can be displayed on any tab. Otherwise, the sort expression won't be displayed on any of the specified tabs.
4875-
*/
4876-
"tabsExcluded"?: string[] | string;
4877-
/**
4878-
* The tabs on which the sort expression can be displayed. This property should not be used at the same time as `tabs-excluded`. Set this property as a stringified JSON array, for example: ```html <atomic-sort-expression tabs-included='["tabIDA", "tabIDB"]'></atomic-sort-expression snippet> ``` If you don't set this property, the sort expression can be displayed on any tab. Otherwise, the sort expression can only be displayed on the specified tabs.
4879-
*/
4880-
"tabsIncluded"?: string[] | string;
4881-
}
48824830
/**
48834831
* @deprecated Use `atomic-facet-date-input` instead. This component is meant to be used with Stencil components only.
48844832
* Internal component made to be integrated in a TimeframeFacet.
@@ -5124,7 +5072,6 @@ declare namespace LocalJSX {
51245072
"atomic-smart-snippet-feedback-modal": AtomicSmartSnippetFeedbackModal;
51255073
"atomic-smart-snippet-source": AtomicSmartSnippetSource;
51265074
"atomic-smart-snippet-suggestions": AtomicSmartSnippetSuggestions;
5127-
"atomic-sort-expression": AtomicSortExpression;
51285075
"atomic-stencil-facet-date-input": AtomicStencilFacetDateInput;
51295076
"atomic-suggestion-renderer": AtomicSuggestionRenderer;
51305077
"atomic-tab-bar": AtomicTabBar;
@@ -5429,10 +5376,6 @@ declare module "@stencil/core" {
54295376
* ```
54305377
*/
54315378
"atomic-smart-snippet-suggestions": LocalJSX.AtomicSmartSnippetSuggestions & JSXBase.HTMLAttributes<HTMLAtomicSmartSnippetSuggestionsElement>;
5432-
/**
5433-
* The `atomic-sort-expression` component defines a sort expression. This component must be inside an `atomic-sort-dropdown` component.
5434-
*/
5435-
"atomic-sort-expression": LocalJSX.AtomicSortExpression & JSXBase.HTMLAttributes<HTMLAtomicSortExpressionElement>;
54365379
/**
54375380
* @deprecated Use `atomic-facet-date-input` instead. This component is meant to be used with Stencil components only.
54385381
* Internal component made to be integrated in a TimeframeFacet.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { Meta } from '@storybook/addon-docs/blocks';
2+
import * as AtomicSortExpressionStories from './atomic-sort-expression.new.stories';
3+
import { AtomicDocTemplate } from '../../../../storybook-utils/documentation/atomic-doc-template';
4+
5+
6+
<Meta of={AtomicSortExpressionStories} />
7+
8+
<AtomicDocTemplate
9+
stories={AtomicSortExpressionStories}
10+
githubPath="search/atomic-sort-expression/atomic-sort-expression.ts"
11+
tagName="atomic-sort-expression"
12+
className="AtomicSortExpression"
13+
>
14+
15+
The `atomic-sort-expression` component defines a sort expression. This component must be inside an `atomic-sort-dropdown` component.
16+
17+
This component is not used standalone. It must be a child of `atomic-sort-dropdown`.
18+
19+
See the [atomic-sort-dropdown documentation](?path=/docs/atomic-sort-dropdown--docs) for additional usage examples.
20+
21+
```html
22+
<atomic-search-interface>
23+
<!-- other components -->
24+
25+
<atomic-sort-dropdown>
26+
<atomic-sort-expression label="Relevance" expression="relevancy"></atomic-sort-expression>
27+
<atomic-sort-expression label="Newest" expression="date descending"></atomic-sort-expression>
28+
<atomic-sort-expression label="Oldest" expression="date ascending"></atomic-sort-expression>
29+
<atomic-sort-expression label="Size" expression="size descending"></atomic-sort-expression>
30+
</atomic-sort-dropdown>
31+
32+
<!-- other components -->
33+
</atomic-search-interface>
34+
```
35+
36+
## Sort Criteria
37+
38+
The available sort criteria are:
39+
40+
- `relevancy` - Sort by relevance score
41+
- `date ascending` / `date descending` - Sort by date
42+
- `qre` - Sort using Query Ranking Expression
43+
- `<FIELD> ascending` / `<FIELD> descending` - Sort by a specific field (e.g., `size ascending`)
44+
45+
### Complex Sort Expressions
46+
47+
You can specify multiple sort criteria separated by commas. The API applies them sequentially:
48+
49+
```html
50+
<atomic-sort-expression
51+
label="Size then Date"
52+
expression="size ascending, date descending">
53+
</atomic-sort-expression>
54+
```
55+
56+
Valid combinations:
57+
- A relevancy criterion followed by field or date criteria
58+
- A qre criterion followed by field or date criteria
59+
- Two or more field criteria
60+
- A date criterion and one or more field criteria
61+
62+
## Tab Filtering
63+
64+
### tabs-included
65+
66+
Specify which tabs should display this sort expression:
67+
68+
```html
69+
<atomic-sort-expression
70+
label="Relevance"
71+
expression="relevancy"
72+
tabs-included='["all", "documents"]'>
73+
</atomic-sort-expression>
74+
```
75+
76+
### tabs-excluded
77+
78+
Specify which tabs should NOT display this sort expression:
79+
80+
```html
81+
<atomic-sort-expression
82+
label="Date"
83+
expression="date descending"
84+
tabs-excluded='["images"]'>
85+
</atomic-sort-expression>
86+
```
87+
88+
> **Note:** Do not use both `tabs-included` and `tabs-excluded` on the same component, as this may lead to unexpected behavior.
89+
90+
## Related Components
91+
92+
- [atomic-sort-dropdown](?path=/docs/atomic-sort-dropdown--docs): Renders a dropdown that allows users to select sort criteria
93+
94+
</AtomicDocTemplate>

packages/atomic/src/components/search/atomic-sort-expression/atomic-sort-expression.new.stories.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type {Meta, StoryObj as Story} from '@storybook/web-components-vite';
22
import {getStorybookHelpers} from '@wc-toolkit/storybook-helpers';
33
import {html} from 'lit/static-html.js';
4+
import {MockSearchApi} from '@/storybook-utils/api/search/mock';
45
import {parameters} from '@/storybook-utils/common/common-meta-parameters';
56
import {wrapInSearchInterface} from '@/storybook-utils/search/search-interface-wrapper';
67

8+
const searchApiHarness = new MockSearchApi();
79
const {decorator, play} = wrapInSearchInterface();
810
const {events, args, argTypes, template} = getStorybookHelpers(
911
'atomic-sort-expression',
@@ -24,6 +26,9 @@ const meta: Meta = {
2426
],
2527
parameters: {
2628
...parameters,
29+
msw: {
30+
handlers: [...searchApiHarness.handlers],
31+
},
2732
actions: {
2833
handles: events,
2934
},
@@ -43,3 +48,37 @@ export const Default: Story = {
4348
expression: 'relevancy',
4449
},
4550
};
51+
52+
export const DateDescending: Story = {
53+
name: 'Date Descending Sort',
54+
args: {
55+
label: 'Newest',
56+
expression: 'date descending',
57+
},
58+
};
59+
60+
export const WithTabsIncluded: Story = {
61+
name: 'With Tabs Included',
62+
args: {
63+
label: 'Relevance',
64+
expression: 'relevancy',
65+
'tabs-included': '["all", "documents"]',
66+
},
67+
};
68+
69+
export const WithTabsExcluded: Story = {
70+
name: 'With Tabs Excluded',
71+
args: {
72+
label: 'Relevance',
73+
expression: 'relevancy',
74+
'tabs-excluded': '["images"]',
75+
},
76+
};
77+
78+
export const ComplexExpression: Story = {
79+
name: 'Complex Sort Expression',
80+
args: {
81+
label: 'Size then Date',
82+
expression: 'size ascending, date descending',
83+
},
84+
};

0 commit comments

Comments
 (0)