Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b3586c8
[UIK-5640][radio-cards] new component/stories/unit tests
slizhevskyv-semrush Aug 4, 2026
6bf93e1
[UIK-5640][radio-cards] add doc page/props description/changelog & pa…
slizhevskyv-semrush Aug 4, 2026
2ccfdca
[UIK-5640][radio-cards] add default color for addons
slizhevskyv-semrush Aug 5, 2026
09b0876
[UIK-5640][radio-cards] add default color for addons
slizhevskyv-semrush Aug 5, 2026
5988718
[UIK-5640][radio-cards] update styles/package.json
slizhevskyv-semrush Aug 5, 2026
6ecf7c4
[UIK-5640][radio-cards] update styles/package.json
slizhevskyv-semrush Aug 5, 2026
247b944
[UIK-5640][radio-cards] update styles/markup for advanced mode
slizhevskyv-semrush Aug 7, 2026
8c5c117
Merge branch 'UIK-5351/add-more-variables-to-theme' into UIK-5640/rad…
Valeria-Zimnitskaya Aug 12, 2026
a1beee3
Merge branch 'UIK-5351/add-more-variables-to-theme' into UIK-5640/rad…
Valeria-Zimnitskaya Aug 13, 2026
8f1f0e3
[stories] update test stories
Valeria-Zimnitskaya Aug 14, 2026
50b3e84
[chore] add tests
Valeria-Zimnitskaya Aug 14, 2026
14a0549
[pills] remove pill example
Valeria-Zimnitskaya Aug 14, 2026
6970455
[stories] update fills file
Valeria-Zimnitskaya Aug 18, 2026
2ce76df
[UIK-5640][radio-cards] PR fixes
slizhevskyv-semrush Aug 18, 2026
25b67bb
Merge branch 'UIK-5640/radio-cards' of github.com:semrush/intergalact…
slizhevskyv-semrush Aug 18, 2026
81f3e28
Merge branch 'UIK-5351/add-more-variables-to-theme' into UIK-5640/rad…
Valeria-Zimnitskaya Aug 19, 2026
b57ab85
[chore] update test story and axe test
Valeria-Zimnitskaya Aug 19, 2026
0ef88e8
[UIK-5640][radio-cards] PR fixes
slizhevskyv-semrush Aug 19, 2026
9bad493
Merge branch 'UIK-5640/radio-cards' of github.com:semrush/intergalact…
slizhevskyv-semrush Aug 19, 2026
9ce4681
[chore] Merge branch 'UIK-5640/radio-cards' of https://github.com/sem…
Valeria-Zimnitskaya Aug 19, 2026
f302687
[UIK-5640][radio-cards] PR fixes
slizhevskyv-semrush Aug 19, 2026
e6718e0
[UIK-5640][radio-cards] PR fixes
slizhevskyv-semrush Aug 20, 2026
5203233
[UIK-5640][radio-cards] PR fixes
slizhevskyv-semrush Aug 20, 2026
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
21 changes: 20 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 0 additions & 7 deletions semcore/pills/__tests__/pills.axe-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,4 @@ test.describe(`@pills ${TAG.ACCESSIBILITY}`, () => {
const violations = await getAccessibilityViolations({ page });
expect(violations).toEqual([]);
});

test('Custom pills example', async ({ page }) => {
await loadPage(page, 'stories/components/pills/docs/examples/custom_pills_example.tsx', 'en');

const violations = await getAccessibilityViolations({ page });
expect(violations).toEqual([]);
});
});
22 changes: 0 additions & 22 deletions semcore/pills/__tests__/pills.browser-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,28 +68,6 @@ test.describe(`${TAG.VISUAL}`, () => {
});
});

test('Verify custom pills', {
tag: [TAG.PRIORITY_HIGH, '@pills'],
}, async ({ page }) => {
await loadPage(page, 'stories/components/pills/docs/examples/custom_pills_example.tsx', 'en');

await test.step('Verify hover state', async () => {
await locators.pillsItem(page).nth(1).hover();
await expect(page).toHaveScreenshot();
});

await test.step('Verify focus state', async () => {
await page.keyboard.press('Tab');
await expect(page).toHaveScreenshot();
});

await test.step('Verify navigation and hover', async () => {
await page.keyboard.press('ArrowRight');
await locators.pillsItem(page).nth(1).hover();
await expect(page).toHaveScreenshot();
});
});

