@rebilly/instruments 3.3.2-beta.0 → 3.5.2-beta.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rebilly/instruments",
3
- "version": "3.3.2-beta.0",
3
+ "version": "3.5.2-beta.0",
4
4
  "author": "Rebilly",
5
5
  "main": "dist/index.js",
6
6
  "unpkg": "dist/index.min.js",
@@ -5,7 +5,7 @@ import { fetchData } from './fetch-data';
5
5
  import setupElement from './setup-element';
6
6
  import setupStorefront from './setup-storefront';
7
7
  import setupOptions from './setup-options';
8
- import setupFramepay from './setup-framepay';
8
+ import setupFramepayInstance from './setup-framepay';
9
9
  import setupStyles from './setup-styles';
10
10
  import setupI18n from './setup-i18n';
11
11
  import setupFramepayTheme from './setup-framepay-theme';
@@ -63,6 +63,7 @@ import setupUserFlow from './setup-user-flow';
63
63
  * Mount library with configurations.
64
64
  * @param {object} options - The options object
65
65
  * @param {object} options.state - Global state
66
+ * @param {function} options.setupFramepayInstance - Helper for adding FramePay scripts to the DOM
66
67
  * @param {string | HTMLElement} options.form - The CSS class or HTML element were the form will be mounted.
67
68
  * @param {string | HTMLElement} options.summary - The CSS class or HTML element were the summary will be mounted.
68
69
  * @param {Item[]} options.items - Which plans the customer is purchasing.
@@ -75,6 +76,7 @@ import setupUserFlow from './setup-user-flow';
75
76
  */
