├── .DS_Store ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── .gitignore ├── CHANGE_LOG.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── package.json ├── src ├── Bullets.tsx ├── ContentLoader.tsx ├── FacebookLoader.tsx ├── InstagramLoader.tsx ├── index.tsx └── shared.tsx ├── tsconfig.json ├── tslint.json └── yarn.lock /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sarmad1995/react-native-easy-content-loader/559cf7f0fc22901e041151a747401cbfc1b7fed2/.DS_Store -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Smartphone (please complete the following information):** 27 | - Device: [e.g. iPhone6] 28 | - OS: [e.g. iOS8.1] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib 3 | 4 | yarn.* 5 | yarn.lock -------------------------------------------------------------------------------- /CHANGE_LOG.md: -------------------------------------------------------------------------------- 1 | ## - 0.0.5 2 | - Beta 3 | ## - 0.0.1 4 | - Work in progress 5 | ## - 0.1.0 6 | - Initial Release 7 | ## - 0.2.0 8 | ## BREAKING CHANGES 9 | Changed the default Title and Paragraph height. 10 | 11 | ## FEATURES 12 | - Added FACEBOOK style. 13 | - Added INSTAGRAM style. 14 | - Added Bullet style. 15 | - Added List functionality. 16 | - Add support for hex colors. 17 | 18 | ## - 0.2.3 19 | ## BREAKING CHANGES 20 | No breaking changes :) 21 | 22 | ## FEATURES 23 | - Typescript support. 24 | - Fully typed. 25 | - Removed extra things from npm, will be more lighter weight now. -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at aijaz.sarmad@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Sarmad Shah 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 | [![NPM Version][npm-image]][npm-url] 2 | [![Downloads Stats][npm-downloads]][npm-url] 3 | 4 |

5 | Example's react-native-easycontent-loader 6 |