test('Verify pills with tab panel', {
tag: [TAG.PRIORITY_HIGH, '@pills'],
}, async ({ page }) => {
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
5 changes: 5 additions & 0 deletions semcore/radio-cards/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
__tests__
src
tsconfig.json
tsconfig.tsbuildinfo
9 changes: 9 additions & 0 deletions semcore/radio-cards/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog

CHANGELOG.md standards are inspired by [keepachangelog.com](https://keepachangelog.com/en/1.0.0/).

## [18.0.0] - 2026-08-04

### Added

- `RadioCards` component.
37 changes: 37 additions & 0 deletions semcore/radio-cards/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# @semcore/radio-cards

[![version](https://img.shields.io/npm/v/@semcore/radio-cards.svg)](https://www.npmjs.com/@semcore/radio-cards)
[![downloads](https://img.shields.io/npm/dt/@semcore/radio-cards.svg)](https://www.npmjs.com/package/@semcore/radio-cards)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/semrush/intergalactic/blob/HEAD/LICENSE)

> This component is part of the Intergalactic Design System

### 📖 [Component documentation](https://developer.semrush.com/intergalactic/components/radio-cards/)

### 🏠 [Design system](https://developer.semrush.com/intergalactic/)

## Install

```sh
npm install @semcore/radio-cards
```



## 👤 Author

[UI-kit team](https://github.com/semrush/intergalactic/blob/HEAD/MAINTAINERS) and [others ❤️](https://github.com/semrush/intergalactic/graphs/contributors)

## 🤝 Contributing

Contributions, issues and feature requests are welcome!

Feel free to check [issues page](https://github.com/semrush/intergalactic/issues). You can also take a look at the [contributing guide](https://github.com/semrush/intergalactic/blob/HEAD/CONTRIBUTING.md).

## Show your support

Give a ⭐️ if this project helped you!

## 📝 License

This project is [MIT](https://github.com/semrush/intergalactic/blob/HEAD/LICENSE) licensed.
42 changes: 42 additions & 0 deletions semcore/radio-cards/__tests__/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`RadioCards > Verify data-ui-name 1`] = `
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"uiName": "Text",
},
],
"uiName": "Flex",
},
],
"uiName": "RadioCards.Item",
},
{
"children": [
{
"children": [
{
"children": [],
"uiName": "Text",
},
],
"uiName": "Flex",
},
],
"uiName": "RadioCards.Item",
},
],
"uiName": "RadioCards",
},
],
"uiName": null,
}
`;
107 changes: 107 additions & 0 deletions semcore/radio-cards/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { extractUIName } from '@semcore/testing-utils/shared/extractUINameTree.ts';
import { runDependencyCheckTests } from '@semcore/testing-utils/shared-tests';
import { render, cleanup, userEvent } from '@semcore/testing-utils/testing-library';
import { expect, test, describe, beforeEach, vi } from '@semcore/testing-utils/vitest';
import React from 'react';

import RadioCards from '../src';

describe('pills Dependency imports', () => {
runDependencyCheckTests('radio-cards');
});

describe('RadioCards', () => {
beforeEach(cleanup);

test('Verify data-ui-name', () => {
const radioCards = (
<RadioCards aria-label='Radio cards' value='1'>
<RadioCards.Item value='1' text='1' />
<RadioCards.Item value='2' text='2' />
</RadioCards>
);

const { container } = render(radioCards);
const result = extractUIName(container);

expect(result).toMatchSnapshot();
});

test('calls onChange with selected value', async () => {
const onChange = vi.fn();

const { getByRole } = render(
<RadioCards aria-label='Radio cards' value='' onChange={onChange}>
<RadioCards.Item value='1'>1</RadioCards.Item>
<RadioCards.Item value='2'>2</RadioCards.Item>
<RadioCards.Item value='4'>4</RadioCards.Item>
</RadioCards>,
);

await userEvent.click(getByRole('radio', { name: '4' }));

expect(onChange).toHaveBeenCalledWith(
'4',
expect.any(Object),
);
});

test('clicks aren\'t propagated on disabled tab', async () => {
const spy = vi.fn();

const { getByRole } = render(
<RadioCards aria-label='Radio cards' value='' onChange={spy}>
<RadioCards.Item value='1'>1</RadioCards.Item>
<RadioCards.Item value='2'>2</RadioCards.Item>
<RadioCards.Item value='3'>3</RadioCards.Item>
<RadioCards.Item value='4' disabled>4</RadioCards.Item>
</RadioCards>,
);

await expect(userEvent.click(getByRole('radio', { name: '4' }))).rejects.toThrow('pointer-events: none');
expect(spy).not.toHaveBeenCalled();
});

test('does not call onChange when group is disabled', async () => {
const spy = vi.fn();

const { getByRole } = render(
<RadioCards
aria-label='Radio cards'
value=''
disabled
onChange={spy}
>
<RadioCards.Item value='1'>1</RadioCards.Item>
<RadioCards.Item value='2'>2</RadioCards.Item>
</RadioCards>,
);

await expect(userEvent.click(getByRole('radio', { name: '2' }))).rejects.toThrow('pointer-events: none');
expect(spy).not.toHaveBeenCalled();
});

test('supports keyboard navigation with ArrowRight', async () => {
const spy = vi.fn();

const { getByRole } = render(
<RadioCards aria-label='Radio cards' value='1' onChange={spy}>
<RadioCards.Item value='1'>1</RadioCards.Item>
<RadioCards.Item value='2'>2</RadioCards.Item>
<RadioCards.Item value='3'>3</RadioCards.Item>
</RadioCards>,
);

const firstRadio = getByRole('radio', { name: '1' });

firstRadio.focus();
expect(firstRadio).toHaveFocus();

await userEvent.keyboard('{ArrowRight}');

expect(spy).toHaveBeenCalledWith(
'2',
expect.any(Object),
);
});
});
39 changes: 39 additions & 0 deletions semcore/radio-cards/__tests__/radio-cards.axe-test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { expect, test, getAccessibilityViolations } from '@semcore/testing-utils/playwright';
import { loadPage } from '@semcore/testing-utils/shared/helpers';
import { TAG } from '@semcore/testing-utils/shared/tags';

test.describe(`@radio-cards ${TAG.ACCESSIBILITY}`, () => {
test('Basic', async ({ page }) => {
await loadPage(page, 'stories/components/radio-cards/docs/examples/basic.tsx', 'en');

{
const violations = await getAccessibilityViolations({ page });
expect(violations).toEqual([]);
}

{
await page.keyboard.press('Tab');
await page.keyboard.press('ArrowRight');

const violations = await getAccessibilityViolations({ page });
expect(violations).toEqual([]);
}
});

test('Advanced', async ({ page }) => {
await loadPage(page, 'stories/components/radio-cards/docs/examples/advanced.tsx', 'en');

{
const violations = await getAccessibilityViolations({ page });
expect(violations).toEqual([]);
}

{
await page.keyboard.press('Tab');
await page.keyboard.press('Enter');

const violations = await getAccessibilityViolations({ page });
expect(violations).toEqual([]);
}
});
});
Loading
Loading