UNPKG

3.13 kBJavaScriptView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 * @typechecks
7 *
8 * Example usage:
9 * <Rectangle
10 * width={50}
11 * height={50}
12 * stroke="green"
13 * fill="blue"
14 * />
15 *
16 * Additional optional properties:
17 * (Number) radius
18 * (Number) radiusTopLeft
19 * (Number) radiusTopRight
20 * (Number) radiusBottomLeft
21 * (Number) radiusBottomRight
22 *
23 */
24
25'use strict';
26
27var assign = require('object-assign');
28var PropTypes = require('prop-types');
29var React = require('react');
30var ReactART = require('react-art');
31
32var createReactClass = require('create-react-class');
33
34var Shape = ReactART.Shape;
35var Path = ReactART.Path;
36
37/**
38 * Rectangle is a React component for drawing rectangles. Like other ReactART
39 * components, it must be used in a <Surface>.
40 */
41var Rectangle = createReactClass({
42 displayName: 'Rectangle',
43
44 propTypes: {
45 width: PropTypes.number.isRequired,
46 height: PropTypes.number.isRequired,
47 radius: PropTypes.number,
48 radiusTopLeft: PropTypes.number,
49 radiusTopRight: PropTypes.number,
50 radiusBottomRight: PropTypes.number,
51 radiusBottomLeft: PropTypes.number,
52 },
53
54 render: function render() {
55 var width = this.props.width;
56 var height = this.props.height;
57 var radius = this.props.radius ? this.props.radius : 0;
58
59 // if unspecified, radius(Top|Bottom)(Left|Right) defaults to the radius
60 // property
61 var tl = this.props.radiusTopLeft ? this.props.radiusTopLeft : radius;
62 var tr = this.props.radiusTopRight ? this.props.radiusTopRight : radius;
63 var br = this.props.radiusBottomRight
64 ? this.props.radiusBottomRight
65 : radius;
66 var bl = this.props.radiusBottomLeft ? this.props.radiusBottomLeft : radius;
67
68 var path = Path();
69
70 // for negative width/height, offset the rectangle in the negative x/y
71 // direction. for negative radius, just default to 0.
72 if (width < 0) {
73 path.move(width, 0);
74 width = -width;
75 }
76 if (height < 0) {
77 path.move(0, height);
78 height = -height;
79 }
80 if (tl < 0) {
81 tl = 0;
82 }
83 if (tr < 0) {
84 tr = 0;
85 }
86 if (br < 0) {
87 br = 0;
88 }
89 if (bl < 0) {
90 bl = 0;
91 }
92
93 // disable border radius if it doesn't fit within the specified
94 // width/height
95 if (tl + tr > width) {
96 tl = 0;
97 tr = 0;
98 }
99 if (bl + br > width) {
100 bl = 0;
101 br = 0;
102 }
103 if (tl + bl > height) {
104 tl = 0;
105 bl = 0;
106 }
107 if (tr + br > height) {
108 tr = 0;
109 br = 0;
110 }
111
112 path.move(0, tl);
113
114 if (tl > 0) {
115 path.arc(tl, -tl);
116 }
117 path.line(width - (tr + tl), 0);
118
119 if (tr > 0) {
120 path.arc(tr, tr);
121 }
122 path.line(0, height - (tr + br));
123
124 if (br > 0) {
125 path.arc(-br, br);
126 }
127 path.line(-width + (br + bl), 0);
128
129 if (bl > 0) {
130 path.arc(-bl, -bl);
131 }
132 path.line(0, -height + (bl + tl));
133
134 return React.createElement(Shape, assign({}, this.props, {d: path}));
135 },
136});
137
138module.exports = Rectangle;