@rebilly/instruments 1.0.2-beta.1 → 1.0.2-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. package/.babelrc +13 -4
  2. package/.eslintrc.js +27 -0
  3. package/.prettierrc.js +11 -0
  4. package/CONTRIBUTING.md +4 -0
  5. package/README.md +350 -0
  6. package/dist/events/base-event.js +40 -11
  7. package/dist/events/events.spec.js +18 -0
  8. package/dist/events/index.js +10 -7
  9. package/dist/functions/destroy.js +27 -5
  10. package/dist/functions/destroy.spec.js +69 -0
  11. package/dist/functions/initialize.js +24 -20
  12. package/dist/functions/initialize.spec.js +4 -4
  13. package/dist/functions/mount/fetch-summary-data.js +26 -11
  14. package/dist/functions/mount/fetch-summary-data.spec.js +15 -16
  15. package/dist/functions/mount/index.js +168 -106
  16. package/dist/functions/mount/mount.spec.js +14 -36
  17. package/dist/functions/on.js +25 -17
  18. package/dist/functions/on.spec.js +36 -18
  19. package/dist/functions/purchase.js +33 -74
  20. package/dist/functions/purchase.spec.js +17 -14
  21. package/dist/functions/show.js +31 -8
  22. package/dist/functions/show.spec.js +42 -17
  23. package/dist/functions/update.js +60 -4
  24. package/dist/functions/update.spec.js +100 -0
  25. package/dist/i18n/en.json +19 -0
  26. package/dist/i18n/es.json +19 -0
  27. package/dist/i18n/index.js +5 -0
  28. package/dist/index.js +67 -55
  29. package/dist/index.spec.js +6 -10
  30. package/dist/loader/index.js +24 -4
  31. package/dist/loader/loader.spec.js +4 -4
  32. package/dist/storefront/models/ready-to-pay-model.js +7 -1
  33. package/dist/storefront/plans.js +9 -10
  34. package/dist/storefront/plans.spec.js +20 -20
  35. package/dist/storefront/products.js +9 -10
  36. package/dist/storefront/products.spec.js +20 -20
  37. package/dist/storefront/purchase.js +9 -8
  38. package/dist/storefront/purchase.spec.js +7 -4
  39. package/dist/storefront/ready-to-pay.js +12 -11
  40. package/dist/storefront/ready-to-pay.spec.js +24 -19
  41. package/dist/storefront/storefront.spec.js +1 -1
  42. package/dist/storefront/summary.js +11 -12
  43. package/dist/storefront/summary.spec.js +25 -24
  44. package/dist/style/base/__snapshots__/theme.spec.js.snap +52 -0
  45. package/dist/style/base/index.js +72 -0
  46. package/dist/style/base/theme.js +73 -0
  47. package/dist/style/base/theme.spec.js +30 -0
  48. package/dist/style/browserslist.js +8 -0
  49. package/dist/style/components/address.js +64 -0
  50. package/dist/style/components/button.js +61 -0
  51. package/dist/style/components/divider.js +48 -0
  52. package/dist/style/components/forms/checkbox.js +83 -0
  53. package/dist/style/components/forms/field.js +53 -0
  54. package/dist/style/components/forms/form.js +28 -0
  55. package/dist/style/components/forms/input.js +45 -0
  56. package/dist/style/components/forms/label.js +43 -0
  57. package/dist/style/components/forms/select.js +63 -0
  58. package/dist/style/components/forms/validation.js +34 -0
  59. package/dist/style/components/icons.js +22 -0
  60. package/dist/style/components/index.js +57 -0
  61. package/dist/style/components/loader.js +48 -0
  62. package/dist/style/components/methods.js +104 -0
  63. package/dist/style/components/overlay.js +33 -0
  64. package/dist/style/helpers/index.js +59 -0
  65. package/dist/style/index.js +48 -0
  66. package/dist/style/payment-instruments/content.js +17 -0
  67. package/dist/style/payment-instruments/index.js +20 -0
  68. package/dist/{styles → style/payment-instruments}/payment-card.js +14 -6
  69. package/dist/{styles/shade-tint-values-helper.js → style/utils/color-values.js} +5 -9
  70. package/dist/style/vendor/framepay.js +34 -0
  71. package/dist/style/vendor/postmate.js +17 -0
  72. package/dist/style/views/confirmation.js +85 -0
  73. package/dist/style/views/index.js +29 -0
  74. package/dist/style/views/method-selector.js +20 -0
  75. package/dist/style/views/modal.js +93 -0
  76. package/dist/style/views/result.js +61 -0
  77. package/dist/style/views/summary.js +123 -0
  78. package/dist/utils/format-currency.js +1 -0
  79. package/dist/utils/has-valid-css-selector.js +1 -1
  80. package/dist/utils/index.js +3 -19
  81. package/dist/utils/process-property-as-dom-element.js +0 -2
  82. package/dist/utils/sleep.js +10 -0
  83. package/{src/components → dist/views}/__snapshots__/summary.spec.js.snap +7 -3
  84. package/dist/views/common/iframe/base-iframe.js +57 -0
  85. package/dist/views/common/iframe/event-listeners.js +50 -0
  86. package/dist/views/common/iframe/index.js +19 -0
  87. package/dist/views/common/iframe/method-iframe.js +33 -0
  88. package/dist/views/common/iframe/modal-iframe.js +38 -0
  89. package/dist/views/common/iframe/view-iframe.js +31 -0
  90. package/dist/views/common/render-utilities.js +11 -0
  91. package/dist/views/confirmation.js +82 -0
  92. package/dist/views/method-selector/__snapshots__/method-selector.spec.js.snap +3 -0
  93. package/dist/views/method-selector/express-methods/apple-pay.js +92 -0
  94. package/dist/views/method-selector/express-methods/google-pay.js +32 -0
  95. package/dist/views/method-selector/express-methods/paypal.js +19 -0
  96. package/dist/views/method-selector/generate-digital-wallet.js +59 -0
  97. package/dist/views/method-selector/generate-digital-wallet.spec.js +132 -0
  98. package/dist/views/method-selector/get-method-data.js +25 -0
  99. package/dist/{components/form → views/method-selector}/get-payment-methods.js +22 -6
  100. package/dist/views/method-selector/get-payment-methods.spec.js +44 -0
  101. package/dist/views/method-selector/index.js +133 -0
  102. package/dist/views/method-selector/method-selector.spec.js +139 -0
  103. package/dist/views/method-selector/mount-express-methods.js +69 -0
  104. package/dist/views/method-selector/mount-methods.js +78 -0
  105. package/dist/views/modal.js +83 -0
  106. package/dist/views/result.js +42 -0
  107. package/dist/{components → views}/summary.js +36 -25
  108. package/dist/{components → views}/summary.spec.js +49 -22
  109. package/package.json +11 -5
  110. package/src/events/base-event.js +35 -12
  111. package/src/events/events.spec.js +11 -0
  112. package/src/events/index.js +12 -6
  113. package/src/functions/destroy.js +22 -3
  114. package/src/functions/destroy.spec.js +63 -0
  115. package/src/functions/initialize.js +23 -18
  116. package/src/functions/initialize.spec.js +9 -7
  117. package/src/functions/mount/fetch-summary-data.js +16 -13
  118. package/src/functions/mount/fetch-summary-data.spec.js +22 -27
  119. package/src/functions/mount/index.js +194 -133
  120. package/src/functions/mount/mount.spec.js +83 -84
  121. package/src/functions/on.js +17 -14
  122. package/src/functions/on.spec.js +39 -29
  123. package/src/functions/purchase.js +24 -64
  124. package/src/functions/purchase.spec.js +19 -17
  125. package/src/functions/show.js +26 -6
  126. package/src/functions/show.spec.js +41 -19
  127. package/src/functions/update.js +49 -3
  128. package/src/functions/update.spec.js +107 -0
  129. package/src/i18n/i18n.spec.js +6 -4
  130. package/src/i18n/index.js +19 -11
  131. package/src/index.js +42 -51
  132. package/src/index.spec.js +11 -20
  133. package/src/loader/index.js +55 -39
  134. package/src/loader/loader.spec.js +30 -23
  135. package/src/storefront/index.js +9 -7
  136. package/src/storefront/models/plan-model.js +1 -1
  137. package/src/storefront/models/product-model.js +1 -1
  138. package/src/storefront/models/ready-to-pay-model.js +10 -4
  139. package/src/storefront/models/summary-model.js +8 -15
  140. package/src/storefront/plans.js +16 -12
  141. package/src/storefront/plans.spec.js +29 -37
  142. package/src/storefront/products.js +16 -12
  143. package/src/storefront/products.spec.js +28 -39
  144. package/src/storefront/purchase.js +8 -6
  145. package/src/storefront/purchase.spec.js +18 -17
  146. package/src/storefront/ready-to-pay.js +19 -13
  147. package/src/storefront/ready-to-pay.spec.js +41 -41
  148. package/src/storefront/storefront.spec.js +1 -1
  149. package/src/storefront/summary.js +14 -12
  150. package/src/storefront/summary.spec.js +37 -50
  151. package/src/style/base/__snapshots__/theme.spec.js.snap +52 -0
  152. package/src/style/base/index.js +63 -0
  153. package/src/style/base/theme.js +61 -0
  154. package/src/style/base/theme.spec.js +32 -0
  155. package/src/style/browserslist.js +1 -0
  156. package/src/style/components/address.js +55 -0
  157. package/src/style/components/button.js +54 -0
  158. package/src/style/components/divider.js +39 -0
  159. package/src/style/components/forms/checkbox.js +76 -0
  160. package/src/style/components/forms/field.js +44 -0
  161. package/src/style/components/forms/form.js +19 -0
  162. package/src/style/components/forms/input.js +36 -0
  163. package/src/style/components/forms/label.js +34 -0
  164. package/src/style/components/forms/select.js +54 -0
  165. package/src/style/components/forms/validation.js +25 -0
  166. package/src/style/components/icons.js +13 -0
  167. package/src/style/components/index.js +35 -0
  168. package/src/style/components/loader.js +41 -0
  169. package/src/style/components/methods.js +93 -0
  170. package/src/style/components/overlay.js +24 -0
  171. package/src/style/helpers/index.js +51 -0
  172. package/src/style/index.js +30 -0
  173. package/src/style/payment-instruments/content.js +8 -0
  174. package/src/style/payment-instruments/index.js +10 -0
  175. package/src/style/payment-instruments/payment-card.js +26 -0
  176. package/src/style/utils/color-values.js +9 -0
  177. package/src/style/vendor/framepay.js +25 -0
  178. package/src/style/vendor/postmate.js +8 -0
  179. package/src/style/views/confirmation.js +76 -0
  180. package/src/style/views/index.js +16 -0
  181. package/src/style/views/method-selector.js +11 -0
  182. package/src/style/views/modal.js +84 -0
  183. package/src/style/views/result.js +52 -0
  184. package/src/style/views/summary.js +114 -0
  185. package/src/utils/add-dom-element.js +12 -13
  186. package/src/utils/format-currency.js +4 -1
  187. package/src/utils/has-valid-css-selector.js +2 -2
  188. package/src/utils/index.js +2 -6
  189. package/src/utils/is-dom-element.js +1 -1
  190. package/src/utils/process-property-as-dom-element.js +27 -24
  191. package/src/utils/sleep.js +3 -0
  192. package/src/views/__snapshots__/summary.spec.js.snap +292 -0
  193. package/src/views/common/iframe/base-iframe.js +46 -0
  194. package/src/views/common/iframe/event-listeners.js +27 -0
  195. package/src/views/common/iframe/index.js +7 -0
  196. package/src/views/common/iframe/method-iframe.js +21 -0
  197. package/src/views/common/iframe/modal-iframe.js +27 -0
  198. package/src/views/common/iframe/view-iframe.js +18 -0
  199. package/src/views/common/render-utilities.js +4 -0
  200. package/src/views/confirmation.js +57 -0
  201. package/src/views/method-selector/__snapshots__/method-selector.spec.js.snap +3 -0
  202. package/src/views/method-selector/express-methods/apple-pay.js +78 -0
  203. package/src/views/method-selector/express-methods/google-pay.js +25 -0
  204. package/src/views/method-selector/express-methods/paypal.js +7 -0
  205. package/src/views/method-selector/generate-digital-wallet.js +44 -0
  206. package/src/views/method-selector/generate-digital-wallet.spec.js +131 -0
  207. package/src/{components/form → views/method-selector}/get-method-data.js +9 -5
  208. package/src/views/method-selector/get-payment-methods.js +40 -0
  209. package/src/views/method-selector/get-payment-methods.spec.js +40 -0
  210. package/src/views/method-selector/index.js +110 -0
  211. package/src/views/method-selector/method-selector.spec.js +146 -0
  212. package/src/views/method-selector/mount-express-methods.js +53 -0
  213. package/src/views/method-selector/mount-methods.js +71 -0
  214. package/src/views/modal.js +84 -0
  215. package/src/views/result.js +30 -0
  216. package/src/{components → views}/summary.js +65 -33
  217. package/src/views/summary.spec.js +170 -0
  218. package/tests/async-utilities.js +22 -0
  219. package/tests/mocks/rebilly-instruments-mock.js +105 -7
  220. package/dist/components/confirmation.js +0 -113
  221. package/dist/components/form/form.js +0 -143
  222. package/dist/components/form/form.spec.js +0 -111
  223. package/dist/components/form/get-method-data.js +0 -21
  224. package/dist/components/form/method-selector.js +0 -60
  225. package/dist/components/form/mount-express-payment-methods.js +0 -102
  226. package/dist/components/form/process-digital-wallet-options.js +0 -24
  227. package/dist/components/form/zoid-helpers.js +0 -131
  228. package/dist/components/result.js +0 -68
  229. package/dist/events/instrument-ready.js +0 -24
  230. package/dist/events/purchase-complete.js +0 -24
  231. package/dist/styles/base-styles.js +0 -793
  232. package/dist/styles/flat-theme-object.js +0 -23
  233. package/dist/styles/framepay.js +0 -38
  234. package/dist/styles/main.js +0 -29
  235. package/dist/styles/style-variables.js +0 -44
  236. package/dist/utils/camel-case.js +0 -10
  237. package/dist/utils/kebab-case.js +0 -10
  238. package/dist/utils/un-kebab-case.js +0 -10
  239. package/src/components/confirmation.js +0 -81
  240. package/src/components/form/__snapshots__/form.spec.js.snap +0 -43
  241. package/src/components/form/form.js +0 -117
  242. package/src/components/form/form.spec.js +0 -109
  243. package/src/components/form/get-payment-methods.js +0 -32
  244. package/src/components/form/method-selector.js +0 -47
  245. package/src/components/form/mount-express-payment-methods.js +0 -84
  246. package/src/components/form/process-digital-wallet-options.js +0 -11
  247. package/src/components/form/zoid-helpers.js +0 -117
  248. package/src/components/result.js +0 -50
  249. package/src/components/summary.spec.js +0 -106
  250. package/src/events/instrument-ready.js +0 -11
  251. package/src/events/purchase-complete.js +0 -11
  252. package/src/styles/base-styles.js +0 -784
  253. package/src/styles/flat-theme-object.js +0 -12
  254. package/src/styles/framepay.js +0 -30
  255. package/src/styles/main.js +0 -17
  256. package/src/styles/payment-card.js +0 -18
  257. package/src/styles/shade-tint-values-helper.js +0 -13
  258. package/src/styles/style-variables.js +0 -34
  259. package/src/utils/camel-case.js +0 -3
  260. package/src/utils/kebab-case.js +0 -3
  261. package/src/utils/un-kebab-case.js +0 -3