76
77
  export async function mount({
77
78
  state,
79
+ setupFramepay = setupFramepayInstance,
78
80
  ...options
79
81
  } = {}) {
80
82
  try {
@@ -100,7 +102,7 @@ export async function mount({
100
102
  state.options.themeFramepay = await setupFramepayTheme({ state, options });
101
103
  state.i18n = setupI18n({ state });
102
104
 
103
- setupFramepay({ state });
105
+ await setupFramepay(state);
104
106
 
105
107
  // Update state options from data
106
108
  if ((!state.options.websiteId) && state.data.transaction?.websiteId) {
@@ -8,9 +8,9 @@ import ProductModel from '@/storefront/models/product-model';
8
8
  import SummaryModel from '@/storefront/models/summary-model';
9
9
 
10
10
  describe('RebillyInstruments instance', () => {
11
- it("should inject HTML to the merchant's website", async () => {
11
+ it('should inject HTML to the merchant\'s website', async () => {
12
12
  const framePayScriptUrl = 'https://framepay.rebilly.com/rebilly.js';
13
- const framePayStyleUrl = 'https://dev.framepay.rebilly.com/rebilly.css';
13
+ const framePayStyleUrl = 'https://framepay.rebilly.com/rebilly.css';
14
14
 
15
15
  const options = {
16
16
  form: '.form-selector',
@@ -34,7 +34,6 @@ describe('RebillyInstruments instance', () => {
34
34
  framePayStyleLink: framePayStyleUrl
35
35
  },
36
36
  };
37
-
38
37
  await RenderMockRebillyInstruments(options);
39
38
 
40
39
  // Mounts form and summary
@@ -64,15 +63,14 @@ describe('RebillyInstruments instance', () => {
64
63
 
65
64
  // Mounts _dev FramePay style
66
65
  const STYLE_LINKS = [...document.querySelectorAll('head link')];
67
- const FRAMEPAY_STYLE = STYLE_LINKS.find(
68
- (script) => script.href === framePayStyleUrl
69
- );
66
+ const FRAMEPAY_STYLE = STYLE_LINKS.find(script => script.href === framePayStyleUrl);
67
+
70
68
  expect(FRAMEPAY_STYLE.href).toEqual(framePayStyleUrl);
71
69
  });
72
70
 
73
71
  it('should mount with JWT pruchase data', async () => {
74
72
  // Use https://www.jwt.io to help encode and decode JWT
75
- const jwt = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkMGYzNWEzYy03N2M0LTQ0NDItOWFhNC03ODA5NDA2NzBjN2IiLCJleHAiOjE2NzM2NDk0ODcsImlhdCI6MTY0MjExMDczOS4zMjYyNDQsImFjbCI6W3sic2NvcGUiOnsib3JnYW5pemF0aW9uSWQiOlsidGVzdC1vcmdhbml6YXRpb24tZCJdLCJ0cmFuc2FjdGlvbklkIjpbInRlc3QtdHJhbnNhY3Rpb24taWQiXX0sInBlcm1pc3Npb25zIjpbMV19XSwiY2xhaW1zIjp7InRyYW5zYWN0aW9uSWQiOiJ0ZXN0LXRyYW5zYWN0aW9uLWlkIn0sIm1lcmNoYW50IjoidGVzdC1vcmdhbml6YXRpb24taWQiLCJjdXN0b21lciI6eyJpZCI6InRlc3QtY3VzdG9tZXItaWQiLCJuYW1lIjoiVGVzdGVyIFRlc3RlcnNvbiIsImNyZWF0ZWRUaW1lIjoiMjAyMi0wMS0xNFQwMDowMDowMCswMDowMCJ9fQ.h4voW-UvXzXRm1JlxkN8cNHhQ_IIPSWWN9BANfBWEHQ`;
73
+ const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkMGYzNWEzYy03N2M0LTQ0NDItOWFhNC03ODA5NDA2NzBjN2IiLCJleHAiOjE2NzM2NDk0ODcsImlhdCI6MTY0MjExMDczOS4zMjYyNDQsImFjbCI6W3sic2NvcGUiOnsib3JnYW5pemF0aW9uSWQiOlsidGVzdC1vcmdhbml6YXRpb24tZCJdLCJ0cmFuc2FjdGlvbklkIjpbInRlc3QtdHJhbnNhY3Rpb24taWQiXX0sInBlcm1pc3Npb25zIjpbMV19XSwiY2xhaW1zIjp7InRyYW5zYWN0aW9uSWQiOiJ0ZXN0LXRyYW5zYWN0aW9uLWlkIn0sIm1lcmNoYW50IjoidGVzdC1vcmdhbml6YXRpb24taWQiLCJjdXN0b21lciI6eyJpZCI6InRlc3QtY3VzdG9tZXItaWQiLCJuYW1lIjoiVGVzdGVyIFRlc3RlcnNvbiIsImNyZWF0ZWRUaW1lIjoiMjAyMi0wMS0xNFQwMDowMDowMCswMDowMCJ9fQ.h4voW-UvXzXRm1JlxkN8cNHhQ_IIPSWWN9BANfBWEHQ';
76
74
 
77
75
  const options = {
78
76
  form: '.form-selector',
@@ -1,41 +1,20 @@
1
- import { addDOMElement } from '../../utils';
1
+ export default async function setupFramepay (state = {}) {
2
+ const {_dev} = state.options || {};
3
+ const urls = {
4
+ script: _dev?.framePayScriptLink || 'https://framepay.rebilly.com/rebilly.js',
5
+ style: _dev?.framePayStyleLink || 'https://framepay.rebilly.com/rebilly.css',
6
+ };
2
7
 
3
- export default ({
4
- state: {
5
- options: {
6
- _dev
7
- }
8
- }
9
- } = {}) => {
10
- const framePayUrls = {
11
- script: _dev
12
- ? _dev.framePayScriptLink || 'https://framepay.rebilly.com/rebilly.js'
13
- : 'https://framepay.rebilly.com/rebilly.js',
14
- style: _dev
15
- ? _dev.framePayStyleLink || 'https://framepay.rebilly.com/rebilly.css'
16
- : 'https://framepay.rebilly.com/rebilly.css'
17
- };
8
+ return new Promise((resolve) => {
9
+ const framepayStyle = document.createElement('link');
10
+ framepayStyle.setAttribute('href', urls.style);
11
+ framepayStyle.setAttribute('rel', 'stylesheet');
12
+ document.head.prepend(framepayStyle);
18
13
 
19
- if (!document.querySelectorAll('[framepay*="script"]').length) {
20
- addDOMElement({
21
- element: 'script',
22
- attributes: {
23
- framepay: 'script',
24
- src: framePayUrls.script
25
- },
26
- target: 'head'
14
+ const framepayScript = document.createElement('script');
15
+ framepayScript.setAttribute('src', urls.script);
16
+
17
+ framepayScript.onload = () => resolve();
18
+ document.head.append(framepayScript);
27
19
  });
28
- }
29
-
30
- if (!document.querySelectorAll('[framepay*="stylesheet"]').length) {
31
- addDOMElement({
32
- element: 'link',
33
- attributes: {
34
- framepay: 'stylesheet',
35
- href: framePayUrls.style,
36
- rel: 'stylesheet'
37
- },
38
- target: 'head'
39
- });
40
- }
41
- }
20
+ }
@@ -6,15 +6,24 @@ import { DataInstance } from './mount/fetch-data';
6
6
  export async function makePayment({ state, payload }) {
7
7
  const {
8
8
  _raw: {
9
- id: token
10
- }
9
+ id
10
+ },
11
+ isExistingInstrument
11
12
  } = payload;
13
+ delete payload.isExistingInstrument;
14
+ delete payload._raw;
12
15
 
13
16
  const data = {
14
- token,
15
17
  ...payload
16
18
  };
17
19
 
20
+ if (isExistingInstrument) {
21
+ data.paymentInstrumentId = id;
22
+
23
+ } else {
24
+ data.token = id;
25
+ }
26
+
18
27
  if (state.options.invoiceId) {
19
28
  data.invoiceId = state.options.invoiceId;
20
29
  }
@@ -5,12 +5,30 @@ import { DataInstance } from './mount/fetch-data';
5
5
 
6
6
  export async function setup({ state, payload }) {
7
7
  try {
8
+ const {
9
+ _raw: {
10
+ id
11
+ },
12
+ isExistingInstrument
13
+ } = payload;
14
+ delete payload.isExistingInstrument;
15
+ delete payload._raw;
16
+
17
+ const data = {
18
+ ...payload
19
+ };
20
+
21
+ if (isExistingInstrument) {
22
+ data.paymentInstrumentId = id;
23
+ } else {
24
+ data.token = id;
25
+ }
26
+
8
27
  const {instrument, transaction} = await setupPaymentInstrument({
9
28
  state,
10
29
  data: {
11
- token: payload._raw.id,
12
30
  websiteId: state.options?.websiteId,
13
- ...payload
31
+ ...data
14
32
  }
15
33
  });
16
34
 
@@ -1,6 +1,7 @@
1
+ import { avoidUnhandledPromises } from 'tests/async-utilities';
2
+ import { setupFramepayMock } from 'tests/mocks/rebilly-instruments-mock';
1
3
  import RebillyInstruments from './index';
2
4
  import { RebillyInstrumentsInstance } from './instance';
3
- import { avoidUnhandledPromises } from 'tests/async-utilities';
4
5
 
5
6
  describe('RebillyInstruments instance', () => {
6
7
  let rebillyInstruments;
@@ -24,7 +25,8 @@ describe('RebillyInstruments instance', () => {
24
25
  const options = {
25
26
  form: '.form-selector',
26
27
  summary: '.summary-selector',
27
- items: []
28
+ items: [],
29
+ setupFramepay: setupFramepayMock,
28
30
  };
29
31
 
30
32
  await rebillyInstruments.mount(options);
@@ -5,6 +5,10 @@ export class ReadyToPayFeatureModel {
5
5
  name = '',
6
6
  expirationTime = '',
7
7
 
8
+ // Apple Pay fields
9
+ displayName = '',
10
+ country = '',
11
+
8
12
  // Google Pay fields
9
13
  merchantName = '',
10
14
  merchantOrigin = '',
@@ -19,6 +23,8 @@ export class ReadyToPayFeatureModel {
19
23
  this.name = name;
20
24
  this.expirationTime = expirationTime;
21
25
 
26
+ this.displayName = displayName;
27
+ this.country = country;
22
28
 
23
29
  this.merchantName = merchantName;
24
30
  this.merchantOrigin = merchantOrigin;
@@ -16,10 +16,10 @@ export async function setupPaymentInstrument({ data, state }) {
16
16
  }
17
17
  }
18
18
 
19
- if(state.data.getAmountAndCurrency) {
19
+ if(state.data.amountAndCurrency) {
20
20
  setupPayload.data = {
21
21
  ...setupPayload.data,
22
- ...state.data.getAmountAndCurrency
22
+ ...state.data.amountAndCurrency
23
23
  }
24
24
  }
25
25
 
@@ -1,20 +1,22 @@
1
- import { lighten } from '../utils/color-values';
2
-
3
1
  // -----------------------------------------------------------------------------
4
2
  // This file contains all styles related to the accordion component.
5
3
  // -----------------------------------------------------------------------------
6
4
 
7
- export const accordion = (theme) => `
5
+ export const accordion = () => `
8
6
  /* ACCORDION CLOSED */
9
7
  .rebilly-instruments-accordion {
10
8
  border: 1px solid var(--rebilly-colorMutedBorder);
11
- padding: 0 var(--rebilly-spacings-s);
9
+ padding: 0 calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
12
10
  background: var(--rebilly-colorBackground);
13
- transition: border 0.2s ease, box-shadow 0.2s ease;
11
+ transition: border 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
14
12
  margin: var(--rebilly-spacings-s) 0;
15
13
  border-radius: var(--rebilly-borderRadius);
16
14
  overflow: hidden;
17
- cursor: pointer;
15
+ opacity: 0.7;
16
+ }
17
+
18
+ .rebilly-instruments-accordion:hover {
19
+ opacity: 1;
18
20
  }
19
21
 
20
22
  .rebilly-instruments-accordion:first-of-type {
@@ -30,98 +32,109 @@ export const accordion = (theme) => `
30
32
  }
31
33
 
32
34
  .rebilly-instruments-accordion .rebilly-instruments-accordion-summary {
35
+ cursor: pointer;
33
36
  display: flex;
34
37
  align-items: center;
35
38
  list-style: none;
36
- padding: var(--rebilly-spacings-xs) var(--rebilly-spacings-s);
37
- margin: 0px calc(-1 * var(--rebilly-spacings-s));
39
+ padding: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-s)) calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
40
+ margin: 0px calc(-1 * calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs)));
41
+ background: var(--rebilly-colorBackground);
38
42
  }
39
43
 
40
- .rebilly-instruments-accordion .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio {
41
- height: 18px;
42
- width: 18px;
44
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-checkmark {
45
+ position: relative;
46
+ width: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
47
+ height: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
43
48
  border-radius: 50%;
44
- margin-right: var(--rebilly-spacings-s);
45
- border: 1px solid var(--rebilly-colorMutedBorder);
46
- box-shadow: 0 0 0 0 transparent;
49
+ opacity: 0;
50
+ background: var(--rebilly-colorText);
51
+ margin-left: var(--rebilly-spacings-m);
47
52
  transition: all 0.2s ease;
48
- position: relative;
49
53
  }
50
54
 
51
- .rebilly-instruments-accordion .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio::after {
55
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-checkmark::after {
52
56
  content: '';
53
57
  position: absolute;
54
- width: 10px;
55
- height: 10px;
58
+ border: solid var(--rebilly-colorBackground);
59
+ width: calc(var(--rebilly-spacings-xs) + var(--rebilly-spacings-2xs));
60
+ height: calc(var(--rebilly-spacings-xs) - var(--rebilly-spacings-2xs) + 2px);
61
+ border-width: 2px 2px 0 0;
62
+ border-radius: 2px;
56
63
  top: 50%;
57
64
  left: 50%;
58
- transform: translate(-50%, -50%) scale(0.4);
59
- opacity: 0;
60
- background: var(--rebilly-colorPrimary);
61
- border-radius: 50%;
65
+ transform: translateY(-60%) translateX(-50%) rotate(135deg);
62
66
  transition: all 0.2s ease;
63
67
  }
64
68
 
65
- .rebilly-instruments-accordion:hover .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio {
66
- border-color: ${lighten(theme.colorText, 60)};
69
+ .rebilly-instruments-accordion-summary:hover .rebilly-instruments-accordion-summary-checkmark {
70
+ opacity: 0.5;
67
71
  }
68
72
 
69
- .rebilly-instruments-accordion .rebilly-instruments-accordion-summary img {
73
+ .rebilly-instruments-accordion .rebilly-instruments-accordion-summary > img {
70
74
  margin-right: var(--rebilly-spacings-s);
71
75
  height: auto;
72
76
  max-width: 40px;
73
77
  width: 100%;
74
78
  }
75
79
 
76
- .rebilly-instruments-accordion .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-title {
80
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-title {
77
81
  margin: 0;
78
82
  font-weight: 500;
79
83
  flex: 2;
80
84
  }
81
85
 
82
- .rebilly-instruments-accordion .rebilly-instruments-accordion-brands {
86
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-brands {
83
87
  display: inline-flex;
84
88
  justify-content: flex-end;
85
89
  align-items: center;
86
90
  }
87
91
 
88
- .rebilly-instruments-accordion .rebilly-instruments-accordion-brands figure {
92
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-brands figure {
89
93
  margin: auto;
90
94
  padding: 0;
91
95
  height: 26px;
92
96
  }
93
97
 
94
- .rebilly-instruments-accordion .rebilly-instruments-accordion-brands figure img {
98
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-brands figure img {
95
99
  width: auto;
96
100
  height: 100%;
97
- border-radius: 4px;
101
+ border-radius: var(--rebilly-borderRadius);
98
102
  margin-right: var(--rebilly-spacings-xs);
99
103
  }
100
104
 
101
- .rebilly-instruments-accordion .rebilly-instruments-accordion-brands span {
105
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-brands span {
102
106
  color: var(--rebilly-colorMutedText);
103
- margin: 0;
107
+ margin: 0 0 0 var(--rebilly-spacings-xs);
104
108
  font-size: calc(var(--rebilly-fontSizeBase) * 0.875);
105
109
  line-height: 1;
106
110
  }
107
111
 
108
112
  /* ACCORDION OPENED */
109
113
  .rebilly-instruments-accordion[open] {
110
- padding: 0 var(--rebilly-spacings-s) var(--rebilly-spacings-s);
114
+ padding: 0 calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs)) calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
115
+ opacity: 1;
111
116
  }
112
117
 
113
118
  .rebilly-instruments-accordion[open] .rebilly-instruments-accordion-summary {
114
119
  border-bottom: 1px solid var(--rebilly-colorMutedBorder);
115
- margin-bottom: var(--rebilly-spacings-m);
120
+ margin-bottom: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
116
121
  }
117
122
 
118
- .rebilly-instruments-accordion[open] .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio {
119
- border-color: var(--rebilly-colorPrimary);
120
- box-shadow: 0 0 0 1px var(--rebilly-colorPrimary);
123
+ .rebilly-instruments-accordion[open] .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-checkmark {
124
+ background: var(--rebilly-colorText);
125
+ opacity: 1;
121
126
  }
122
127
 
123
- .rebilly-instruments-accordion[open] .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio::after {
124
- transform: translate(-50%, -50%) scale(1);
125
- opacity: 1;
128
+ @media screen and (max-width: 600px) {
129
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-brands figure:nth-child(2),
130
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-brands figure:nth-child(3) {
131
+ display: none;
132
+ }
133
+ }
134
+
135
+ @media screen and (max-width: 480px) {
136
+ .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-brands {
137
+ display: none;
138
+ }
126
139
  }
127
140
  `;
@@ -79,4 +79,21 @@ export const button = () => `
79
79
  .rebilly-instruments-button:first-of-type { margin-top: 0; }
80
80
 
81
81
  .rebilly-instruments-button:last-of-type { margin-bottom: 0; }
82
+
83
+ .rebilly-instruments-button-group {
84
+ display: flex;
85
+ align-items: stretch;
86
+ }
87
+
88
+ .rebilly-instruments-button-group .rebilly-instruments-button {
89
+ margin: 0 var(--rebilly-spacings-xs);
90
+ }
91
+
92
+ .rebilly-instruments-button-group .rebilly-instruments-button:first-of-type {
93
+ margin-left: 0;
94
+ }
95
+
96
+ .rebilly-instruments-button-group .rebilly-instruments-button:last-of-type {
97
+ margin-right: 0;
98
+ }
82
99
  `;
@@ -1,8 +1,7 @@
1
- import { lighten } from '../../utils/color-values';
2
1
  // -----------------------------------------------------------------------------
3
2
  // This file contains all styles related to the checkbox component.
4
3
  // -----------------------------------------------------------------------------
5
- export const checkbox = (theme) => `
4
+ export const checkbox = () => `
6
5
  /**
7
6
  * Checkbox
8
7
  */
@@ -33,10 +32,11 @@ export const checkbox = (theme) => `
33
32
  position: relative;
34
33
  top: 0;
35
34
  left: 0;
36
- height: 24px;
37
- width: 24px;
35
+ width: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
36
+ height: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
37
+ min-width: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
38
38
  border-radius: 4px;
39
- box-shadow: inset 0 0 0 1px var(--rebilly-colorMutedBorder);
39
+ box-shadow: inset 0 0 0 2px var(--rebilly-colorMutedBorder);
40
40
  margin-right: var(--rebilly-spacings-s);
41
41
  background-color: transparent;
42
42
  transition: all 200ms;
@@ -45,17 +45,20 @@ export const checkbox = (theme) => `
45
45
  .rebilly-instruments-form-field-checkbox span:after {
46
46
  content: '';
47
47
  position: absolute;
48
- left: 9px;
49
- top: 4px;
50
- opacity: 0;
51
- width: 5px;
52
- height: 11px;
53
48
  border: solid var(--rebilly-colorPrimary);
54
- border-width: 0 2px 2px 0;
55
- -webkit-transform: rotate(45deg);
56
- -ms-transform: rotate(45deg);
57
- transform: rotate(45deg);
58
- transition: all 200ms;
49
+ width: calc(var(--rebilly-spacings-xs) + var(--rebilly-spacings-2xs));
50
+ height: calc(var(--rebilly-spacings-xs) - var(--rebilly-spacings-2xs) + 2px);
51
+ border-width: 2px 2px 0 0;
52
+ border-radius: 2px;
53
+ top: 50%;
54
+ left: 50%;
55
+ opacity: 0;
56
+ transform: translateY(-60%) translateX(-50%) rotate(135deg);
57
+ transition: all 0.2s ease;
58
+ }
59
+
60
+ .rebilly-instruments-form-field-checkbox input[type="checkbox"]:focus ~ span {
61
+ box-shadow: inset 0 0 0 2px var(--rebilly-colorPrimary);
59
62
  }
60
63
 
61
64
  .rebilly-instruments-form-field-checkbox input[type="checkbox"]:checked ~ span {
@@ -66,10 +69,6 @@ export const checkbox = (theme) => `
66
69
  opacity: 1;
67
70
  }
68
71
 
69
- .rebilly-instruments-form-field-checkbox input[type="checkbox"]:focus ~ span {
70
- box-shadow: 0 0 0 2px ${lighten(theme.colorPrimary, 80)}, inset 0 0 0 1px var(--rebilly-colorPrimary);
71
- }
72
-
73
72
  .rebilly-instruments-form-field-checkbox input[type="checkbox"]:disabled ~ span {
74
73
  opacity: 0.6;
75
74
  }
@@ -0,0 +1,80 @@
1
+ // -----------------------------------------------------------------------------
2
+ // This file contains all styles related to the radio component.
3
+ // -----------------------------------------------------------------------------
4
+ export const radio = () => `
5
+ /**
6
+ * Checkbox
7
+ */
8
+ .rebilly-instruments-form-field-radio {
9
+ position: relative;
10
+ opacity: 1;
11
+ align-items: center;
12
+ display: flex;
13
+ flex-direction: row-reverse;
14
+ justify-content: start;
15
+ cursor: pointer;
16
+ transform: none;
17
+ }
18
+
19
+ .rebilly-instruments-form-field-radio > * {
20
+ cursor: pointer;
21
+ }
22
+
23
+ .rebilly-instruments-form-field-radio input[type="radio"] {
24
+ position: absolute;
25
+ opacity: 0;
26
+ cursor: pointer;
27
+ height: 0;
28
+ width: 0;
29
+ }
30
+
31
+ .rebilly-instruments-form-field-radio > span {
32
+ position: relative;
33
+ top: 0;
34
+ left: 0;
35
+ height: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
36
+ width: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
37
+ min-width: calc(var(--rebilly-spacings-m) - var(--rebilly-spacings-2xs));
38
+ border-radius: 50%;
39
+ box-shadow: inset 0 0 0 2px var(--rebilly-colorMutedBorder);
40
+ margin-right: var(--rebilly-spacings-s);
41
+ background-color: transparent;
42
+ transition: all 200ms;
43
+ }
44
+
45
+ .rebilly-instruments-form-field-radio > span:after {
46
+ content: '';
47
+ position: absolute;
48
+ left: 50%;
49
+ top: 50%;
50
+ transform: translateX(-50%) translateY(-50%);
51
+ opacity: 0;
52
+ width: calc(var(--rebilly-spacings-xs) + 4px);
53
+ height: calc(var(--rebilly-spacings-xs) + 4px);
54
+ border-radius: 50%;
55
+ background: var(--rebilly-colorMutedBorder);
56
+ transition: all 200ms;
57
+ }
58
+
59
+ .rebilly-instruments-form-field-radio:hover > span:after {
60
+ opacity: 1;
61
+ }
62
+
63
+ .rebilly-instruments-form-field-radio input[type="radio"]:checked ~ span {
64
+ box-shadow: inset 0 0 0 2px var(--rebilly-colorPrimary);
65
+ }
66
+
67
+ .rebilly-instruments-form-field-radio input[type="radio"]:checked ~ span:after {
68
+ background: var(--rebilly-colorPrimary);
69
+ opacity: 1;
70
+ }
71
+
72
+ .rebilly-instruments-form-field-radio input[type="radio"]:focus ~ span {
73
+ opacity: 1;
74
+ box-shadow: inset 0 0 0 2px var(--rebilly-colorPrimary);
75
+ }
76
+
77
+ .rebilly-instruments-form-field-radio input[type="radio"]:disabled ~ span {
78
+ opacity: 0.6;
79
+ }
80
+ `;
@@ -1,6 +1,7 @@
1
1
  import { expressMethods, methods } from './methods';
2
2
  import { form } from './forms/form';
3
3
  import { checkbox } from './forms/checkbox';
4
+ import { radio } from './forms/radio';
4
5
  import { field } from './forms/field';
5
6
  import { input } from './forms/input';
6
7
  import { label } from './forms/label';
@@ -12,7 +13,7 @@ import { loader } from './loader';
12
13
  import { icons } from './icons';
13
14
  import { address } from './address';
14
15
  import { overlay } from './overlay';
15
- import {accordion} from './accordion';
16
+ import { accordion } from './accordion';
16
17
 
17
18
  // Order of components matters for style cascade
18
19
  export const components = (theme) => `
@@ -25,7 +26,8 @@ export const components = (theme) => `
25
26
  ${input(theme)}
26
27
  ${select(theme)}
27
28
  ${label(theme)}
28
- ${checkbox(theme)}
29
+ ${checkbox()}
30
+ ${radio()}
29
31
  ${validation(theme)}
30
32
  ${button(theme)}
31
33
  ${divider(theme)}
@@ -33,5 +35,5 @@ export const components = (theme) => `
33
35
  ${icons(theme)}
34
36
  ${address(theme)}
35
37
  ${overlay(theme)}
36
- ${accordion(theme)}
38
+ ${accordion()}
37
39
  `;
@@ -48,4 +48,7 @@ export const helpers = () => `
48
48
  .rebilly-instruments-helper-ml-xl { margin-left: var(--rebilly-spacings-xl) !important }
49
49
  .rebilly-instruments-helper-ml-xxl { margin-left: var(--rebilly-spacings-2xl) !important }
50
50
  .rebilly-instruments-helper-ml-0 { margin-left: 0!important }
51
+
52
+ .rebilly-instruments-display-flex { display: flex!important }
53
+ .rebilly-instruments-align-items-center { align-items: center!important }
51
54
  `;
@@ -1,5 +1,7 @@
1
1
  import { methodContent } from './content';
2
2
  import { paymentCard } from './payment-card';
3
+ import { paymentInstrumentList } from './payment-instrument-list';
4
+ import { paymentInstrument } from './payment-instrument';
3
5
 
4
6
  // Order of components matters for style cascade
5
7
  export const paymentInstruments = (theme) => `
@@ -7,4 +9,6 @@ export const paymentInstruments = (theme) => `
7
9
  ------------------------------------------------------------ */
8
10
  ${methodContent()}
9
11
  ${paymentCard(theme)}
12
+ ${paymentInstrument()}
13
+ ${paymentInstrumentList()}
10
14
  `;