diff --git a/.changeset/migrate-icon-to-css-modules.md b/.changeset/migrate-icon-to-css-modules.md new file mode 100644 index 000000000..ead70ff6c --- /dev/null +++ b/.changeset/migrate-icon-to-css-modules.md @@ -0,0 +1,5 @@ +--- +'@clickhouse/click-ui': patch +--- + +Migrate Icon from styled-components to css modules with no change in behavior diff --git a/src/components/Assets/Flags/system/Flag.tsx b/src/components/Assets/Flags/system/Flag.tsx index ed67b35c1..0d8556762 100644 --- a/src/components/Assets/Flags/system/Flag.tsx +++ b/src/components/Assets/Flags/system/Flag.tsx @@ -40,7 +40,7 @@ const Flag = ({ name, theme, size, ...props }: FlagPropsWithAliases) => { return ( { return ( { return ( { return ( , }; +const IconHarness = (props: ImageType) => ( +
+ +
+); + +export const DefaultMd: Story = { + render: () => , +}; + +export const SizeXs: Story = { + render: () => ( + + ), +}; + +export const SizeSm: Story = { + render: () => ( + + ), +}; + +export const SizeMd: Story = { + render: () => ( + + ), +}; + +export const SizeLg: Story = { + render: () => ( + + ), +}; + +export const SizeXl: Story = { + render: () => ( + + ), +}; + +export const SizeXxl: Story = { + render: () => ( + + ), +}; + +export const StateSuccess: Story = { + render: () => ( + + ), +}; + +export const StateWarning: Story = { + render: () => ( + + ), +}; + +export const StateDanger: Story = { + render: () => ( + + ), +}; + +export const StateInfo: Story = { + render: () => ( + + ), +}; + +export const StateSuccessSm: Story = { + render: () => ( + + ), +}; + +export const StateSuccessXl: Story = { + render: () => ( + + ), +}; + +export const CustomColor: Story = { + render: () => ( + + ), +}; + +export const CustomWidthHeight: Story = { + render: () => ( + + ), +}; + +export const FlagAsset: Story = { + render: () => ( + + ), +}; + +export const LogoAsset: Story = { + render: () => ( + + ), +}; + +export const PaymentAsset: Story = { + render: () => ( + + ), +}; + type IconGalleryProps = { name: IconName; }; @@ -79,23 +249,15 @@ const IconGallery = ({ name }: IconGalleryProps) => ( ); -const ResponsiveGridContainer = styled(GridContainer)` - grid-template-columns: repeat(6, 1fr); - gap: 1em; - - @media (max-width: 1400px) { - grid-template-columns: repeat(4, 1fr); - } - @media (max-width: 1100px) { - grid-template-columns: repeat(3, 1fr); - } - @media (max-width: 800px) { - grid-template-columns: repeat(2, 1fr); - } - @media (max-width: 500px) { - grid-template-columns: 1fr; - } -`; +const ResponsiveGridContainer = ({ + className, + ...props +}: ComponentProps) => ( + +); export const Icons: Story = { render: () => { diff --git a/src/components/Icon/Icon.tsx b/src/components/Icon/Icon.tsx index d1f9e008b..c328f4b28 100644 --- a/src/components/Icon/Icon.tsx +++ b/src/components/Icon/Icon.tsx @@ -1,6 +1,6 @@ -import { styled } from 'styled-components'; -import type { AssetSize } from '@/types'; -import { IconName, IconProps, IconState, ImageType } from './Icon.types'; +import { CSSProperties } from 'react'; +import { cn, cva } from '@/lib/cva'; +import { IconName, IconProps, ImageType } from './Icon.types'; import { ICONS_MAP } from '@/components/Icon/IconCommon'; import { Flag } from '@/components/Assets/Flags/system/Flag'; import FlagsLight from '@/components/Assets/Flags/system/FlagsLight'; @@ -11,6 +11,31 @@ import { LogoName } from '@/components/Assets/Logos/system/types'; import { Payment } from '@/components/Assets/Payments/system/Payment'; import { PaymentName } from '@/components/Assets/Payments/system/types'; import PaymentsLight from '@/components/Assets/Payments/system/PaymentsLight'; +import styles from './Icon.module.css'; + +const svgWrapperVariants = cva(styles['svg-wrapper'], { + variants: { + size: { + xs: styles['svg-wrapper_size_xs'], + sm: styles['svg-wrapper_size_sm'], + md: styles['svg-wrapper_size_md'], + lg: styles['svg-wrapper_size_lg'], + xl: styles['svg-wrapper_size_xl'], + xxl: styles['svg-wrapper_size_xxl'], + }, + state: { + default: '', + success: styles['svg-wrapper_state_success'], + warning: styles['svg-wrapper_state_warning'], + danger: styles['svg-wrapper_state_danger'], + info: styles['svg-wrapper_state_info'], + }, + }, + defaultVariants: { + size: 'md', + state: 'default', + }, +}); const SVGIcon = ({ name, @@ -28,53 +53,22 @@ const SVGIcon = ({ return null; } + const wrapperStyle = { + ...(color !== undefined ? { '--svg-icon-color': color } : {}), + ...(width !== undefined ? { '--svg-width': String(width) } : {}), + ...(height !== undefined ? { '--svg-height': String(height) } : {}), + } as CSSProperties; + return ( - - + ); }; -const SvgWrapper = styled.div<{ - $color?: string; - $width?: number | string; - $height?: number | string; - $size?: AssetSize; - state?: IconState; -}>` - display: flex; - align-items: center; - - ${({ theme, $color = 'currentColor', $width, $height, $size }) => ` - & path[stroke], & svg[stroke]:not([stroke="none"]), & rect[stroke], & circle[fill] { - stroke: ${$color}; - } - - & path[fill], & svg[fill]:not([fill="none"]), & rect[fill], & circle[fill] { - fill: ${$color}; - } - - & svg { - width: ${$width || theme.click.image[$size || 'md'].size.width || '24px'}; - height: ${$height || theme.click.image[$size || 'md'].size.height || '24px'}; - } - `} - - ${({ theme, $color = 'currentColor', state = 'default', $size = 'md' }) => ` - background: ${theme.click.icon.color.background[state]}; - border-radius: ${theme.border.radii.full}; - padding: ${state === 'default' ? 'none' : theme.click.icon.space[$size].all}; - color: ${state === 'default' ? $color : theme.click.icon.color.text[state]}; - `} -`; - const SvgImage = ({ name, size, theme, ...props }: ImageType) => { if (Object.keys(FlagsLight).includes(name)) { return ( diff --git a/src/components/Icon/SvgImageElement.tsx b/src/components/Icon/SvgImageElement.tsx index 0937172a3..006fdc2cf 100644 --- a/src/components/Icon/SvgImageElement.tsx +++ b/src/components/Icon/SvgImageElement.tsx @@ -1,20 +1,45 @@ -import { styled } from 'styled-components'; +import { ComponentType, SVGAttributes } from 'react'; +import { cn, cva } from '@/lib/cva'; import type { AssetSize } from '@/types'; +import styles from './Icon.module.css'; -export const SvgImageElement = styled.svg<{ - $size?: AssetSize; -}>` - display: flex; - align-items: center; +const svgImageVariants = cva(styles['svg-image'], { + variants: { + size: { + xs: styles['svg-image_size_xs'], + sm: styles['svg-image_size_sm'], + md: styles['svg-image_size_md'], + lg: styles['svg-image_size_lg'], + xl: styles['svg-image_size_xl'], + xxl: styles['svg-image_size_xxl'], + }, + }, +}); - ${({ theme, $size }) => ` - ${ - $size - ? ` - width: ${theme.click.image[$size].size.width}; - height: ${theme.click.image[$size].size.height}; - ` - : '' - } - `} -`; +export interface SvgImageElementProps extends SVGAttributes { + as?: ComponentType>; + size?: AssetSize; +} + +export const SvgImageElement = ({ + as: Component, + size, + className, + ...props +}: SvgImageElementProps) => { + const mergedClassName = cn(svgImageVariants({ size }), className); + if (Component) { + return ( + + ); + } + return ( + + ); +}; diff --git a/tests/display/icon.spec.ts b/tests/display/icon.spec.ts new file mode 100644 index 000000000..5c71d3cd2 --- /dev/null +++ b/tests/display/icon.spec.ts @@ -0,0 +1,438 @@ +import { test as it, expect } from '@playwright/test'; +import { getStoryUrl } from '../utils'; + +const { describe, use } = it; + +const harnessLocator = '[data-testid="icon-harness"]'; + +describe('Icon Visual Regression', () => { + describe('Light Theme (Storybook Global)', () => { + describe('Size Variants', () => { + it('default size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--default-md', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-default-md-light.png', { + maxDiffPixels: 100, + }); + }); + + it('xs size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-xs', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-xs-light.png', { + maxDiffPixels: 100, + }); + }); + + it('sm size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-sm', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-sm-light.png', { + maxDiffPixels: 100, + }); + }); + + it('md size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-md', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-md-light.png', { + maxDiffPixels: 100, + }); + }); + + it('lg size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-lg', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-lg-light.png', { + maxDiffPixels: 100, + }); + }); + + it('xl size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-xl', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-xl-light.png', { + maxDiffPixels: 100, + }); + }); + + it('xxl size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-xxl', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-xxl-light.png', { + maxDiffPixels: 100, + }); + }); + }); + + describe('State Variants', () => { + it('success state matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-success', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-success-light.png', { + maxDiffPixels: 100, + }); + }); + + it('warning state matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-warning', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-warning-light.png', { + maxDiffPixels: 100, + }); + }); + + it('danger state matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-danger', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-danger-light.png', { + maxDiffPixels: 100, + }); + }); + + it('info state matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-info', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-info-light.png', { + maxDiffPixels: 100, + }); + }); + + it('success state with sm size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-success-sm', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-success-sm-light.png', { + maxDiffPixels: 100, + }); + }); + + it('success state with xl size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-success-xl', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-success-xl-light.png', { + maxDiffPixels: 100, + }); + }); + }); + + describe('Custom Overrides', () => { + it('custom color matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--custom-color', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-custom-color-light.png', { + maxDiffPixels: 100, + }); + }); + + it('custom width/height matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--custom-width-height', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-custom-width-height-light.png', { + maxDiffPixels: 100, + }); + }); + }); + + describe('Asset Variants', () => { + it('flag asset matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--flag-asset', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-flag-asset-light.png', { + maxDiffPixels: 100, + }); + }); + + it('logo asset matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--logo-asset', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-logo-asset-light.png', { + maxDiffPixels: 100, + }); + }); + + it('payment asset matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--payment-asset', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-payment-asset-light.png', { + maxDiffPixels: 100, + }); + }); + }); + + describe('Accessibility', () => { + it('glyph icon exposes accessible name', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--default-md', 'light'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + const img = harness.getByRole('img'); + await expect(img).toHaveAttribute('aria-label', 'users'); + }); + }); + }); + + describe('Dark Theme (System prefers-color-scheme)', () => { + use({ colorScheme: 'dark' }); + + describe('Size Variants', () => { + it('default size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--default-md'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-default-md-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('xs size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-xs'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-xs-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('sm size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-sm'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-sm-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('md size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-md'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-md-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('lg size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-lg'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-lg-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('xl size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-xl'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-xl-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('xxl size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--size-xxl'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-size-xxl-dark.png', { + maxDiffPixels: 100, + }); + }); + }); + + describe('State Variants', () => { + it('success state matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-success'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-success-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('warning state matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-warning'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-warning-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('danger state matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-danger'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-danger-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('info state matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-info'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-info-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('success state with sm size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-success-sm'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-success-sm-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('success state with xl size matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--state-success-xl'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-state-success-xl-dark.png', { + maxDiffPixels: 100, + }); + }); + }); + + describe('Custom Overrides', () => { + it('custom color matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--custom-color'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-custom-color-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('custom width/height matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--custom-width-height'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-custom-width-height-dark.png', { + maxDiffPixels: 100, + }); + }); + }); + + describe('Asset Variants', () => { + it('flag asset matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--flag-asset'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-flag-asset-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('logo asset matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--logo-asset'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-logo-asset-dark.png', { + maxDiffPixels: 100, + }); + }); + + it('payment asset matches snapshot', async ({ page }) => { + await page.goto(getStoryUrl('assets-icon--payment-asset'), { + waitUntil: 'networkidle', + }); + const harness = page.locator(harnessLocator).first(); + await expect(harness).toBeVisible({ timeout: 10000 }); + await expect(harness).toHaveScreenshot('icon-payment-asset-dark.png', { + maxDiffPixels: 100, + }); + }); + }); + }); +}); diff --git a/tests/display/icon.spec.ts-snapshots/icon-custom-color-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-custom-color-dark-chromium-linux.png new file mode 100644 index 000000000..927913f64 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-custom-color-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-custom-color-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-custom-color-light-chromium-linux.png new file mode 100644 index 000000000..50f4233ef Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-custom-color-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-custom-width-height-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-custom-width-height-dark-chromium-linux.png new file mode 100644 index 000000000..cdb00a52e Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-custom-width-height-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-custom-width-height-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-custom-width-height-light-chromium-linux.png new file mode 100644 index 000000000..4e6019d16 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-custom-width-height-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-default-md-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-default-md-dark-chromium-linux.png new file mode 100644 index 000000000..99e0142c7 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-default-md-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-default-md-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-default-md-light-chromium-linux.png new file mode 100644 index 000000000..ddd58a4ce Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-default-md-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-flag-asset-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-flag-asset-dark-chromium-linux.png new file mode 100644 index 000000000..e9c538b02 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-flag-asset-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-flag-asset-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-flag-asset-light-chromium-linux.png new file mode 100644 index 000000000..253920677 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-flag-asset-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-logo-asset-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-logo-asset-dark-chromium-linux.png new file mode 100644 index 000000000..40ba2de23 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-logo-asset-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-logo-asset-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-logo-asset-light-chromium-linux.png new file mode 100644 index 000000000..01ac270f7 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-logo-asset-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-payment-asset-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-payment-asset-dark-chromium-linux.png new file mode 100644 index 000000000..f86b04334 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-payment-asset-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-payment-asset-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-payment-asset-light-chromium-linux.png new file mode 100644 index 000000000..7ac6a296d Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-payment-asset-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-lg-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-lg-dark-chromium-linux.png new file mode 100644 index 000000000..acd97ba2b Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-lg-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-lg-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-lg-light-chromium-linux.png new file mode 100644 index 000000000..eee1221e0 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-lg-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-md-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-md-dark-chromium-linux.png new file mode 100644 index 000000000..99e0142c7 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-md-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-md-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-md-light-chromium-linux.png new file mode 100644 index 000000000..ddd58a4ce Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-md-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-sm-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-sm-dark-chromium-linux.png new file mode 100644 index 000000000..2c77641a1 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-sm-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-sm-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-sm-light-chromium-linux.png new file mode 100644 index 000000000..a956b76cb Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-sm-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-xl-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-xl-dark-chromium-linux.png new file mode 100644 index 000000000..b95eceb00 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-xl-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-xl-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-xl-light-chromium-linux.png new file mode 100644 index 000000000..c98881f61 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-xl-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-xs-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-xs-dark-chromium-linux.png new file mode 100644 index 000000000..2025d8aa3 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-xs-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-xs-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-xs-light-chromium-linux.png new file mode 100644 index 000000000..f768fb13c Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-xs-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-xxl-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-xxl-dark-chromium-linux.png new file mode 100644 index 000000000..6f54cc0e9 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-xxl-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-size-xxl-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-size-xxl-light-chromium-linux.png new file mode 100644 index 000000000..90bf26e8a Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-size-xxl-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-danger-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-danger-dark-chromium-linux.png new file mode 100644 index 000000000..2d5393a0a Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-danger-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-danger-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-danger-light-chromium-linux.png new file mode 100644 index 000000000..3fa8a0739 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-danger-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-info-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-info-dark-chromium-linux.png new file mode 100644 index 000000000..1dfdd56cf Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-info-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-info-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-info-light-chromium-linux.png new file mode 100644 index 000000000..b267a1c0d Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-info-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-success-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-success-dark-chromium-linux.png new file mode 100644 index 000000000..50540b20b Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-success-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-success-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-success-light-chromium-linux.png new file mode 100644 index 000000000..9234e4a65 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-success-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-success-sm-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-success-sm-dark-chromium-linux.png new file mode 100644 index 000000000..c641b8719 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-success-sm-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-success-sm-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-success-sm-light-chromium-linux.png new file mode 100644 index 000000000..0448296a0 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-success-sm-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-success-xl-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-success-xl-dark-chromium-linux.png new file mode 100644 index 000000000..9cf1a6486 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-success-xl-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-success-xl-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-success-xl-light-chromium-linux.png new file mode 100644 index 000000000..87fe27e5f Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-success-xl-light-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-warning-dark-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-warning-dark-chromium-linux.png new file mode 100644 index 000000000..5a129a071 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-warning-dark-chromium-linux.png differ diff --git a/tests/display/icon.spec.ts-snapshots/icon-state-warning-light-chromium-linux.png b/tests/display/icon.spec.ts-snapshots/icon-state-warning-light-chromium-linux.png new file mode 100644 index 000000000..9f7468353 Binary files /dev/null and b/tests/display/icon.spec.ts-snapshots/icon-state-warning-light-chromium-linux.png differ