Skip to content

Commit

Permalink
Merge branch 'master' of github.com:coveo/ui-kit into KIT-3948
Browse files Browse the repository at this point in the history
  • Loading branch information
y-lakhdar committed Feb 24, 2025
2 parents 79c649e + eed82ab commit 0789c80
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 59 deletions.
36 changes: 17 additions & 19 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,6 @@ jobs:
- uses: ./.github/actions/setup
- name: Promote NPM package to production
run: npm run promote:npm:latest
docs-prod:
needs: release
runs-on: ubuntu-latest
environment: 'Docs Production'
steps:
- name: Harden Runner
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
with:
egress-policy: audit

- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
ref: 'release/v3'
- uses: ./.github/actions/setup
- name: Notify Docs
run: npm run notify:docs
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
quantic-prod:
needs: release
runs-on: ubuntu-latest
Expand Down Expand Up @@ -159,7 +141,6 @@ jobs:
with:
name: headless-docs-${{ env.version }}
path: typedoc-headless-site/

typedoc-headless-react:
needs: release
runs-on: ubuntu-latest
Expand Down Expand Up @@ -200,7 +181,24 @@ jobs:
with:
name: headless-react-docs-${{ env.version }}
path: typedoc-headless-react-site/
docs-prod:
needs: release
runs-on: ubuntu-latest
environment: 'Docs Production'
steps:
- name: Harden Runner
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
with:
egress-policy: audit

- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
ref: 'release/v3'
- uses: ./.github/actions/setup
- name: Notify Docs
run: npm run notify:docs
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
# TODO KIT-3074 Fix the publication into the GitHub Packages, and uncomment
# github-prod:
# needs: release
Expand Down
6 changes: 2 additions & 4 deletions packages/atomic/src/components/common/button.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {FunctionalComponentWithChildren} from '@/src/utils/functional-component-utils';
import {html} from 'lit';
import {ifDefined} from 'lit/directives/if-defined.js';
import {when} from 'lit/directives/when.js';
Expand Down Expand Up @@ -40,12 +41,9 @@ export interface ButtonProps {
title?: string;
}

