├── .gitignore
├── LICENSE
├── README.md
├── example
├── .npmignore
├── data.ts
├── index.html
├── index.tsx
├── package.json
├── tsconfig.json
└── yarn.lock
├── package.json
├── src
├── ignore.d.ts
├── index.tsx
└── utils
│ ├── ToolTip.tsx
│ └── darkenColor.ts
├── test
└── blah.test.tsx
├── tsconfig.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .DS_Store
3 | node_modules
4 | .rts2_cache_cjs
5 | .rts2_cache_es
6 | .rts2_cache_umd
7 | dist
8 | .cache
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Harshit Pant
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 | # Recontrib
2 |
3 | React Component that implements GiHub's commit graph UI. https://pantharshit00.github.io/recontrib
4 |
5 | 
6 |
7 | ## Usage
8 |
9 | 1. Add the Reach UI tooltip CSS
10 |
11 | ```js
12 | import '@reach/tooltip/style.css';
13 | ```
14 |
15 | 2. Use the component and pass the data
16 |
17 | ```js
18 | const App = () => {
19 | return (
20 |
21 |
22 |
23 | );
24 | };
25 | ```
26 |
27 | Data is structured as following. You can directly pass the data from the GitHub API(https://api.github.com/repos/:owner/:repo/stats/commit_activity):
28 |
29 | ```ts
30 | interface WeekData {
31 | days: number[]; // commits in individual days in the week
32 | total: number; // total number commits in the week
33 | week: number; // Timestamp in seconds of the seconds of the starting of the week
34 | }
35 | ```
36 |
37 | ## Props
38 |
39 | ```ts
40 | interface Props {
41 | data: Array; // data
42 | gridSize?: number; // size of the tile
43 | fontSize?: string; // fontSize of months and weekdays
44 | }
45 | ```
46 |
47 | ---
48 |
49 | MIT️ ©️ [Harshit Pant](https://twitter.com/pantharshit00) 2019
50 |
--------------------------------------------------------------------------------
/example/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .cache
3 | dist
--------------------------------------------------------------------------------
/example/data.ts:
--------------------------------------------------------------------------------
1 | export const data = [
2 | {
3 | days: [1, 0, 57, 28, 30, 18, 1],
4 | total: 135,
5 | week: 1526774400,
6 | },
7 | {
8 | days: [0, 18, 11, 11, 27, 50, 3],
9 | total: 120,
10 | week: 1527379200,
11 | },
12 | {
13 | days: [1, 20, 21, 14, 13, 16, 0],
14 | total: 85,
15 | week: 1527984000,
16 | },
17 | {
18 | days: [2, 21, 29, 12, 7, 0, 2],
19 | total: 73,
20 | week: 1528588800,
21 | },
22 | {
23 | days: [0, 18, 24, 21, 17, 10, 1],
24 | total: 91,
25 | week: 1529193600,
26 | },
27 | {
28 | days: [0, 20, 32, 21, 32, 41, 1],
29 | total: 147,
30 | week: 1529798400,
31 | },
32 | {
33 | days: [0, 19, 12, 15, 11, 4, 0],
34 | total: 61,
35 | week: 1530403200,
36 | },
37 | {
38 | days: [1, 6, 0, 1, 5, 4, 0],
39 | total: 17,
40 | week: 1531008000,
41 | },
42 | {
43 | days: [1, 6, 26, 14, 5, 7, 1],
44 | total: 60,
45 | week: 1531612800,
46 | },
47 | {
48 | days: [1, 4, 7, 11, 16, 3, 2],
49 | total: 44,
50 | week: 1532217600,
51 | },
52 | {
53 | days: [21, 25, 13, 26, 10, 5, 0],
54 | total: 100,
55 | week: 1532822400,
56 | },
57 | {
58 | days: [0, 6, 5, 25, 15, 3, 1],
59 | total: 55,
60 | week: 1533427200,
61 | },
62 | {
63 | days: [2, 9, 15, 9, 4, 16, 0],
64 | total: 55,
65 | week: 1534032000,
66 | },
67 | {
68 | days: [4, 12, 4, 1, 6, 17, 2],
69 | total: 46,
70 | week: 1534636800,
71 | },
72 | {
73 | days: [5, 17, 22, 15, 32, 31, 12],
74 | total: 134,
75 | week: 1535241600,
76 | },
77 | {
78 | days: [0, 37, 51, 48, 1, 0, 0],
79 | total: 137,
80 | week: 1535846400,
81 | },
82 | {
83 | days: [9, 113, 74, 30, 21, 5, 0],
84 | total: 252,
85 | week: 1536451200,
86 | },
87 | {
88 | days: [0, 35, 14, 8, 26, 9, 2],
89 | total: 94,
90 | week: 1537056000,
91 | },
92 | {
93 | days: [11, 20, 26, 32, 29, 17, 1],
94 | total: 136,
95 | week: 1537660800,
96 | },
97 | {
98 | days: [5, 12, 17, 16, 38, 23, 7],
99 | total: 118,
100 | week: 1538265600,
101 | },
102 | {
103 | days: [1, 20, 15, 14, 10, 1, 2],
104 | total: 63,
105 | week: 1538870400,
106 | },
107 | {
108 | days: [2, 13, 17, 6, 12, 8, 1],
109 | total: 59,
110 | week: 1539475200,
111 | },
112 | {
113 | days: [1, 12, 22, 19, 7, 4, 2],
114 | total: 67,
115 | week: 1540080000,
116 | },
117 | {
118 | days: [0, 11, 15, 22, 10, 10, 0],
119 | total: 68,
120 | week: 1540684800,
121 | },
122 | {
123 | days: [0, 13, 33, 18, 66, 35, 18],
124 | total: 183,
125 | week: 1541289600,
126 | },
127 | {
128 | days: [1, 7, 33, 37, 25, 13, 0],
129 | total: 116,
130 | week: 1541894400,
131 | },
132 | {
133 | days: [6, 31, 25, 27, 27, 25, 1],
134 | total: 142,
135 | week: 1542499200,
136 | },
137 | {
138 | days: [1, 7, 23, 9, 9, 11, 3],
139 | total: 63,
140 | week: 1543104000,
141 | },
142 | {
143 | days: [0, 13, 40, 29, 38, 13, 1],
144 | total: 134,
145 | week: 1543708800,
146 | },
147 | {
148 | days: [4, 29, 20, 8, 25, 1, 3],
149 | total: 90,
150 | week: 1544313600,
151 | },
152 | {
153 | days: [1, 20, 17, 31, 10, 15, 2],
154 | total: 96,
155 | week: 1544918400,
156 | },
157 | {
158 | days: [0, 0, 1, 1, 3, 5, 1],
159 | total: 11,
160 | week: 1545523200,
161 | },
162 | {
163 | days: [0, 0, 0, 3, 17, 12, 0],
164 | total: 32,
165 | week: 1546128000,
166 | },
167 | {
168 | days: [0, 11, 25, 27, 20, 21, 0],
169 | total: 104,
170 | week: 1546732800,
171 | },
172 | {
173 | days: [2, 17, 22, 17, 17, 19, 6],
174 | total: 100,
175 | week: 1547337600,
176 | },
177 | {
178 | days: [0, 32, 34, 31, 22, 13, 3],
179 | total: 135,
180 | week: 1547942400,
181 | },
182 | {
183 | days: [3, 7, 14, 13, 24, 27, 1],
184 | total: 89,
185 | week: 1548547200,
186 | },
187 | {
188 | days: [1, 25, 22, 32, 20, 16, 0],
189 | total: 116,
190 | week: 1549152000,
191 | },
192 | {
193 | days: [0, 28, 12, 22, 19, 13, 0],
194 | total: 94,
195 | week: 1549756800,
196 | },
197 | {
198 | days: [0, 3, 13, 9, 8, 4, 4],
199 | total: 41,
200 | week: 1550361600,
201 | },
202 | {
203 | days: [2, 12, 11, 31, 29, 28, 14],
204 | total: 127,
205 | week: 1550966400,
206 | },
207 | {
208 | days: [0, 25, 36, 31, 19, 0, 4],
209 | total: 115,
210 | week: 1551571200,
211 | },
212 | {
213 | days: [2, 31, 22, 42, 21, 22, 0],
214 | total: 140,
215 | week: 1552176000,
216 | },
217 | {
218 | days: [0, 16, 20, 18, 14, 28, 0],
219 | total: 96,
220 | week: 1552780800,
221 | },
222 | {
223 | days: [0, 15, 17, 31, 4, 24, 2],
224 | total: 93,
225 | week: 1553385600,
226 | },
227 | {
228 | days: [0, 16, 12, 46, 31, 15, 0],
229 | total: 120,
230 | week: 1553990400,
231 | },
232 | {
233 | days: [1, 31, 17, 25, 10, 20, 0],
234 | total: 104,
235 | week: 1554595200,
236 | },
237 | {
238 | days: [0, 26, 29, 35, 14, 0, 0],
239 | total: 104,
240 | week: 1555200000,
241 | },
242 | {
243 | days: [0, 0, 12, 3, 18, 8, 0],
244 | total: 41,
245 | week: 1555804800,
246 | },
247 | {
248 | days: [0, 17, 12, 3, 19, 4, 0],
249 | total: 55,
250 | week: 1556409600,
251 | },
252 | {
253 | days: [0, 6, 2, 2, 0, 8, 0],
254 | total: 18,
255 | week: 1557014400,
256 | },
257 | {
258 | days: [0, 0, 4, 3, 0, 1, 0],
259 | total: 8,
260 | week: 1557619200,
261 | },
262 | ];
263 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Recontrib - React Component that implements GitHub commit UI
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/index.tsx:
--------------------------------------------------------------------------------
1 | import 'react-app-polyfill/ie11';
2 | import * as React from 'react';
3 | import * as ReactDOM from 'react-dom';
4 | import '@reach/tooltip/styles.css';
5 | import { Recontrib } from '../.';
6 | import { Container, Table, Input, Form, FormGroup } from 'reactstrap';
7 | import 'prismjs';
8 | import 'prismjs/components/prism-bash';
9 | import 'prismjs/components/prism-javascript';
10 | import 'prismjs/components/prism-typescript';
11 | import 'prismjs/plugins/line-numbers/prism-line-numbers';
12 | import 'prismjs/themes/prism-tomorrow.css';
13 | import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
14 |
15 | import 'bootstrap/dist/css/bootstrap.min.css';
16 |
17 | const INSTALL_CODE = `npm install recontrib @reach/tooltip
18 | # or yarn add recontrib @reach/tooltip
19 | `;
20 |
21 | const CSS_CODE = `import '@reach/tooltip/style.css`;
22 |
23 | const APP_CODE = `import React, { useEffect, useState } from 'react';
24 | import { Recontrib } from 'recontrib';
25 |
26 | const App = () => {
27 | let [data, setData] = useState([]);
28 | useEffect(() => {
29 | fetch('https://api.github.com/repos/zeit/next.js/stats/commit_activity')
30 | .then(res => res.json())
31 | .then(res => { setData(res) })
32 | },[]);
33 |
34 | return (
35 |
36 |
41 |
42 | )
43 | }
44 | `;
45 |
46 | const WEEK_DATA = `interface WeekData {
47 | days: number[]; // commits in individual days in the week
48 | total: number; // total number commits in the week
49 | week: number; // Timestamp in seconds of the seconds of the starting of the week
50 | }`;
51 |
52 | const PROP = `interface Props {
53 | data: Array;
54 | gridSize?: number;
55 | fontSize?: string;
56 | }`;
57 |
58 | const App = () => {
59 | let [repoData, setData] = React.useState({ error: null, data: [] });
60 | const [{ repo, owner }, setForm] = React.useState({
61 | repo: 'prisma',
62 | owner: 'prisma',
63 | });
64 | let [url, setUrl] = React.useState(
65 | `https://api.github.com/repos/${owner}/${repo}/stats/commit_activity`
66 | );
67 | React.useEffect(() => {
68 | fetch(url)
69 | .then(res => {
70 | if (res.status === 404) {
71 | throw new Error('Not found');
72 | }
73 | return res.json();
74 | })
75 | .then(res => {
76 | setData({ error: null, data: res });
77 | })
78 | .catch(err => {
79 | setData({ error: err.message, data: [] });
80 | });
81 | }, [url]);
82 | return (
83 |
84 |
85 | Recontrib
86 | React Component that implements GitHub Commit Graph
87 |
88 |
89 |
121 |
122 | {repoData.data && repoData.data.length ? (
123 |
124 | ) : repoData.error ? (
125 |
{repoData.error}
126 | ) : (
127 | 'Loading....'
128 | )}
129 |
130 |
131 |
132 |
133 | Usuage
134 | 1. Install the dependencies
135 |
136 | {INSTALL_CODE}
137 |
138 | 2. Add the Reach UI tooltip CSS
139 |
140 | This component use Reach UI's Tooltip component. Install it as a peer
141 | dependency
142 |
143 |
144 | {CSS_CODE}
145 |
146 | 2. Use the component in your code
147 |
148 | {APP_CODE}
149 |
150 |
151 |
152 |
153 | API
154 |
155 |
156 |
157 | Prop
158 | Type
159 | optional
160 |
161 |
162 |
163 |
164 | data
165 |
166 | WeekData
167 |
168 | no
169 |
170 |
171 | gridSize
172 |
173 | number
174 |
175 | yes - default 10
176 |
177 |
178 | fontSize
179 |
180 | string
181 |
182 | yes - default 9px
183 |
184 |
185 |
186 |
187 |
188 | Interfaces
189 | WeekData
190 |
191 | {WEEK_DATA}
192 |
193 | Prop
194 |
195 | {PROP}
196 |
197 |
198 |
199 | MIT ©️ Harshit Pant {' '}
200 | 2019
201 |
202 |
203 |
204 | );
205 | };
206 |
207 | ReactDOM.render( , document.getElementById('root'));
208 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "homepage": "https://pantharshit00.github.io/recontrib",
7 | "scripts": {
8 | "start": "parcel index.html",
9 | "build": "parcel build index.html --public-url /recontrib/"
10 | },
11 | "dependencies": {
12 | "@reach/tooltip": "^0.2.0",
13 | "bootstrap": "^4.3.1",
14 | "prismjs": "^1.16.0",
15 | "react": "^16.8.0",
16 | "react-app-polyfill": "^1.0.0",
17 | "react-dom": "^16.8.0",
18 | "reactstrap": "^8.0.0"
19 | },
20 | "alias": {
21 | "react": "../node_modules/react",
22 | "react-dom": "../node_modules/react-dom"
23 | },
24 | "devDependencies": {
25 | "@babel/core": "^7.4.4",
26 | "@types/prismjs": "^1.16.0",
27 | "@types/react": "^16.8.15",
28 | "@types/react-dom": "^16.8.4",
29 | "@types/reactstrap": "^8.0.1",
30 | "parcel": "^1.12.3",
31 | "typescript": "^3.4.5"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowSyntheticDefaultImports": false,
4 | "target": "es5",
5 | "module": "commonjs",
6 | "jsx": "react",
7 | "moduleResolution": "node",
8 | "noImplicitAny": false,
9 | "noUnusedLocals": false,
10 | "noUnusedParameters": false,
11 | "removeComments": true,
12 | "strictNullChecks": true,
13 | "preserveConstEnums": true,
14 | "sourceMap": true,
15 | "lib": ["es2015", "es2016", "dom"],
16 | "baseUrl": ".",
17 | "types": ["node"]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "recontrib",
3 | "version": "0.3.1",
4 | "license": "MIT",
5 | "homepage": "https://pantharshit00.github.io/recontrib",
6 | "author": "Harshit Pant ",
7 | "main": "dist/index.js",
8 | "umd:main": "dist/recontrib.umd.production.js",
9 | "module": "dist/recontrib.es.production.js",
10 | "typings": "dist/index.d.ts",
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/pantharshit00/recontrib"
14 | },
15 | "files": [
16 | "dist"
17 | ],
18 | "scripts": {
19 | "start": "tsdx watch",
20 | "build": "tsdx build",
21 | "test": "tsdx test --env=jsdom"
22 | },
23 | "peerDependencies": {
24 | "@reach/tooltip": "~0.2.0",
25 | "react": ">=16"
26 | },
27 | "husky": {
28 | "hooks": {
29 | "pre-commit": "pretty-quick --staged"
30 | }
31 | },
32 | "prettier": {
33 | "printWidth": 80,
34 | "semi": true,
35 | "singleQuote": true,
36 | "trailingComma": "es5"
37 | },
38 | "devDependencies": {
39 | "@types/jest": "^24.0.13",
40 | "@types/react": "^16.8.17",
41 | "@types/react-dom": "^16.8.4",
42 | "husky": "^2.3.0",
43 | "prettier": "^1.17.1",
44 | "pretty-quick": "^1.10.0",
45 | "prop-types": "^15.7.2",
46 | "react": "^16.8.0",
47 | "react-dom": "^16.8.0",
48 | "tsdx": "^0.5.11",
49 | "tslib": "^1.9.3",
50 | "typescript": "^3.4.5"
51 | },
52 | "dependencies": {
53 | "@reach/portal": "^0.2.1",
54 | "@reach/tooltip": "^0.2.0",
55 | "dayjs": "^1.8.14"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/ignore.d.ts:
--------------------------------------------------------------------------------
1 | declare module '@reach/tooltip';
2 | declare module '@reach/portal';
3 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import dayjs from 'dayjs';
3 | import { TriangleTooltip } from './utils/ToolTip';
4 |
5 | interface WeekData {
6 | days: number[];
7 | total: number;
8 | week: number;
9 | }
10 |
11 | interface Data {
12 | month: string;
13 | id: string;
14 | weeks: Array;
15 | }
16 |
17 | const MONTHS = [
18 | 'Jan',
19 | 'Feb',
20 | 'Mar',
21 | 'Apr',
22 | 'May',
23 | 'Jun',
24 | 'Jul',
25 | 'Aug',
26 | 'Sep',
27 | 'Oct',
28 | 'Nov',
29 | 'Dec',
30 | ];
31 |
32 | const COLORS = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];
33 |
34 | interface Props {
35 | data: Array;
36 | gridSize?: number;
37 | fontSize?: string;
38 | }
39 |
40 | export const Recontrib: React.FC = ({
41 | data,
42 | gridSize = 10,
43 | fontSize = '9px',
44 | }) => {
45 | const finalData = React.useMemo(() => {
46 | let massagedData: Array = [];
47 |
48 | data.forEach(history => {
49 | const month = dayjs.unix(history.week).get('month');
50 | const year = dayjs.unix(history.week).get('year');
51 | const monthIndex = massagedData.findIndex(
52 | d => d.id === `${MONTHS[month]}${year}`
53 | );
54 | if (monthIndex === -1) {
55 | massagedData.push({
56 | month: MONTHS[month],
57 | weeks: [history],
58 | id: `${MONTHS[month]}${year}`,
59 | });
60 | } else {
61 | massagedData[monthIndex].weeks.push(history);
62 | }
63 | });
64 | return massagedData;
65 | }, [data]);
66 |
67 | let weekCount = 1;
68 | return (
69 |
74 |
75 | {finalData.map(val => {
76 | return (
77 |
78 | 2 ? 'visible' : 'hidden'}
82 | style={{
83 | fill: '#767676',
84 | fontSize,
85 | fontFamily: 'sans-serif',
86 | }}
87 | >
88 | {val.month}
89 |
90 | {val.weeks.map(week => {
91 | return (
92 |
96 | {week.days.map((val, idx) => (
97 |
108 |
122 |
123 | ))}
124 |
125 | );
126 | })}
127 |
128 | );
129 | })}
130 |
135 | Mon
136 |
137 |
142 | Wed
143 |
144 |
149 | Fri
150 |
151 |
152 |
153 | );
154 | };
155 |
--------------------------------------------------------------------------------
/src/utils/ToolTip.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { useTooltip, TooltipPopup } from '@reach/tooltip';
3 | import Portal from '@reach/portal';
4 |
5 | interface Rects {
6 | top: number;
7 | right: number;
8 | bottom: number;
9 | left: number;
10 | width: number;
11 | }
12 |
13 | const centered = (triggerRect: Rects, tooltipRect: Rects) => {
14 | const triggerCenter = triggerRect.left + triggerRect.width / 2;
15 | const left = triggerCenter - tooltipRect.width / 2;
16 | const maxLeft = window.innerWidth - tooltipRect.width - 2;
17 | return {
18 | left: Math.min(Math.max(2, left), maxLeft) + window.scrollX,
19 | top: triggerRect.bottom + 8 + window.scrollY,
20 | };
21 | };
22 |
23 | interface Props {
24 | label: string;
25 | ariaLabel?: string;
26 | }
27 |
28 | export const TriangleTooltip: React.FC = ({
29 | children,
30 | label,
31 | ariaLabel,
32 | }) => {
33 | // get the props from useTooltip
34 | const [trigger, tooltip] = useTooltip();
35 |
36 | // destructure off what we need to position the triangle
37 | const { isVisible, triggerRect } = tooltip;
38 |
39 | return (
40 |
41 | {React.isValidElement(children)
42 | ? React.cloneElement(children, trigger)
43 | : ''}
44 |
45 | {isVisible && (
46 | // The Triangle. We position it relative to the trigger, not the popup
47 | // so that collisions don't have a triangle pointing off to nowhere.
48 | // Using a Portal may seem a little extreme, but we can keep the
49 | // positioning logic simpler here instead of needing to consider
50 | // the popup's position relative to the trigger and collisions
51 |
52 |
65 |
66 | )}
67 |
81 |
82 | );
83 | };
84 |
--------------------------------------------------------------------------------
/src/utils/darkenColor.ts:
--------------------------------------------------------------------------------
1 | export function LightenDarkenColor(col: string, amt: number) {
2 | var usePound = false;
3 |
4 | if (col[0] == '#') {
5 | col = col.slice(1);
6 | usePound = true;
7 | }
8 |
9 | var num = parseInt(col, 16);
10 |
11 | var r = (num >> 16) + amt;
12 |
13 | if (r > 255) r = 255;
14 | else if (r < 0) r = 0;
15 |
16 | var b = ((num >> 8) & 0x00ff) + amt;
17 |
18 | if (b > 255) b = 255;
19 | else if (b < 0) b = 0;
20 |
21 | var g = (num & 0x0000ff) + amt;
22 |
23 | if (g > 255) g = 255;
24 | else if (g < 0) g = 0;
25 |
26 | return (usePound ? '#' : '') + (g | (b << 8) | (r << 16)).toString(16);
27 | }
28 |
--------------------------------------------------------------------------------
/test/blah.test.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import * as ReactDOM from 'react-dom';
3 | import { Thing } from '../src';
4 |
5 | describe('it', () => {
6 | it('renders without crashing', () => {
7 | const div = document.createElement('div');
8 | ReactDOM.render( , div);
9 | ReactDOM.unmountComponentAtNode(div);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src", "types", "example/data.ts"],
3 | "compilerOptions": {
4 | "target": "es5",
5 | "module": "esnext",
6 | "lib": ["dom", "esnext"],
7 | "importHelpers": true,
8 | "declaration": true,
9 | "sourceMap": true,
10 | "rootDir": "./",
11 | "strict": true,
12 | "noImplicitAny": true,
13 | "strictNullChecks": true,
14 | "strictFunctionTypes": true,
15 | "strictPropertyInitialization": true,
16 | "noImplicitThis": true,
17 | "alwaysStrict": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "noImplicitReturns": true,
21 | "noFallthroughCasesInSwitch": true,
22 | "moduleResolution": "node",
23 | "baseUrl": "./",
24 | "paths": {
25 | "*": ["src/*", "node_modules/*"]
26 | },
27 | "jsx": "react",
28 | "esModuleInterop": true
29 | }
30 | }
31 |
--------------------------------------------------------------------------------