Skip to content

Commit 3da2ba8

Browse files
committed
Add {{stripe-elements}} contextual component
1 parent aab8c7b commit 3da2ba8

File tree

6 files changed

+141
-10
lines changed

6 files changed

+141
-10
lines changed

README.md

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,15 @@ ENV.stripe = {
6565

6666
### Mocking the Stripe API
6767

68-
You can configure the Stripe API to be mocked instead of loaded from `https://js.stripe.com/v3/`. This is useful for testing.
68+
You can configure the Stripe API to be mocked instead of loaded from `https://js.stripe.com/v3/`. This is useful for testing.
6969

7070
```js
7171
ENV.stripe = {
7272
mock: true
7373
};
7474
```
7575

76-
When enabled, a [mock Stripe object](https://github.com/code-corps/ember-stripe-elements/blob/develop/addon/utils/stripe-mock.js) will be assigned to `window.Stripe` when your app is initialized.
76+
When enabled, a [mock Stripe object](https://github.com/code-corps/ember-stripe-elements/blob/develop/addon/utils/stripe-mock.js) will be assigned to `window.Stripe` when your app is initialized.
7777

7878
When using the Stripe mock in tests you will likely need to override the mock's methods according to the needs of your test like so:
7979

@@ -154,13 +154,54 @@ You could handle these actions yourself, for example:
154154

155155
This addon gives you components that match the different [Element types](https://stripe.com/docs/elements/reference#element-types):
156156

157-
- `{{stripe-card}}` - `card` (recommended) A flexible single-line input that collects all necessary card details.
158-
- `{{stripe-card-number}}` - `cardNumber` The card number.
159-
- `{{stripe-card-expiry}}` - `cardExpiry` The card's expiration date.
160-
- `{{stripe-card-cvc}}` - `cardCvc` The card's CVC number.
161-
- `{{stripe-postal-code}}` - `postalCode` the ZIP/postal code.
157+
Stripe recommend using the their `card` element - a flexible single-line input that collects all necessary card details.
158+
The `{{stripe-card}}` component provides this input.
162159

163-
### Block usage with `options`
160+
Additionally Stripe provide the following elements, which you can use to build your own form to collect card details:
161+
162+
- `cardNumber`: the card number.
163+
- `cardExpiry`: the card's expiration date.
164+
- `cardCvc`: the card's CVC number.
165+
- `postalCode`: the ZIP/postal code.
166+
167+
These are provided via our `{{stripe-elements}}` contextual component, which yields sub-components for each element type:
168+
169+
```hbs
170+
{{#stripe-elements as |elements|}}
171+
{{elements.cardNumber}}
172+
{{elements.cardExpiry}}
173+
{{elements.cardCvc}}
174+
{{elements.postalCode}}
175+
{{/stripe-elements}}
176+
```
177+
178+
> The `{{stripe-elements}}` component is a tagless component, so does not have any classes etc on it.
179+
180+
### Elements Options
181+
182+
The `{{stripe-elements}}` contextual component ensures all the individual elements are created from
183+
the same [Stripe Elements object](https://stripe.com/docs/stripe-js/reference#the-elements-object).
184+
185+
If you want to pass options to the Stripe Elements object, pass them to the `{{stripe-elements}}`
186+
contextual component. For example, when using the single-line `card` element:
187+
188+
```hbs
189+
{{#stripe-elements options=elementOptions as |elements|}}
190+
{{elements.card options=cardOptions}}
191+
{{/stripe-elements}}
192+
```
193+
194+
Or when creating your own form:
195+
196+
```hbs
197+
{{#stripe-elements options=elementsOptions as |elements|}}
198+
{{elements.cardNumber options=cardNumberOptions}}
199+
{{elements.cardExpiry}}
200+
{{elements.cardCvc}}
201+
{{/stripe-elements}}
202+
```
203+
204+
### Block usage with element `options`
164205

165206
In addition to the simple usage above, like `{{stripe-card}}`, you can also yield to a block, which will yield both an `stripeError` object and [the `stripeElement` itself](https://stripe.com/docs/elements/reference#the-element).
166207

addon/components/stripe-element.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,15 @@ export default Component.extend({
1717
},
1818

1919
stripev3: service(),
20-
elements: computed(function() {
21-
return get(this, 'stripev3.elements')();
20+
21+
elements: computed({
22+
get() {
23+
return get(this, 'stripev3.elements')();
24+
},
25+
26+
set(key, value) {
27+
return value;
28+
}
2229
}),
2330

2431
didInsertElement() {

addon/components/stripe-elements.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Component from '@ember/component';
2+
import layout from '../templates/components/stripe-elements';
3+
import { inject as service } from '@ember/service';
4+
import { get, set } from '@ember/object';
5+
6+
export default Component.extend({
7+
stripe: service('stripev3'),
8+
tagName: '',
9+
layout,
10+
11+
init() {
12+
this._super(...arguments);
13+
let options = get(this, 'options') || {};
14+
let elements = get(this, 'stripe').elements(options);
15+
set(this, 'elements', elements);
16+
}
17+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{{yield (hash
2+
card=(component "stripe-card"
3+
elements=elements
4+
)
5+
cardNumber=(component "stripe-card-number"
6+
elements=elements
7+
)
8+
cardExpiry=(component "stripe-card-expiry"
9+
elements=elements
10+
)
11+
cardCvc=(component "stripe-card-cvc"
12+
elements=elements
13+
)
14+
postalCode=(component "stripe-postal-code"
15+
elements=elements
16+
)
17+
)}}

app/components/stripe-elements.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from 'ember-stripe-elements/components/stripe-elements';
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { module, test } from 'qunit';
2+
import { setupRenderingTest } from 'ember-qunit';
3+
import { render } from '@ember/test-helpers';
4+
import hbs from 'htmlbars-inline-precompile';
5+
import StripeMock from 'ember-stripe-elements/utils/stripe-mock';
6+
import StripeService from 'dummy/services/stripev3';
7+
import env from 'dummy/config/environment';
8+
9+
module('Integration | Component | stripe-elements', function(hooks) {
10+
setupRenderingTest(hooks);
11+
12+
hooks.beforeEach(function() {
13+
window.Stripe = StripeMock;
14+
const config = {
15+
mock: true,
16+
publishableKey: env.stripe.publishableKey,
17+
};
18+
19+
this.owner.register(
20+
'service:stripev3',
21+
StripeService.create({ config }),
22+
{ instantiate: false }
23+
);
24+
});
25+
26+
test('it renders single-line element', async function (assert) {
27+
assert.expect(0);
28+
29+
await render(hbs`
30+
{{#stripe-elements as |elements|}}
31+
{{elements.card}}
32+
{{/stripe-elements}}
33+
`);
34+
});
35+
36+
test('it renders individual elements', async function (assert) {
37+
assert.expect(0);
38+
39+
await render(hbs`
40+
{{#stripe-elements as |elements|}}
41+
{{elements.cardNumber}}
42+
{{elements.cardExpiry}}
43+
{{elements.cardCvc}}
44+
{{elements.postalCode}}
45+
{{/stripe-elements}}
46+
`);
47+
});
48+
});

0 commit comments

Comments
 (0)