Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style: [M3-6639] - Add outline to country flags that contain white #9288

Merged
Merged
Show file tree
Hide file tree
Changes from 4 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
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-9288-added-1687360493313.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Added
---

Outline to some country flags ([#9288](https://github.com/linode/manager/pull/9288))
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { _SingleValue } from 'src/components/EnhancedSelect/components/SingleVal
import { Region } from '@linode/api-v4/lib/regions';
import { RegionOption, RegionItem } from './RegionOption';
import { Flag } from 'src/components/Flag';
import { ContinentNames } from './utils';
import { ContinentNames, Country } from './utils';
import { getRegionCountryGroup } from 'src/utilities/formatRegion';

interface Props<IsClearable extends boolean>
Expand Down Expand Up @@ -49,7 +49,7 @@ export const getRegionOptions = (regions: Region[]) => {
groups[group].push({
label: `${region.label} (${region.id})`,
value: region.id,
flag: <Flag country={region.country} />,
flag: <Flag country={region.country as Lowercase<Country>} />,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The as is unfortunate but it lets us maintain the typesafety of <Flag />'s props, which I think is more preferable... This also enables the storybook story to auto generate the country options.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just have country defined as Country in the Regions type? https://github.com/linode/manager/blob/develop/packages/api-v4/src/regions/types.ts#L24

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This crossed my mind. We could but we'd have to copy over all of the country data to the api-v4 package, which I'm not sure we should do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also feel like that's where it belongs (rather than defined in the manager package) but this could be a follow up discussion/task

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. What I don't know is if would it be appropriate to list all 243 countries as a possible response from the API. I guess we'd have to

country: region.country,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ export const COUNTRY_CODE_TO_CONTINENT_CODE = Object.freeze({
ZW: 'AF',
});

export type Country = keyof typeof COUNTRY_CODE_TO_CONTINENT_CODE;

export const CONTINENT_CODE_TO_CONTINENT = Object.freeze({
EU: 'Europe',
AS: 'Asia',
Expand Down
19 changes: 19 additions & 0 deletions packages/manager/src/components/Flag.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { Meta, StoryObj } from '@storybook/react';
import { Flag } from './Flag';

const meta: Meta<typeof Flag> = {
title: 'Components/Flag',
component: Flag,
};

type Story = StoryObj<typeof Flag>;

export const Default: Story = {
render: (args) => <Flag {...args} />,
args: {
country: 'us',
},
};

export default meta;
30 changes: 24 additions & 6 deletions packages/manager/src/components/Flag.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
import React from 'react';
import 'flag-icons/css/flag-icons.min.css';
import { Country } from './EnhancedSelect/variants/RegionSelect/utils';
import { styled } from '@mui/material/styles';
import { isPropValid } from 'src/utilities/isPropValid';

const countryFlagOverrides = {
const COUNTRY_FLAG_OVERRIDES = {
uk: 'gb',
};

const COUNTRIES_TO_OUTLINE = ['jp', 'id', 'sg'];

interface Props {
/** expects a iso code of a country - `us`, `ca`, etc... */
country: string;
country: Lowercase<Country>;
}

/**
* Flag icons are provided by the [flag-icons](https://www.npmjs.com/package/flag-icon) package
*/
export const Flag = (props: Props) => {
const country = props.country.toLowerCase();

return (
<div
className={`fi fi-${countryFlagOverrides[country] ?? country} fi-xx`}
style={{ fontSize: '1.5rem', verticalAlign: 'top' }}
<StyledFlag
className={`fi fi-${COUNTRY_FLAG_OVERRIDES[country] ?? country} fi-xx`}
hasOutline={COUNTRIES_TO_OUTLINE.includes(country)}
/>
);
};

const StyledFlag = styled('div', {
label: 'StyledFlag',
shouldForwardProp: (prop) => isPropValid(['hasOutline'], prop),
})<{ hasOutline: boolean }>(({ theme, ...props }) => ({
fontSize: '1.5rem',
outline: props.hasOutline ? `1px solid ${theme.color.border3}` : 'none',
verticalAlign: 'top',
width: '1.41rem',
}));
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { RegionSelect } from 'src/components/EnhancedSelect/variants/RegionSelec
import { useRegionsQuery } from 'src/queries/regions';
import { getRegionCountryGroup } from 'src/utilities/formatRegion';
import { Flag } from 'src/components/Flag';
import { Country } from 'src/components/EnhancedSelect/variants/RegionSelect/utils';

const useStyles = makeStyles((theme: Theme) => ({
root: {
Expand Down Expand Up @@ -53,7 +54,7 @@ const ConfigureForm = (props: Props) => {
<Typography variant="h3">Configure Migration</Typography>
<Typography>Current Region</Typography>
<div className={classes.currentRegion}>
<Flag country={country} />
<Flag country={country as Lowercase<Country>} />
<Typography>{`${getRegionCountryGroup(currentActualRegion)}: ${
currentActualRegion?.label ?? currentRegion
}`}</Typography>
Expand Down
5 changes: 2 additions & 3 deletions packages/manager/src/utilities/formatRegion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Region } from '@linode/api-v4';
import {
COUNTRY_CODE_TO_CONTINENT_CODE,
CONTINENT_CODE_TO_CONTINENT,
Country,
} from 'src/components/EnhancedSelect/variants/RegionSelect/utils';

export const getRegionCountryGroup = (region: Region | undefined) => {
Expand All @@ -10,9 +11,7 @@ export const getRegionCountryGroup = (region: Region | undefined) => {
}

const continentCode =
COUNTRY_CODE_TO_CONTINENT_CODE[
region.country.toUpperCase() as keyof typeof COUNTRY_CODE_TO_CONTINENT_CODE
];
COUNTRY_CODE_TO_CONTINENT_CODE[region.country.toUpperCase() as Country];

return continentCode
? CONTINENT_CODE_TO_CONTINENT[continentCode] ?? 'Other'
Expand Down