├── .babelrc
├── .editorconfig
├── .eslintrc
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── __tests__
├── .eslintrc
├── test.js
└── util.js
├── dist
├── index.es.js
├── index.es.js.map
├── index.js
└── index.js.map
├── package.json
├── rollup.config.js
├── screenshots
├── react-bulletproof-button-2.png
└── react-bulletproof-button.png
├── src
├── index.js
└── util.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-env",
4 | "@babel/react"
5 | ],
6 | "plugins": [
7 | "@babel/plugin-proposal-class-properties",
8 | "@babel/plugin-transform-runtime"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": [
4 | "standard",
5 | "standard-react"
6 | ],
7 | "env": {
8 | "es6": true
9 | },
10 | "plugins": [
11 | "react"
12 | ],
13 | "parserOptions": {
14 | "sourceType": "module"
15 | },
16 | "rules": {
17 | // don't force es6 functions to include space before paren
18 | "space-before-function-paren": 0,
19 |
20 | // allow specifying true explicitly for boolean props
21 | "react/jsx-boolean-value": 0,
22 |
23 | "semi": [1, "always"]
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 |
4 | # production
5 | /build
6 | /demo
7 |
8 | # testing
9 | /coverage
10 |
11 | # misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 9
4 | - 8
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jackson Trieu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-bulletproof-button
2 | React component that allows you design and create goregous email buttons that are compatible with modern email clients & Outlook 2007+. HTML output is based on [Campaign Monitor's "Bulletproof email buttons" concept](https://buttons.cm/).
3 |
4 | ## Table of contents
5 |
6 | - [Why Do I Need Bulletproof Buttons?](#why-do-i-need-bulletproof-buttons)
7 | - [Screenshots](#screenshots)
8 | - [Default Button style](#default-button-style)
9 | - [Button with updated colors and border radius](#button-with-updated-colors-and-border-radius)
10 | - [Install](#install)
11 | - [Usage](#usage)
12 | - [API](#api)
13 | - [Props](#props)
14 | - [Development](#development)
15 | - [Test](#test)
16 | - [Coverage](#coverage)
17 | - [License](#license)
18 |
19 |
20 | ## Why Do I Need Bulletproof Buttons?
21 |
22 | CSS support for HTML emails differs wildly between email clients, making it difficult to create HTML that will render consistently across a wide range of email clients.
23 |
24 | In particular, older Outlook clients (2007/2010/2013) use the Microsoft Word rendering engine which limits HTML emails to a subset of the modern CSS spec.
25 |
26 | Bulletproof buttons allow you to design and render gorgeous buttons using progressively enhanced VML and CSS.
27 |
28 | Older Outlook clients are supported by the use of VML and conditional rendering via the `').join('')
18 |
19 | const parser = new DOMParser();
20 | const doc = parser.parseFromString(strippedofIfs, 'text/xml');
21 |
22 | return doc.documentElement;
23 | };
24 |
25 | const getVmlCenterElement = (vmlElement) => {
26 | return vmlElement.querySelector('center');
27 | };
28 |
29 | test('vendor specific styles are rendered', async () => {
30 | const { container } = render(
31 |
33 | );
34 | const linkElement = getLinkElement(container);
35 |
36 | expect(linkElement.getAttribute('style').includes('mso-hide: all')).toBeTruthy();
37 | expect(linkElement.getAttribute('style').includes('-webkit-text-size-adjust: none')).toBeTruthy();
38 | });
39 |
40 | test("'backgroundColor' prop is rendered", async () => {
41 | const backgroundColor = '#123456';
42 |
43 | const { container } = render(
44 |
47 | );
48 | const linkElement = getLinkElement(container);
49 | const vmlElement = getVmlElement(container);
50 |
51 | expect(linkElement).toHaveStyle(`background-color: ${backgroundColor}`, requiredProps.backgroundColor);
52 | expect(vmlElement.getAttribute('fillcolor')).toBe(backgroundColor);
53 | });
54 |
55 | test("'borderColor' prop is rendered", async () => {
56 | const borderColor = '#123456';
57 |
58 | const { container } = render(
59 |
62 | );
63 | const linkElement = getLinkElement(container);
64 | const vmlElement = getVmlElement(container);
65 |
66 | expect(linkElement).toHaveStyle(`border-color: ${borderColor}`, requiredProps.borderColor);
67 | expect(vmlElement.getAttribute('strokecolor')).toBe(borderColor);
68 | });
69 |
70 | test("'borderStyle' prop is rendered", async () => {
71 | const borderStyle = 'dashed';
72 |
73 | const { container } = render(
74 |
77 | );
78 | const linkElement = getLinkElement(container);
79 |
80 | expect(linkElement).toHaveStyle(`border-style: ${borderStyle}`, borderStyle);
81 | });
82 |
83 | test("'borderWidth' prop is rendered", async () => {
84 | const borderWidth = 20;
85 |
86 | const { container } = render(
87 |
90 | );
91 | const linkElement = getLinkElement(container);
92 |
93 | expect(linkElement).toHaveStyle(`border-width: ${borderWidth}px`, borderWidth);
94 | });
95 |
96 | test("'fontColor' prop is rendered", async () => {
97 | const fontColor = '#654321';
98 |
99 | const { container } = render(
100 |
103 | );
104 | const linkElement = getLinkElement(container);
105 | const vmlElement = getVmlElement(container);
106 | const vmlCenterElement = getVmlCenterElement(vmlElement);
107 |
108 | expect(linkElement).toHaveStyle(`color: ${fontColor}`, fontColor);
109 | expect(vmlCenterElement.getAttribute('style').includes(`color: ${fontColor}`)).toBeTruthy();
110 | });
111 |
112 | test("'fontFamily' prop is rendered", async () => {
113 | const fontFamily = 'Arial, sans-serif, serif';
114 |
115 | const { container } = render(
116 |
119 | );
120 | const linkElement = getLinkElement(container);
121 | const vmlElement = getVmlElement(container);
122 | const vmlCenterElement = getVmlCenterElement(vmlElement);
123 |
124 | expect(linkElement).toHaveStyle(`font-family: ${fontFamily}`, fontFamily);
125 | expect(vmlCenterElement.getAttribute('style').includes(`font-family: ${fontFamily}`)).toBeTruthy();
126 | });
127 |
128 | test("'fontSize' prop is rendered", async () => {
129 | const fontSize = 24;
130 |
131 | const { container } = render(
132 |
135 | );
136 | const linkElement = getLinkElement(container);
137 | const vmlElement = getVmlElement(container);
138 | const vmlCenterElement = getVmlCenterElement(vmlElement);
139 |
140 | expect(linkElement).toHaveStyle(`font-size: ${fontSize}px`, fontSize);
141 | expect(vmlCenterElement.getAttribute('style').includes(`font-size: ${fontSize}px`)).toBeTruthy();
142 | });
143 |
144 | test("'fontWeight' prop is rendered", async () => {
145 | const fontWeight = '600';
146 |
147 | const { container } = render(
148 |
151 | );
152 | const linkElement = getLinkElement(container);
153 | const vmlElement = getVmlElement(container);
154 | const vmlCenterElement = getVmlCenterElement(vmlElement);
155 |
156 | expect(linkElement).toHaveStyle(`font-weight: ${fontWeight}`, fontWeight);
157 | expect(vmlCenterElement.getAttribute('style').includes(`font-weight: ${fontWeight}`)).toBeTruthy();
158 | });
159 |
160 | test("'height' prop is rendered", async () => {
161 | const height = 55;
162 |
163 | const { container } = render(
164 |
167 | );
168 | const linkElement = getLinkElement(container);
169 | const vmlElement = getVmlElement(container);
170 |
171 | expect(linkElement).toHaveStyle(`height: ${height}px`, height);
172 | expect(linkElement).toHaveStyle(`line-height: ${height}px`, height);
173 | expect(vmlElement.getAttribute('style').includes(`height: ${height}px`)).toBeTruthy();
174 | });
175 |
176 | test("'width' prop is rendered", async () => {
177 | const width = 222;
178 |
179 | const { container } = render(
180 |
183 | );
184 | const linkElement = getLinkElement(container);
185 | const vmlElement = getVmlElement(container);
186 |
187 | expect(linkElement).toHaveStyle(`width: ${width}px`, width);
188 | expect(vmlElement.getAttribute('style').includes(`width: ${width}px`)).toBeTruthy();
189 | });
190 |
191 | test("'href' prop is rendered", async () => {
192 | const { container } = render(
193 |
195 | );
196 | const linkElement = getLinkElement(container);
197 | const vmlElement = getVmlElement(container);
198 |
199 | expect(linkElement).toHaveAttribute('href', requiredProps.href);
200 | expect(vmlElement.getAttribute('href')).toBe(requiredProps.href);
201 | });
202 |
203 | test("'text' prop is rendered", async () => {
204 | const { container } = render(
205 |
207 | );
208 | const linkElement = getLinkElement(container);
209 | const vmlElement = getVmlElement(container);
210 | const vmlCenterElement = getVmlCenterElement(vmlElement);
211 |
212 | expect(linkElement).toHaveTextContent(requiredProps.text);
213 | expect(vmlCenterElement.textContent.trim()).toBe(requiredProps.text);
214 | });
215 |
--------------------------------------------------------------------------------
/__tests__/util.js:
--------------------------------------------------------------------------------
1 | import { hashToStyles, toPx } from '../src/util';
2 |
3 | test('hashToStyles generates a css style formatted string', async () => {
4 | const styleHash = {
5 | 'background': '#fff',
6 | 'font-size': '13px',
7 | '-webkit-text-size-adjust': 'none'
8 | };
9 | const styleString = hashToStyles(styleHash);
10 |
11 | expect(styleString).toEqual('background: #fff; font-size: 13px; -webkit-text-size-adjust: none');
12 | });
13 |
14 | test('hashToStyles does not sort', async () => {
15 | const styleHash = {
16 | 'font-size': '13px',
17 | 'background': '#fff',
18 | '-webkit-text-size-adjust': 'none'
19 | };
20 | const styleString = hashToStyles(styleHash);
21 |
22 | expect(styleString).toEqual('font-size: 13px; background: #fff; -webkit-text-size-adjust: none');
23 | });
24 |
25 | test('toPx adds px to end of number', async () => {
26 | expect(toPx(10)).toEqual('10px');
27 | });
28 |
29 | test('toPx does not add px to string already ending with px', async () => {
30 | expect(toPx('10px')).toEqual('10px');
31 | });
32 |
33 | test('toPx returns 0 if value is falsy', async () => {
34 | expect(toPx(null)).toEqual('0');
35 | expect(toPx(undefined)).toEqual('0');
36 | expect(toPx('')).toEqual('0');
37 | });
38 |
--------------------------------------------------------------------------------
/dist/index.es.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | function _classCallCheck(instance, Constructor) {
5 | if (!(instance instanceof Constructor)) {
6 | throw new TypeError("Cannot call a class as a function");
7 | }
8 | }
9 |
10 | var classCallCheck = _classCallCheck;
11 |
12 | function _defineProperties(target, props) {
13 | for (var i = 0; i < props.length; i++) {
14 | var descriptor = props[i];
15 | descriptor.enumerable = descriptor.enumerable || false;
16 | descriptor.configurable = true;
17 | if ("value" in descriptor) descriptor.writable = true;
18 | Object.defineProperty(target, descriptor.key, descriptor);
19 | }
20 | }
21 |
22 | function _createClass(Constructor, protoProps, staticProps) {
23 | if (protoProps) _defineProperties(Constructor.prototype, protoProps);
24 | if (staticProps) _defineProperties(Constructor, staticProps);
25 | return Constructor;
26 | }
27 |
28 | var createClass = _createClass;
29 |
30 | function createCommonjsModule(fn, module) {
31 | return module = { exports: {} }, fn(module, module.exports), module.exports;
32 | }
33 |
34 | var _typeof_1 = createCommonjsModule(function (module) {
35 | function _typeof2(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); }
36 |
37 | function _typeof(obj) {
38 | if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
39 | module.exports = _typeof = function _typeof(obj) {
40 | return _typeof2(obj);
41 | };
42 | } else {
43 | module.exports = _typeof = function _typeof(obj) {
44 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
45 | };
46 | }
47 |
48 | return _typeof(obj);
49 | }
50 |
51 | module.exports = _typeof;
52 | });
53 |
54 | function _assertThisInitialized(self) {
55 | if (self === void 0) {
56 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
57 | }
58 |
59 | return self;
60 | }
61 |
62 | var assertThisInitialized = _assertThisInitialized;
63 |
64 | function _possibleConstructorReturn(self, call) {
65 | if (call && (_typeof_1(call) === "object" || typeof call === "function")) {
66 | return call;
67 | }
68 |
69 | return assertThisInitialized(self);
70 | }
71 |
72 | var possibleConstructorReturn = _possibleConstructorReturn;
73 |
74 | var getPrototypeOf = createCommonjsModule(function (module) {
75 | function _getPrototypeOf(o) {
76 | module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
77 | return o.__proto__ || Object.getPrototypeOf(o);
78 | };
79 | return _getPrototypeOf(o);
80 | }
81 |
82 | module.exports = _getPrototypeOf;
83 | });
84 |
85 | var setPrototypeOf = createCommonjsModule(function (module) {
86 | function _setPrototypeOf(o, p) {
87 | module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
88 | o.__proto__ = p;
89 | return o;
90 | };
91 |
92 | return _setPrototypeOf(o, p);
93 | }
94 |
95 | module.exports = _setPrototypeOf;
96 | });
97 |
98 | function _inherits(subClass, superClass) {
99 | if (typeof superClass !== "function" && superClass !== null) {
100 | throw new TypeError("Super expression must either be null or a function");
101 | }
102 |
103 | subClass.prototype = Object.create(superClass && superClass.prototype, {
104 | constructor: {
105 | value: subClass,
106 | writable: true,
107 | configurable: true
108 | }
109 | });
110 | if (superClass) setPrototypeOf(subClass, superClass);
111 | }
112 |
113 | var inherits = _inherits;
114 |
115 | function _defineProperty(obj, key, value) {
116 | if (key in obj) {
117 | Object.defineProperty(obj, key, {
118 | value: value,
119 | enumerable: true,
120 | configurable: true,
121 | writable: true
122 | });
123 | } else {
124 | obj[key] = value;
125 | }
126 |
127 | return obj;
128 | }
129 |
130 | var defineProperty = _defineProperty;
131 |
132 | var hashToStyles = function hashToStyles(styleHash) {
133 | var result = '';
134 | var keys = Object.keys(styleHash);
135 |
136 | for (var _i = 0; _i < keys.length; _i++) {
137 | var key = keys[_i];
138 |
139 | if (result) {
140 | result += '; ';
141 | }
142 |
143 | result += key + ': ' + styleHash[key];
144 | }
145 |
146 | return result;
147 | };
148 | var toPx = function toPx(value) {
149 | if (!value) {
150 | return '0';
151 | }
152 |
153 | if (typeof value === 'string' && value.endsWith('px')) {
154 | return value;
155 | }
156 |
157 | return "".concat(value, "px");
158 | };
159 |
160 | var BulletproofButton =
161 | /*#__PURE__*/
162 | function (_Component) {
163 | inherits(BulletproofButton, _Component);
164 |
165 | function BulletproofButton() {
166 | var _getPrototypeOf2;
167 |
168 | var _this;
169 |
170 | classCallCheck(this, BulletproofButton);
171 |
172 | for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
173 | args[_key] = arguments[_key];
174 | }
175 |
176 | _this = possibleConstructorReturn(this, (_getPrototypeOf2 = getPrototypeOf(BulletproofButton)).call.apply(_getPrototypeOf2, [this].concat(args)));
177 |
178 | defineProperty(assertThisInitialized(assertThisInitialized(_this)), "calculateVmlArcSize", function () {
179 | return Math.round(_this.props.borderRadius / _this.props.width * 100).toString() + '%';
180 | });
181 |
182 | return _this;
183 | }
184 |
185 | createClass(BulletproofButton, [{
186 | key: "render",
187 | value: function render() {
188 | var vmlButton = this.renderVmlButton();
189 | var htmlButton = this.renderHtmlButton();
190 | return React.createElement("div", null, React.createElement("div", {
191 | dangerouslySetInnerHTML: {
192 | __html: vmlButton
193 | }
194 | }), React.createElement("div", {
195 | dangerouslySetInnerHTML: {
196 | __html: htmlButton
197 | }
198 | }));
199 | }
200 | }, {
201 | key: "renderVmlButton",
202 | value: function renderVmlButton() {
203 | var vmlRectStyles = this.calculateVmlRectStyles();
204 | var vmlCenterStyles = this.calculateVmlCenterStyles();
205 | var vmlArcSize = this.calculateVmlArcSize();
206 | return "\n \n ");
207 | }
208 | }, {
209 | key: "calculateVmlRectStyles",
210 | value: function calculateVmlRectStyles() {
211 | return hashToStyles({
212 | 'height': toPx(this.props.height),
213 | 'v-text-anchor': 'middle',
214 | 'width': toPx(this.props.width)
215 | });
216 | }
217 | }, {
218 | key: "calculateVmlCenterStyles",
219 | value: function calculateVmlCenterStyles() {
220 | return hashToStyles({
221 | 'color': this.props.fontColor,
222 | 'font-family': this.props.fontFamily,
223 | 'font-size': toPx(this.props.fontSize),
224 | 'font-weight': this.props.fontWeight
225 | });
226 | }
227 | }, {
228 | key: "renderHtmlButton",
229 | value: function renderHtmlButton() {
230 | var htmlLinkStyles = this.calculateHtmlLinkStyles();
231 | return "\n \n ").concat(this.props.text, "\n \n ");
232 | }
233 | }, {
234 | key: "calculateHtmlLinkStyles",
235 | value: function calculateHtmlLinkStyles() {
236 | return hashToStyles({
237 | 'background-color': this.props.backgroundColor,
238 | 'border-color': this.props.borderColor,
239 | 'border-style': this.props.borderStyle,
240 | 'border-width': toPx(this.props.borderWidth),
241 | 'border-radius': toPx(this.props.borderRadius),
242 | 'color': this.props.fontColor,
243 | 'display': 'inline-block',
244 | 'font-family': this.props.fontFamily,
245 | 'font-size': toPx(this.props.fontSize),
246 | 'font-weight': this.props.fontWeight,
247 | 'height': toPx(this.props.height),
248 | 'line-height': toPx(this.props.height),
249 | 'mso-hide': 'all',
250 | 'text-align': 'center',
251 | 'text-decoration': 'none',
252 | 'width': toPx(this.props.width),
253 | '-webkit-text-size-adjust': 'none'
254 | });
255 | }
256 | }]);
257 |
258 | return BulletproofButton;
259 | }(Component);
260 | BulletproofButton.defaultProps = {
261 | backgroundColor: '#556270',
262 | borderColor: '#1e3650',
263 | borderRadius: 4,
264 | borderStyle: 'solid',
265 | borderWidth: 1,
266 | fontFamily: 'sans-serif',
267 | fontSize: 13,
268 | fontWeight: 'bold',
269 | fontColor: '#fff',
270 | height: 40,
271 | width: 200
272 | };
273 | BulletproofButton.propTypes = {
274 | backgroundColor: PropTypes.string,
275 | borderColor: PropTypes.string,
276 | borderRadius: PropTypes.number,
277 | borderStyle: PropTypes.string,
278 | borderWidth: PropTypes.number,
279 | fontColor: PropTypes.string,
280 | fontFamily: PropTypes.string,
281 | fontSize: PropTypes.number,
282 | fontWeight: PropTypes.string,
283 | height: PropTypes.number,
284 | href: PropTypes.string.isRequired,
285 | text: PropTypes.string.isRequired,
286 | width: PropTypes.number
287 | };
288 |
289 | export default BulletproofButton;
290 | //# sourceMappingURL=index.es.js.map
291 |
--------------------------------------------------------------------------------
/dist/index.es.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.es.js","sources":["../node_modules/@babel/runtime/helpers/classCallCheck.js","../node_modules/@babel/runtime/helpers/createClass.js","../node_modules/@babel/runtime/helpers/typeof.js","../node_modules/@babel/runtime/helpers/assertThisInitialized.js","../node_modules/@babel/runtime/helpers/possibleConstructorReturn.js","../node_modules/@babel/runtime/helpers/getPrototypeOf.js","../node_modules/@babel/runtime/helpers/setPrototypeOf.js","../node_modules/@babel/runtime/helpers/inherits.js","../node_modules/@babel/runtime/helpers/defineProperty.js","../src/util.js","../src/index.js"],"sourcesContent":["function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nmodule.exports = _classCallCheck;","function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}\n\nmodule.exports = _createClass;","function _typeof2(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof2(obj); }\n\nfunction _typeof(obj) {\n if (typeof Symbol === \"function\" && _typeof2(Symbol.iterator) === \"symbol\") {\n module.exports = _typeof = function _typeof(obj) {\n return _typeof2(obj);\n };\n } else {\n module.exports = _typeof = function _typeof(obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : _typeof2(obj);\n };\n }\n\n return _typeof(obj);\n}\n\nmodule.exports = _typeof;","function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}\n\nmodule.exports = _assertThisInitialized;","var _typeof = require(\"../helpers/typeof\");\n\nvar assertThisInitialized = require(\"./assertThisInitialized\");\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n }\n\n return assertThisInitialized(self);\n}\n\nmodule.exports = _possibleConstructorReturn;","function _getPrototypeOf(o) {\n module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}\n\nmodule.exports = _getPrototypeOf;","function _setPrototypeOf(o, p) {\n module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}\n\nmodule.exports = _setPrototypeOf;","var setPrototypeOf = require(\"./setPrototypeOf\");\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}\n\nmodule.exports = _inherits;","function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nmodule.exports = _defineProperty;","export const hashToStyles = (styleHash) => {\n let result = '';\n\n const keys = Object.keys(styleHash);\n\n for (let key of keys) {\n if (result) {\n result += '; ';\n }\n\n result += key + ': ' + styleHash[key];\n }\n\n return result;\n};\n\nexport const toPx = (value) => {\n if (!value) { return '0'; }\n if (typeof(value) === 'string' && value.endsWith('px')) { return value; }\n\n return `${value}px`;\n};\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { hashToStyles, toPx } from './util';\n\nexport default class BulletproofButton extends Component {\n render() {\n const vmlButton = this.renderVmlButton();\n const htmlButton = this.renderHtmlButton();\n\n return (\n
\n );\n }\n\n renderVmlButton() {\n const vmlRectStyles = this.calculateVmlRectStyles();\n const vmlCenterStyles = this.calculateVmlCenterStyles();\n const vmlArcSize = this.calculateVmlArcSize();\n\n return `\n \n `;\n }\n\n calculateVmlRectStyles() {\n return hashToStyles({\n 'height': toPx(this.props.height),\n 'v-text-anchor': 'middle',\n 'width': toPx(this.props.width)\n });\n }\n\n calculateVmlCenterStyles() {\n return hashToStyles({\n 'color': this.props.fontColor,\n 'font-family': this.props.fontFamily,\n 'font-size': toPx(this.props.fontSize),\n 'font-weight': this.props.fontWeight\n });\n }\n\n calculateVmlArcSize = () => {\n return Math.round((this.props.borderRadius / this.props.width) * 100).toString() + '%';\n }\n\n renderHtmlButton() {\n const htmlLinkStyles = this.calculateHtmlLinkStyles();\n return `\n \n ${this.props.text}\n \n `;\n }\n\n calculateHtmlLinkStyles() {\n return hashToStyles({\n 'background-color': this.props.backgroundColor,\n 'border-color': this.props.borderColor,\n 'border-style': this.props.borderStyle,\n 'border-width': toPx(this.props.borderWidth),\n 'border-radius': toPx(this.props.borderRadius),\n 'color': this.props.fontColor,\n 'display': 'inline-block',\n 'font-family': this.props.fontFamily,\n 'font-size': toPx(this.props.fontSize),\n 'font-weight': this.props.fontWeight,\n 'height': toPx(this.props.height),\n 'line-height': toPx(this.props.height),\n 'mso-hide': 'all',\n 'text-align': 'center',\n 'text-decoration': 'none',\n 'width': toPx(this.props.width),\n '-webkit-text-size-adjust': 'none'\n });\n }\n}\n\nBulletproofButton.defaultProps = {\n backgroundColor: '#556270',\n borderColor: '#1e3650',\n borderRadius: 4,\n borderStyle: 'solid',\n borderWidth: 1,\n fontFamily: 'sans-serif',\n fontSize: 13,\n fontWeight: 'bold',\n fontColor: '#fff',\n height: 40,\n width: 200\n};\n\nBulletproofButton.propTypes = {\n backgroundColor: PropTypes.string,\n borderColor: PropTypes.string,\n borderRadius: PropTypes.number,\n borderStyle: PropTypes.string,\n borderWidth: PropTypes.number,\n fontColor: PropTypes.string,\n fontFamily: PropTypes.string,\n fontSize: PropTypes.number,\n fontWeight: PropTypes.string,\n height: PropTypes.number,\n href: PropTypes.string.isRequired,\n text: PropTypes.string.isRequired,\n width: PropTypes.number\n};\n"],"names":["_typeof","hashToStyles","styleHash","result","keys","Object","key","toPx","value","endsWith","BulletproofButton","Math","round","props","borderRadius","width","toString","vmlButton","renderVmlButton","htmlButton","renderHtmlButton","__html","vmlRectStyles","calculateVmlRectStyles","vmlCenterStyles","calculateVmlCenterStyles","vmlArcSize","calculateVmlArcSize","href","borderColor","backgroundColor","text","height","fontColor","fontFamily","fontSize","fontWeight","htmlLinkStyles","calculateHtmlLinkStyles","borderStyle","borderWidth","Component","defaultProps","propTypes","PropTypes","string","number","isRequired"],"mappings":"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"}
--------------------------------------------------------------------------------
/dist/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4 |
5 | var React = require('react');
6 | var React__default = _interopDefault(React);
7 | var PropTypes = _interopDefault(require('prop-types'));
8 |
9 | function _classCallCheck(instance, Constructor) {
10 | if (!(instance instanceof Constructor)) {
11 | throw new TypeError("Cannot call a class as a function");
12 | }
13 | }
14 |
15 | var classCallCheck = _classCallCheck;
16 |
17 | function _defineProperties(target, props) {
18 | for (var i = 0; i < props.length; i++) {
19 | var descriptor = props[i];
20 | descriptor.enumerable = descriptor.enumerable || false;
21 | descriptor.configurable = true;
22 | if ("value" in descriptor) descriptor.writable = true;
23 | Object.defineProperty(target, descriptor.key, descriptor);
24 | }
25 | }
26 |
27 | function _createClass(Constructor, protoProps, staticProps) {
28 | if (protoProps) _defineProperties(Constructor.prototype, protoProps);
29 | if (staticProps) _defineProperties(Constructor, staticProps);
30 | return Constructor;
31 | }
32 |
33 | var createClass = _createClass;
34 |
35 | function createCommonjsModule(fn, module) {
36 | return module = { exports: {} }, fn(module, module.exports), module.exports;
37 | }
38 |
39 | var _typeof_1 = createCommonjsModule(function (module) {
40 | function _typeof2(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); }
41 |
42 | function _typeof(obj) {
43 | if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
44 | module.exports = _typeof = function _typeof(obj) {
45 | return _typeof2(obj);
46 | };
47 | } else {
48 | module.exports = _typeof = function _typeof(obj) {
49 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
50 | };
51 | }
52 |
53 | return _typeof(obj);
54 | }
55 |
56 | module.exports = _typeof;
57 | });
58 |
59 | function _assertThisInitialized(self) {
60 | if (self === void 0) {
61 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
62 | }
63 |
64 | return self;
65 | }
66 |
67 | var assertThisInitialized = _assertThisInitialized;
68 |
69 | function _possibleConstructorReturn(self, call) {
70 | if (call && (_typeof_1(call) === "object" || typeof call === "function")) {
71 | return call;
72 | }
73 |
74 | return assertThisInitialized(self);
75 | }
76 |
77 | var possibleConstructorReturn = _possibleConstructorReturn;
78 |
79 | var getPrototypeOf = createCommonjsModule(function (module) {
80 | function _getPrototypeOf(o) {
81 | module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
82 | return o.__proto__ || Object.getPrototypeOf(o);
83 | };
84 | return _getPrototypeOf(o);
85 | }
86 |
87 | module.exports = _getPrototypeOf;
88 | });
89 |
90 | var setPrototypeOf = createCommonjsModule(function (module) {
91 | function _setPrototypeOf(o, p) {
92 | module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
93 | o.__proto__ = p;
94 | return o;
95 | };
96 |
97 | return _setPrototypeOf(o, p);
98 | }
99 |
100 | module.exports = _setPrototypeOf;
101 | });
102 |
103 | function _inherits(subClass, superClass) {
104 | if (typeof superClass !== "function" && superClass !== null) {
105 | throw new TypeError("Super expression must either be null or a function");
106 | }
107 |
108 | subClass.prototype = Object.create(superClass && superClass.prototype, {
109 | constructor: {
110 | value: subClass,
111 | writable: true,
112 | configurable: true
113 | }
114 | });
115 | if (superClass) setPrototypeOf(subClass, superClass);
116 | }
117 |
118 | var inherits = _inherits;
119 |
120 | function _defineProperty(obj, key, value) {
121 | if (key in obj) {
122 | Object.defineProperty(obj, key, {
123 | value: value,
124 | enumerable: true,
125 | configurable: true,
126 | writable: true
127 | });
128 | } else {
129 | obj[key] = value;
130 | }
131 |
132 | return obj;
133 | }
134 |
135 | var defineProperty = _defineProperty;
136 |
137 | var hashToStyles = function hashToStyles(styleHash) {
138 | var result = '';
139 | var keys = Object.keys(styleHash);
140 |
141 | for (var _i = 0; _i < keys.length; _i++) {
142 | var key = keys[_i];
143 |
144 | if (result) {
145 | result += '; ';
146 | }
147 |
148 | result += key + ': ' + styleHash[key];
149 | }
150 |
151 | return result;
152 | };
153 | var toPx = function toPx(value) {
154 | if (!value) {
155 | return '0';
156 | }
157 |
158 | if (typeof value === 'string' && value.endsWith('px')) {
159 | return value;
160 | }
161 |
162 | return "".concat(value, "px");
163 | };
164 |
165 | var BulletproofButton =
166 | /*#__PURE__*/
167 | function (_Component) {
168 | inherits(BulletproofButton, _Component);
169 |
170 | function BulletproofButton() {
171 | var _getPrototypeOf2;
172 |
173 | var _this;
174 |
175 | classCallCheck(this, BulletproofButton);
176 |
177 | for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
178 | args[_key] = arguments[_key];
179 | }
180 |
181 | _this = possibleConstructorReturn(this, (_getPrototypeOf2 = getPrototypeOf(BulletproofButton)).call.apply(_getPrototypeOf2, [this].concat(args)));
182 |
183 | defineProperty(assertThisInitialized(assertThisInitialized(_this)), "calculateVmlArcSize", function () {
184 | return Math.round(_this.props.borderRadius / _this.props.width * 100).toString() + '%';
185 | });
186 |
187 | return _this;
188 | }
189 |
190 | createClass(BulletproofButton, [{
191 | key: "render",
192 | value: function render() {
193 | var vmlButton = this.renderVmlButton();
194 | var htmlButton = this.renderHtmlButton();
195 | return React__default.createElement("div", null, React__default.createElement("div", {
196 | dangerouslySetInnerHTML: {
197 | __html: vmlButton
198 | }
199 | }), React__default.createElement("div", {
200 | dangerouslySetInnerHTML: {
201 | __html: htmlButton
202 | }
203 | }));
204 | }
205 | }, {
206 | key: "renderVmlButton",
207 | value: function renderVmlButton() {
208 | var vmlRectStyles = this.calculateVmlRectStyles();
209 | var vmlCenterStyles = this.calculateVmlCenterStyles();
210 | var vmlArcSize = this.calculateVmlArcSize();
211 | return "\n \n ");
212 | }
213 | }, {
214 | key: "calculateVmlRectStyles",
215 | value: function calculateVmlRectStyles() {
216 | return hashToStyles({
217 | 'height': toPx(this.props.height),
218 | 'v-text-anchor': 'middle',
219 | 'width': toPx(this.props.width)
220 | });
221 | }
222 | }, {
223 | key: "calculateVmlCenterStyles",
224 | value: function calculateVmlCenterStyles() {
225 | return hashToStyles({
226 | 'color': this.props.fontColor,
227 | 'font-family': this.props.fontFamily,
228 | 'font-size': toPx(this.props.fontSize),
229 | 'font-weight': this.props.fontWeight
230 | });
231 | }
232 | }, {
233 | key: "renderHtmlButton",
234 | value: function renderHtmlButton() {
235 | var htmlLinkStyles = this.calculateHtmlLinkStyles();
236 | return "\n \n ").concat(this.props.text, "\n \n ");
237 | }
238 | }, {
239 | key: "calculateHtmlLinkStyles",
240 | value: function calculateHtmlLinkStyles() {
241 | return hashToStyles({
242 | 'background-color': this.props.backgroundColor,
243 | 'border-color': this.props.borderColor,
244 | 'border-style': this.props.borderStyle,
245 | 'border-width': toPx(this.props.borderWidth),
246 | 'border-radius': toPx(this.props.borderRadius),
247 | 'color': this.props.fontColor,
248 | 'display': 'inline-block',
249 | 'font-family': this.props.fontFamily,
250 | 'font-size': toPx(this.props.fontSize),
251 | 'font-weight': this.props.fontWeight,
252 | 'height': toPx(this.props.height),
253 | 'line-height': toPx(this.props.height),
254 | 'mso-hide': 'all',
255 | 'text-align': 'center',
256 | 'text-decoration': 'none',
257 | 'width': toPx(this.props.width),
258 | '-webkit-text-size-adjust': 'none'
259 | });
260 | }
261 | }]);
262 |
263 | return BulletproofButton;
264 | }(React.Component);
265 | BulletproofButton.defaultProps = {
266 | backgroundColor: '#556270',
267 | borderColor: '#1e3650',
268 | borderRadius: 4,
269 | borderStyle: 'solid',
270 | borderWidth: 1,
271 | fontFamily: 'sans-serif',
272 | fontSize: 13,
273 | fontWeight: 'bold',
274 | fontColor: '#fff',
275 | height: 40,
276 | width: 200
277 | };
278 | BulletproofButton.propTypes = {
279 | backgroundColor: PropTypes.string,
280 | borderColor: PropTypes.string,
281 | borderRadius: PropTypes.number,
282 | borderStyle: PropTypes.string,
283 | borderWidth: PropTypes.number,
284 | fontColor: PropTypes.string,
285 | fontFamily: PropTypes.string,
286 | fontSize: PropTypes.number,
287 | fontWeight: PropTypes.string,
288 | height: PropTypes.number,
289 | href: PropTypes.string.isRequired,
290 | text: PropTypes.string.isRequired,
291 | width: PropTypes.number
292 | };
293 |
294 | module.exports = BulletproofButton;
295 | //# sourceMappingURL=index.js.map
296 |
--------------------------------------------------------------------------------
/dist/index.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.js","sources":["../node_modules/@babel/runtime/helpers/classCallCheck.js","../node_modules/@babel/runtime/helpers/createClass.js","../node_modules/@babel/runtime/helpers/typeof.js","../node_modules/@babel/runtime/helpers/assertThisInitialized.js","../node_modules/@babel/runtime/helpers/possibleConstructorReturn.js","../node_modules/@babel/runtime/helpers/getPrototypeOf.js","../node_modules/@babel/runtime/helpers/setPrototypeOf.js","../node_modules/@babel/runtime/helpers/inherits.js","../node_modules/@babel/runtime/helpers/defineProperty.js","../src/util.js","../src/index.js"],"sourcesContent":["function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nmodule.exports = _classCallCheck;","function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}\n\nmodule.exports = _createClass;","function _typeof2(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof2(obj); }\n\nfunction _typeof(obj) {\n if (typeof Symbol === \"function\" && _typeof2(Symbol.iterator) === \"symbol\") {\n module.exports = _typeof = function _typeof(obj) {\n return _typeof2(obj);\n };\n } else {\n module.exports = _typeof = function _typeof(obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : _typeof2(obj);\n };\n }\n\n return _typeof(obj);\n}\n\nmodule.exports = _typeof;","function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}\n\nmodule.exports = _assertThisInitialized;","var _typeof = require(\"../helpers/typeof\");\n\nvar assertThisInitialized = require(\"./assertThisInitialized\");\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n }\n\n return assertThisInitialized(self);\n}\n\nmodule.exports = _possibleConstructorReturn;","function _getPrototypeOf(o) {\n module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}\n\nmodule.exports = _getPrototypeOf;","function _setPrototypeOf(o, p) {\n module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}\n\nmodule.exports = _setPrototypeOf;","var setPrototypeOf = require(\"./setPrototypeOf\");\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}\n\nmodule.exports = _inherits;","function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nmodule.exports = _defineProperty;","export const hashToStyles = (styleHash) => {\n let result = '';\n\n const keys = Object.keys(styleHash);\n\n for (let key of keys) {\n if (result) {\n result += '; ';\n }\n\n result += key + ': ' + styleHash[key];\n }\n\n return result;\n};\n\nexport const toPx = (value) => {\n if (!value) { return '0'; }\n if (typeof(value) === 'string' && value.endsWith('px')) { return value; }\n\n return `${value}px`;\n};\n","import React, { Component } from 'react';\nimport PropTypes from 'prop-types';\nimport { hashToStyles, toPx } from './util';\n\nexport default class BulletproofButton extends Component {\n render() {\n const vmlButton = this.renderVmlButton();\n const htmlButton = this.renderHtmlButton();\n\n return (\n \n );\n }\n\n renderVmlButton() {\n const vmlRectStyles = this.calculateVmlRectStyles();\n const vmlCenterStyles = this.calculateVmlCenterStyles();\n const vmlArcSize = this.calculateVmlArcSize();\n\n return `\n \n `;\n }\n\n calculateVmlRectStyles() {\n return hashToStyles({\n 'height': toPx(this.props.height),\n 'v-text-anchor': 'middle',\n 'width': toPx(this.props.width)\n });\n }\n\n calculateVmlCenterStyles() {\n return hashToStyles({\n 'color': this.props.fontColor,\n 'font-family': this.props.fontFamily,\n 'font-size': toPx(this.props.fontSize),\n 'font-weight': this.props.fontWeight\n });\n }\n\n calculateVmlArcSize = () => {\n return Math.round((this.props.borderRadius / this.props.width) * 100).toString() + '%';\n }\n\n renderHtmlButton() {\n const htmlLinkStyles = this.calculateHtmlLinkStyles();\n return `\n \n ${this.props.text}\n \n `;\n }\n\n calculateHtmlLinkStyles() {\n return hashToStyles({\n 'background-color': this.props.backgroundColor,\n 'border-color': this.props.borderColor,\n 'border-style': this.props.borderStyle,\n 'border-width': toPx(this.props.borderWidth),\n 'border-radius': toPx(this.props.borderRadius),\n 'color': this.props.fontColor,\n 'display': 'inline-block',\n 'font-family': this.props.fontFamily,\n 'font-size': toPx(this.props.fontSize),\n 'font-weight': this.props.fontWeight,\n 'height': toPx(this.props.height),\n 'line-height': toPx(this.props.height),\n 'mso-hide': 'all',\n 'text-align': 'center',\n 'text-decoration': 'none',\n 'width': toPx(this.props.width),\n '-webkit-text-size-adjust': 'none'\n });\n }\n}\n\nBulletproofButton.defaultProps = {\n backgroundColor: '#556270',\n borderColor: '#1e3650',\n borderRadius: 4,\n borderStyle: 'solid',\n borderWidth: 1,\n fontFamily: 'sans-serif',\n fontSize: 13,\n fontWeight: 'bold',\n fontColor: '#fff',\n height: 40,\n width: 200\n};\n\nBulletproofButton.propTypes = {\n backgroundColor: PropTypes.string,\n borderColor: PropTypes.string,\n borderRadius: PropTypes.number,\n borderStyle: PropTypes.string,\n borderWidth: PropTypes.number,\n fontColor: PropTypes.string,\n fontFamily: PropTypes.string,\n fontSize: PropTypes.number,\n fontWeight: PropTypes.string,\n height: PropTypes.number,\n href: PropTypes.string.isRequired,\n text: PropTypes.string.isRequired,\n width: PropTypes.number\n};\n"],"names":["_typeof","hashToStyles","styleHash","result","keys","Object","key","toPx","value","endsWith","BulletproofButton","Math","round","props","borderRadius","width","toString","vmlButton","renderVmlButton","htmlButton","renderHtmlButton","React","__html","vmlRectStyles","calculateVmlRectStyles","vmlCenterStyles","calculateVmlCenterStyles","vmlArcSize","calculateVmlArcSize","href","borderColor","backgroundColor","text","height","fontColor","fontFamily","fontSize","fontWeight","htmlLinkStyles","calculateHtmlLinkStyles","borderStyle","borderWidth","Component","defaultProps","propTypes","PropTypes","string","number","isRequired"],"mappings":"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"}
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-bulletproof-button",
3 | "version": "1.0.4",
4 | "description": "React component that creates styled <a> bulletproof email buttons that are compatible with a large list of email clients.",
5 | "author": "jacksontrieu",
6 | "license": "MIT",
7 | "repository": "jacksontrieu/react-bulletproof-button",
8 | "main": "dist/index.js",
9 | "module": "dist/index.es.js",
10 | "jsnext:main": "dist/index.es.js",
11 | "engines": {
12 | "node": ">=8",
13 | "npm": ">=5"
14 | },
15 | "scripts": {
16 | "test": "jest",
17 | "coverage": "jest --coverage",
18 | "test:watch": "react-scripts test --env=jsdom",
19 | "build": "rollup -c",
20 | "start": "rollup -c -w",
21 | "prepare": "yarn run build"
22 | },
23 | "peerDependencies": {
24 | "prop-types": "^15.5.4",
25 | "react": "^15.0.0 || ^16.0.0",
26 | "react-dom": "^15.0.0 || ^16.0.0"
27 | },
28 | "devDependencies": {
29 | "@babel/core": "^7.2.2",
30 | "@babel/plugin-external-helpers": "^7.2.0",
31 | "@babel/plugin-proposal-class-properties": "^7.3.0",
32 | "@babel/plugin-transform-runtime": "^7.2.0",
33 | "@babel/preset-env": "^7.3.1",
34 | "@babel/preset-es2015": "^7.0.0-beta.53",
35 | "@babel/preset-es2016": "^7.0.0-beta.53",
36 | "@babel/preset-react": "^7.0.0",
37 | "@babel/preset-stage-0": "^7.0.0",
38 | "@babel/runtime": "^7.3.1",
39 | "@svgr/rollup": "^2.4.1",
40 | "babel-eslint": "^8.2.6",
41 | "cross-env": "^5.1.4",
42 | "eslint": "^5.0.1",
43 | "eslint-config-standard": "^11.0.0",
44 | "eslint-config-standard-react": "^6.0.0",
45 | "eslint-plugin-import": "^2.13.0",
46 | "eslint-plugin-node": "^7.0.1",
47 | "eslint-plugin-promise": "^4.0.0",
48 | "eslint-plugin-react": "^7.10.0",
49 | "eslint-plugin-standard": "^3.1.0",
50 | "gh-pages": "^1.2.0",
51 | "jest": "^24.0.0",
52 | "jest-dom": "^3.0.1",
53 | "react": "^16.4.1",
54 | "react-dom": "^16.4.1",
55 | "react-scripts": "^2.1.3",
56 | "react-test-renderer": "^16.7.0",
57 | "react-testing-library": "^5.4.4",
58 | "rollup": "^0.64.1",
59 | "rollup-plugin-babel": "^4.3.2",
60 | "rollup-plugin-commonjs": "^9.1.3",
61 | "rollup-plugin-node-resolve": "^3.3.0",
62 | "rollup-plugin-peer-deps-external": "^2.2.0",
63 | "rollup-plugin-postcss": "^1.6.2",
64 | "rollup-plugin-url": "^1.4.0"
65 | },
66 | "files": [
67 | "dist"
68 | ],
69 | "keywords": [
70 | "react",
71 | "email",
72 | "reactjs",
73 | "react-components",
74 | "bulletproof-button",
75 | "email-template",
76 | "email-boilerplate",
77 | "email-button",
78 | "bulletproof",
79 | "email-css",
80 | "vml"
81 | ]
82 | }
83 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel'
2 | import commonjs from 'rollup-plugin-commonjs'
3 | import external from 'rollup-plugin-peer-deps-external'
4 | import postcss from 'rollup-plugin-postcss'
5 | import resolve from 'rollup-plugin-node-resolve'
6 | import url from 'rollup-plugin-url'
7 | import svgr from '@svgr/rollup'
8 |
9 | import pkg from './package.json'
10 |
11 | export default {
12 | input: 'src/index.js',
13 | output: [
14 | {
15 | file: pkg.main,
16 | format: 'cjs',
17 | sourcemap: true
18 | },
19 | {
20 | file: pkg.module,
21 | format: 'es',
22 | sourcemap: true
23 | }
24 | ],
25 | plugins: [
26 | external(),
27 | postcss({
28 | modules: true
29 | }),
30 | url(),
31 | svgr(),
32 | babel({
33 | exclude: 'node_modules/**',
34 | runtimeHelpers: true
35 | }),
36 | resolve(),
37 | commonjs()
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/screenshots/react-bulletproof-button-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacksontrieu/react-bulletproof-button/560022650729c6c40323b16b9e8b71d7ef83aa2f/screenshots/react-bulletproof-button-2.png
--------------------------------------------------------------------------------
/screenshots/react-bulletproof-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jacksontrieu/react-bulletproof-button/560022650729c6c40323b16b9e8b71d7ef83aa2f/screenshots/react-bulletproof-button.png
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import PropTypes from 'prop-types';
3 | import { hashToStyles, toPx } from './util';
4 |
5 | export default class BulletproofButton extends Component {
6 | render() {
7 | const vmlButton = this.renderVmlButton();
8 | const htmlButton = this.renderHtmlButton();
9 |
10 | return (
11 |
15 | );
16 | }
17 |
18 | renderVmlButton() {
19 | const vmlRectStyles = this.calculateVmlRectStyles();
20 | const vmlCenterStyles = this.calculateVmlCenterStyles();
21 | const vmlArcSize = this.calculateVmlArcSize();
22 |
23 | return `
24 |
38 | `;
39 | }
40 |
41 | calculateVmlRectStyles() {
42 | return hashToStyles({
43 | 'height': toPx(this.props.height),
44 | 'v-text-anchor': 'middle',
45 | 'width': toPx(this.props.width)
46 | });
47 | }
48 |
49 | calculateVmlCenterStyles() {
50 | return hashToStyles({
51 | 'color': this.props.fontColor,
52 | 'font-family': this.props.fontFamily,
53 | 'font-size': toPx(this.props.fontSize),
54 | 'font-weight': this.props.fontWeight
55 | });
56 | }
57 |
58 | calculateVmlArcSize = () => {
59 | return Math.round((this.props.borderRadius / this.props.width) * 100).toString() + '%';
60 | }
61 |
62 | renderHtmlButton() {
63 | const htmlLinkStyles = this.calculateHtmlLinkStyles();
64 | return `
65 |
68 | ${this.props.text}
69 |
70 | `;
71 | }
72 |
73 | calculateHtmlLinkStyles() {
74 | return hashToStyles({
75 | 'background-color': this.props.backgroundColor,
76 | 'border-color': this.props.borderColor,
77 | 'border-style': this.props.borderStyle,
78 | 'border-width': toPx(this.props.borderWidth),
79 | 'border-radius': toPx(this.props.borderRadius),
80 | 'color': this.props.fontColor,
81 | 'display': 'inline-block',
82 | 'font-family': this.props.fontFamily,
83 | 'font-size': toPx(this.props.fontSize),
84 | 'font-weight': this.props.fontWeight,
85 | 'height': toPx(this.props.height),
86 | 'line-height': toPx(this.props.height),
87 | 'mso-hide': 'all',
88 | 'text-align': 'center',
89 | 'text-decoration': 'none',
90 | 'width': toPx(this.props.width),
91 | '-webkit-text-size-adjust': 'none'
92 | });
93 | }
94 | }
95 |
96 | BulletproofButton.defaultProps = {
97 | backgroundColor: '#556270',
98 | borderColor: '#1e3650',
99 | borderRadius: 4,
100 | borderStyle: 'solid',
101 | borderWidth: 1,
102 | fontFamily: 'sans-serif',
103 | fontSize: 13,
104 | fontWeight: 'bold',
105 | fontColor: '#fff',
106 | height: 40,
107 | width: 200
108 | };
109 |
110 | BulletproofButton.propTypes = {
111 | backgroundColor: PropTypes.string,
112 | borderColor: PropTypes.string,
113 | borderRadius: PropTypes.number,
114 | borderStyle: PropTypes.string,
115 | borderWidth: PropTypes.number,
116 | fontColor: PropTypes.string,
117 | fontFamily: PropTypes.string,
118 | fontSize: PropTypes.number,
119 | fontWeight: PropTypes.string,
120 | height: PropTypes.number,
121 | href: PropTypes.string.isRequired,
122 | text: PropTypes.string.isRequired,
123 | width: PropTypes.number
124 | };
125 |
--------------------------------------------------------------------------------
/src/util.js:
--------------------------------------------------------------------------------
1 | export const hashToStyles = (styleHash) => {
2 | let result = '';
3 |
4 | const keys = Object.keys(styleHash);
5 |
6 | for (let key of keys) {
7 | if (result) {
8 | result += '; ';
9 | }
10 |
11 | result += key + ': ' + styleHash[key];
12 | }
13 |
14 | return result;
15 | };
16 |
17 | export const toPx = (value) => {
18 | if (!value) { return '0'; }
19 | if (typeof(value) === 'string' && value.endsWith('px')) { return value; }
20 |
21 | return `${value}px`;
22 | };
23 |
--------------------------------------------------------------------------------