Skip to content
Open
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
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,60 @@ const JustAFlag = () =>
```

### Props
#### from (optional)
#### Type: `{}`
#### Default value: `await import('./flags')` (all available flags).
The flags you want to use.

By default, [all available flags](https://github.com/frostney/react-native-flags/blob/master/flags/index.js) are bundled/imported.
However, *bundling all flags is discouraged*, because you might not need all of them.
Instead, you could import your flags beforehand and use this prop to pass your flags.

Below are a few examples:

Load all flat 32 flags:
```javascript
import Flag from 'react-native-flags';
import * as allFlatFlags32 from 'react-native-flags/flags/flat/32';

const JustAFlag = ({ code }) =>
<Flag
from={allFlatFlags32}
code={code}
size={32}
type="flat"
/>
```

Load all shiny 16/24/32/48/64 flags:
```javascript
import Flag from 'react-native-flags';
import * as allShinyFlags from 'react-native-flags/flags/shiny';

const JustAFlag = ({ code, size }) =>
<Flag
from={allShinyFlags}
code={code}
size={size}
type="shiny"
/>
```

Load all flat/shiny 16/24/32/48/64 flags.
This is the same as removing the `from` prop:
```javascript
import Flag from 'react-native-flags';
import * as allFlags from 'react-native-flags/flags';

const JustAFlag = ({ code, size, type }) =>
<Flag
from={allFlags}
code={code}
size={size}
type={type}
/>
```

#### code
#### Type: `String`
The ISO code of a flag, for example "DE", "FR" or "GB"
Expand Down
68 changes: 62 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,79 @@
// @flow

import React from 'react';
import React, { useState, useEffect } from 'react';
import { Image } from 'react-native';
import * as flags from './flags';

type Props = {
from?: {},
size: 16 | 24 | 32 | 48 | 64,
code: string,
type?: 'flat' | 'shiny',
style?: any,
};

const Flag = ({ size = 64, code, type = 'shiny', style }: Props) => {
const flag = flags[type][`icons${size}`][code];
const unknownFlag = flags[type][`icons${size}`]['unknown'];
/**
* Find a flag exported from ./flags' sub-directories
* (or directories that match the same structure)
* and return it.
*
* @example
* import * as flags from './flags';
* import * as flatFlags from './flags/flat';
* import * as flatFlags16 from './flags/flat/16';
*
* const emptyFlags = {};
* const props = { type: 'flat', size: 16, code: 'ZW' };
*
* getFlag(flatFlags16, props) === getFlag(flatFlags, props); // > true
* getFlag(flatFlags, props) === getFlag(flags, props); // > true
* getFlag(emptyFlags, props); // > null
*/
const getFlag = (flags: {}, { type, size, code }: {
type: string,
size: number,
code: string
}) => {
const sizeKey = `icons${size}`;

return (type in flags // ./flags was imported.
? flags[type][sizeKey][code]
: sizeKey in flags // ./flags/{type} was imported.
? flags[sizeKey][code]
: code in flags // ./flags/{type}/{size} was imported.
? flags[code]
: null
);
};

const Flag = ({ from, size = 64, code, type = 'shiny', style }: Props) => {
// @TODO Set an initial value.
const [source, setSource] = useState();

// Load flags asynchronously.
useEffect(() => {
let isMounted = true;

(async () => {
// Use our flags or import all of them.
const flags = from || await import('./flags');
const flag = getFlag(flags, { type, size, code });
const unknownFlag = getFlag(flags, { type, size, code: 'unknown' });

if (isMounted) {
setSource(flag || unknownFlag);
}
})();

return () => {
// Anti-pattern.
// @TODO Abort import instead.
isMounted = false;
};
}, [from, type, size, code, setSource]);

return (
<Image
source={flag || unknownFlag}
source={source}
style={[{ width: size, height: size }, style]}
/>
);
Expand Down