├── .gitignore ├── LICENSE ├── README.md ├── Triangle.js ├── index.d.ts ├── package.json ├── sampletriangle.png └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Justin Poliachik 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-triangle 2 | Draw triangles in code with React Native 3 | 4 | A class to encapsulate the CSS triangle hack. Based off the output of the triangle generator http://apps.eky.hk/css-triangle-generator/ but modified for React Native syntax. 5 | 6 | ## Installation 7 | `npm install react-native-triangle --save` 8 | 9 | Then 10 | 11 | `import Triangle from 'react-native-triangle';` 12 | 13 | ## Usage 14 | Sample JSX will produce the triangle below: 15 | ``` 16 | 22 | ``` 23 | ![alt text](https://raw.githubusercontent.com/Jpoliachik/react-native-triangle/master/sampletriangle.png "react-native-triangle") 24 | 25 | The width and height act as bounds to fit the triangle into. 26 | 27 | ### Supported Directions 28 | - up 29 | - right 30 | - down 31 | - left 32 | - up-left 33 | - up-right 34 | - down-left 35 | - down-right 36 | -------------------------------------------------------------------------------- /Triangle.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import React from 'react'; 4 | import { 5 | StyleSheet, 6 | View 7 | } from 'react-native'; 8 | var createReactClass = require('create-react-class'); 9 | var PropTypes = require('prop-types') 10 | 11 | var Triangle = createReactClass({ 12 | 13 | displayName: 'Triangle', 14 | 15 | propTypes: { 16 | direction: PropTypes.oneOf(['up', 'right', 'down', 'left', 'up-right', 'up-left', 'down-right', 'down-left']), 17 | width: PropTypes.number, 18 | height: PropTypes.number, 19 | color: PropTypes.string, 20 | }, 21 | 22 | getDefaultProps: function() { 23 | return { 24 | direction: 'up', 25 | width: 0, 26 | height: 0, 27 | color: 'white', 28 | }; 29 | }, 30 | 31 | _borderStyles() { 32 | if (this.props.direction == 'up') { 33 | return { 34 | borderTopWidth: 0, 35 | borderRightWidth: this.props.width/2.0, 36 | borderBottomWidth: this.props.height, 37 | borderLeftWidth: this.props.width/2.0, 38 | borderTopColor: 'transparent', 39 | borderRightColor: 'transparent', 40 | borderBottomColor: this.props.color, 41 | borderLeftColor: 'transparent', 42 | }; 43 | } else if (this.props.direction == 'right') { 44 | return { 45 | borderTopWidth: this.props.height/2.0, 46 | borderRightWidth: 0, 47 | borderBottomWidth: this.props.height/2.0, 48 | borderLeftWidth: this.props.width, 49 | borderTopColor: 'transparent', 50 | borderRightColor: 'transparent', 51 | borderBottomColor: 'transparent', 52 | borderLeftColor: this.props.color, 53 | }; 54 | } else if (this.props.direction == 'down') { 55 | return { 56 | borderTopWidth: this.props.height, 57 | borderRightWidth: this.props.width/2.0, 58 | borderBottomWidth: 0, 59 | borderLeftWidth: this.props.width/2.0, 60 | borderTopColor: this.props.color, 61 | borderRightColor: 'transparent', 62 | borderBottomColor: 'transparent', 63 | borderLeftColor: 'transparent', 64 | }; 65 | } else if (this.props.direction == 'left') { 66 | return { 67 | borderTopWidth: this.props.height/2.0, 68 | borderRightWidth: this.props.width, 69 | borderBottomWidth: this.props.height/2.0, 70 | borderLeftWidth: 0, 71 | borderTopColor: 'transparent', 72 | borderRightColor: this.props.color, 73 | borderBottomColor: 'transparent', 74 | borderLeftColor: 'transparent', 75 | }; 76 | } else if (this.props.direction == 'up-left') { 77 | return { 78 | borderTopWidth: this.props.height, 79 | borderRightWidth: this.props.width, 80 | borderBottomWidth: 0, 81 | borderLeftWidth: 0, 82 | borderTopColor: this.props.color, 83 | borderRightColor: 'transparent', 84 | borderBottomColor: 'transparent', 85 | borderLeftColor: 'transparent', 86 | }; 87 | } else if (this.props.direction == 'up-right') { 88 | return { 89 | borderTopWidth: 0, 90 | borderRightWidth: this.props.width, 91 | borderBottomWidth: this.props.height, 92 | borderLeftWidth: 0, 93 | borderTopColor: 'transparent', 94 | borderRightColor: this.props.color, 95 | borderBottomColor: 'transparent', 96 | borderLeftColor: 'transparent', 97 | }; 98 | } else if (this.props.direction == 'down-left') { 99 | return { 100 | borderTopWidth: this.props.height, 101 | borderRightWidth: 0, 102 | borderBottomWidth: 0, 103 | borderLeftWidth: this.props.width, 104 | borderTopColor: 'transparent', 105 | borderRightColor: 'transparent', 106 | borderBottomColor: 'transparent', 107 | borderLeftColor: this.props.color, 108 | }; 109 | } else if (this.props.direction == 'down-right') { 110 | return { 111 | borderTopWidth: 0, 112 | borderRightWidth: 0, 113 | borderBottomWidth: this.props.height, 114 | borderLeftWidth: this.props.width, 115 | borderTopColor: 'transparent', 116 | borderRightColor: 'transparent', 117 | borderBottomColor: this.props.color, 118 | borderLeftColor: 'transparent', 119 | }; 120 | } else { 121 | console.error('Triangle.js wrong direction. ' + this.props.direction + ' is invalid. Must be one of: ' + ['up', 'right', 'down', 'left', 'up-right', 'up-left', 'down-right', 'down-left']); 122 | return {}; 123 | } 124 | }, 125 | 126 | render: function() { 127 | var borderStyles = this._borderStyles(); 128 | return ( 129 | 130 | ) 131 | }, 132 | 133 | }); 134 | 135 | var styles = StyleSheet.create({ 136 | triangle: { 137 | width: 0, 138 | height: 0, 139 | backgroundColor: 'transparent', 140 | borderStyle: 'solid', 141 | }, 142 | }); 143 | 144 | module.exports = Triangle; 145 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for react-native-triangle 0.0.6 2 | // Project: https://github.com/Jpoliachik/react-native-triangle 3 | // Definitions by: Kyle Roach 4 | // TypeScript Version: 2.2.2 5 | 6 | import React, { Component } from 'react' 7 | 8 | type TrianglePropsDirection = 'up' | 'right' | 'down' | 'left' | 'up-left' | 'up-right' | 'down-left' | 'down-right' 9 | 10 | interface TriangleProps { 11 | /** 12 | * The width of the rendered triangle 13 | * Default value is 0 14 | */ 15 | width?: number 16 | 17 | /** 18 | * Height of the rendered triangle 19 | * Default value is 0 20 | */ 21 | height?: number 22 | 23 | 24 | /** 25 | * Fill color of triangle 26 | * Accepts color strings such as hex, literals, rgba 27 | * 28 | * Default value is 'white' 29 | */ 30 | color?: string 31 | 32 | /** 33 | * Orientation for the triangle 34 | * Default value is 'up' 35 | */ 36 | direction?: TrianglePropsDirection 37 | } 38 | 39 | export default class Triangle extends Component { } 40 | 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-triangle", 3 | "version": "0.0.9", 4 | "description": "draw triangle views in react native", 5 | "main": "Triangle.js", 6 | "types": "index.d.ts", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/Jpoliachik/react-native-triangle" 10 | }, 11 | "keywords": [ 12 | "triangle", 13 | "react-native" 14 | ], 15 | "author": "Justin Poliachik (https://github.com/Jpoliachik)", 16 | "license": "MIT", 17 | "dependencies": { 18 | "create-react-class": "^15.6.0", 19 | "prop-types": "^15.5.10" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sampletriangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jpoliachik/react-native-triangle/d551f8f98a22876ef73b86b043caf4e2649f67fe/sampletriangle.png -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | asap@~2.0.3: 6 | version "2.0.6" 7 | resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" 8 | 9 | core-js@^1.0.0: 10 | version "1.2.7" 11 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" 12 | 13 | create-react-class@^15.6.0: 14 | version "15.6.0" 15 | resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4" 16 | dependencies: 17 | fbjs "^0.8.9" 18 | loose-envify "^1.3.1" 19 | object-assign "^4.1.1" 20 | 21 | encoding@^0.1.11: 22 | version "0.1.12" 23 | resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" 24 | dependencies: 25 | iconv-lite "~0.4.13" 26 | 27 | fbjs@^0.8.9: 28 | version "0.8.12" 29 | resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04" 30 | dependencies: 31 | core-js "^1.0.0" 32 | isomorphic-fetch "^2.1.1" 33 | loose-envify "^1.0.0" 34 | object-assign "^4.1.0" 35 | promise "^7.1.1" 36 | setimmediate "^1.0.5" 37 | ua-parser-js "^0.7.9" 38 | 39 | iconv-lite@~0.4.13: 40 | version "0.4.18" 41 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" 42 | 43 | is-stream@^1.0.1: 44 | version "1.1.0" 45 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 46 | 47 | isomorphic-fetch@^2.1.1: 48 | version "2.2.1" 49 | resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" 50 | dependencies: 51 | node-fetch "^1.0.1" 52 | whatwg-fetch ">=0.10.0" 53 | 54 | js-tokens@^3.0.0: 55 | version "3.0.2" 56 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 57 | 58 | loose-envify@^1.0.0, loose-envify@^1.3.1: 59 | version "1.3.1" 60 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" 61 | dependencies: 62 | js-tokens "^3.0.0" 63 | 64 | node-fetch@^1.0.1: 65 | version "1.7.1" 66 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.1.tgz#899cb3d0a3c92f952c47f1b876f4c8aeabd400d5" 67 | dependencies: 68 | encoding "^0.1.11" 69 | is-stream "^1.0.1" 70 | 71 | object-assign@^4.1.0, object-assign@^4.1.1: 72 | version "4.1.1" 73 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 74 | 75 | promise@^7.1.1: 76 | version "7.3.1" 77 | resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" 78 | dependencies: 79 | asap "~2.0.3" 80 | 81 | prop-types@^15.5.10: 82 | version "15.5.10" 83 | resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154" 84 | dependencies: 85 | fbjs "^0.8.9" 86 | loose-envify "^1.3.1" 87 | 88 | setimmediate@^1.0.5: 89 | version "1.0.5" 90 | resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" 91 | 92 | ua-parser-js@^0.7.9: 93 | version "0.7.13" 94 | resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.13.tgz#cd9dd2f86493b3f44dbeeef3780fda74c5ee14be" 95 | 96 | whatwg-fetch@>=0.10.0: 97 | version "2.0.3" 98 | resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" 99 | --------------------------------------------------------------------------------