├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .prettierrc ├── .travis.yml ├── LICENSE ├── README.md ├── example ├── README.md ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json ├── src │ ├── App.test.tsx │ ├── App.tsx │ ├── index.css │ ├── index.tsx │ ├── react-app-env.d.ts │ └── setupTests.ts ├── tsconfig.json └── yarn.lock ├── package.json ├── src ├── .eslintrc ├── components │ ├── fixedhflag.tsx │ ├── fixedwflag.tsx │ ├── index.tsx │ ├── svgflag.tsx │ └── waveyflag.tsx ├── constants.ts ├── index.tsx ├── react-app-env.d.ts ├── types.ts └── typings.d.ts ├── tsconfig.json ├── tsconfig.test.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | node_modules/ 4 | .snapshots/ 5 | *.min.js -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": [ 4 | "standard", 5 | "standard-react", 6 | "plugin:prettier/recommended", 7 | "prettier/standard", 8 | "prettier/react", 9 | "plugin:@typescript-eslint/eslint-recommended" 10 | ], 11 | "env": { 12 | "node": true 13 | }, 14 | "parserOptions": { 15 | "ecmaVersion": 2020, 16 | "ecmaFeatures": { 17 | "legacyDecorators": true, 18 | "jsx": true 19 | } 20 | }, 21 | "settings": { 22 | "react": { 23 | "version": "16" 24 | } 25 | }, 26 | "rules": { 27 | "space-before-function-paren": 0, 28 | "react/prop-types": 0, 29 | "react/jsx-handler-names": 0, 30 | "react/jsx-fragments": 0, 31 | "react/no-unused-prop-types": 0, 32 | "import/export": 0 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Serverless directories 108 | .serverless/ 109 | 110 | # FuseBox cache 111 | .fusebox/ 112 | 113 | # DynamoDB Local files 114 | .dynamodb/ 115 | 116 | # TernJS port file 117 | .tern-port 118 | 119 | # Stores VSCode versions used for testing VSCode extensions 120 | .vscode-test 121 | 122 | # yarn v2 123 | .yarn/cache 124 | .yarn/unplugged 125 | .yarn/build-state.yml 126 | .yarn/install-state.gz 127 | .pnp.* 128 | 129 | build 130 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "jsxSingleQuote": true, 4 | "semi": false, 5 | "tabWidth": 2, 6 | "bracketSpacing": true, 7 | "arrowParens": "always", 8 | "trailingComma": "none" 9 | } 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 12 4 | - 10 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 CanCodes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # use-flags 2 | 3 | > Country flags from Flagpedia to use in your React project 4 | 5 | [![NPM](https://img.shields.io/npm/v/use-flags.svg)](https://www.npmjs.com/package/use-flags) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) 6 | 7 | ## Install 8 | 9 | ```bash 10 | npm install --save use-flags 11 | ``` 12 | 13 | ## Flag Types 14 | 15 | Flagpedia has 2 different flag types: 16 | 17 | - Wavey 18 | 19 | ![Wavey](https://flagcdn.com/160x120/tr.png) 20 | 21 | - Flat 22 | 23 | ![Fixed Height](https://flagcdn.com/h120/tr.png) 24 | 25 | But for the **Flat** type, there are also two different subtypes: 26 | 27 | - Fixed Height 28 | - Fixed Width 29 | 30 | ## Usage 31 | 32 | ### Usage of Wavey Flags 33 | 34 | `WaveyFlag` requires 3 attributes: 35 | 36 | - country (ISO 3166) 37 | - fileType (webp or png) 38 | - ratio 39 | 40 | ```tsx 41 | import React from 'react' 42 | import { WaveyFlag } from 'use-flags' 43 | 44 | const App = () => { 45 | return 46 | } 47 | ``` 48 | 49 | ### Usage of Flat Flags 50 | 51 | Flat Flags have two subtypes: Fixed Height and Fixed Width. 52 | Both require 3 attributes: 53 | 54 | - country (ISO 3166) 55 | - fileType (webp, png, jpeg) 56 | - flagHeight or flagWidth 57 | 58 | ```tsx 59 | import React from 'react' 60 | import { FixedHeightFlag, FixedWidthFlag } from 'use-flags' 61 | 62 | const App = () => { 63 | return ( 64 |
65 | 66 | 67 |
68 | ) 69 | } 70 | ``` 71 | 72 | ### SVG Flags 73 | 74 | SVG Flags require 2 attributes: 75 | 76 | - country (ISO 3166) 77 | - width 78 | 79 | ```tsx 80 | import React from 'react' 81 | import { SVGFlag } from 'use-flags' 82 | 83 | const App = () => { 84 | return 85 | } 86 | ``` 87 | 88 | ## License 89 | 90 | MIT © [CanCodes](https://github.com/CanCodes) 91 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | This example was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | It is linked to the use-flags package in the parent directory for development purposes. 4 | 5 | You can run `yarn install` and then `yarn start` to test your package. 6 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "use-flags-example", 3 | "homepage": ".", 4 | "version": "0.0.0", 5 | "private": true, 6 | "scripts": { 7 | "start": "node ../node_modules/react-scripts/bin/react-scripts.js start", 8 | "build": "node ../node_modules/react-scripts/bin/react-scripts.js build", 9 | "test": "node ../node_modules/react-scripts/bin/react-scripts.js test", 10 | "eject": "node ../node_modules/react-scripts/bin/react-scripts.js eject" 11 | }, 12 | "dependencies": { 13 | "@testing-library/jest-dom": "link:../node_modules/@testing-library/jest-dom", 14 | "@testing-library/react": "link:../node_modules/@testing-library/react", 15 | "@testing-library/user-event": "link:../node_modules/@testing-library/user-event", 16 | "@types/jest": "link:../node_modules/@types/jest", 17 | "@types/node": "link:../node_modules/@types/node", 18 | "@types/react": "link:../node_modules/@types/react", 19 | "@types/react-dom": "link:../node_modules/@types/react-dom", 20 | "react": "link:../node_modules/react", 21 | "react-dom": "link:../node_modules/react-dom", 22 | "use-flags": "link:..", 23 | "react-scripts": "link:../node_modules/react-scripts", 24 | "typescript": "link:../node_modules/typescript" 25 | }, 26 | "devDependencies": { 27 | "@babel/plugin-syntax-object-rest-spread": "^7.8.3", 28 | "tailwindcss": "^3.0.9" 29 | }, 30 | "eslintConfig": { 31 | "extends": "react-app" 32 | }, 33 | "browserslist": { 34 | "production": [ 35 | ">0.2%", 36 | "not dead", 37 | "not op_mini all" 38 | ], 39 | "development": [ 40 | "last 1 chrome version", 41 | "last 1 firefox version", 42 | "last 1 safari version" 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CanCodes/use-flags/76e256a83bb357d168567140fe5f12b55dd10908/example/public/favicon.ico -------------------------------------------------------------------------------- /example/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 16 | 17 | 18 | 27 | use-flags 28 | 29 | 30 | 31 | 32 | 33 |
34 | 35 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /example/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "use-flags", 3 | "name": "use-flags", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /example/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './App' 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div') 7 | ReactDOM.render(, div) 8 | ReactDOM.unmountComponentAtNode(div) 9 | }) 10 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { WaveyFlag, FixedHeightFlag, SVGFlag, FixedWidthFlag } from 'use-flags' 4 | const App = () => { 5 | const country = 'fr' 6 | return ( 7 |
8 | 9 |
10 | 11 |
12 | 13 |
14 | 15 |
16 |
17 | ) 18 | } 19 | 20 | export default App 21 | -------------------------------------------------------------------------------- /example/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 5 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /example/src/index.tsx: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | 3 | import React from 'react' 4 | import ReactDOM from 'react-dom' 5 | import App from './App' 6 | 7 | ReactDOM.render(, document.getElementById('root')) 8 | -------------------------------------------------------------------------------- /example/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "module": "esnext", 5 | "lib": [ 6 | "dom", 7 | "esnext" 8 | ], 9 | "moduleResolution": "node", 10 | "jsx": "react", 11 | "sourceMap": true, 12 | "declaration": true, 13 | "esModuleInterop": true, 14 | "noImplicitReturns": true, 15 | "noImplicitThis": true, 16 | "noImplicitAny": true, 17 | "strictNullChecks": true, 18 | "suppressImplicitAnyIndexErrors": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "allowSyntheticDefaultImports": true, 22 | "target": "es5", 23 | "allowJs": true, 24 | "skipLibCheck": true, 25 | "strict": true, 26 | "forceConsistentCasingInFileNames": true, 27 | "resolveJsonModule": true, 28 | "isolatedModules": true, 29 | "noEmit": true 30 | }, 31 | "include": [ 32 | "src" 33 | ], 34 | "exclude": [ 35 | "node_modules", 36 | "build" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "use-flags", 3 | "version": "1.0.1", 4 | "description": "Country flags from Flagpedia to use in your React project", 5 | "author": "CanCodes", 6 | "license": "MIT", 7 | "repository": "CanCodes/use-flags", 8 | "main": "dist/index.js", 9 | "module": "dist/index.modern.js", 10 | "source": "src/index.tsx", 11 | "engines": { 12 | "node": ">=10" 13 | }, 14 | "scripts": { 15 | "build": "microbundle-crl --no-compress --format modern,cjs", 16 | "start": "microbundle-crl watch --no-compress --format modern,cjs", 17 | "prepare": "run-s build", 18 | "predeploy": "cd example && yarn install && yarn run build", 19 | "deploy": "gh-pages -d example/build", 20 | "format": "prettier --write 'src/**/*.{ts,tsx}'" 21 | }, 22 | "peerDependencies": { 23 | "react": "^16.0.0" 24 | }, 25 | "devDependencies": { 26 | "@testing-library/jest-dom": "^4.2.4", 27 | "@testing-library/react": "^9.5.0", 28 | "@testing-library/user-event": "^7.2.1", 29 | "@types/jest": "^25.1.4", 30 | "@types/node": "^12.12.38", 31 | "@types/react": "^16.9.27", 32 | "@types/react-dom": "^16.9.7", 33 | "@typescript-eslint/eslint-plugin": "^2.26.0", 34 | "@typescript-eslint/parser": "^2.26.0", 35 | "microbundle-crl": "^0.13.10", 36 | "babel-eslint": "^10.0.3", 37 | "cross-env": "^7.0.2", 38 | "eslint": "^6.8.0", 39 | "eslint-config-prettier": "^6.7.0", 40 | "eslint-config-standard": "^14.1.0", 41 | "eslint-config-standard-react": "^9.2.0", 42 | "eslint-plugin-import": "^2.18.2", 43 | "eslint-plugin-node": "^11.0.0", 44 | "eslint-plugin-prettier": "^3.1.1", 45 | "eslint-plugin-promise": "^4.2.1", 46 | "eslint-plugin-react": "^7.17.0", 47 | "eslint-plugin-standard": "^4.0.1", 48 | "gh-pages": "^2.2.0", 49 | "npm-run-all": "^4.1.5", 50 | "prettier": "^2.0.4", 51 | "react": "^16.13.1", 52 | "react-dom": "^16.13.1", 53 | "react-scripts": "^3.4.1", 54 | "typescript": "^3.7.5" 55 | }, 56 | "files": [ 57 | "dist" 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /src/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "jest": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/components/fixedhflag.tsx: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-vars 2 | import type { FHeightProps } from '../types' 3 | import React from 'react' 4 | import { API_URL } from '../constants' 5 | 6 | export const FixedHeightFlag = ({ 7 | country, 8 | fileType, 9 | flagHeight 10 | }: FHeightProps) => { 11 | const parsedHeight = parseInt(flagHeight.slice(1)) 12 | const src = `${API_URL}/${flagHeight}/${country}.${ 13 | fileType === 'jpeg' ? 'jpg' : 'png' 14 | }` 15 | 16 | let srcset: string 17 | switch (fileType) { 18 | case 'jpeg': 19 | srcset = '' 20 | break 21 | case 'png': 22 | srcset = 23 | parsedHeight < 240 24 | ? `${API_URL}/h${parsedHeight * 2}/${country}.png 2x, 25 | ${API_URL}/h${parsedHeight * 3}/${country}.png 3x` 26 | : '' 27 | break 28 | default: 29 | srcset = 30 | parsedHeight < 240 31 | ? `${API_URL}/${flagHeight}/${country}.webp, 32 | ${API_URL}/h${parsedHeight * 2}/${country}.webp 2x, 33 | ${API_URL}/h${parsedHeight * 3}/${country}.webp 3x` 34 | : '' 35 | } 36 | return fileType === 'webp' ? ( 37 | 38 | 39 | 40 | {country} 41 | 42 | ) : ( 43 | {country} 44 | ) 45 | } 46 | -------------------------------------------------------------------------------- /src/components/fixedwflag.tsx: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-vars 2 | import type { FWidthProps } from '../types' 3 | import React from 'react' 4 | import { API_URL } from '../constants' 5 | 6 | export const FixedWidthFlag = ({ 7 | country, 8 | flagWidth, 9 | fileType 10 | }: FWidthProps) => { 11 | const parsedWidth = parseInt(flagWidth.slice(1)) 12 | const src = `${API_URL}/${flagWidth}/${country}.${ 13 | fileType === 'jpeg' ? 'jpg' : 'png' 14 | }` 15 | 16 | let srcset: string 17 | switch (fileType) { 18 | case 'jpeg': 19 | srcset = '' 20 | break 21 | case 'png': 22 | srcset = 23 | parsedWidth !== 2560 24 | ? `${API_URL}/w${parsedWidth * 2}/${country}.png 2x` 25 | : '' 26 | break 27 | 28 | default: 29 | srcset = 30 | parsedWidth !== 2560 31 | ? `${API_URL}/${flagWidth}/${country}.webp, 32 | ${API_URL}/w${parsedWidth * 2}/${country}.webp 2x` 33 | : `${API_URL}/${flagWidth}/${country}.webp` 34 | } 35 | 36 | return fileType === 'webp' ? ( 37 | 38 | 39 | 40 | {country} 41 | 42 | ) : ( 43 | {country} 44 | ) 45 | } 46 | -------------------------------------------------------------------------------- /src/components/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './fixedhflag' 2 | export * from './fixedwflag' 3 | export * from './svgflag' 4 | export * from './waveyflag' 5 | -------------------------------------------------------------------------------- /src/components/svgflag.tsx: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-vars 2 | import type { SVGProps } from '../types' 3 | import React from 'react' 4 | import { API_URL } from '../constants' 5 | 6 | export const SVGFlag = ({ country, flagWidth }: SVGProps) => { 7 | return ( 8 | {country} 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /src/components/waveyflag.tsx: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-unused-vars 2 | import type { WaveyProps } from '../types' 3 | import React from 'react' 4 | import { API_URL } from '../constants' 5 | 6 | export const WaveyFlag = ({ country, fileType, ratio }: WaveyProps) => { 7 | const splitSize = ratio.split('x') 8 | const width = splitSize[0] 9 | const height = splitSize[1] 10 | const sizes = { 11 | '2x': `${parseInt(width) * 2}x${parseInt(height) * 2}`, 12 | '3x': `${parseInt(width) * 3}x${parseInt(height) * 3}` 13 | } 14 | const src = `${API_URL}/${ratio}/${country}.png` 15 | 16 | let srcset: string 17 | switch (fileType) { 18 | case 'png': 19 | srcset = 20 | parseInt(width) < 128 21 | ? `${API_URL}/${sizes['2x']}/${country}.${fileType} 2x, ${API_URL}/${sizes['3x']}/${country}.png 3x` 22 | : '' 23 | break 24 | default: 25 | srcset = 26 | parseInt(width) < 128 27 | ? `${API_URL}/${ratio}/${country}.webp, 28 | ${API_URL}/${sizes['2x']}/${country}.webp 2x, 29 | ${API_URL}/${sizes['3x']}/${country}.webp 3x` 30 | : `${API_URL}/${ratio}/${country}.webp` 31 | } 32 | 33 | return fileType === 'webp' ? ( 34 | 35 | 36 | 37 | {country} 38 | 39 | ) : ( 40 | {country} 47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const API_URL = 'https://flagcdn.com' 2 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './components' 2 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export interface DefaultProps { 2 | country: COUNTRY_C0DE 3 | fileType: 'png' | 'webp' | 'jpeg' 4 | } 5 | 6 | export interface WaveyProps extends DefaultProps { 7 | ratio: ASPECT_RATIO 8 | } 9 | 10 | export interface FHeightProps extends DefaultProps { 11 | flagHeight: 'h20' | 'h24' | 'h40' | 'h60' | 'h80' | 'h120' | 'h240' 12 | } 13 | 14 | export interface FWidthProps extends DefaultProps { 15 | flagWidth: 16 | | 'w20' 17 | | 'w40' 18 | | 'w80' 19 | | 'w160' 20 | | 'w320' 21 | | 'w640' 22 | | 'w1280' 23 | | 'w2560' 24 | } 25 | 26 | export interface SVGProps { 27 | country: COUNTRY_C0DE 28 | flagWidth: string 29 | } 30 | 31 | export type FILE_TYPES = 'png' | 'webp' | 'svg' | 'jpeg' 32 | 33 | export type ASPECT_RATIO = 34 | | '16x12' 35 | | '20x15' 36 | | '24x18' 37 | | '28x21' 38 | | '32x24' 39 | | '36x27' 40 | | '40x30' 41 | | '48x36' 42 | | '56x42' 43 | | '60x45' 44 | | '64x48' 45 | | '72x54' 46 | | '80x60' 47 | | '84x63' 48 | | '96x72' 49 | | '108x81' 50 | | '112x84' 51 | | '120x90' 52 | | '128x96' 53 | | '144x108' 54 | | '160x120' 55 | | '192x144' 56 | | '224x168' 57 | | '256x192' 58 | 59 | export type COUNTRY_C0DE = 60 | | 'ad' 61 | | 'ae' 62 | | 'af' 63 | | 'ag' 64 | | 'ai' 65 | | 'al' 66 | | 'am' 67 | | 'ao' 68 | | 'aq' 69 | | 'ar' 70 | | 'as' 71 | | 'at' 72 | | 'au' 73 | | 'aw' 74 | | 'ax' 75 | | 'az' 76 | | 'ba' 77 | | 'bb' 78 | | 'bd' 79 | | 'be' 80 | | 'bf' 81 | | 'bg' 82 | | 'bh' 83 | | 'bi' 84 | | 'bj' 85 | | 'bl' 86 | | 'bm' 87 | | 'bn' 88 | | 'bo' 89 | | 'bq' 90 | | 'br' 91 | | 'bs' 92 | | 'bt' 93 | | 'bv' 94 | | 'bw' 95 | | 'by' 96 | | 'bz' 97 | | 'ca' 98 | | 'cc' 99 | | 'cd' 100 | | 'cf' 101 | | 'cg' 102 | | 'ch' 103 | | 'ci' 104 | | 'ck' 105 | | 'cl' 106 | | 'cm' 107 | | 'cn' 108 | | 'co' 109 | | 'cr' 110 | | 'cu' 111 | | 'cv' 112 | | 'cw' 113 | | 'cx' 114 | | 'cy' 115 | | 'cz' 116 | | 'de' 117 | | 'dj' 118 | | 'dk' 119 | | 'dm' 120 | | 'do' 121 | | 'dz' 122 | | 'ec' 123 | | 'ee' 124 | | 'eg' 125 | | 'eh' 126 | | 'er' 127 | | 'es' 128 | | 'et' 129 | | 'fi' 130 | | 'fj' 131 | | 'fk' 132 | | 'fm' 133 | | 'fo' 134 | | 'fr' 135 | | 'ga' 136 | | 'gb-eng' 137 | | 'gb-nir' 138 | | 'gb-sct' 139 | | 'gb-wls' 140 | | 'gb' 141 | | 'gd' 142 | | 'ge' 143 | | 'gf' 144 | | 'gg' 145 | | 'gh' 146 | | 'gi' 147 | | 'gl' 148 | | 'gm' 149 | | 'gn' 150 | | 'gp' 151 | | 'gq' 152 | | 'gr' 153 | | 'gs' 154 | | 'gt' 155 | | 'gu' 156 | | 'gw' 157 | | 'gy' 158 | | 'hk' 159 | | 'hm' 160 | | 'hn' 161 | | 'hr' 162 | | 'ht' 163 | | 'hu' 164 | | 'id' 165 | | 'ie' 166 | | 'il' 167 | | 'im' 168 | | 'in' 169 | | 'io' 170 | | 'iq' 171 | | 'ir' 172 | | 'is' 173 | | 'it' 174 | | 'je' 175 | | 'jm' 176 | | 'jo' 177 | | 'jp' 178 | | 'ke' 179 | | 'kg' 180 | | 'kh' 181 | | 'ki' 182 | | 'km' 183 | | 'kn' 184 | | 'kp' 185 | | 'kr' 186 | | 'kw' 187 | | 'ky' 188 | | 'kz' 189 | | 'la' 190 | | 'lb' 191 | | 'lc' 192 | | 'li' 193 | | 'lk' 194 | | 'lr' 195 | | 'ls' 196 | | 'lt' 197 | | 'lu' 198 | | 'lv' 199 | | 'ly' 200 | | 'ma' 201 | | 'mc' 202 | | 'md' 203 | | 'me' 204 | | 'mf' 205 | | 'mg' 206 | | 'mh' 207 | | 'mk' 208 | | 'ml' 209 | | 'mm' 210 | | 'mn' 211 | | 'mo' 212 | | 'mp' 213 | | 'mq' 214 | | 'mr' 215 | | 'ms' 216 | | 'mt' 217 | | 'mu' 218 | | 'mv' 219 | | 'mw' 220 | | 'mx' 221 | | 'my' 222 | | 'mz' 223 | | 'na' 224 | | 'nc' 225 | | 'ne' 226 | | 'nf' 227 | | 'ng' 228 | | 'ni' 229 | | 'nl' 230 | | 'no' 231 | | 'np' 232 | | 'nr' 233 | | 'nu' 234 | | 'nz' 235 | | 'om' 236 | | 'pa' 237 | | 'pe' 238 | | 'pf' 239 | | 'pg' 240 | | 'ph' 241 | | 'pk' 242 | | 'pl' 243 | | 'pm' 244 | | 'pn' 245 | | 'pr' 246 | | 'ps' 247 | | 'pt' 248 | | 'pw' 249 | | 'py' 250 | | 'qa' 251 | | 're' 252 | | 'ro' 253 | | 'rs' 254 | | 'ru' 255 | | 'rw' 256 | | 'sa' 257 | | 'sb' 258 | | 'sc' 259 | | 'sd' 260 | | 'se' 261 | | 'sg' 262 | | 'sh' 263 | | 'si' 264 | | 'sj' 265 | | 'sk' 266 | | 'sl' 267 | | 'sm' 268 | | 'sn' 269 | | 'so' 270 | | 'sr' 271 | | 'ss' 272 | | 'st' 273 | | 'sv' 274 | | 'sx' 275 | | 'sy' 276 | | 'sz' 277 | | 'tc' 278 | | 'td' 279 | | 'tf' 280 | | 'tg' 281 | | 'th' 282 | | 'tj' 283 | | 'tk' 284 | | 'tl' 285 | | 'tm' 286 | | 'tn' 287 | | 'to' 288 | | 'tr' 289 | | 'tt' 290 | | 'tv' 291 | | 'tw' 292 | | 'tz' 293 | | 'ua' 294 | | 'ug' 295 | | 'um' 296 | | 'us' 297 | | 'uy' 298 | | 'uz' 299 | | 'va' 300 | | 'vc' 301 | | 've' 302 | | 'vg' 303 | | 'vi' 304 | | 'vn' 305 | | 'vu' 306 | | 'wf' 307 | | 'ws' 308 | | 'xk' 309 | | 'ye' 310 | | 'yt' 311 | | 'za' 312 | | 'zm' 313 | | 'zw' 314 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Default CSS definition for typescript, 3 | * will be overridden with file-specific definitions by rollup 4 | */ 5 | declare module '*.css' { 6 | const content: { [className: string]: string } 7 | export default content 8 | } 9 | 10 | interface SvgrComponent 11 | extends React.StatelessComponent> {} 12 | 13 | declare module '*.svg' { 14 | const svgUrl: string 15 | const svgComponent: SvgrComponent 16 | export default svgUrl 17 | export { svgComponent as ReactComponent } 18 | } 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "module": "esnext", 5 | "lib": [ 6 | "dom", 7 | "esnext" 8 | ], 9 | "moduleResolution": "node", 10 | "jsx": "react", 11 | "sourceMap": true, 12 | "declaration": true, 13 | "esModuleInterop": true, 14 | "noImplicitReturns": true, 15 | "noImplicitThis": true, 16 | "noImplicitAny": true, 17 | "strictNullChecks": true, 18 | "suppressImplicitAnyIndexErrors": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "allowSyntheticDefaultImports": true, 22 | "target": "es5", 23 | "allowJs": true, 24 | "skipLibCheck": true, 25 | "strict": true, 26 | "forceConsistentCasingInFileNames": true, 27 | "resolveJsonModule": true, 28 | "isolatedModules": true, 29 | "noEmit": true 30 | }, 31 | "include": [ 32 | "src" 33 | ], 34 | "exclude": [ 35 | "node_modules", 36 | "dist", 37 | "example" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs" 5 | } 6 | } --------------------------------------------------------------------------------