diff --git a/types/react-stripe-elements/index.d.ts b/types/react-stripe-elements/index.d.ts new file mode 100644 index 0000000000..4322dfab89 --- /dev/null +++ b/types/react-stripe-elements/index.d.ts @@ -0,0 +1,81 @@ +// Type definitions for react-stripe-elements 1.0 +// Project: https://github.com/stripe/react-stripe-elements#readme +// Definitions by: dan-j +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + +/// +import * as React from 'react'; + +export namespace ReactStripeElements { + import ElementChangeResponse = stripe.elements.ElementChangeResponse; + import ElementsOptions = stripe.elements.ElementsOptions; + import TokenOptions = stripe.TokenOptions; + import TokenResponse = stripe.TokenResponse; + + /** + * There's a bug in @types/stripe which defines the property as + * `declined_code` (with a 'd') but it's in fact `decline_code` + */ + type PatchedTokenResponse = TokenResponse & { + error?: { decline_code?: string }; + }; + + interface StripeProviderProps { + apiKey: string; + } + + interface StripeProps { + // I'm not sure what the definition for this is + createSource(): void; + + createToken(options?: TokenOptions): Promise; + } + + interface InjectOptions { + withRef?: boolean; + } + + interface InjectedStripeProps { + stripe: StripeProps; + } + + interface ElementProps extends ElementsOptions { + className?: string; + + elementRef?(): void; + + onChange?(event: ElementChangeResponse): void; + + onBlur?(event: ElementChangeResponse): void; + + onFocus?(event: ElementChangeResponse): void; + + onReady?(): void; + } +} + +export class StripeProvider extends React.Component { +} + +export class Elements extends React.Component { +} + +export function injectStripe

( + WrappedComponent: React.ComponentType

, + componentOptions?: ReactStripeElements.InjectOptions): React.ComponentType

; + +export class CardElement extends React.Component { +} + +export class CardNumberElement extends React.Component { +} + +export class CardExpiryElement extends React.Component { +} + +export class CardCVCElement extends React.Component { +} + +export class PostalCodeElement extends React.Component { +} diff --git a/types/react-stripe-elements/react-stripe-elements-tests.tsx b/types/react-stripe-elements/react-stripe-elements-tests.tsx new file mode 100644 index 0000000000..715f3c1f83 --- /dev/null +++ b/types/react-stripe-elements/react-stripe-elements-tests.tsx @@ -0,0 +1,156 @@ +import * as React from 'react'; +import { + StripeProvider, + CardElement, + Elements, + injectStripe, + CardNumberElement, + CardExpiryElement, + CardCVCElement, + PostalCodeElement, + ReactStripeElements, +} from 'react-stripe-elements'; +import InjectedStripeProps = ReactStripeElements.InjectedStripeProps; + +import ElementChangeResponse = stripe.elements.ElementChangeResponse; +import ElementsOptions = stripe.elements.ElementsOptions; +import PatchedTokenResponse = ReactStripeElements.PatchedTokenResponse; + +const cardElementProps: ElementsOptions = { + iconStyle: 'solid', + style: { + base: { + color: '#32325d', + lineHeight: '24px', + fontFamily: 'Roboto, "Helvetica Neue", sans-serif', + fontSmoothing: 'antialiased', + fontSize: '16px', + '::placeholder': { + color: '#aab7c4', + }, + }, + invalid: { + color: '#B71C1C', + iconColor: '#B71C1C', + }, + }, + hidePostalCode: true, + classes: { + base: 'field', + complete: 'complete', + empty: 'is-empty', + focus: 'is-focused', + invalid: 'is-invalid', + webkitAutofill: 'webkit-autofill', + }, + hideIcon: true, +}; + +const ElementsWithPropsTest: React.SFC = () => ( +

+ void 0} + onBlur={(event: ElementChangeResponse) => void 0} + onReady={() => void 0} + onFocus={(event: ElementChangeResponse) => void 0} + /> + void 0} + onBlur={(event: ElementChangeResponse) => void 0} + onReady={() => void 0} + onFocus={(event: ElementChangeResponse) => void 0} + /> + void 0} + onBlur={(event: ElementChangeResponse) => void 0} + onReady={() => void 0} + onFocus={(event: ElementChangeResponse) => void 0} + /> + void 0} + onBlur={(event: ElementChangeResponse) => void 0} + onReady={() => void 0} + onFocus={(event: ElementChangeResponse) => void 0} + /> + void 0} + onBlur={(event: ElementChangeResponse) => void 0} + onReady={() => void 0} + onFocus={(event: ElementChangeResponse) => void 0} + /> +
+); + +interface ComponentProps { + tokenCallback(token: PatchedTokenResponse): void; +} + +class WrappedComponent extends React.Component { + onSubmit = () => { + this.props.stripe.createToken({ + name: '', + address_line1: '', + address_line2: '', + address_city: '', + address_state: '', + address_zip: '', + address_country: '', + currency: '', + }).then((response: PatchedTokenResponse) => this.props.tokenCallback(response)); + } + + isFormValid = () => { + // use onChange callbacks from *Element components to detect if form is valid for submission + return false; + } + + render() { + return ( +
+ +