export const button = <T>({
export const button: FunctionalComponentWithChildren<ButtonProps> = ({
props,
children,
}: {
props: ButtonProps;
children: T;
}) => {
const rippleColor = getRippleColorForButtonStyle(props.style);
const className = getClassNameForButtonStyle(props.style);
Expand Down
9 changes: 5 additions & 4 deletions packages/atomic/src/components/common/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ describe('checkbox', () => {
const renderCheckbox = (props: Partial<CheckboxProps>): HTMLButtonElement => {
render(
html`${checkbox({
...props,
checked: props.checked ?? false,
onToggle: props.onToggle ?? vi.fn(),
props: {
...props,
checked: props.checked ?? false,
onToggle: props.onToggle ?? vi.fn(),
},
})}`,
container
);
Expand Down Expand Up @@ -111,7 +113,6 @@ describe('checkbox', () => {
expect(button).toHaveClass(
'w-4',
// TODO: KIT-3907
// @ts-expect-error the typing is incorrect. matchers should be a string[]
'h-4',
'grid',
'place-items-center',
Expand Down
5 changes: 3 additions & 2 deletions packages/atomic/src/components/common/checkbox.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {html, TemplateResult} from 'lit';
import {FunctionalComponent} from '@/src/utils/functional-component-utils';
import {html} from 'lit';
import {classMap} from 'lit/directives/class-map.js';
import {ifDefined} from 'lit/directives/if-defined.js';
import {ref, RefOrCallback} from 'lit/directives/ref.js';
Expand Down Expand Up @@ -26,7 +27,7 @@ export interface CheckboxProps {
onMouseDown?(evt: MouseEvent): void;
}

export const checkbox = (props: CheckboxProps): TemplateResult => {
export const checkbox: FunctionalComponent<CheckboxProps> = ({props}) => {
const partName = props.part ?? 'checkbox';
const baseClassNames =
'w-4 h-4 grid place-items-center rounded no-outline hover:border-primary-light focus-visible:border-primary-light';
Expand Down
11 changes: 4 additions & 7 deletions packages/atomic/src/components/common/heading.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,10 @@ describe('heading', () => {
children?: string
): HTMLElement => {
render(
html`${heading(
{
...props,
level: props.level ?? 1,
},
html`${children}`
)}`,
html` ${heading({
props: {...props, level: props.level ?? 1},
children: html`${children}`,
})}`,
container
);
return within(container).getByRole(
Expand Down
11 changes: 7 additions & 4 deletions packages/atomic/src/components/common/heading.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {FunctionalComponentWithChildren} from '@/src/utils/functional-component-utils';
import {ifDefined} from 'lit/directives/if-defined.js';
import {html, literal, unsafeStatic} from 'lit/static-html.js';

Expand All @@ -18,10 +19,12 @@ export interface HeadingProps {
part?: string;
}

export const heading = <T>(
{level, class: classname, part}: HeadingProps,
children?: T
) => {
export const heading: FunctionalComponentWithChildren<HeadingProps> = ({
props,
children,
}) => {
const {level, class: classname, part} = props;

const headingTag =
level > 0 && level <= 6 ? unsafeStatic(`h${level}`) : literal`div`;

Expand Down
70 changes: 70 additions & 0 deletions packages/atomic/src/components/common/load-more/button.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import enTranslations from '@/dist/atomic/lang/en.json';
import i18next, {i18n as I18n} from 'i18next';
import {html, render} from 'lit';
import {loadMoreButton} from './button';

describe('loadMoreButton', () => {
let container: HTMLElement;
let i18n: I18n;

beforeAll(async () => {
i18n = i18next.createInstance();
await i18n.init({
lng: 'en',
resources: {
en: {
translation: enTranslations,
},
},
});
});

beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});

afterEach(() => {
document.body.removeChild(container);
});

const renderLoadMoreButton = (props: {
moreAvailable: boolean;
label?: 'load-more-results' | 'load-more-products';
}) => {
render(
html`${loadMoreButton({
props: {
i18n,
onClick: () => {},
moreAvailable: props.moreAvailable,
label: props.label ?? 'load-more-results',
},
})}`,
container
);
};

test('should render nothing when moreAvailable is false', () => {
renderLoadMoreButton({moreAvailable: false});

expect(container).toBeEmptyDOMElement();
});

test('should render a button with the correct props', () => {
renderLoadMoreButton({moreAvailable: true});

const button = container.querySelector('button');
expect(button).toHaveClass('btn-primary');
expect(button).toHaveClass('my-2');
expect(button).toHaveClass('p-3');
expect(button).toHaveClass('font-bold');
});

test('should render the children as the label', () => {
renderLoadMoreButton({moreAvailable: true, label: 'load-more-products'});

const button = container.querySelector('button');
expect(button).toHaveTextContent('Load more products');
});
});
23 changes: 13 additions & 10 deletions packages/atomic/src/components/common/load-more/button.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
import {FunctionalComponent} from '@/src/utils/functional-component-utils';
import {i18n} from 'i18next';
import {html} from 'lit';
import {button, ButtonProps} from '../button';

interface LoadMoreButtonProps {
i18n: i18n;
onClick: () => void;
moreAvailable: boolean;
label?: 'load-more-results' | 'load-more-products';
label: 'load-more-results' | 'load-more-products';
}

export function loadMoreButton({
i18n,
onClick,
moreAvailable,
label,
}: LoadMoreButtonProps) {
export const loadMoreButton: FunctionalComponent<LoadMoreButtonProps> = ({
props,
}) => {
const {i18n, onClick, moreAvailable, label} = props;
if (!moreAvailable) {
return;
}
const props: ButtonProps = {
const buttonProps: ButtonProps = {
style: 'primary',
part: 'load-more-results-button',
class: 'my-2 p-3 font-bold',
onClick: () => onClick(),
};
return button({props, children: i18n.t(label || 'load-more-results')});
}
return button({
props: buttonProps,
children: html`${i18n.t(label)}`,
});
};
11 changes: 6 additions & 5 deletions packages/atomic/src/components/common/radio-button.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ describe('radioButton', () => {
props: Partial<RadioButtonProps>
): HTMLInputElement => {
render(
html`${radioButton({...props, groupName: 'test-group'})}`,
html`${radioButton({props: {...props, groupName: 'test-group'}})}`,
container
);

return within(container).getByRole('radio');
};

Expand Down Expand Up @@ -69,9 +70,9 @@ describe('radioButton', () => {
};

render(
html`${radioButton({...props, text: 'radio-1'})}
${radioButton({...props, text: 'radio-2'})}
${radioButton({...props, text: 'radio-3'})}`,
html`${radioButton({props: {...props, text: 'radio-1'}})}
${radioButton({props: {...props, text: 'radio-2'}})}
${radioButton({props: {...props, text: 'radio-3'}})}`,
container
);

Expand Down Expand Up @@ -131,7 +132,7 @@ describe('radioButton', () => {
ref,
};

render(html`${radioButton(props)}`, container);
render(html`${radioButton({props})}`, container);

expect(ref).toHaveBeenCalled();
});
Expand Down
5 changes: 3 additions & 2 deletions packages/atomic/src/components/common/radio-button.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {html, TemplateResult} from 'lit';
import {FunctionalComponent} from '@/src/utils/functional-component-utils';
import {html} from 'lit';
import {classMap} from 'lit/directives/class-map.js';
import {ifDefined} from 'lit/directives/if-defined.js';
import {ref, RefOrCallback} from 'lit/directives/ref.js';
Expand Down Expand Up @@ -31,7 +32,7 @@ export interface RadioButtonProps {
ref?: RefOrCallback;
}

export const radioButton = (props: RadioButtonProps): TemplateResult => {
export const radioButton: FunctionalComponent<RadioButtonProps> = ({props}) => {
const classNames = {
'btn-radio': true,
selected: Boolean(props.checked),
Expand Down
18 changes: 18 additions & 0 deletions packages/atomic/src/utils/functional-component-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {TemplateResult} from 'lit';

export interface FunctionalComponent<T> {
({props}: {props: T}): TemplateResult | undefined;
}

export interface FunctionalComponentWithChildren<T> {
({
props,
children,
}: {
props: T;
children:
| TemplateResult
| TemplateResult[]
| (TemplateResult | undefined)[];
}): TemplateResult;
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export default function SearchBox(props: ISearchBoxProps) {

controller.updateText(e.target.value);
instantProductsController.updateQuery(e.target.value);
controller.showSuggestions();
showDropdown();
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export default function StandaloneSearchBox(props: IStandaloneSearchBoxProps) {

controller.updateText(e.target.value);
instantProductsController.updateQuery(e.target.value);
controller.showSuggestions();
showDropdown();
};

Expand Down

0 comments on commit 0789c80

Please sign in to comment.