diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c6c122843e..7d039e4916 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1568,6 +1568,22 @@ importers: specifier: workspace:* version: link:../../tools/testing-utils + semcore/radio-cards: + dependencies: + '@semcore/typography': + specifier: ^17.2.1 + version: link:../typography + devDependencies: + '@semcore/base-components': + specifier: workspace:* + version: link:../base-components + '@semcore/core': + specifier: workspace:* + version: link:../core + '@semcore/testing-utils': + specifier: workspace:* + version: link:../../tools/testing-utils + semcore/select: dependencies: '@semcore/base-trigger': diff --git a/semcore/radio-cards/.npmignore b/semcore/radio-cards/.npmignore new file mode 100644 index 0000000000..036da2936b --- /dev/null +++ b/semcore/radio-cards/.npmignore @@ -0,0 +1,5 @@ +node_modules +__tests__ +src +tsconfig.json +tsconfig.tsbuildinfo diff --git a/semcore/radio-cards/CHANGELOG.md b/semcore/radio-cards/CHANGELOG.md new file mode 100644 index 0000000000..edc662bcc8 --- /dev/null +++ b/semcore/radio-cards/CHANGELOG.md @@ -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. diff --git a/semcore/radio-cards/README.md b/semcore/radio-cards/README.md new file mode 100644 index 0000000000..08de0012d7 --- /dev/null +++ b/semcore/radio-cards/README.md @@ -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. diff --git a/semcore/radio-cards/__tests__/index.test.tsx b/semcore/radio-cards/__tests__/index.test.tsx new file mode 100644 index 0000000000..c67a10c0a2 --- /dev/null +++ b/semcore/radio-cards/__tests__/index.test.tsx @@ -0,0 +1,92 @@ +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('calls onChange with selected value', async () => { + const onChange = vi.fn(); + + const { getByRole } = render( + + 1 + 2 + 4 + , + ); + + 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( + + 1 + 2 + 3 + 4 + , + ); + + 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( + + 1 + 2 + , + ); + + 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( + + 1 + 2 + 3 + , + ); + + const firstRadio = getByRole('radio', { name: '1' }); + + firstRadio.focus(); + expect(firstRadio).toHaveFocus(); + + await userEvent.keyboard('{ArrowRight}'); + + expect(spy).toHaveBeenCalledWith( + '2', + expect.any(Object), + ); + }); +}); diff --git a/semcore/radio-cards/package.json b/semcore/radio-cards/package.json new file mode 100644 index 0000000000..7b1583f3d0 --- /dev/null +++ b/semcore/radio-cards/package.json @@ -0,0 +1,35 @@ +{ + "name": "@semcore/radio-cards", + "description": "Semrush RadioCards Component", + "version": "18.0.0", + "main": "lib/cjs/index.js", + "module": "lib/es6/index.js", + "typings": "lib/types/index.d.ts", + "sideEffects": false, + "author": "UI-kit team ", + "license": "MIT", + "scripts": { + "build": "pnpm semcore-builder && pnpm vite build" + }, + "exports": { + "types": "./lib/types/index.d.ts", + "import": "./lib/esm/index.mjs", + "require": "./lib/cjs/index.js" + }, + "dependencies": { + "@semcore/typography": "^17.2.1" + }, + "peerDependencies": { + "@semcore/base-components": "^17.2.1" + }, + "repository": { + "type": "git", + "url": "https://github.com/semrush/intergalactic.git", + "directory": "semcore/radio-cards" + }, + "devDependencies": { + "@semcore/core": "workspace:*", + "@semcore/base-components": "workspace:*", + "@semcore/testing-utils": "workspace:*" + } +} diff --git a/semcore/radio-cards/src/RadioCards.tsx b/semcore/radio-cards/src/RadioCards.tsx new file mode 100644 index 0000000000..e026df1b99 --- /dev/null +++ b/semcore/radio-cards/src/RadioCards.tsx @@ -0,0 +1,134 @@ +import { Flex, NeighborLocation } from '@semcore/base-components'; +import type { Intergalactic } from '@semcore/core'; +import { Root, Component, createComponent, sstyled } from '@semcore/core'; +import a11yEnhance from '@semcore/core/lib/utils/enhances/a11yEnhance'; +import { Text as SemcoreText } from '@semcore/typography'; +import React from 'react'; + +import type { NSRadioCards } from './RadioCards.type'; +import style from './styles/radio-cards.shadow.css'; + +class RadioCardsRoot extends Component< + Intergalactic.InternalTypings.InferComponentProps, + typeof RadioCardsRoot.enhance, + NSRadioCards.Handlers, + {}, + {}, + NSRadioCards.DefaultProps +> { + static displayName = 'RadioCards'; + static style = style; + + static enhance = [a11yEnhance({ + onNeighborChange: (neighborElement) => { + if (neighborElement) { + neighborElement.focus(); + neighborElement.click(); + } + }, + childSelector: () => { + const selector: [string, string] = ['role', 'radio']; + + return selector; + }, + })] as const; + + static defaultProps = { + defaultValue: '', + } as const; + + uncontrolledProps() { + return { + value: '', + }; + } + + handleClick = (value: NSRadioCards.Value) => (e: React.MouseEvent) => { + this.handlers.value(value, e); + }; + + handleKeyDown = (value: NSRadioCards.Value) => (e: React.KeyboardEvent) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + + this.handlers.value(value, e); + } + }; + + getItemProps({ value: itemValue }: NSRadioCards.Item.Props) { + const { value, disabled } = this.asProps; + const isChecked = value === itemValue; + + return { + tabIndex: isChecked ? 0 : -1, + checked: isChecked, + disabled, + onClick: this.handleClick(itemValue), + onKeyDown: this.handleClick(itemValue), + }; + } + + render() { + const SRadioCards = Root; + const { Children, styles, value, disabled } = this.asProps; + + return sstyled(styles)( + + + + + , + ); + } +} + +function Item( + props: Intergalactic.InternalTypings.InferChildComponentProps< + NSRadioCards.Item.Component, + typeof RadioCardsRoot, + 'Item' + >, +) { + const SRadioItem = Root; + const SRadioItemHeader = Flex; + const SRadioItemHeaderLeftAddon = Flex; + const SRadioItemHeaderRightAddon = SemcoreText; + const { Children, styles, iconAddon, text, textAddon, description, disabled, checked, children } = props; + + const isAdvancedMode = children !== undefined; + + return sstyled(styles)( + + {isAdvancedMode + ? ( + + ) + : ( + <> + + {iconAddon && {iconAddon}} + {text && {text}} + {textAddon && ( + + {textAddon} + + )} + + {description && {description}} + + )} + , + ); +} + +const RadioCards = createComponent(RadioCardsRoot, { + Item, +}); + +export default RadioCards; diff --git a/semcore/radio-cards/src/RadioCards.type.ts b/semcore/radio-cards/src/RadioCards.type.ts new file mode 100644 index 0000000000..14e7ce093d --- /dev/null +++ b/semcore/radio-cards/src/RadioCards.type.ts @@ -0,0 +1,51 @@ +import type { NSFlex } from '@semcore/base-components'; +import type { Intergalactic } from '@semcore/core'; +import type { NSText } from '@semcore/typography'; + +declare namespace NSRadioCards { + type Value = string; + type Props = NSFlex.Props & Intergalactic.RequireAtLeastOne<{ + /** Accessible name for the radio group. */ + 'aria-label'?: string; + /** References an element that labels the radio group. */ + 'aria-labelledby'?: string; + }> & { + /** Currently selected radio card value. */ + value?: NSRadioCards.Value; + /** Called when the selected radio card changes. */ + onChange?: (value: NSRadioCards.Value, event?: React.SyntheticEvent) => void; + /** Disables the entire radio group and all radio cards. */ + disabled?: boolean; + }; + type DefaultProps = { + defaultValue: ''; + }; + type Handlers = { + value: NSRadioCards.Value; + }; + + namespace Item { + type Props = NSFlex.Props & { + /** Disables radio card. */ + disabled?: boolean; + /** Optional icon displayed before the content. */ + iconAddon?: React.ReactNode; + /** Optional text displayed in the header. */ + text?: string; + /** Unique value associated with the radio card. */ + value: NSRadioCards.Value; + /** Additional text displayed in the header. */ + textAddon?: string; + /** Description displayed below the header. */ + description?: string; + }; + + type Component = Intergalactic.Component<'button', Props>; + } + + type Component = Intergalactic.Component<'div', Props> & { + Item: Item.Component; + }; +} + +export type { NSRadioCards }; diff --git a/semcore/radio-cards/src/index.ts b/semcore/radio-cards/src/index.ts new file mode 100644 index 0000000000..6fb1a9626e --- /dev/null +++ b/semcore/radio-cards/src/index.ts @@ -0,0 +1,2 @@ +export { default } from './RadioCards'; +export * from './RadioCards.type'; diff --git a/semcore/radio-cards/src/styles/radio-cards.shadow.css b/semcore/radio-cards/src/styles/radio-cards.shadow.css new file mode 100644 index 0000000000..c8e0bbf478 --- /dev/null +++ b/semcore/radio-cards/src/styles/radio-cards.shadow.css @@ -0,0 +1,40 @@ +SRadioCards { + gap: var(--intergalactic-spacing-content-gap-large, 8px); +} + +SRadioItem { + flex-direction: column; + flex: 1 0 0; + gap: var(--intergalactic-spacing-content-gap-small, 4px); + padding: var(--intergalactic-spacing-content-padding-medium, 12px) var(--intergalactic-spacing-content-padding-xlarge, 20px); + align-items: flex-start; + + border-radius: var(--intergalactic-pills-rounded, 6px); + background: var(--intergalactic-control-presets-bg, oklch(1 0 0)); + box-shadow: var(--intergalactic-box-shadow-control-elevated, 0px 0px 1px 0px oklch(0.176 0.033 175.7 / 0.07), 0px 1px 3px 0px oklch(0.176 0.033 175.7 / 0.07)); + cursor: pointer; + border: 1px solid transparent; + + &:hover { + border: 1px solid var(--intergalactic-control-presets-border-hover, oklch(0.137 0.026 175.7 / 0.161)); + } + + &[aria-checked='true'] { + border: 1px solid var(--intergalactic-control-presets-border-selected, oklch(0.23 0.01 140)); + } + + &[aria-disabled='true'] { + pointer-events: none; + opacity: var(--intergalactic-disabled-opacity, 0.4); + } +} + +SRadioItemHeader { + align-items: center; + gap: var(--intergalactic-spacing-content-gap-medium, 6px); +} + +SRadioItemHeaderLeftAddon, +SRadioItemHeaderRightAddon { + color: var(--intergalactic-text-secondary, oklch(0.088 0.026 147.7 / 0.583)); +} diff --git a/semcore/radio-cards/tsconfig.json b/semcore/radio-cards/tsconfig.json new file mode 100644 index 0000000000..3ed2a1cc8b --- /dev/null +++ b/semcore/radio-cards/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.json"], + "compilerOptions": { + "rootDir": "./src" + } +} diff --git a/semcore/radio-cards/vite.config.ts b/semcore/radio-cards/vite.config.ts new file mode 100644 index 0000000000..90f46b4cb2 --- /dev/null +++ b/semcore/radio-cards/vite.config.ts @@ -0,0 +1,17 @@ +import { defineConfig, mergeConfig } from 'vite'; + +import viteConfig from '../../commonVite.config'; + +export default mergeConfig( + viteConfig, + defineConfig({ + build: { + lib: { + entry: './src/index.ts', + }, + rollupOptions: { + external: ['react', 'react-dom', 'react/jsx-runtime', /@babel\/runtime\/*/, /@semcore\/*/], + }, + }, + }), +); diff --git a/semcore/radio-cards/vitest.config.mts b/semcore/radio-cards/vitest.config.mts new file mode 100644 index 0000000000..36006d4f8e --- /dev/null +++ b/semcore/radio-cards/vitest.config.mts @@ -0,0 +1,17 @@ +import { resolve as resolvePath } from 'node:path'; + +import { defineConfig } from 'vitest/config'; + +import { vitestPlugins, vitestResolve } from '../../vitest.config.mts'; + +export default defineConfig({ + plugins: vitestPlugins, + resolve: vitestResolve, + test: { + include: [ + '__tests__/**/*.test.tsx', + ], + environment: 'jsdom', + setupFiles: [resolvePath(__dirname, '../../tools/testing-utils/setupTests')], + }, +}); diff --git a/stories/components/radio-cards/docs/examples/advanced.tsx b/stories/components/radio-cards/docs/examples/advanced.tsx new file mode 100644 index 0000000000..02c4799591 --- /dev/null +++ b/stories/components/radio-cards/docs/examples/advanced.tsx @@ -0,0 +1,39 @@ +import FileExport from '@semcore/icon/FileExport/m'; +import Info from '@semcore/icon/Info/m'; +import { Flex } from '@semcore/ui/base-components'; +import RadioCards from '@semcore/ui/radio-cards'; +import Spin from '@semcore/ui/spin'; +import Tag, { TagContainer } from '@semcore/ui/tag'; +import { Text } from '@semcore/ui/typography'; +import React from 'react'; + +const Demo = () => { + return ( + + + + + Icons everywhere! + + + Help! + + + + + Configuration...🀀 + + + + Tags! + + + + + Help! + + + ); +}; + +export default Demo; diff --git a/stories/components/radio-cards/docs/examples/basic.tsx b/stories/components/radio-cards/docs/examples/basic.tsx new file mode 100644 index 0000000000..84e6ca6202 --- /dev/null +++ b/stories/components/radio-cards/docs/examples/basic.tsx @@ -0,0 +1,15 @@ +import ThumbUp from '@semcore/icon/ThumbUp/m'; +import RadioCards from '@semcore/ui/radio-cards'; +import React from 'react'; + +const Demo = () => { + return ( + + + + } description='Secondary text' /> + + ); +}; + +export default Demo; diff --git a/stories/components/radio-cards/docs/radio-cards.stories.tsx b/stories/components/radio-cards/docs/radio-cards.stories.tsx new file mode 100644 index 0000000000..96649f2cd7 --- /dev/null +++ b/stories/components/radio-cards/docs/radio-cards.stories.tsx @@ -0,0 +1,20 @@ +import RadioCards from '@semcore/ui/radio-cards'; +import type { Meta, StoryObj } from '@storybook/react-vite'; + +import AdvancedExample from './examples/advanced'; +import BasicExample from './examples/basic'; + +const meta: Meta = { + title: 'Components/RadioCards/Documentation', + component: RadioCards, +}; + +export default meta; + +export const BasicRadioCardsExample: StoryObj = { + render: BasicExample, +}; + +export const AdvancedRadioCardsExample: StoryObj = { + render: AdvancedExample, +}; diff --git a/website/docs/.vitepress/sidebarConfig.ts b/website/docs/.vitepress/sidebarConfig.ts index a5f9562fe8..b367fece4f 100644 --- a/website/docs/.vitepress/sidebarConfig.ts +++ b/website/docs/.vitepress/sidebarConfig.ts @@ -354,6 +354,11 @@ export const sideBarConfig: SidebarConfig = [ activeMatch: '/components/radio/', text: 'Radio', }, + { + link: '/components/radio-cards/radio-cards', + activeMatch: '/components/radio-cards/', + text: 'RadioCards', + }, { link: '/components/scroll-area/scroll-area', activeMatch: '/components/scroll-area/', diff --git a/website/docs/components/radio-cards/radio-cards-a11y.md b/website/docs/components/radio-cards/radio-cards-a11y.md new file mode 100644 index 0000000000..2f5dcc6ae7 --- /dev/null +++ b/website/docs/components/radio-cards/radio-cards-a11y.md @@ -0,0 +1,46 @@ +--- +title: Radio Cards +fileSource: radio-cards +tabs: Design('radio-cards'), A11y('radio-cards-a11y'), API('radio-cards-api'), Examples('radio-cards-code'), Changelog('radio-cards-changelog') +--- + +## What component has + +Component `RadioCards` functions as a group of radio buttons. + +### Keyboard support + +Table: Keyboard support + +| Key | Function | +|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------| +| `Tab` | When focus moves to the `RadioCards`, it moves to the active `RadioCards.Item`. | +| `Left Arrow` , `Right Arrow` | Set `checked` value to the next/previous button in the group. If focus is on the last/first button, moves focus to the first/last button respectively. | + +See detailed information about the keyboard support for clickable elements in the [Keyboard control guide](/core-principles/a11y/a11y-keyboard#any-other-controls-filtertrigger-pills-tabline-etc). + +### Roles & attributes + +The following list describes roles and attributes that the component with already has. + +Table: Roles & attributes + +| Component / Element | Roles & attributes | Usage | +|---------------------|-----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `RadioCards` | `radiogroup` | Identifies the `div` element as a container for a group of radio buttons. Isn’t focusable because focus is managed using a roving tabindex strategy as described below. | +| `RadioCards.Item` | `radio` | Identifies the `div` element as an ARIA radio button. The accessible name is computed from the child text content of the `div` element. | +| | `tabIndex="0"` | Makes the radio button focusable and includes it in the page `Tab` sequence. Set on only one radio in the radio group. Moves with focus inside the radio group so the most recently focused radio button is included in the page `Tab` sequence. This approach to managing focus is described in the section on [roving tabindex](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd-roving-tabindex). | +| | `tabindex="-1"` | Makes the element focusable but not part of the page `Tab` sequence. Applied to all radio buttons contained in the radio group except for one that's included in the page `Tab` sequence. This approach to managing focus is described in the section on [Roving tabindex](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#keyboardnavigationinsidecomponents). | +| | `aria-checked="true/false"` | Identifies whether radio buttons are checked or unchecked. | | + +## Considerations for developers + +Since `RadioCards` behaves as a radio group, do not forget to add the `aria-labelledby` or `aria-label` attribute to the root element. + +## Resources + +- [A11y style guide](https://a11y-style-guide.com/style-guide/section-forms.html#kssref-forms-radio-buttons) gives core recommendations for the accessible radio buttons. + +## Other recommendations + +Find more accessibility recommendations in the common [Accessibility guide](/core-principles/a11y/a11y). diff --git a/website/docs/components/radio-cards/radio-cards-api.md b/website/docs/components/radio-cards/radio-cards-api.md new file mode 100644 index 0000000000..ebe37f4880 --- /dev/null +++ b/website/docs/components/radio-cards/radio-cards-api.md @@ -0,0 +1,25 @@ +--- +title: Radio Cards +fileSource: radio-cards +tabs: Design('radio-cards'), A11y('radio-cards-a11y'), API('radio-cards-api'), Examples('radio-cards-code'), Changelog('radio-cards-changelog') +--- + +## RadioCards + +```jsx +import RadioCards from '@semcore/ui/radio-cards'; +; +``` + + + +## RadioCards.Item + +```jsx +import RadioCards from '@semcore/ui/radio-cards'; +; +``` + + + + diff --git a/website/docs/components/radio-cards/radio-cards-changelog.md b/website/docs/components/radio-cards/radio-cards-changelog.md new file mode 100644 index 0000000000..6df201a9cc --- /dev/null +++ b/website/docs/components/radio-cards/radio-cards-changelog.md @@ -0,0 +1,7 @@ +--- +title: Radio Cards +fileSource: radio-cards +tabs: Design('radio-cards'), A11y('radio-cards-a11y'), API('radio-cards-api'), Examples('radio-cards-code'), Changelog('radio-cards-changelog') +--- + +::: changelog radio-cards ::: diff --git a/website/docs/components/radio-cards/radio-cards-code.md b/website/docs/components/radio-cards/radio-cards-code.md new file mode 100644 index 0000000000..9b5edb9ebe --- /dev/null +++ b/website/docs/components/radio-cards/radio-cards-code.md @@ -0,0 +1,25 @@ +--- +title: Radio Cards +fileSource: radio-cards +tabs: Design('radio-cards'), A11y('radio-cards-a11y'), API('radio-cards-api'), Examples('radio-cards-code'), Changelog('radio-cards-changelog') +--- + +## Basic usage + +::: sandbox + + + +::: + +## Advanced usage + +::: sandbox + + + +::: \ No newline at end of file diff --git a/website/docs/components/radio-cards/radio-cards.md b/website/docs/components/radio-cards/radio-cards.md new file mode 100644 index 0000000000..5ad38b27c6 --- /dev/null +++ b/website/docs/components/radio-cards/radio-cards.md @@ -0,0 +1,7 @@ +--- +title: Radio Cards +fileSource: radio-cards +tabs: Design('radio-cards'), A11y('radio-cards-a11y'), API('radio-cards-api'), Examples('radio-cards-code'), Changelog('radio-cards-changelog') +--- + +TODO: Needs to be filled. \ No newline at end of file diff --git a/website/docs/style/design-tokens/design-tokens.json b/website/docs/style/design-tokens/design-tokens.json index bae9eb82fc..ea6a66449f 100644 --- a/website/docs/style/design-tokens/design-tokens.json +++ b/website/docs/style/design-tokens/design-tokens.json @@ -2009,19 +2009,25 @@ "name": "--intergalactic-control-presets-bg", "value": "oklch(1 0 0)", "description": "Background of the Presets items.", - "components": [] + "components": [ + "radio-cards" + ] }, { "name": "--intergalactic-control-presets-border-selected", "value": "oklch(0.23 0.01 140)", "description": "Border color of the selected Preset item.", - "components": [] + "components": [ + "radio-cards" + ] }, { "name": "--intergalactic-control-presets-border-hover", "value": "oklch(0.137 0.026 175.7 / 0.161)", "description": "Border color of the hovered Preset item.", - "components": [] + "components": [ + "radio-cards" + ] }, { "name": "--intergalactic-progress-bar-bg", @@ -2899,6 +2905,7 @@ "flags", "fullscreen-modal", "pills", + "radio-cards", "slider", "switch", "tab-panel", @@ -3022,6 +3029,7 @@ "link", "pills", "radio", + "radio-cards", "slider", "switch", "tab-line", @@ -3050,6 +3058,7 @@ "value": "0px 0px 1px 0px oklch(0.176 0.033 175.7 / 0.07), 0px 1px 3px 0px oklch(0.176 0.033 175.7 / 0.07)", "description": "Shadow of the Switch toggle.", "components": [ + "radio-cards", "switch" ] }, @@ -3187,6 +3196,7 @@ "dropdown", "input", "modal", + "radio-cards", "time-picker" ] }, @@ -3201,7 +3211,8 @@ "value": "20px", "description": "Extra large padding for content inside controls and surfaces.", "components": [ - "card" + "card", + "radio-cards" ] }, { @@ -3219,7 +3230,8 @@ "components": [ "base-trigger", "dropdown-menu", - "inline-input" + "inline-input", + "radio-cards" ] }, { @@ -3234,6 +3246,7 @@ "dropdown-menu", "input", "radio", + "radio-cards", "select" ] }, @@ -3246,6 +3259,7 @@ "checkbox", "dropdown", "radio", + "radio-cards", "select" ] }, @@ -3329,7 +3343,9 @@ "name": "--intergalactic-pills-rounded", "value": "6px", "description": "Use for rounding Pills.", - "components": [] + "components": [ + "radio-cards" + ] }, { "name": "--intergalactic-popper-rounded",