@@ -2,27 +2,20 @@ import { MockStorefront } from 'tests/mocks/storefront-mock';
2
2
  import { ok, post } from 'msw-when-then';
3
3
  import { when } from 'tests/msw/server';
4
4
  import { storefrontURL } from 'tests/mocks/storefront-api-mock';
5
- import { FetchSummary } from './summary';
5
+ import { fetchSummary } from './summary';
6
6
  import SummaryModel from '@/storefront/models/summary-model';
7
+ import { expectConfigurationError } from 'tests/async-utilities';
7
8
 
8
9
  describe('Storefront API Summary', () => {
9
10
  class TestSummaryInstance {
10
- constructor({
11
- configs = {},
12
- options = {},
13
- storefront = null,
14
- } = {}) {
11
+ constructor({ configs = {}, options = {}, storefront = null } = {}) {
15
12
  this.configs = configs;
16
13
  this.options = options;
17
14
  this.storefront = storefront === null ? MockStorefront() : storefront;
18
15
  }
19
-
20
- fetchSummary(...args) {
21
- return FetchSummary.apply(this, args);
22
- }
23
16
  }
24
-
25
- it ('can fetch preview', async () => {
17
+
18
+ it('can fetch preview', async () => {
26
19
  const configs = {
27
20
  websiteId: 'test-website-id'
28
21
  };
@@ -42,7 +35,7 @@ describe('Storefront API Summary', () => {
42
35
  {
43
36
  description: 'test-plan-id-1',
44
37
  planId: 'test-plan-id-1',
45
- quantity: 1,
38
+ quantity: 1
46
39
  }
47
40
  ]
48
41
  };
@@ -51,26 +44,25 @@ describe('Storefront API Summary', () => {
51
44
 
52
45
  const instance = new TestSummaryInstance({
53
46
  configs,
54
- options,
47
+ options
55
48
  });
56
49
 
57
50
  jest.spyOn(instance.storefront.purchase, 'preview');
58
51
 
59
- const response = await instance.fetchSummary();
60
-
52
+ const response = await fetchSummary({ state: instance });
53
+
61
54
  expect(instance.storefront.purchase.preview).toBeCalledTimes(1);
62
55
  expect(instance.storefront.purchase.preview).toBeCalledWith({
63
56
  data: {
64
57
  items: options.intent.items,
65
- websiteId: configs.websiteId,
58
+ websiteId: configs.websiteId
66
59
  }
67
60
  });
68
61
  expect(response).toBeInstanceOf(SummaryModel);
69
62
  expect(response).toEqual(new SummaryModel(testSummary));
70
-
71
63
  });
72
64
 
73
- it ('Adds billing address to preview payload', async () => {
65
+ it('Adds billing address to preview payload', async () => {
74
66
  const configs = {
75
67
  websiteId: 'test-website-id'
76
68
  };
@@ -90,28 +82,29 @@ describe('Storefront API Summary', () => {
90
82
  };
91
83
  const instance = new TestSummaryInstance({
92
84
  configs,
93
- options,
85
+ options
94
86
  });
95
87
 
96
88
  jest.spyOn(instance.storefront.purchase, 'preview');
97
89
 
98
- await instance.fetchSummary({
90
+ await fetchSummary({
99
91
  data: {
100
- billingAddress,
101
- }
92
+ billingAddress
93
+ },
94
+ state: instance
102
95
  });
103
-
96
+
104
97
  expect(instance.storefront.purchase.preview).toBeCalledTimes(1);
105
98
  expect(instance.storefront.purchase.preview).toBeCalledWith({
106
99
  data: {
107
100
  items: options.intent.items,
108
101
  websiteId: configs.websiteId,
109
- billingAddress,
102
+ billingAddress
110
103
  }
111
104
  });
112
105
  });
113
106
 
114
- it ('Adds delivery address to preview payload', async () => {
107
+ it('Adds delivery address to preview payload', async () => {
115
108
  const configs = {
116
109
  websiteId: 'test-website-id'
117
110
  };
@@ -131,53 +124,47 @@ describe('Storefront API Summary', () => {
131
124
  };
132
125
  const instance = new TestSummaryInstance({
133
126
  configs,
134
- options,
127
+ options
135
128
  });
136
129
 
137
130
  jest.spyOn(instance.storefront.purchase, 'preview');
138
131
 
139
- await instance.fetchSummary({
132
+ await fetchSummary({
140
133
  data: {
141
- deliveryAddress,
142
- }
134
+ deliveryAddress
135
+ },
136
+ state: instance
143
137
  });
144
-
138
+
145
139
  expect(instance.storefront.purchase.preview).toBeCalledTimes(1);
146
140
  expect(instance.storefront.purchase.preview).toBeCalledWith({
147
141
  data: {
148
142
  items: options.intent.items,
149
143
  websiteId: configs.websiteId,
150
- deliveryAddress,
144
+ deliveryAddress
151
145
  }
152
146
  });
153
-
154
147
  });
155
148
 
156
- it ('should throw errors with no configs or options', () => {
157
- const NoConfigOrOptionsError = new Error('Could not use Rebilly Instruments configurations or mount options to fetch Rebilly data');
149
+ it('should throw errors with no configs or options', async () => {
158
150
  const noConfigOrOptionsInstance = new TestSummaryInstance({
159
151
  configs: null,
160
- options: null,
152
+ options: null
161
153
  });
154
+ await expectConfigurationError(
155
+ fetchSummary({ state: noConfigOrOptionsInstance })
156
+ );
157
+
162
158
  const noConfigInstance = new TestSummaryInstance({
163
159
  configs: null,
164
- options: {},
160
+ options: {}
165
161
  });
162
+ await expectConfigurationError(fetchSummary({ state: noConfigInstance }));
163
+
166
164
  const noOptionsInstance = new TestSummaryInstance({
167
165
  configs: {},
168
- options: null,
166
+ options: null
169
167
  });
170
-
171
- expect(async () => {
172
- await noConfigOrOptionsInstance.fetchSummary();
173
- }).rejects.toEqual(NoConfigOrOptionsError);
174
-
175
- expect(async () => {
176
- await noConfigInstance.fetchSummary();
177
- }).rejects.toEqual(NoConfigOrOptionsError);
178
-
179
- expect(async () => {
180
- await noOptionsInstance.fetchSummary();
181
- }).rejects.toEqual(NoConfigOrOptionsError);
168
+ await expectConfigurationError(fetchSummary({ state: noOptionsInstance }));
182
169
  });
183
170
  });
@@ -0,0 +1,52 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`RebillyInstruments theme builds the theme object 1`] = `
4
+ Object {
5
+ "borderRadius": "4px",
6
+ "color": Object {
7
+ "background": "#ffffff",
8
+ "buttonText": "#ffffff",
9
+ "errorText": "#cd5c5c",
10
+ "primary": "#0044d4",
11
+ "text": "#0D2B3E",
12
+ },
13
+ "getComputed": Object {
14
+ "color": Object {
15
+ "mutedBorder": "rgba(13, 43, 62, 0.25)",
16
+ "mutedText": "rgba(13, 43, 62, 0.6)",
17
+ "primaryValues": Values {
18
+ "alpha": 1,
19
+ "rgb": Array [
20
+ 0,
21
+ 68,
22
+ 212,
23
+ ],
24
+ "type": "base",
25
+ "weight": 0,
26
+ },
27
+ },
28
+ },
29
+ "space": Object {
30
+ "form": Object {
31
+ "horizontalPadding": "16px",
32
+ "minHeight": "44px",
33
+ "padding": "8px 16px",
34
+ "verticalPadding": "8px",
35
+ },
36
+ "l": "48px",
37
+ "m": "24px",
38
+ "s": "12px",
39
+ "xl": "96px",
40
+ "xs": "6px",
41
+ "xxl": "112px",
42
+ "xxs": "4px",
43
+ },
44
+ "typography": Object {
45
+ "captionFontSize": "12px",
46
+ "captionLineHeight": "12px",
47
+ "fontFamily": "Avenir, Helvetica, Arial, sans-serif",
48
+ "fontSize": "16px",
49
+ "lineHeight": "24px",
50
+ },
51
+ }
52
+ `;
@@ -0,0 +1,63 @@
1
+ export const base = (theme) => `
2
+ /* Base, Typography
3
+ ------------------------------------------------------------ */
4
+ /* Base setup for top level elements */
5
+ .rebilly-instruments-content,
6
+ .rebilly-instruments-method-content,
7
+ .rebilly-instruments-confirmation,
8
+ .rebilly-instruments-results {
9
+ color: ${theme.color.text};
10
+ background: ${theme.color.background};
11
+ font-size: ${theme.typography.fontSize};
12
+ line-height: ${theme.typography.lineHeight};
13
+ font-family: ${theme.typography.fontFamily};
14
+ -webkit-font-smoothing: antialiased;
15
+ -moz-osx-font-smoothing: grayscale;
16
+ text-align: left;
17
+ transition: all 200ms;
18
+ }
19
+
20
+ .rebilly-instruments-link {
21
+ color: ${theme.color.primary};
22
+ cursor: pointer;
23
+ }
24
+
25
+ .rebilly-instruments-link:hover {
26
+ text-decoration: none;
27
+ }
28
+
29
+ .rebilly-instruments-link .rebilly-instruments-icon {
30
+ fill: ${theme.color.primary};
31
+ }
32
+
33
+ .rebilly-instruments-link.has-icon-left,
34
+ .rebilly-instruments-link.has-icon-right {
35
+ display: inline-flex;
36
+ }
37
+
38
+ .rebilly-instruments-link.has-icon-left .rebilly-instruments-icon {
39
+ margin-right: ${theme.space.xs};
40
+ }
41
+
42
+ .rebilly-instruments-link.has-icon-right .rebilly-instruments-icon {
43
+ margin-left: ${theme.space.xs};
44
+ }
45
+
46
+ /* Typography */
47
+ .rebilly-instruments-h1,
48
+ .rebilly-instruments-h2 {
49
+ font-weight: 500;
50
+ }
51
+
52
+ .rebilly-instruments-h1 {
53
+ font-size: calc(${theme.typography.fontSize} * 1.5);
54
+ line-height: calc(${theme.typography.lineHeight} * 1.5);
55
+ margin: 0 0 calc(${theme.space.m} * 1.5) 0;
56
+ }
57
+
58
+ .rebilly-instruments-h2 {
59
+ font-size: calc(${theme.typography.fontSize} * 1.12);
60
+ line-height: ${theme.typography.lineHeight};
61
+ margin: 0 0 ${theme.space.m} 0;
62
+ }
63
+ `;
@@ -0,0 +1,61 @@
1
+ import merge from 'lodash.merge';
2
+ import { colorValues, alphaColor } from '../utils/color-values';
3
+
4
+ export class Theme {
5
+ constructor(overrides = {}) {
6
+ this.overrides = overrides;
7
+ this.theme = {
8
+ color: {
9
+ primary: '#0044d4',
10
+ errorText: '#cd5c5c',
11
+ text: '#0D2B3E',
12
+ buttonText: '#ffffff',
13
+ background: '#ffffff'
14
+ },
15
+ typography: {
16
+ fontFamily: 'Avenir, Helvetica, Arial, sans-serif',
17
+ fontSize: '16px',
18
+ lineHeight: '24px',
19
+ captionFontSize: '12px',
20
+ captionLineHeight: '12px'
21
+ },
22
+ space: {
23
+ xxs: '4px',
24
+ xs: '6px',
25
+ s: '12px',
26
+ m: '24px',
27
+ l: '48px',
28
+ xl: '96px',
29
+ xxl: '112px',
30
+ form: {
31
+ padding: '8px 16px',
32
+ verticalPadding: '8px',
33
+ horizontalPadding: '16px',
34
+ minHeight: '44px'
35
+ }
36
+ },
37
+ borderRadius: '4px'
38
+ };
39
+ }
40
+
41
+ get getComputed() {
42
+ return this.computed();
43
+ }
44
+
45
+ computed() {
46
+ return {
47
+ color: {
48
+ primaryValues: colorValues(this.theme.color.primary),
49
+ mutedText: alphaColor(this.theme.color.text, 0.6),
50
+ mutedBorder: alphaColor(this.theme.color.text, 0.25)
51
+ }
52
+ };
53
+ }
54
+
55
+ build() {
56
+ return {
57
+ ...merge(this.theme, this.overrides),
58
+ getComputed: this.getComputed
59
+ };
60
+ }
61
+ }
@@ -0,0 +1,32 @@
1
+ import { Theme } from './theme';
2
+ import Values from 'values.js';
3
+
4
+ describe('RebillyInstruments theme', () => {
5
+ it('builds the theme object', () => {
6
+ const theme = new Theme().build();
7
+
8
+ expect(theme).toMatchSnapshot();
9
+ });
10
+
11
+ it('properly overrides the default properties', () => {
12
+ const overrides = {
13
+ color: {
14
+ primary: 'purple',
15
+ text: 'gray'
16
+ }
17
+ };
18
+ const theme = new Theme(overrides).build();
19
+
20
+ expect(theme.color.primary).toEqual('purple');
21
+ expect(theme.color.text).toEqual('gray');
22
+ });
23
+
24
+ it('computes new styles from theme properties', () => {
25
+ const theme = new Theme().build();
26
+
27
+ expect(theme.getComputed.color.primaryValues instanceof Values).toEqual(
28
+ true
29
+ );
30
+ expect(theme.getComputed.color.mutedText).toEqual('rgba(13, 43, 62, 0.6)');
31
+ });
32
+ });
@@ -0,0 +1 @@
1
+ export const browserslist = ['> 1%', 'last 2 versions'];
@@ -0,0 +1,55 @@
1
+ // -----------------------------------------------------------------------------
2
+ // This file contains all styles related to the address component.
3
+ // -----------------------------------------------------------------------------
4
+ export const address = (theme) => `
5
+ /**
6
+ * Address
7
+ */
8
+ .rebilly-instruments-address {
9
+ margin: 0 0 ${theme.space.m};
10
+ color: ${theme.getComputed.color.mutedText};
11
+ font-style: normal;
12
+ }
13
+
14
+ /**
15
+ * Address Name: Default
16
+ */
17
+ .rebilly-instruments-address-name-default {
18
+ /* No style changes */
19
+ }
20
+
21
+ /**
22
+ * Address Name: Combined
23
+ */
24
+ .rebilly-instruments-address-name-combined {
25
+ /* No style changes */
26
+ }
27
+
28
+ /**
29
+ * Address Name: Stacked
30
+ */
31
+ .rebilly-instruments-address-name-stacked {
32
+ /* No style changes */
33
+ }
34
+
35
+ /**
36
+ * Address Region: Default
37
+ */
38
+ .rebilly-instruments-address-region-default {
39
+ /* No style changes */
40
+ }
41
+
42
+ /**
43
+ * Address Region: Split
44
+ */
45
+ .rebilly-instruments-address-region-split {
46
+ /* No style changes */
47
+ }
48
+
49
+ /**
50
+ * Address Name: Stacked
51
+ */
52
+ .rebilly-instruments-address-region-stacked {
53
+ /* No style changes */
54
+ }
55
+ `;
@@ -0,0 +1,54 @@
1
+ // -----------------------------------------------------------------------------
2
+ // This file contains all styles related to the button component.
3
+ // -----------------------------------------------------------------------------
4
+ export const button = (theme) => `
5
+ /**
6
+ * Buttons
7
+ */
8
+ .rebilly-instruments-button {
9
+ font-size: ${theme.typography.fontSize};
10
+ font-family: ${theme.typography.fontFamily};
11
+ line-height: ${theme.typography.lineHeight};
12
+ padding: ${theme.space.form.padding};
13
+ box-sizing: border-box;
14
+ background: ${theme.color.primary};
15
+ color: ${theme.color.buttonText};
16
+ border-radius: ${theme.borderRadius};
17
+ margin: calc(${theme.space.xxs} + ${theme.space.s} / 2) 0;
18
+ font-weight: 500;
19
+ border: none;
20
+ width: 100%;
21
+ cursor: pointer;
22
+ min-height: 44px;
23
+ transition: all 0.2s ease;
24
+ outline: none;
25
+ }
26
+
27
+ .rebilly-instruments-button:hover,
28
+ .rebilly-instruments-button:active {
29
+ background: ${theme.getComputed.color.primaryValues.shade(20).hexString()};
30
+ }
31
+
32
+ .rebilly-instruments-button.rebilly-instruments-button-secondary {
33
+ background: ${theme.color.background};
34
+ box-shadow: inset 0 0 0 1px ${theme.color.primary};
35
+ color: ${theme.color.primary};
36
+ }
37
+
38
+ .rebilly-instruments-button.rebilly-instruments-button-secondary:hover,
39
+ .rebilly-instruments-button.rebilly-instruments-button-secondary:active {
40
+ background: ${theme.color.background};
41
+ }
42
+
43
+ .rebilly-instruments-button:focus { box-shadow: 0 0 0 2px ${theme.getComputed.color.primaryValues
44
+ .tint(60)
45
+ .hexString()}; }
46
+
47
+ .rebilly-instruments-button:disabled { opacity: 0.6; }
48
+
49
+ .rebilly-instruments-button::first-letter { text-transform: uppercase; }
50
+
51
+ .rebilly-instruments-button:first-of-type { margin-top: 0; }
52
+
53
+ .rebilly-instruments-button:last-of-type { margin-bottom: 0; }
54
+ `;
@@ -0,0 +1,39 @@
1
+ // -----------------------------------------------------------------------------
2
+ // This file contains all styles related to the divider component.
3
+ // -----------------------------------------------------------------------------
4
+ export const divider = (theme) => `
5
+ /**
6
+ * Divider
7
+ */
8
+ .rebilly-instruments-divider {
9
+ line-height: ${theme.typography.lineHeight};
10
+ padding: ${theme.space.m} 0;
11
+ margin: 0;
12
+ position: relative;
13
+ outline: 0;
14
+ border: 0;
15
+ text-align: center;
16
+ }
17
+
18
+ .rebilly-instruments-divider::before {
19
+ background: ${theme.getComputed.color.mutedBorder};
20
+ content: '';
21
+ position: absolute;
22
+ left: 0;
23
+ top: 50%;
24
+ width: 100%;
25
+ height: 1px;
26
+ }
27
+
28
+ .rebilly-instruments-divider .rebilly-instruments-divider-label {
29
+ color: ${theme.getComputed.color.mutedText};
30
+ font-weight: 500;
31
+ text-transform: uppercase;
32
+ padding: 0 ${theme.space.s};
33
+ line-height: 14px;
34
+ background-color: ${theme.color.background};
35
+ font-size: 12px;
36
+ position: relative;
37
+ display: inline-block;
38
+ }
39
+ `;
@@ -0,0 +1,76 @@
1
+ // -----------------------------------------------------------------------------
2
+ // This file contains all styles related to the checkbox component.
3
+ // -----------------------------------------------------------------------------
4
+ export const checkbox = (theme) => `
5
+ /**
6
+ * Checkbox
7
+ */
8
+ .rebilly-instruments-form-field-checkbox {
9
+ position: relative;
10
+ opacity: 1;
11
+ padding-left: calc(${theme.space.m} + ${theme.space.s});
12
+ align-items: center;
13
+ display: inline-block;
14
+ cursor: pointer;
15
+ transform: none;
16
+ }
17
+
18
+ .rebilly-instruments-form-field-checkbox > * {
19
+ cursor: pointer;
20
+ }
21
+
22
+ .rebilly-instruments-form-field-checkbox input[type="checkbox"] {
23
+ position: absolute;
24
+ opacity: 0;
25
+ cursor: pointer;
26
+ height: 0;
27
+ width: 0;
28
+ }
29
+
30
+ .rebilly-instruments-form-field-checkbox span {
31
+ position: absolute;
32
+ top: 0;
33
+ left: 0;
34
+ height: 24px;
35
+ width: 24px;
36
+ border-radius: ${theme.borderRadius};
37
+ box-shadow: inset 0 0 0 1px ${theme.getComputed.color.mutedBorder};
38
+ background-color: transparent;
39
+ transition: all 200ms;
40
+ }
41
+
42
+ .rebilly-instruments-form-field-checkbox span:after {
43
+ content: '';
44
+ position: absolute;
45
+ left: 9px;
46
+ top: 4px;
47
+ opacity: 0;
48
+ width: 5px;
49
+ height: 11px;
50
+ border: solid ${theme.color.primary};
51
+ border-width: 0 2px 2px 0;
52
+ -webkit-transform: rotate(45deg);
53
+ -ms-transform: rotate(45deg);
54
+ transform: rotate(45deg);
55
+ transition: all 200ms;
56
+ }
57
+
58
+ .rebilly-instruments-form-field-checkbox input[type="checkbox"]:checked ~ span {
59
+ box-shadow: inset 0 0 0 2px ${theme.color.primary};
60
+ }
61
+
62
+ .rebilly-instruments-form-field-checkbox input[type="checkbox"]:checked ~ span:after {
63
+ opacity: 1;
64
+ }
65
+
66
+ .rebilly-instruments-form-field-checkbox input[type="checkbox"]:focus ~ span {
67
+ box-shadow: 0 0 0 2px ${theme.getComputed.color.primaryValues
68
+ .tint(80)
69
+ .hexString()},
70
+ inset 0 0 0 1px ${theme.color.primary};
71
+ }
72
+
73
+ .rebilly-instruments-form-field-checkbox input[type="checkbox"]:disabled ~ span {
74
+ opacity: 0.6;
75
+ }
76
+ `;
@@ -0,0 +1,44 @@
1
+ // -----------------------------------------------------------------------------
2
+ // This file contains all styles related to the field component.
3
+ // -----------------------------------------------------------------------------
4
+ export const field = (theme) => `
5
+ /**
6
+ * Field
7
+ */
8
+ .rebilly-instruments-form-field {
9
+ margin: calc(${theme.space.xxs} + ${theme.space.s}) 0;
10
+ position: relative;
11
+ }
12
+
13
+ /* Field group */
14
+ .rebilly-instruments-form-field-group {
15
+ margin: calc(-${theme.space.xxs} - ${theme.space.s}) 0;
16
+ display: flex;
17
+ }
18
+
19
+ .rebilly-instruments-form-field-group > * {
20
+ flex: 1 0;
21
+ margin-left: ${theme.space.xs};
22
+ margin-right: ${theme.space.xs}
23
+ }
24
+
25
+ .rebilly-instruments-form-field-group > *:first-child {
26
+ margin-left: 0;
27
+ }
28
+
29
+ .rebilly-instruments-form-field-group > *:last-child {
30
+ margin-right: 0;
31
+ }
32
+
33
+ @media (max-width: 480px) {
34
+ .rebilly-instruments-form-field-group {
35
+ display: block;
36
+ margin: calc(${theme.space.xxs} + ${theme.space.s}) 0;
37
+ }
38
+
39
+ .rebilly-instruments-form-field-group > * {
40
+ margin-left: 0;
41
+ margin-right: 0;
42
+ }
43
+ }
44
+ `;
@@ -0,0 +1,19 @@
1
+ // -----------------------------------------------------------------------------
2
+ // This file contains all styles related to the form component.
3
+ // -----------------------------------------------------------------------------
4
+ export const form = (theme) => `
5
+ /**
6
+ * Form
7
+ */
8
+ /* Chrome autocomplete styles */
9
+ .rebilly-instruments-form input:-webkit-autofill,
10
+ .rebilly-instruments-form input:-webkit-autofill:hover,
11
+ .rebilly-instruments-form input:-webkit-autofill:focus,
12
+ .rebilly-instruments-form select:-webkit-autofill,
13
+ .rebilly-instruments-form select:-webkit-autofill:hover,
14
+ .rebilly-instruments-form select:-webkit-autofill:focus {
15
+ -webkit-text-fill-color: ${theme.color.text};
16
+ -webkit-box-shadow: 0 0 0px 1000px transparent inset;
17
+ transition: background-color 5000s ease-in-out 0s;
18
+ }
19
+ `;