7 | 8 | Provide a placeholder at the place which need waiting for loading, 9 | Easy to implement and fun to use, this package is highly customizable, Please go through docs to find info :). 10 | 11 | ### 12 | 13 | ### I tried to move this package to @sarmad1995/react-native-content-loader, but seems like people are using this version a lot, so I will be maintaining this version from now, @sarmad1995/react-native-content-loader also has all the features. 14 | 15 | ## Features 16 | 17 | - :gear: **Customizable:** Feel free to change the colors, speed, sizes, paragraphs, title and much more. 18 | - ⚛️ **Lightweight:** Lightweight with only neccessory code. 19 | - :tada: **Typescript:** Fully typed 20 | 21 | ## Index 22 | 23 | - [Getting Started](#getting-started) 24 | - [Usage](#usage) 25 | - [Options](#options) 26 | - [Examples](#examples) 27 | 28 | ## Getting Started 29 | 30 | ```sh 31 | npm install react-native-easy-content-loader --save 32 | yarn add react-native-easy-content-loader 33 | ``` 34 | 35 | ## Examples 36 | 37 | ### Simple Example 38 | 39 | ```jsx 40 | 41 | ``` 42 | 43 | ### With Avatar 44 | 45 | ```jsx 46 | 47 | ``` 48 | 49 | ### With Loading State 50 | 51 | ```jsx 52 | 53 | This would be rendered with loading is false 54 | 55 | ``` 56 | 57 | ### Number of paragraphs 58 | 59 | ```jsx 60 | 61 | ``` 62 | 63 | ### Different Widths for differnt paragrahs lines 64 | 65 | ```jsx 66 | 67 | ``` 68 | 69 | ### Facebook and Instagram Style 70 | 71 | These are also flexible and customizable 72 | 73 | | Facebook loader | Instagram loader | 74 | | :---------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------: | 75 | | ![Facebook Style](https://user-images.githubusercontent.com/38377482/63653305-932a1880-c788-11e9-8f74-aeb758e11336.gif) | ![Instagram Style](https://user-images.githubusercontent.com/38377482/63653295-7a216780-c788-11e9-9f02-88e5f71cd5cd.gif) | 76 | 77 | ```jsx 78 | import { FacebookLoader, InstagramLoader } from 'react-native-easy-content-loader'; 79 | 80 | 81 | 82 | 83 | ``` 84 | 85 | ### Bullets Style 86 | 87 | ```jsx 88 | 89 | ``` 90 | 91 | ![Bullets Style](https://user-images.githubusercontent.com/38377482/63653257-054e2d80-c788-11e9-8b15-eb8e1c39885e.gif) 92 | 93 | ### Default Style 94 | 95 | ## It is highly customizable, please refer the options sections. 96 | 97 | ```jsx 98 | import ContentLoader from "react-native-easy-content-loader"; 99 | ; 105 | ``` 106 | 107 | | Added custom heights and widths | Same with other loaders | 108 | | :---------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------: | 109 | | | | 110 | 111 | Some more examples, 112 | 113 | ```jsx 114 | 115 | 116 | 117 | ``` 118 | 119 | ```jsx 120 | 121 | ``` 122 | 123 | | Default Loader | Colored | 124 | | :--------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------: | 125 | | ![ContentLoader Style](https://user-images.githubusercontent.com/38377482/63653286-5d852f80-c788-11e9-8093-2f428e7e3daf.gif) | ![ContentLoader Style](https://user-images.githubusercontent.com/38377482/63653283-434b5180-c788-11e9-84ee-f275a71334bc.gif) | 126 | 127 | ## Usage 128 | 129 | ```jsx 130 | import ContentLoader, { 131 | FacebookLoader, 132 | InstagramLoader, 133 | Bullets 134 | } from "react-native-easy-content-loader"; 135 | ``` 136 | 137 | ```jsx 138 | 139 | ``` 140 | 141 | ## Options 142 | 143 | ## These Options are common with every component, 144 | 145 | #### **`primaryColor?: string, rgba/hex`** 146 | 147 | Defaults to `rgba(220, 220, 220, 1)`. 148 | 149 | #### **`secondaryColor? string, rgba/hex`** 150 | 151 | Defaults to `rgba(200, 200, 200, 1)`. 152 | 153 | #### **`animationDuration? number`** 154 | 155 | Defaults to `500`. The animation transition time from primaryColor to secondaryColor 156 | 157 | #### **`loading?: bool | null`** 158 | 159 | Defaults to `null`, If given a bool value, when false, it will return children (Works as a wrapper component) 160 | 161 | #### **`active? bool`** 162 | 163 | Defaults to `false`, `true` if you want to animate the compoennt. 164 | 165 | #### **`title? bool`** 166 | 167 | Defaults to `true`. If you want to show the title, **Works only with ContentLoader**. 168 | 169 | #### **`titleStyles? object`** 170 | 171 | Add styles to title. 172 | 173 | #### **`listSize? number`** 174 | 175 | Defaults to `1`. If you want to render a list of loaders, **Works with all the loaders**. 176 | 177 | #### **`avatar? bool`** 178 | 179 | Defaults to `false`. If you want to render the avatar. 180 | 181 | #### **`aShape? string 'circle' | 'square'`** 182 | 183 | Defaults to `circle`. shape of the avatar, can be circle or square. 184 | 185 | #### **`aSize? string 'default' 'small' 'large' | number`** 186 | 187 | Defaults to `default`. can be a specific number. 188 | 189 | #### **`reverse? bool`** 190 | 191 | Defaults to `false`. if you want to reverse the view. 192 | 193 | #### **`containerStyles? object`** 194 | 195 | If you want to add style to container. 196 | 197 | ## Title specific options. 198 | 199 | #### **`tHeight? string | number`** 200 | 201 | Used to change the title height. 202 | 203 | #### **`tWidth? stirng | number`** 204 | 205 | Used to change the title width. 206 | 207 | #### **`sTHeight? string | number`** 208 | 209 | Used to change the secondary title height **Works with only Facebook and Instagram**. 210 | 211 | #### **`sTWidth? string | number`** 212 | 213 | Used to change the secondary title width **Works with only Facebook and Instagram**. 214 | 215 | #### **`titleStyles? object`** 216 | 217 | Add styles to title. 218 | 219 | #### **`secondaryTitleStyles? object`** 220 | 221 | Add styles to secondaryTitle. **Works with only Facebook and Instagram**. 222 | 223 | ## Paragraph specific options. 224 | 225 | #### **`pHeight? string | number | array`** 226 | 227 | Paragraph line height, 228 | Can specify same height with single value, Or could use array for different heights, eg ['100%', 200, 300], you can use pHeight and pWidth to achieve different shapes as well, 229 | 230 | #### **`pWidth? string | number | array`** 231 | 232 | Paragraph line width, 233 | Can specify same width with single value, Or could use array for different widths, eg ['100%', 200, 300] 234 | 235 | #### **`paragraphStyles? objecct`** 236 | 237 | Add paragraph styles 238 | 239 | ## Instagram specific options. 240 | 241 | #### **`imageHeight? number`** 242 | 243 | Change the height of the image 244 | 245 | #### **`imageStyles? number`** 246 | 247 | Add styles to image 248 | 249 | ## Release History 250 | 251 | See CHANGE_LOG.md. 252 | 253 | ## Contributing 254 | 255 | Feel free to contribute, this is still in beta and I have plans to include more features in future :) 256 | 257 | 258 | 259 | [npm-image]: https://img.shields.io/npm/v/react-native-easy-content-loader.svg 260 | [npm-url]: https://www.npmjs.com/package/react-native-easy-content-loader 261 | [npm-downloads]: https://img.shields.io/npm/dm/rn-placeholder.svg?style=flat-square 262 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-easy-content-loader", 3 | "version": "0.3.2", 4 | "description": "easy content loader for react-native apps", 5 | "main": "lib/index.js", 6 | "types": "lib/index.d.ts", 7 | "scripts": { 8 | "build": "tsc" 9 | }, 10 | "files": [ 11 | "lib" 12 | ], 13 | "keywords": [ 14 | "react-native", 15 | "react native skeleton", 16 | "react native loader", 17 | "react-native-content-loader", 18 | "skeleton", 19 | "react-native-loader", 20 | "sarmad1995" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/sarmad1995/react-native-easy-content-loader" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/sarmad1995/react-native-easy-content-loader" 28 | }, 29 | "homepage": "https://github.com/sarmad1995/react-native-easy-content-loader", 30 | "author": "Sarmad", 31 | "license": "MIT", 32 | "devDependencies": { 33 | "@types/react": "^16.0.40", 34 | "@types/react-native": "^0.52.16", 35 | "tslint": "^5.9.1", 36 | "tslint-config-prettier": "^1.9.0", 37 | "tslint-react": "^3.5.1", 38 | "typescript": "^2.7.1" 39 | }, 40 | "peerDependencies": { 41 | "react": "*", 42 | "react-native": "*" 43 | }, 44 | "dependencies": { 45 | "hex-to-rgba": "^2.0.1" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Bullets.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Animated, View, StyleSheet, ViewStyle } from 'react-native'; 3 | import { 4 | getInterpolatedColor, 5 | commonDefaultProps, 6 | startAnimationHelper, 7 | THeightType, 8 | TWidthType, 9 | CommonProps 10 | } from './shared'; 11 | 12 | const AVATAR_SIZE = { 13 | default: 20, 14 | large: 30, 15 | small: 25 16 | }; 17 | interface Props extends CommonProps { 18 | /** 19 | * Used to determine the height of the main title 20 | */ 21 | tHeight: THeightType, 22 | /** 23 | * Used to determine the width of the main title 24 | */ 25 | tWidth: TWidthType, 26 | /** 27 | * add additinal avatarstyles or overwrite previous ones 28 | */ 29 | avatarStyles?: ViewStyle 30 | } 31 | class ContentLoader extends React.PureComponent { 32 | static defaultProps: Props; 33 | state = { 34 | animation: new Animated.Value(0) 35 | } 36 | 37 | componentDidMount() { 38 | const { active } = this.props; 39 | if (active) { 40 | this.startAnimation(); 41 | } 42 | } 43 | 44 | componentDidUpdate(prevProps) { 45 | const { loading } = this.props; 46 | if (prevProps.loading !== loading) { 47 | if (loading) { 48 | this.startAnimation(); 49 | } 50 | } 51 | } 52 | 53 | startAnimation = () => { 54 | const { animation } = this.state; 55 | const { animationDuration } = this.props; 56 | startAnimationHelper(animation, animationDuration); 57 | }; 58 | 59 | render() { 60 | const { 61 | tHeight, 62 | tWidth, 63 | titleStyles, 64 | aShape, 65 | aSize, 66 | avatarStyles, 67 | reverse, 68 | containerStyles, 69 | loading, 70 | listSize, 71 | primaryColor, 72 | secondaryColor, 73 | children 74 | } = this.props; 75 | const { animation } = this.state; 76 | 77 | const interpolatedBackground = getInterpolatedColor(animation, primaryColor, secondaryColor); 78 | 79 | if (loading === false) { 80 | return children || null; 81 | } 82 | 83 | const titleInitialStyles = { 84 | height: tHeight, 85 | width: tWidth 86 | }; 87 | const avatarInitialStyles = { 88 | height: AVATAR_SIZE[aSize] || aSize, 89 | width: AVATAR_SIZE[aSize] || aSize, 90 | borderRadius: aShape === 'circle' ? AVATAR_SIZE[aSize] / 2 || (aSize as any) / 2 : 3, 91 | marginRight: reverse ? 0 : 5, 92 | marginLeft: reverse ? 5 : 0 93 | }; 94 | return [...Array(listSize)].map((_, index) => ( 95 | 96 | 103 | 111 | 112 | 113 | 121 | 122 | 123 | 124 | )); 125 | } 126 | } 127 | 128 | ContentLoader.defaultProps = { 129 | ...commonDefaultProps, 130 | tWidth: '80%', 131 | tHeight: 10 132 | }; 133 | const styles = StyleSheet.create({ 134 | container: { 135 | flexDirection: 'row', 136 | width: '100%', 137 | paddingHorizontal: 10, 138 | alignItems: 'center' 139 | }, 140 | content: { 141 | flex: 1, 142 | marginLeft: 10 143 | }, 144 | avatar: { 145 | borderRadius: 2 146 | }, 147 | title: { 148 | borderRadius: 3 149 | }, 150 | paragraph: { 151 | marginVertical: 5, 152 | borderRadius: 3 153 | } 154 | }); 155 | export default ContentLoader; 156 | -------------------------------------------------------------------------------- /src/ContentLoader.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { Animated, View, StyleSheet, ViewStyle } from 'react-native'; 4 | 5 | import { 6 | getInterpolatedColor, 7 | commonDefaultProps, 8 | startAnimationHelper, 9 | paragraphInitialStyles, 10 | CommonProps, 11 | PHeightType, 12 | PWidthType, 13 | TWidthType, 14 | THeightType, 15 | } from './shared'; 16 | /** 17 | * default content loader . 18 | * 19 | * 20 | * can be customized to the needs, . 21 | */ 22 | interface ContentLoaderAvatar { 23 | default: string | number, 24 | large: string | number , 25 | small: string | number 26 | } 27 | const AVATAR_SIZE: ContentLoaderAvatar= { 28 | default: 50, 29 | large: 70, 30 | small: 35 31 | } 32 | interface Props extends CommonProps { 33 | /** 34 | * Enables or disables paragraph lines. 35 | */ 36 | paragraph?: boolean, 37 | /** 38 | * Used to determine height of the paragraph line. 39 | */ 40 | pHeight: PHeightType, 41 | /** 42 | * Duration of fade animation, default = 500ms 43 | */ 44 | animationDuration: number, 45 | /** 46 | * Used to determine the width of the paragraph lines, If you want dymanic widths for each line, you can add an array 47 | * [100,200,300] 48 | */ 49 | pWidth: PWidthType 50 | /** 51 | * Used to determine how many paragraph rows should be rendered. 52 | */ 53 | pRows: number, 54 | /** 55 | * Used to determine the width of the title. 56 | */ 57 | tWidth: TWidthType, 58 | /** 59 | * Used to determine the height of the title 60 | */ 61 | tHeight: THeightType, 62 | /** 63 | * If you want to add additional styles/overwrite styles of paragraph 64 | */ 65 | paragraphStyles?: ViewStyle, 66 | /** 67 | * If you want to add additional styles/overwrite styles of avatar 68 | */ 69 | avatarStyles?: ViewStyle 70 | } 71 | 72 | class ContentLoader extends React.PureComponent { 73 | static defaultProps: Props; 74 | state = { 75 | animation: new Animated.Value(0) 76 | }; 77 | componentDidMount() { 78 | const { active } = this.props; 79 | if (active) { 80 | this.startAnimation(); 81 | } 82 | } 83 | 84 | componentDidUpdate(prevProps: Props) { 85 | const { loading } = this.props; 86 | if (prevProps.loading !== loading) { 87 | if (loading) { 88 | this.startAnimation(); 89 | } 90 | } 91 | } 92 | 93 | private startAnimation= (): void=> { 94 | const { animation } = this.state; 95 | const { animationDuration } = this.props; 96 | startAnimationHelper(animation, animationDuration); 97 | }; 98 | 99 | render() { 100 | const { 101 | title, 102 | paragraph, 103 | pHeight, 104 | pWidth, 105 | pRows, 106 | paragraphStyles, 107 | tHeight, 108 | tWidth, 109 | titleStyles, 110 | avatar, 111 | aShape, 112 | aSize, 113 | avatarStyles, 114 | reverse, 115 | containerStyles, 116 | loading, 117 | listSize, 118 | primaryColor, 119 | secondaryColor, 120 | children 121 | } = this.props; 122 | const { animation } = this.state; 123 | 124 | const interpolatedBackground = getInterpolatedColor(animation, primaryColor, secondaryColor); 125 | 126 | if (loading === false) { 127 | return children || null; 128 | } 129 | const titleInitialStyles: ViewStyle = { 130 | height: tHeight, 131 | width: tWidth 132 | }; 133 | const avatarInitialStyles: ViewStyle = { 134 | height: (AVATAR_SIZE as any)[aSize] || aSize, 135 | width: (AVATAR_SIZE as any)[aSize] || aSize, 136 | borderRadius: aShape === 'circle' ? (AVATAR_SIZE as any)[aSize] / 2 || (aSize as any) / 2 : 3, 137 | marginRight: reverse ? 0 : 10, 138 | marginLeft: reverse ? 10 : 0 139 | }; 140 | return [...Array(listSize)].map((_, index) => ( 141 | 1 ? 20 : 0 }, 145 | styles.container, 146 | { flexDirection: reverse ? 'row-reverse' : 'row' }, 147 | containerStyles 148 | ]} 149 | > 150 | {avatar && ( 151 | 159 | )} 160 | 161 | {title && ( 162 | 170 | )} 171 | {paragraph && ( 172 | 173 | {[...Array(pRows)].map((_, index) => ( 174 | 183 | ))} 184 | 185 | )} 186 | 187 | 188 | )); 189 | } 190 | } 191 | ContentLoader.defaultProps = { 192 | ...commonDefaultProps, 193 | paragraph: true, 194 | pHeight: 8, 195 | pWidth: '80%', 196 | pRows: 4, 197 | tWidth: '60%', 198 | tHeight: 15, 199 | paragraphStyles: {} 200 | }; 201 | const styles = StyleSheet.create({ 202 | container: { 203 | flexDirection: 'row', 204 | width: '100%', 205 | paddingHorizontal: 10 206 | }, 207 | content: { 208 | flex: 1 209 | }, 210 | avatar: { 211 | borderRadius: 2 212 | }, 213 | title: { 214 | marginBottom: 10, 215 | borderRadius: 3 216 | }, 217 | paragraph: { 218 | marginVertical: 5, 219 | borderRadius: 3 220 | }, 221 | paragraphContainer: {} 222 | }); 223 | export default ContentLoader; 224 | -------------------------------------------------------------------------------- /src/FacebookLoader.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Animated, View, StyleSheet, ViewStyle } from 'react-native'; 3 | import { 4 | getInterpolatedColor, 5 | startAnimationHelper, 6 | commonDefaultProps, 7 | paragraphInitialStyles, 8 | CommonProps, 9 | PHeightType, 10 | PWidthType, 11 | THeightType, 12 | TWidthType 13 | } from './shared'; 14 | 15 | const AVATAR_SIZE = { 16 | default: 70, 17 | large: 30, 18 | small: 25 19 | }; 20 | interface Props extends CommonProps { 21 | /** 22 | * Used to determine height of the paragraph line. 23 | */ 24 | pHeight: PHeightType, 25 | /** 26 | * Used to determine the width of the paragraph lines, If you want dymanic widths for each line, you can add an array 27 | * [100,200,300] 28 | */ 29 | pWidth: PWidthType, 30 | /** 31 | * Used to determine how many paragraph rows should be rendered. 32 | */ 33 | pRows: number, 34 | /** 35 | * Add additional styles or overwrite previous ones 36 | */ 37 | paragraphStyles?: ViewStyle, 38 | /** 39 | * Used to determine the height of the main title 40 | */ 41 | tHeight: THeightType, 42 | /** 43 | * Used to determine the width of the main title 44 | */ 45 | tWidth: TWidthType, 46 | /** 47 | * Add additional styles or overwrite previous ones 48 | */ 49 | secondaryTitleStyles?: ViewStyle, 50 | /** 51 | * Used to determine the height of the secondary title 52 | */ 53 | sTWidth: string | number, 54 | /** 55 | * Used to determine the width of the secondary title 56 | */ 57 | avatarStyles?: ViewStyle 58 | } 59 | class ContentLoader extends React.PureComponent { 60 | static defaultProps: Props; 61 | state = { 62 | animation: new Animated.Value(0) 63 | }; 64 | 65 | 66 | componentDidMount() { 67 | const { active } = this.props; 68 | if (active) { 69 | this.startAnimation(); 70 | } 71 | } 72 | 73 | componentDidUpdate(prevProps) { 74 | const { loading } = this.props; 75 | if (prevProps.loading !== loading) { 76 | if (loading) { 77 | this.startAnimation(); 78 | } 79 | } 80 | } 81 | 82 | startAnimation = () => { 83 | const { animation } = this.state; 84 | const { animationDuration } = this.props; 85 | startAnimationHelper(animation, animationDuration); 86 | }; 87 | 88 | render() { 89 | const { 90 | pHeight, 91 | pWidth, 92 | pRows, 93 | paragraphStyles, 94 | tHeight, 95 | tWidth, 96 | titleStyles, 97 | secondaryTitleStyles, 98 | aShape, 99 | sTWidth, 100 | aSize, 101 | avatarStyles, 102 | reverse, 103 | containerStyles, 104 | loading, 105 | listSize, 106 | primaryColor, 107 | secondaryColor, 108 | children 109 | } = this.props; 110 | const { animation } = this.state; 111 | 112 | const interpolatedBackground = getInterpolatedColor(animation, primaryColor, secondaryColor); 113 | 114 | if (loading === false) { 115 | return children || null; 116 | } 117 | 118 | const titleInitialStyles = { 119 | height: tHeight, 120 | width: tWidth 121 | }; 122 | const secondaryTitleInitialStyles = { 123 | height: tHeight, 124 | width: sTWidth 125 | }; 126 | const avatarInitialStyles = { 127 | height: AVATAR_SIZE[aSize] || aSize, 128 | width: AVATAR_SIZE[aSize] || aSize, 129 | borderRadius: aShape === 'circle' ? AVATAR_SIZE[aSize] / 2 || (aSize as any) / 2 : 3, 130 | marginRight: reverse ? 0 : 10, 131 | marginLeft: reverse ? 10 : 0 132 | }; 133 | return [...Array(listSize)].map((_, index) => ( 134 | 135 | 142 | 150 | 151 | 152 | 160 | 168 | 169 | 170 | 171 | {[...Array(pRows)].map((_, index) => ( 172 | 181 | ))} 182 | 183 | 184 | )); 185 | } 186 | } 187 | 188 | ContentLoader.defaultProps = { 189 | ...commonDefaultProps, 190 | pHeight: 7, 191 | pWidth: ['85%', '95%', '75%'], 192 | pRows: 3, 193 | tWidth: '50%', 194 | tHeight: 7, 195 | sTWidth: '30%', 196 | paragraphStyles: {}, 197 | secondaryTitleStyles: {} 198 | }; 199 | const styles = StyleSheet.create({ 200 | container: { 201 | flexDirection: 'row', 202 | width: '100%', 203 | paddingHorizontal: 10, 204 | alignItems: 'center' 205 | }, 206 | 207 | content: { 208 | flex: 1, 209 | marginLeft: 0 210 | }, 211 | avatar: { 212 | borderRadius: 2, 213 | marginLeft: 10 214 | }, 215 | title: { 216 | marginBottom: 12, 217 | borderRadius: 3 218 | }, 219 | secondaryTitle: { 220 | marginBottom: 10, 221 | borderRadius: 3 222 | }, 223 | paragraph: { 224 | marginVertical: 7, 225 | borderRadius: 3 226 | }, 227 | 228 | paragraphContainer: { 229 | paddingHorizontal: 12, 230 | marginTop: 10 231 | } 232 | }); 233 | export default ContentLoader; 234 | -------------------------------------------------------------------------------- /src/InstagramLoader.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Animated, View, StyleSheet, ViewStyle } from 'react-native'; 3 | import { 4 | getInterpolatedColor, 5 | startAnimationHelper, 6 | commonDefaultProps, 7 | CommonProps, 8 | THeightType, 9 | TWidthType 10 | } from './shared'; 11 | 12 | const AVATAR_SIZE = { 13 | default: 60, 14 | large: 30, 15 | small: 25 16 | }; 17 | interface Props extends CommonProps { 18 | /** 19 | * Used to determine the height of the main title. 20 | */ 21 | tHeight: THeightType, 22 | /** 23 | * Used to determine the width of the main title. 24 | */ 25 | tWidth: TWidthType, 26 | /** 27 | * Used to determine the height of secondary title. 28 | */ 29 | sTHeight: string | number, 30 | /** 31 | * Used to determine the width of secondary title. 32 | */ 33 | sTWidth: string | number, 34 | /** 35 | * add additinal imageStyles or overwrite previous ones. 36 | */ 37 | imageStyles?: ViewStyle, 38 | /** 39 | * Used to determine height of the image 40 | */ 41 | imageHeight: string | number, 42 | /** 43 | * add additional avatarStyles or overwrite them 44 | */ 45 | avatarStyles?: ViewStyle 46 | /** 47 | * add additional secondary title styles or overwrite them. 48 | */ 49 | secondaryTitleStyles?: ViewStyle 50 | } 51 | class ContentLoader extends React.PureComponent { 52 | static defaultProps: Props; 53 | state = { 54 | animation: new Animated.Value(0) 55 | } 56 | componentDidMount() { 57 | const { active } = this.props; 58 | if (active) { 59 | this.startAnimation(); 60 | } 61 | } 62 | 63 | componentDidUpdate(prevProps) { 64 | const { loading } = this.props; 65 | if (prevProps.loading !== loading) { 66 | if (loading) { 67 | this.startAnimation(); 68 | } 69 | } 70 | } 71 | 72 | startAnimation = () => { 73 | const { animation } = this.state; 74 | const { animationDuration } = this.props; 75 | startAnimationHelper(animation, animationDuration); 76 | }; 77 | 78 | render() { 79 | const { 80 | imageStyles, 81 | sTHeight, 82 | sTWidth, 83 | tHeight, 84 | tWidth, 85 | titleStyles, 86 | secondaryTitleStyles, 87 | aShape, 88 | aSize, 89 | avatarStyles, 90 | reverse, 91 | containerStyles, 92 | loading, 93 | imageHeight, 94 | listSize, 95 | primaryColor, 96 | secondaryColor, 97 | children 98 | } = this.props; 99 | const { animation } = this.state; 100 | 101 | const interpolatedBackground = getInterpolatedColor(animation, primaryColor, secondaryColor); 102 | if (loading === false) { 103 | return children || null; 104 | } 105 | const imageInitialStyles = { 106 | height: imageHeight, 107 | width: '100%' 108 | }; 109 | const titleInitialStyles = { 110 | height: tHeight, 111 | width: tWidth 112 | }; 113 | const secondaryTitleInitialStyles = { 114 | height: sTHeight, 115 | width: sTWidth 116 | }; 117 | const avatarInitialStyles = { 118 | height: AVATAR_SIZE[aSize] || aSize, 119 | width: AVATAR_SIZE[aSize] || aSize, 120 | borderRadius: aShape === 'circle' ? AVATAR_SIZE[aSize] / 2 || (aSize as any) / 2 : 3, 121 | marginRight: reverse ? 0 : 5, 122 | marginLeft: reverse ? 5 : 0 123 | }; 124 | 125 | return [...Array(listSize)].map((_, index) => ( 126 | 127 | 134 | 142 | 143 | 144 | 152 | 160 | 161 | 162 | 163 | 171 | 172 | 173 | )); 174 | } 175 | } 176 | 177 | ContentLoader.defaultProps = { 178 | ...commonDefaultProps, 179 | sTWidth: '25%', 180 | tWidth: '40%', 181 | tHeight: 13, 182 | imageHeight: 200, 183 | imageStyles: {}, 184 | sTHeight: 7 185 | }; 186 | const styles = StyleSheet.create({ 187 | container: { 188 | flexDirection: 'row', 189 | width: '100%', 190 | paddingHorizontal: 10, 191 | alignItems: 'center' 192 | }, 193 | content: { 194 | flex: 1, 195 | marginLeft: 10 196 | }, 197 | avatar: { 198 | borderRadius: 2 199 | }, 200 | title: { 201 | marginBottom: 10, 202 | borderRadius: 3 203 | }, 204 | secondaryTitle: { 205 | borderRadius: 3 206 | }, 207 | image: { 208 | marginVertical: 5, 209 | borderRadius: 5 210 | }, 211 | 212 | ImageContainer: { 213 | paddingHorizontal: 12, 214 | marginTop: 10 215 | } 216 | }); 217 | export default ContentLoader; -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import ContentLoader from "./ContentLoader"; 2 | import FacebookLoader from "./FacebookLoader"; 3 | import InstagramLoader from "./InstagramLoader"; 4 | import BulletsLoader from "./Bullets"; 5 | export default ContentLoader; 6 | export { FacebookLoader, BulletsLoader, InstagramLoader }; 7 | export const Facebook = FacebookLoader; 8 | export const Instagram = InstagramLoader; 9 | export const Bullets = BulletsLoader; 10 | -------------------------------------------------------------------------------- /src/shared.tsx: -------------------------------------------------------------------------------- 1 | import hexToRgba from 'hex-to-rgba'; 2 | import { Animated, ViewStyle } from 'react-native'; 3 | 4 | export type WidthArrayType = number | string; 5 | export type AShapeType = 'circle'|'square'; 6 | export type ASizeType = string | number | 'small' | 'large' | 'default'; 7 | export type PHeightType = string | number | Array; 8 | export type PWidthType = string | number | Array; 9 | export type TWidthType = string | number; 10 | export type THeightType = string | number; 11 | export type AnimationType = Animated.Value | Animated.ValueXY 12 | export type ColorType = string; 13 | export const startAnimationHelper = (animation: AnimationType, duration: number) => { 14 | Animated.loop( 15 | Animated.sequence([ 16 | Animated.timing(animation, { 17 | toValue: 1, 18 | duration, 19 | useNativeDriver: false 20 | }), 21 | Animated.timing(animation, { 22 | toValue: 0, 23 | duration, 24 | useNativeDriver: false 25 | }) 26 | ]) 27 | ).start(); 28 | }; 29 | 30 | export const getInterpolatedColor = (animation: Animated.Value, primaryColor: ColorType, secondaryColor: ColorType) => 31 | animation.interpolate({ 32 | inputRange: [0, 1], 33 | outputRange: [ 34 | primaryColor.includes('rgb') ? primaryColor : hexToRgba(primaryColor), 35 | secondaryColor.includes('rgba') ? secondaryColor : hexToRgba(secondaryColor) 36 | ] 37 | }); 38 | 39 | export const paragraphInitialStyles = (index: number, pHeight: PHeightType, pWidth: PWidthType) => { 40 | let height = pHeight; 41 | let width = pWidth; 42 | if ( pWidth.constructor === Array) { 43 | width = pWidth[index] || '100%'; 44 | } 45 | if (pHeight.constructor === Array) { 46 | height = pHeight[index] || 8 47 | } 48 | return { 49 | height, 50 | width 51 | }; 52 | }; 53 | export interface CommonProps { 54 | /** 55 | * The color of primary shade of the loader, can be rgba or hex color. 56 | */ 57 | primaryColor: string, 58 | /** 59 | * The color of secondary shade of the loader, can be rgba or hex color. 60 | */ 61 | secondaryColor: string, 62 | /** 63 | * Animation duration of the fade, default is 500. 64 | */ 65 | animationDuration: number, 66 | /** 67 | * If loading prop is used, it will render children when loading false. 68 | * Usefull when you want to render something after loading finishes, 69 | * just add something like loading={this.state.loading} and you can add your component as children. 70 | */ 71 | loading?: boolean | null, 72 | /** 73 | * Used to toggle animation, 74 | * True - Animation enabled 75 | * False - Animation disabled 76 | */ 77 | active?: boolean, 78 | /** 79 | * Enalbes or disables the title 80 | */ 81 | title?: boolean, 82 | /** 83 | * If you want to render the loaders in list, default is 1. 84 | * If you provide more than one, it will render the loaders in a list. 85 | */ 86 | listSize: number, 87 | /** 88 | * Add addtional title styles. 89 | */ 90 | titleStyles?: ViewStyle, 91 | /** 92 | * Used to determine if avatar should be visible or not 93 | */ 94 | avatar?: boolean, 95 | /** 96 | * Used to determine the shape of avatar 97 | * can be 98 | * circle or square or if you want some kind of custamized shape, you can always overwrite avatarStyles 99 | */ 100 | aShape?: AShapeType 101 | /** 102 | * The size of avatar, can be default, large, small or your custom number 103 | */ 104 | aSize: ASizeType, 105 | /** 106 | * Can be used to reverse the flow, 107 | */ 108 | reverse?: boolean, 109 | /** 110 | * If you want to add additional properties or overwrite the styles of the main container. 111 | */ 112 | containerStyles?: ViewStyle 113 | } 114 | export const commonDefaultProps: CommonProps= { 115 | primaryColor: 'rgba(220, 220, 220, 1)', 116 | secondaryColor: 'rgba(200, 200, 200, 1)', 117 | animationDuration: 500, 118 | loading: null, 119 | active: false, 120 | title: true, 121 | listSize: 1, 122 | titleStyles: {}, 123 | avatar: false, 124 | aShape: 'circle', 125 | aSize: 'default', 126 | reverse: false, 127 | containerStyles: {} 128 | }; 129 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "jsx": "react-native", 6 | "removeComments": false, 7 | "lib": ["dom", "es2015", "es2016"], 8 | "declaration": true, 9 | "sourceMap": true, 10 | "outDir": "./lib", 11 | "esModuleInterop": true, 12 | "strict": true, 13 | "noImplicitAny": false, 14 | "strictNullChecks": true, 15 | "strictFunctionTypes": true, 16 | "strictPropertyInitialization": true, 17 | "noImplicitThis": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noImplicitReturns": true, 21 | "noFallthroughCasesInSwitch": true, 22 | "allowSyntheticDefaultImports": true, 23 | "skipLibCheck": true 24 | 25 | }, 26 | "exclude": ["node_modules"], 27 | "include": ["./src/**/*.tsx", "./src/**/*.ts"], 28 | 29 | } 30 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": ["tslint:latest", "tslint-react", "tslint-config-prettier"], 4 | "jsRules": {}, 5 | "rules": { 6 | "member-access": false, 7 | "object-literal-sort-keys": false, 8 | "ordered-imports": false, 9 | "interface-name": false 10 | }, 11 | "rulesDirectory": [] 12 | } 13 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@^7.0.0": 6 | version "7.8.3" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" 8 | integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== 9 | dependencies: 10 | "@babel/highlight" "^7.8.3" 11 | 12 | "@babel/helper-validator-identifier@^7.9.0": 13 | version "7.9.5" 14 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" 15 | integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== 16 | 17 | "@babel/highlight@^7.8.3": 18 | version "7.9.0" 19 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" 20 | integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== 21 | dependencies: 22 | "@babel/helper-validator-identifier" "^7.9.0" 23 | chalk "^2.0.0" 24 | js-tokens "^4.0.0" 25 | 26 | "@types/prop-types@*": 27 | version "15.7.3" 28 | resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" 29 | integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== 30 | 31 | "@types/react-native@^0.52.16": 32 | version "0.52.25" 33 | resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.52.25.tgz#78c0e6049d4dc0a7af7d4024baac28ae922bedaf" 34 | integrity sha512-JwrONoGfasRORI3QUILXar8xG9Q3rCS2EpfB2abGIvqWRISuRPKpjJOm4OL0tEBTPL/9r6hcngRrmYZSbvDDtw== 35 | dependencies: 36 | "@types/react" "*" 37 | 38 | "@types/react@*", "@types/react@^16.0.40": 39 | version "16.9.34" 40 | resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.34.tgz#f7d5e331c468f53affed17a8a4d488cd44ea9349" 41 | integrity sha512-8AJlYMOfPe1KGLKyHpflCg5z46n0b5DbRfqDksxBLBTUpB75ypDBAO9eCUcjNwE6LCUslwTz00yyG/X9gaVtow== 42 | dependencies: 43 | "@types/prop-types" "*" 44 | csstype "^2.2.0" 45 | 46 | ansi-styles@^3.2.1: 47 | version "3.2.1" 48 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 49 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 50 | dependencies: 51 | color-convert "^1.9.0" 52 | 53 | argparse@^1.0.7: 54 | version "1.0.10" 55 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 56 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 57 | dependencies: 58 | sprintf-js "~1.0.2" 59 | 60 | balanced-match@^1.0.0: 61 | version "1.0.0" 62 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 63 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 64 | 65 | brace-expansion@^1.1.7: 66 | version "1.1.11" 67 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 68 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 69 | dependencies: 70 | balanced-match "^1.0.0" 71 | concat-map "0.0.1" 72 | 73 | builtin-modules@^1.1.1: 74 | version "1.1.1" 75 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 76 | integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= 77 | 78 | chalk@^2.0.0, chalk@^2.3.0: 79 | version "2.4.2" 80 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 81 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 82 | dependencies: 83 | ansi-styles "^3.2.1" 84 | escape-string-regexp "^1.0.5" 85 | supports-color "^5.3.0" 86 | 87 | color-convert@^1.9.0: 88 | version "1.9.3" 89 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 90 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 91 | dependencies: 92 | color-name "1.1.3" 93 | 94 | color-name@1.1.3: 95 | version "1.1.3" 96 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 97 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 98 | 99 | commander@^2.12.1: 100 | version "2.20.3" 101 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 102 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 103 | 104 | concat-map@0.0.1: 105 | version "0.0.1" 106 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 107 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 108 | 109 | csstype@^2.2.0: 110 | version "2.6.10" 111 | resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" 112 | integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w== 113 | 114 | diff@^4.0.1: 115 | version "4.0.2" 116 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 117 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 118 | 119 | escape-string-regexp@^1.0.5: 120 | version "1.0.5" 121 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 122 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 123 | 124 | esprima@^4.0.0: 125 | version "4.0.1" 126 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 127 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 128 | 129 | fs.realpath@^1.0.0: 130 | version "1.0.0" 131 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 132 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 133 | 134 | glob@^7.1.1: 135 | version "7.1.6" 136 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 137 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 138 | dependencies: 139 | fs.realpath "^1.0.0" 140 | inflight "^1.0.4" 141 | inherits "2" 142 | minimatch "^3.0.4" 143 | once "^1.3.0" 144 | path-is-absolute "^1.0.0" 145 | 146 | has-flag@^3.0.0: 147 | version "3.0.0" 148 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 149 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 150 | 151 | hex-to-rgba@^2.0.1: 152 | version "2.0.1" 153 | resolved "https://registry.yarnpkg.com/hex-to-rgba/-/hex-to-rgba-2.0.1.tgz#4176977882a1cb32b83ce5ab1db6828ab84d5a13" 154 | integrity sha512-5XqPJBpsEUMsseJUi2w2Hl7cHFFi3+OO10M2pzAvKB1zL6fc+koGMhmBqoDOCB4GemiRM/zvDMRIhVw6EkB8dQ== 155 | 156 | inflight@^1.0.4: 157 | version "1.0.6" 158 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 159 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 160 | dependencies: 161 | once "^1.3.0" 162 | wrappy "1" 163 | 164 | inherits@2: 165 | version "2.0.4" 166 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 167 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 168 | 169 | js-tokens@^4.0.0: 170 | version "4.0.0" 171 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 172 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 173 | 174 | js-yaml@^3.13.1: 175 | version "3.13.1" 176 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" 177 | integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== 178 | dependencies: 179 | argparse "^1.0.7" 180 | esprima "^4.0.0" 181 | 182 | minimatch@^3.0.4: 183 | version "3.0.4" 184 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 185 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 186 | dependencies: 187 | brace-expansion "^1.1.7" 188 | 189 | minimist@^1.2.5: 190 | version "1.2.5" 191 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" 192 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 193 | 194 | mkdirp@^0.5.1: 195 | version "0.5.5" 196 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" 197 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 198 | dependencies: 199 | minimist "^1.2.5" 200 | 201 | once@^1.3.0: 202 | version "1.4.0" 203 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 204 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 205 | dependencies: 206 | wrappy "1" 207 | 208 | path-is-absolute@^1.0.0: 209 | version "1.0.1" 210 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 211 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 212 | 213 | path-parse@^1.0.6: 214 | version "1.0.7" 215 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 216 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 217 | 218 | resolve@^1.3.2: 219 | version "1.16.1" 220 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.16.1.tgz#49fac5d8bacf1fd53f200fa51247ae736175832c" 221 | integrity sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig== 222 | dependencies: 223 | path-parse "^1.0.6" 224 | 225 | semver@^5.3.0: 226 | version "5.7.1" 227 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 228 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 229 | 230 | sprintf-js@~1.0.2: 231 | version "1.0.3" 232 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 233 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 234 | 235 | supports-color@^5.3.0: 236 | version "5.5.0" 237 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 238 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 239 | dependencies: 240 | has-flag "^3.0.0" 241 | 242 | tslib@^1.8.0, tslib@^1.8.1: 243 | version "1.11.1" 244 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" 245 | integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== 246 | 247 | tslint-config-prettier@^1.9.0: 248 | version "1.18.0" 249 | resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" 250 | integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== 251 | 252 | tslint-react@^3.5.1: 253 | version "3.6.0" 254 | resolved "https://registry.yarnpkg.com/tslint-react/-/tslint-react-3.6.0.tgz#7f462c95c4a0afaae82507f06517ff02942196a1" 255 | integrity sha512-AIv1QcsSnj7e9pFir6cJ6vIncTqxfqeFF3Lzh8SuuBljueYzEAtByuB6zMaD27BL0xhMEqsZ9s5eHuCONydjBw== 256 | dependencies: 257 | tsutils "^2.13.1" 258 | 259 | tslint@^5.9.1: 260 | version "5.20.1" 261 | resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d" 262 | integrity sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg== 263 | dependencies: 264 | "@babel/code-frame" "^7.0.0" 265 | builtin-modules "^1.1.1" 266 | chalk "^2.3.0" 267 | commander "^2.12.1" 268 | diff "^4.0.1" 269 | glob "^7.1.1" 270 | js-yaml "^3.13.1" 271 | minimatch "^3.0.4" 272 | mkdirp "^0.5.1" 273 | resolve "^1.3.2" 274 | semver "^5.3.0" 275 | tslib "^1.8.0" 276 | tsutils "^2.29.0" 277 | 278 | tsutils@^2.13.1, tsutils@^2.29.0: 279 | version "2.29.0" 280 | resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" 281 | integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== 282 | dependencies: 283 | tslib "^1.8.1" 284 | 285 | typescript@^2.7.1: 286 | version "2.9.2" 287 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" 288 | integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w== 289 | 290 | wrappy@1: 291 | version "1.0.2" 292 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 293 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 294 | --------------------------------------------------------------------------------