├── .gitignore ├── .prettierrc.json ├── .storybook ├── main.js └── preview.js ├── LICENSE ├── README.md ├── babel.config.js ├── jest.config.js ├── package-lock.json ├── package.json ├── rollup.config.js ├── src ├── components │ ├── WebsiteCarbonBadge.tsx │ ├── WebsiteCarbonBadge.types.ts │ ├── __stories__ │ │ ├── Introduction.stories.mdx │ │ ├── WebsiteCarbonBadge.stories.tsx │ │ └── assets │ │ │ ├── code-brackets.svg │ │ │ ├── colors.svg │ │ │ ├── comments.svg │ │ │ ├── direction.svg │ │ │ ├── flow.svg │ │ │ ├── plugin.svg │ │ │ ├── repo.svg │ │ │ └── stackalt.svg │ └── __tests__ │ │ └── WebsiteCarbonBadge.test.tsx └── index.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | coverage/ 4 | build/ -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "printWidth": 100 4 | } 5 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | stories: ['../src/**/**/*.stories.mdx', '../src/**/**/*.stories.@(js|jsx|ts|tsx)'], 3 | addons: ['@storybook/addon-links', '@storybook/addon-essentials'], 4 | framework: '@storybook/react', 5 | }; 6 | -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | export const parameters = { 2 | actions: { argTypesRegex: "^on[A-Z].*" }, 3 | controls: { 4 | matchers: { 5 | color: /(background|color)$/i, 6 | date: /Date$/, 7 | }, 8 | }, 9 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 clement-joye 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 | # react-websitecarbon-badge 2 | 3 | React component for Website Carbon badge: https://www.websitecarbon.com/badge/. Can be used both for static and dynamic websites. 4 | 5 | ## Introduction 6 | 7 | This React component fits both static and dynamic web apps. 8 | The values on the badge can be set directly via props or fetched from https://www.websitecarbon.com/api/. 9 | 10 | If using GatsbyJS, this react component goes hand in hand with: https://www.npmjs.com/package/gatsby-source-websitecarbon 11 | 12 | ## Install 13 | 14 | ```bash 15 | npm install react-websitecarbon-badge 16 | ``` 17 | 18 | ## How to use 19 | 20 | ```js 21 | import { WebsiteCarbonBadge } from 'react-websitecarbon-badge'; 22 | 23 | class MyComponent extends React.Component { 24 | render() { 25 | return ; 26 | } 27 | } 28 | ``` 29 | 30 | ## Props 31 | 32 | * `dark`: 33 | * Boolean 34 | * Optional. Default `false` 35 | * Specify to use dark badge version 36 | * `co2`: 37 | * String 38 | * Optional. Default to empty string 39 | * Sets the co2/view value. 40 | * `percentage`: 41 | * String 42 | * Optional. Default to empty string 43 | * Sets the ranking percentage value. 44 | * `url`: 45 | * String 46 | * Optional. Default to empty string 47 | * Sets the url to fetch data from website carbon api. 48 | * `lang`: 49 | * String 50 | * optional. Default to '`en`' 51 | * Sets the default language to use. (Currently supports '`en`' or '`fr`') 52 | 53 | *NB: setting co2 and percentage takes precedence over the url, preventing unnecessary api fetch.* 54 | 55 | ## Examples 56 | 57 | ```js 58 | 59 | ``` 60 | Fetches data from `www.google.com` via http request if not found in local storage. 61 | ```js 62 | 63 | ``` 64 | Uses dark version and sets co2 = 0.12 and percentage = 89%. 65 | ```js 66 | 67 | ``` 68 | Uses french as language for the badge. 69 | ```js 70 | 71 | ``` 72 | Uses co2 = 0.56 and percentage = 41%, and does not use the url provided. 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | "@babel/preset-env", 4 | "@babel/preset-react", 5 | "@babel/preset-typescript", 6 | ], 7 | }; -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * For a detailed explanation regarding each configuration property, visit: 3 | * https://jestjs.io/docs/configuration 4 | */ 5 | 6 | module.exports = { 7 | // All imported modules in your tests should be mocked automatically 8 | // automock: false, 9 | 10 | // Stop running tests after `n` failures 11 | // bail: 0, 12 | 13 | // The directory where Jest should store its cached dependency information 14 | // cacheDirectory: "/private/var/folders/1j/nfv3trk15wz2kxd6g6w_6zd00000gn/T/jest_dx", 15 | 16 | // Automatically clear mock calls, instances and results before every test 17 | // clearMocks: false, 18 | 19 | // Indicates whether the coverage information should be collected while executing the test 20 | collectCoverage: true, 21 | 22 | // An array of glob patterns indicating a set of files for which coverage information should be collected 23 | // collectCoverageFrom: undefined, 24 | 25 | // The directory where Jest should output its coverage files 26 | coverageDirectory: 'coverage', 27 | 28 | // An array of regexp pattern strings used to skip coverage collection 29 | // coveragePathIgnorePatterns: [ 30 | // "/node_modules/" 31 | // ], 32 | 33 | // Indicates which provider should be used to instrument code for coverage 34 | // coverageProvider: "babel", 35 | 36 | // A list of reporter names that Jest uses when writing coverage reports 37 | // coverageReporters: [ 38 | // "json", 39 | // "text", 40 | // "lcov", 41 | // "clover" 42 | // ], 43 | 44 | // An object that configures minimum threshold enforcement for coverage results 45 | // coverageThreshold: undefined, 46 | 47 | // A path to a custom dependency extractor 48 | // dependencyExtractor: undefined, 49 | 50 | // Make calling deprecated APIs throw helpful error messages 51 | // errorOnDeprecated: false, 52 | 53 | // Force coverage collection from ignored files using an array of glob patterns 54 | // forceCoverageMatch: [], 55 | 56 | // A path to a module which exports an async function that is triggered once before all test suites 57 | // globalSetup: undefined, 58 | 59 | // A path to a module which exports an async function that is triggered once after all test suites 60 | // globalTeardown: undefined, 61 | 62 | // A set of global variables that need to be available in all test environments 63 | // globals: {}, 64 | 65 | // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. 66 | // maxWorkers: "50%", 67 | 68 | // An array of directory names to be searched recursively up from the requiring module's location 69 | // moduleDirectories: [ 70 | // "node_modules" 71 | // ], 72 | 73 | // An array of file extensions your modules use 74 | // moduleFileExtensions: [ 75 | // "js", 76 | // "jsx", 77 | // "ts", 78 | // "tsx", 79 | // "json", 80 | // "node" 81 | // ], 82 | 83 | // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module 84 | // moduleNameMapper: {}, 85 | 86 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader 87 | // modulePathIgnorePatterns: [], 88 | 89 | // Activates notifications for test results 90 | // notify: false, 91 | 92 | // An enum that specifies notification mode. Requires { notify: true } 93 | // notifyMode: "failure-change", 94 | 95 | // A preset that is used as a base for Jest's configuration 96 | // preset: undefined, 97 | 98 | // Run tests from one or more projects 99 | // projects: undefined, 100 | 101 | // Use this configuration option to add custom reporters to Jest 102 | // reporters: undefined, 103 | 104 | // Automatically reset mock state before every test 105 | // resetMocks: false, 106 | 107 | // Reset the module registry before running each individual test 108 | // resetModules: false, 109 | 110 | // A path to a custom resolver 111 | // resolver: undefined, 112 | 113 | // Automatically restore mock state and implementation before every test 114 | // restoreMocks: false, 115 | 116 | // The root directory that Jest should scan for tests and modules within 117 | // rootDir: undefined, 118 | 119 | // A list of paths to directories that Jest should use to search for files in 120 | // roots: [ 121 | // "" 122 | // ], 123 | 124 | // Allows you to use a custom runner instead of Jest's default test runner 125 | // runner: "jest-runner", 126 | 127 | // The paths to modules that run some code to configure or set up the testing environment before each test 128 | // setupFiles: [], 129 | 130 | // A list of paths to modules that run some code to configure or set up the testing framework before each test 131 | // setupFilesAfterEnv: [], 132 | 133 | // The number of seconds after which a test is considered as slow and reported as such in the results. 134 | // slowTestThreshold: 5, 135 | 136 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing 137 | // snapshotSerializers: [], 138 | 139 | // The test environment that will be used for testing 140 | testEnvironment: 'jsdom', 141 | 142 | // Options that will be passed to the testEnvironment 143 | // testEnvironmentOptions: {}, 144 | 145 | // Adds a location field to test results 146 | // testLocationInResults: false, 147 | 148 | // The glob patterns Jest uses to detect test files 149 | // testMatch: [ 150 | // "**/__tests__/**/*.[jt]s?(x)", 151 | // "**/?(*.)+(spec|test).[tj]s?(x)" 152 | // ], 153 | 154 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped 155 | // testPathIgnorePatterns: [ 156 | // "/node_modules/" 157 | // ], 158 | 159 | // The regexp pattern or array of patterns that Jest uses to detect test files 160 | // testRegex: [], 161 | 162 | // This option allows the use of a custom results processor 163 | // testResultsProcessor: undefined, 164 | 165 | // This option allows use of a custom test runner 166 | // testRunner: "jest-circus/runner", 167 | 168 | // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href 169 | // testURL: "http://localhost", 170 | 171 | // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" 172 | // timers: "real", 173 | 174 | // A map from regular expressions to paths to transformers 175 | // transform: { 176 | // '^.+\\.(t|j)sx?$': ['@swc/jest'], 177 | // }, 178 | 179 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation 180 | // transformIgnorePatterns: [ 181 | // "/node_modules/", 182 | // "\\.pnp\\.[^\\/]+$" 183 | // ], 184 | 185 | // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them 186 | // unmockedModulePathPatterns: undefined, 187 | 188 | // Indicates whether each individual test should be reported during the run 189 | // verbose: undefined, 190 | 191 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode 192 | // watchPathIgnorePatterns: [], 193 | 194 | // Whether to use watchman for file crawling 195 | // watchman: true, 196 | }; 197 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-websitecarbon-badge", 3 | "version": "1.0.5", 4 | "description": "React component for Website Carbon badge: https://www.websitecarbon.com/badge/", 5 | "keywords": [ 6 | "react", 7 | "website-carbon", 8 | "websitecarbon-badge" 9 | ], 10 | "main": "dist/cjs/index.js", 11 | "module": "dist/esm/index.js", 12 | "scripts": { 13 | "test": "jest", 14 | "build": "rollup -c", 15 | "storybook": "start-storybook -p 6006", 16 | "build-storybook": "build-storybook" 17 | }, 18 | "author": "Clément Joye", 19 | "license": "MIT", 20 | "dependencies": { 21 | "styled-components": "^5.3.3" 22 | }, 23 | "peerDependencies": {}, 24 | "devDependencies": { 25 | "@babel/core": "^7.18.10", 26 | "@babel/preset-env": "^7.18.10", 27 | "@babel/preset-react": "^7.18.6", 28 | "@babel/preset-typescript": "^7.18.6", 29 | "@rollup/plugin-commonjs": "^21.0.1", 30 | "@rollup/plugin-node-resolve": "^13.1.1", 31 | "@rollup/plugin-typescript": "^8.3.0", 32 | "@storybook/addon-actions": "^6.4.9", 33 | "@storybook/addon-essentials": "^6.4.9", 34 | "@storybook/addon-links": "^6.4.9", 35 | "@storybook/react": "^6.4.9", 36 | "@swc/jest": "^0.2.15", 37 | "@testing-library/jest-dom": "^5.16.1", 38 | "@testing-library/react": "^12.1.2", 39 | "@testing-library/user-event": "^13.5.0", 40 | "@types/jest": "^27.0.3", 41 | "@types/react": "^17.0.38", 42 | "@types/react-dom": "^17.0.11", 43 | "@types/styled-components": "^5.1.19", 44 | "babel-jest": "^28.1.3", 45 | "babel-loader": "^8.2.3", 46 | "jest": "^27.4.5", 47 | "react": "^17.0.2", 48 | "react-dom": "^17.0.2", 49 | "rollup": "^2.62.0", 50 | "rollup-plugin-dts": "^4.1.0", 51 | "rollup-plugin-peer-deps-external": "^2.2.4", 52 | "rollup-plugin-terser": "^7.0.2", 53 | "typescript": "^4.5.4" 54 | }, 55 | "repository": { 56 | "type": "git", 57 | "url": "https://github.com/clement-joye/react-websitecarbon-badge" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from "@rollup/plugin-node-resolve"; 2 | import commonjs from "@rollup/plugin-commonjs"; 3 | import typescript from "@rollup/plugin-typescript"; 4 | import dts from "rollup-plugin-dts"; 5 | import { terser } from "rollup-plugin-terser"; 6 | import peerDepsExternal from "rollup-plugin-peer-deps-external"; 7 | 8 | const packageJson = require("./package.json"); 9 | 10 | export default [ 11 | { 12 | input: "src/index.ts", 13 | output: [ 14 | { 15 | file: packageJson.main, 16 | format: "cjs", 17 | sourcemap: true, 18 | }, 19 | { 20 | file: packageJson.module, 21 | format: "esm", 22 | sourcemap: true, 23 | }, 24 | ], 25 | plugins: [ 26 | peerDepsExternal(), 27 | resolve(), 28 | commonjs(), 29 | typescript({ tsconfig: "./tsconfig.json" }), 30 | terser(), 31 | ], 32 | external: ["react", "react-dom", "styled-components"], 33 | }, 34 | { 35 | input: "dist/esm/index.d.ts", 36 | output: [{ file: "dist/index.d.ts", format: "esm" }], 37 | plugins: [dts()], 38 | }, 39 | ]; 40 | -------------------------------------------------------------------------------- /src/components/WebsiteCarbonBadge.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import React, { useEffect, useState } from "react" 4 | import { WebsiteCarbonBadgeProps } from "./WebsiteCarbonBadge.types" 5 | import styled, { css } from "styled-components" 6 | 7 | const Wrapper = styled.div` 8 | --b1: #0e11a8; 9 | --b2: #00ffbc; 10 | font-size: 15px; 11 | text-align: center; 12 | color: var(--b1); 13 | line-height: 1.15; 14 | ` 15 | 16 | const LinkCo2 = styled.a` 17 | display: inline-flex; 18 | justify-content: center; 19 | align-items: center; 20 | text-align: center; 21 | font-size: 1em; 22 | line-height: 1.15; 23 | font-family: -apple-system, BlinkMacSystemFont, sans-serif; 24 | text-decoration: none; 25 | margin: 0.2em 0; 26 | padding: 0.3em 0.5em; 27 | border: 0.13em solid var(--b2); 28 | border-radius: 0.3em 0 0 0.3em; 29 | background: #fff; 30 | border-right: 0; 31 | min-width: 8.2em; 32 | color: var(--b1); 33 | ` 34 | 35 | const Sub = styled.sub` 36 | vertical-align: middle; 37 | position: relative; 38 | top: 0.3em; 39 | font-size: 0.7em; 40 | ` 41 | 42 | const Link = styled.a` 43 | display: inline-flex; 44 | justify-content: center; 45 | align-items: center; 46 | text-align: center; 47 | font-size: 1em; 48 | line-height: 1.15; 49 | font-family: -apple-system, BlinkMacSystemFont, sans-serif; 50 | text-decoration: none; 51 | margin: 0.2em 0; 52 | padding: 0.3em 0.5em; 53 | border: 0.13em solid var(--b2); 54 | border-radius: 0 0.3em 0.3em 0; 55 | border-left: 0; 56 | background: var(--b1); 57 | color: #fff; 58 | font-weight: 700; 59 | border-color: var(--b1); 60 | 61 | ${props => 62 | props.dark && 63 | css` 64 | color: var(--b1); 65 | background: var(--b2); 66 | border-color: var(--b2); 67 | `} 68 | ` 69 | 70 | const Percentage = styled.span` 71 | display: inline-flex; 72 | justify-content: center; 73 | align-items: center; 74 | text-align: center; 75 | font-size: 1em; 76 | line-height: 1.15; 77 | font-family: -apple-system, BlinkMacSystemFont, sans-serif; 78 | text-decoration: none; 79 | margin: 0.2em 0; 80 | 81 | ${props => 82 | props.dark && 83 | css` 84 | color: #fff; 85 | `} 86 | ` 87 | 88 | const dict = { 89 | en: { 90 | p1: "of", 91 | p2: "view", 92 | p3: "Cleaner than", 93 | p4: "Dirtier than", 94 | p5: "of pages tested", 95 | }, 96 | fr: { 97 | p1: "de", 98 | p2: "vue", 99 | p3: "Page web plus légère que", 100 | p4: "Page web plus lourde que", 101 | p5: "des pages testées", 102 | }, 103 | } 104 | 105 | const WebsiteCarbonBadge = (props: WebsiteCarbonBadgeProps) => { 106 | const [data, setData] = useState({ co2: "", percentage: "" }) 107 | 108 | useEffect(() => { 109 | const fetchData = async (props: WebsiteCarbonBadgeProps) => { 110 | let url = props.url ? encodeURIComponent(props.url) : "" 111 | let data = localStorage.getItem(`wcb_${url}`) 112 | 113 | if (props.co2 && props.percentage) { 114 | setData({ co2: props.co2, percentage: props.percentage }) 115 | } else if (data) { 116 | let parsed = JSON.parse(data) 117 | setData({ co2: parsed.c, percentage: parsed.p }) 118 | } else { 119 | if (!props.url) { 120 | throw Error("Website carbon: url is null") 121 | } 122 | 123 | try { 124 | const res = await fetch("https://api.websitecarbon.com/b?url=" + url) 125 | 126 | if (!res.ok) throw Error(JSON.stringify(await res.json())) 127 | const data = await res.json() 128 | 129 | localStorage.setItem(`wcb_${url}`, JSON.stringify(data)) 130 | 131 | setData({ co2: data.c, percentage: data.p }) 132 | } catch (e) { 133 | console.error(e) 134 | localStorage.removeItem(`wcb_${url}`) 135 | } 136 | } 137 | } 138 | 139 | fetchData(props).catch(console.error) 140 | }, [props]) 141 | 142 | let ps = props.lang == "fr" ? dict.fr : dict.en 143 | 144 | return ( 145 | 146 |
147 | 152 | {data.co2 ? data.co2 : "-"}g {ps.p1} CO2/{ps.p2} 153 | 154 | 160 | Website Carbon 161 | 162 |
163 | 164 | {data.percentage 165 | ? parseInt(data.percentage) > 50 166 | ? `${ps.p3} ${data.percentage}% ${ps.p5}` 167 | : `${ps.p4} ${data.percentage}% ${ps.p5}` 168 | : ""} 169 | 170 |
171 | ) 172 | } 173 | 174 | export default WebsiteCarbonBadge 175 | -------------------------------------------------------------------------------- /src/components/WebsiteCarbonBadge.types.ts: -------------------------------------------------------------------------------- 1 | export interface WebsiteCarbonBadgeProps { 2 | dark?: boolean; 3 | co2?: string; 4 | percentage?: string; 5 | url?: string | undefined; 6 | lang?: string; 7 | } 8 | -------------------------------------------------------------------------------- /src/components/__stories__/Introduction.stories.mdx: -------------------------------------------------------------------------------- 1 | import { Meta } from '@storybook/addon-docs'; 2 | import Code from './assets/code-brackets.svg'; 3 | import Colors from './assets/colors.svg'; 4 | import Comments from './assets/comments.svg'; 5 | import Direction from './assets/direction.svg'; 6 | import Flow from './assets/flow.svg'; 7 | import Plugin from './assets/plugin.svg'; 8 | import Repo from './assets/repo.svg'; 9 | import StackAlt from './assets/stackalt.svg'; 10 | 11 | 12 | 13 | 116 | 117 | # Welcome to Storybook 118 | 119 | Storybook helps you build UI components in isolation from your app's business logic, data, and context. 120 | That makes it easy to develop hard-to-reach states. Save these UI states as **stories** to revisit during development, testing, or QA. 121 | 122 | Browse example stories now by navigating to them in the sidebar. 123 | View their code in the `src/stories` directory to learn how they work. 124 | We recommend building UIs with a [**component-driven**](https://componentdriven.org) process starting with atomic components and ending with pages. 125 | 126 |
Configure
127 | 128 | 174 | 175 |
Learn
176 | 177 | 207 | 208 |
209 | TipEdit the Markdown in{' '} 210 | src/stories/Introduction.stories.mdx 211 |
212 | -------------------------------------------------------------------------------- /src/components/__stories__/WebsiteCarbonBadge.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ComponentStory, ComponentMeta } from '@storybook/react'; 3 | 4 | import WebsiteCarbonBadge from '../WebsiteCarbonBadge'; 5 | 6 | export default { 7 | title: 'WebsiteCarbonBadge', 8 | component: WebsiteCarbonBadge, 9 | argTypes: {}, 10 | } as ComponentMeta; 11 | 12 | const Template: ComponentStory = (args) => ; 13 | 14 | export const Light = Template.bind({}); 15 | Light.args = { 16 | dark: false, 17 | co2: '12', 18 | percentage: '90' 19 | }; 20 | 21 | export const Dark = Template.bind({}); 22 | Dark.args = { 23 | dark: true, 24 | co2: '12', 25 | percentage: '90' 26 | }; 27 | 28 | export const English = Template.bind({}); 29 | English.args = { 30 | dark: false, 31 | co2: '12', 32 | percentage: '90', 33 | lang: 'en' 34 | }; 35 | 36 | export const EnglishDirtier = Template.bind({}); 37 | EnglishDirtier.args = { 38 | dark: false, 39 | co2: '89', 40 | percentage: '49', 41 | lang: 'en' 42 | }; 43 | 44 | export const French = Template.bind({}); 45 | French.args = { 46 | dark: false, 47 | co2: '12', 48 | percentage: '90', 49 | lang: 'fr' 50 | }; 51 | 52 | export const FrenchDirtier = Template.bind({}); 53 | FrenchDirtier.args = { 54 | dark: false, 55 | co2: '89', 56 | percentage: '49', 57 | lang: 'fr' 58 | }; 59 | 60 | export const Url = Template.bind({}); 61 | Url.args = { 62 | dark: false, 63 | co2: '12', 64 | percentage: '90', 65 | lang: 'en', 66 | url: "www.example.com" 67 | }; 68 | 69 | export const FetchData = Template.bind({}); 70 | FetchData.args = { 71 | dark: false, 72 | lang: 'en', 73 | url: "www.google.com" 74 | }; 75 | 76 | -------------------------------------------------------------------------------- /src/components/__stories__/assets/code-brackets.svg: -------------------------------------------------------------------------------- 1 | illustration/code-brackets -------------------------------------------------------------------------------- /src/components/__stories__/assets/colors.svg: -------------------------------------------------------------------------------- 1 | illustration/colors -------------------------------------------------------------------------------- /src/components/__stories__/assets/comments.svg: -------------------------------------------------------------------------------- 1 | illustration/comments -------------------------------------------------------------------------------- /src/components/__stories__/assets/direction.svg: -------------------------------------------------------------------------------- 1 | illustration/direction -------------------------------------------------------------------------------- /src/components/__stories__/assets/flow.svg: -------------------------------------------------------------------------------- 1 | illustration/flow -------------------------------------------------------------------------------- /src/components/__stories__/assets/plugin.svg: -------------------------------------------------------------------------------- 1 | illustration/plugin -------------------------------------------------------------------------------- /src/components/__stories__/assets/repo.svg: -------------------------------------------------------------------------------- 1 | illustration/repo -------------------------------------------------------------------------------- /src/components/__stories__/assets/stackalt.svg: -------------------------------------------------------------------------------- 1 | illustration/stackalt -------------------------------------------------------------------------------- /src/components/__tests__/WebsiteCarbonBadge.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '@testing-library/jest-dom'; 3 | import { render } from '@testing-library/react'; 4 | 5 | import WebsiteCarbonBadge from '../WebsiteCarbonBadge'; 6 | 7 | describe('Running Test for WebsiteCarbonBadge', () => { 8 | it('renders the component', () => { 9 | render(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import WebsiteCarbonBadge from "./components/WebsiteCarbonBadge"; 2 | 3 | export { WebsiteCarbonBadge }; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Language and Environment */ 4 | "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 5 | "jsx": "react", /* Specify what JSX code is generated. */ 6 | 7 | /* Modules */ 8 | "module": "ESNext", /* Specify what module code is generated. */ 9 | "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 10 | 11 | /* Emit */ 12 | "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 13 | "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 14 | "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 15 | "outDir": "dist", /* Specify an output folder for all emitted files. */ 16 | "declarationDir": "types", /* Specify the output directory for generated declaration files. */ 17 | 18 | /* Interop Constraints */ 19 | "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 20 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 21 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 22 | 23 | /* Type Checking */ 24 | "strict": true, /* Enable all strict type-checking options. */ 25 | 26 | /* Completeness */ 27 | "skipLibCheck": true, /* Skip type checking all .d.ts files. */ 28 | }, 29 | "exclude": [ 30 | "dist", 31 | "node_modules", 32 | "src/**/*.test.tsx", 33 | "src/**/*.stories.tsx", 34 | ], 35 | } 36 | --------------------------------------------------------------------------------