Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 33 additions & 0 deletions .changeset/dirty-facts-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
'@clickhouse/click-ui': minor
---

Introduces a centralised asset configuration with unified aliases and deprecated name mappings. This provides a single source of truth for asset name resolution across all asset types (Icons, Logos, Flags, and Payments), helping to resolve circular dependencies while offering a flexible aliasing system.

### Why aliases?

Asset naming conventions use kebab-case (e.g., `c-sharp`, `arrow-down`) to facilitate file organisation and ensure valid JavaScript identifiers. However, users may prefer more intuitive names that don't follow these conventions. Aliases bridge this gap.

For example, `c#` contains a `#` character which is not a valid JavaScript identifier, but users might still prefer using `c#` over `c-sharp`.

### How to use aliases

Aliases are defined in `src/components/Assets/config.ts` under `ASSET_NAME_MAPPINGS.aliases`:

```tsx
export const ASSET_NAME_MAPPINGS = {
aliases: {
'c#': 'c-sharp',
// Add more aliases as needed
} as AssetAliasMap,
// ...
};
```

The alias is then automatically resolved when using any asset component:

```tsx
// Both of these work identically:
<Logo name="c#" />
<Logo name="c-sharp" />
```
18 changes: 15 additions & 3 deletions src/components/Assets/Flags/system/Flag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,24 @@
import { useTheme } from 'styled-components';
import { getFallbackThemeName } from '@/theme/theme.utils';
import { SvgImageElement } from '@/components/Icon/SvgImageElement';
import { FlagProps } from './types';
import { resolveFlagName } from './retroactiveNames';
import { FlagName, FlagProps } from './types';
import {
createAssetResolver,
type AssetAlias,
type AssetDeprecatedName,
} from '@/components/Assets/config';
import FlagsDark from './FlagsDark';
import FlagsLight from './FlagsLight';

const Flag = ({ name, theme, size, ...props }: FlagProps) => {
const resolveFlagName = createAssetResolver<FlagName>();

export { resolveFlagName };

Check warning on line 16 in src/components/Assets/Flags/system/Flag.tsx

View workflow job for this annotation

GitHub Actions / code-quality-checks

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components

export interface FlagPropsWithAliases extends Omit<FlagProps, 'name'> {
name: FlagName | AssetAlias | AssetDeprecatedName;
}

const Flag = ({ name, theme, size, ...props }: FlagPropsWithAliases) => {
const { name: themeName } = useTheme();
const resolvedName = resolveFlagName(name);
const resolvedTheme = getFallbackThemeName(theme ?? themeName);
Expand Down
4 changes: 2 additions & 2 deletions src/components/Assets/Flags/system/FlagsDark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { FlagName } from './types';
import type { SVGAssetProps } from '@/types';
import type { ComponentType } from 'react';

const FlagsLight: Record<FlagName, ComponentType<SVGAssetProps>> = {
const FlagsDark: Record<FlagName, ComponentType<SVGAssetProps>> = {
australia: Australia,
brazil: Brazil,
canada: Canada,
Expand All @@ -54,4 +54,4 @@ const FlagsLight: Record<FlagName, ComponentType<SVGAssetProps>> = {
'united-states': United_States,
};

export default FlagsLight;
export default FlagsDark;
63 changes: 0 additions & 63 deletions src/components/Assets/Flags/system/retroactiveNames.ts

This file was deleted.

22 changes: 17 additions & 5 deletions src/components/Assets/Icons/system/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { SVGAttributes } from 'react';
import { useTheme } from 'styled-components';
import { getFallbackThemeName } from '@/theme/theme.utils';
import { resolveIconName } from './retroactiveNames';
import IconsLight from './IconsLight';
import IconsDark from './IconsDark';
import { SvgImageElement } from '@/components/Icon/SvgImageElement';
import { IconProps } from './types';
import { IconName, IconProps } from './types';
import {
createAssetResolver,
type AssetAlias,
type AssetDeprecatedName,
} from '@/components/Assets/config';
import IconsDark from './IconsDark';
import IconsLight from './IconsLight';

const resolveIconName = createAssetResolver<IconName>();

export { resolveIconName };

Check warning on line 16 in src/components/Assets/Icons/system/Icon.tsx

View workflow job for this annotation

GitHub Actions / code-quality-checks

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components

export interface IconPropsWithAliases extends Omit<IconProps, 'name'> {
name: IconName | AssetAlias | AssetDeprecatedName;
}

const Icon = ({ name, theme, size, ...props }: IconProps) => {
const Icon = ({ name, theme, size, ...props }: IconPropsWithAliases) => {
const { name: themeName } = useTheme();
const resolvedName = resolveIconName(name);
const resolvedTheme = getFallbackThemeName(theme ?? themeName);
Expand Down
181 changes: 0 additions & 181 deletions src/components/Assets/Icons/system/retroactiveNames.ts

This file was deleted.

24 changes: 13 additions & 11 deletions src/components/Assets/Logos/system/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,23 @@
import { getFallbackThemeName } from '@/theme/theme.utils';
import { SvgImageElement } from '@/components/Icon/SvgImageElement';
import { LogoName, LogoProps } from './types';
import {
createAssetResolver,
type AssetAlias,
type AssetDeprecatedName,
} from '@/components/Assets/config';
import LogosDark from './LogosDark';
import LogosLight from './LogosLight';

// TODO: This is introducing complexity and more to maintain
// might be best to just deprecate (break change) instead of
// keeping deprecated names, it's small find and replace.
const resolveLogoName = (name: string): LogoName => {
if (name === 'c#') {
console.warn('Logo name "c#" is deprecated, use "c-sharp" instead');
return 'c-sharp' as LogoName;
}
return name as LogoName;
};
const resolveLogoName = createAssetResolver<LogoName>();

export { resolveLogoName };

Check warning on line 16 in src/components/Assets/Logos/system/Logo.tsx

View workflow job for this annotation

GitHub Actions / code-quality-checks

Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components

export interface LogoPropsWithAliases extends Omit<LogoProps, 'name'> {
name: LogoName | AssetAlias | AssetDeprecatedName;
}

const Logo = ({ name, theme, size, ...props }: LogoProps) => {
const Logo = ({ name, theme, size, ...props }: LogoPropsWithAliases) => {
const { name: themeName } = useTheme();
const resolvedName = resolveLogoName(name);
const resolvedTheme = getFallbackThemeName(theme ?? themeName);
Expand Down
Loading
Loading