Skip to content

Commit aeefca7

Browse files
committed
fixes #55 - using icons as actual svgs
1 parent 0f1d6a9 commit aeefca7

6 files changed

Lines changed: 100 additions & 22 deletions

File tree

.eslintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"react/jsx-handler-names": 0,
2929
"react/jsx-fragments": 0,
3030
"react/no-unused-prop-types": 0,
31+
"no-unused-expressions": 0,
3132
"import/export": 0
3233
}
3334
}

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ import { CircleFlag } from 'react-circle-flags'
2828
export const ArgentinianFlag = () => <CircleFlag countryCode="ar" height="35" cdnUrl="https://magic-cdn.com/flags/" />
2929
```
3030

31+
### With inline svgs instead of using images
32+
33+
```jsx
34+
import React from 'react'
35+
import { CircleFlag } from 'react-circle-flags'
36+
37+
export const ArgentinianFlag = () => <CircleFlag countryCode="ar" height="35" cdnUrl="https://magic-cdn.com/flags/" />
38+
```
39+
3140
You can pass all the react's `React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>` props to CircleFlag. :rocket:
3241

3342
### Language flags

docs/.eslintrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"rules": {
3+
"no-unused-expressions": "off"
4+
}
5+
}

index.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ interface CircleFlagProps extends DetailedHTMLProps<
1212
* Custom CDN URL to use.
1313
*/
1414
cdnUrl?: string
15+
/**
16+
* Whether to use inline SVG rendering.
17+
*/
18+
inline?: boolean
1519
}
1620

1721
interface CircleFlagLanguageProps extends DetailedHTMLProps<
@@ -26,6 +30,10 @@ interface CircleFlagLanguageProps extends DetailedHTMLProps<
2630
* Custom CDN URL to use.
2731
*/
2832
cdnUrl?: string
33+
/**
34+
* Whether to use inline SVG rendering.
35+
*/
36+
inline?: boolean
2937
}
3038

3139
/**

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-circle-flags",
3-
"version": "0.0.25",
3+
"version": "0.0.26",
44
"description": "A React component with a collection of 300+ minimal circular SVG country flags",
55
"author": "Tomás Novau(tnovau@ontheedge.cloud)",
66
"license": "MIT",

src/index.js

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,20 @@ const FILE_SUFFIX = 'svg'
77

88
const UNKNOWN_FLAG = 'xx'
99
const DEFAULT_HEIGHT = 100
10+
const DEFAULT_WIDTH = 100
1011

1112
/**
1213
* @param {string} code
1314
* @param {string} cdnUrl
1415
* @param {DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>} otherProps
1516
* @param {string} cdnSuffix
17+
* @return {DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>}
1618
*/
1719
const getSvgProps = (code, cdnUrl, otherProps, cdnSuffix = '') => ({
1820
...otherProps,
1921
title: otherProps.title || code,
2022
height: otherProps.height || DEFAULT_HEIGHT,
23+
width: otherProps.width || DEFAULT_WIDTH,
2124
src: `${cdnUrl || CDN_URL}${cdnSuffix}${code}.${FILE_SUFFIX}`
2225
})
2326

@@ -30,33 +33,85 @@ const parseCountryCode = (countryCode) =>
3033
const parseLanguageCode = (languageCode) =>
3134
languages[languageCode] ? languageCode : UNKNOWN_FLAG
3235

36+
/**
37+
* @param {DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>} props
38+
*/
39+
class SvgInline extends React.Component {
40+
constructor(props) {
41+
super(props);
42+
this.ref = React.createRef();
43+
}
44+
45+
componentDidMount() {
46+
this.loadSvg();
47+
console.log(this.ref.current);
48+
}
49+
50+
componentDidUpdate(prevProps) {
51+
if (prevProps.src !== this.props.src) {
52+
this.loadSvg();
53+
}
54+
debugger;
55+
console.log(this.ref.current);
56+
}
57+
58+
loadSvg() {
59+
fetch(this.props.src)
60+
.then(res => res.text())
61+
.then(svgHTML => {
62+
if (this.ref.current) {
63+
const parser = new DOMParser();
64+
const svgDoc = parser.parseFromString(svgHTML, 'image/svg+xml');
65+
/** @type {SVGSVGElement} */
66+
const svgElement = svgDoc.documentElement;
67+
for (const prop in this.props) {
68+
if (prop === 'src') continue;
69+
svgElement.setAttribute(prop, this.props[prop]);
70+
}
71+
72+
this.ref.current.outerHTML = svgElement.outerHTML;
73+
}
74+
});
75+
}
76+
77+
render() {
78+
return <img {...this.props} ref={this.ref} />;
79+
}
80+
}
81+
3382
/**
3483
* @param {import('../index').CircleFlagProps} param0
3584
*/
36-
export const CircleFlag = ({ countryCode, cdnUrl, ...otherProps }) => (
37-
<img
38-
data-testid='circle-country-flag'
39-
{...getSvgProps(
40-
parseCountryCode(countryCode).toLowerCase(),
41-
cdnUrl,
42-
otherProps
43-
)}
44-
/>
45-
)
85+
export const CircleFlag = ({ countryCode, cdnUrl, inline, ...otherProps }) => {
86+
const Component = inline ? SvgInline : 'img';
87+
return (
88+
<Component
89+
data-testid='circle-country-flag'
90+
{...getSvgProps(
91+
parseCountryCode(countryCode).toLowerCase(),
92+
cdnUrl,
93+
otherProps
94+
)}
95+
/>
96+
)
97+
}
4698

4799
/**
48100
* @param {import('../index').CircleFlagLanguage} param0
49101
*/
50-
export const CircleFlagLanguage = ({ languageCode, cdnUrl, ...otherProps }) => (
51-
<img
52-
data-testid='circle-language-flag'
53-
{...getSvgProps(
54-
parseLanguageCode(languageCode).toLowerCase(),
55-
cdnUrl,
56-
otherProps,
57-
'language/'
58-
)}
59-
/>
60-
)
102+
export const CircleFlagLanguage = ({ languageCode, cdnUrl, inline, ...otherProps }) => {
103+
const Component = inline ? SvgInline : 'img';
104+
return (
105+
<Component
106+
data-testid='circle-language-flag'
107+
{...getSvgProps(
108+
parseLanguageCode(languageCode).toLowerCase(),
109+
cdnUrl,
110+
otherProps,
111+
'language/'
112+
)}
113+
/>
114+
)
115+
}
61116

62117
export { countries, languages }

0 commit comments

Comments
 (0)