Preact

Tabler Payments for Preact offers payment provider logos as tree-shakable components, so you can use them the same way as any other Preact component.

This is an alternative to the CSS payments plugin for Preact projects: instead of adding payment/payment-provider-* classes to a <span>, you render a real Preact component. This gives you type-checked props, no separate CSS file to load, and tree-shaking - a page that only uses PaymentVisa doesn't ship the SVG markup for the other 99 providers.

This package is pre-1.0: the API may still change before a 1.0 release.

Installation

npm install @tabler/payments-preact
yarn add @tabler/payments-preact
pnpm install @tabler/payments-preact
bun install @tabler/payments-preact

preact is a peer dependency - the package reuses the Preact version already in your project instead of bundling its own.

How to use

Every provider - Visa, Mastercard, PayPal, and so on - is exported as its own named component, following the pattern Payment<ProviderName>. Import the one you need and render it like any other Preact component:

import { PaymentVisa } from '@tabler/payments-preact';

function AcceptedCards() {
  return <PaymentVisa variant="dark" size={32} />;
}

This works well when you know exactly which providers you want to show, and you write their names directly in your code - for example a fixed row of cards you accept.

Rendering a provider by name at runtime

Sometimes the provider isn't known ahead of time in your source code - for example, it's a string coming from an API response or a CMS field.

For this case, use the Payment component instead: pass the provider's slug as a provider prop and it renders the right logo for you.

import { Payment } from '@tabler/payments-preact';

<Payment provider="visa" variant="dark" size={32} />

The slug is the component name without the Payment prefix, in kebab-case - for example PaymentGooglePay is "google-pay". This works the same way for any of the 100+ supported payment providers.

If provider doesn't match a known slug, Payment renders nothing rather than throwing - useful when the data driving it isn't fully trusted (for example, a slug typed by hand in a CMS).

Props

Both the named provider components (PaymentVisa, PaymentMastercard, ...) and the dynamic Payment component accept the same set of props. Quick reference:

name type default required
variant 'light' | 'dark' light no
size string | number 24 no
title string - no
provider string - Payment only

variant

Every logo ships in two pre-baked color versions, light and dark - exactly like the CSS plugin's payment-provider-* (light) and payment-provider-*-dark classes. Pick variant="dark" when the logo sits on a dark surface (a dark navbar, a dark card, dark mode), and leave it at the light default everywhere else. There's no automatic detection of the surrounding background - you choose explicitly:

<PaymentVisa variant="light" /> {/* default, for light backgrounds */}
<PaymentVisa variant="dark" />  {/* for dark backgrounds */}

size

Sets the rendered SVG height, in pixels. The width is calculated for you from the provider's fixed 5:3 aspect ratio (width = size * 1.66666, rounded to 2 decimals), so a logo never looks stretched or squashed no matter what size you pick:

<PaymentVisa size={24} /> {/* 24px tall, 40px wide (the default) */}
<PaymentVisa size={48} /> {/* 48px tall, 80px wide */}

If you need a specific width instead - for example to fit a fixed-width column - pass width directly. An explicit width prop overrides the calculated one, while size still controls the height:

<PaymentVisa size={24} width={64} /> {/* 24px tall, but exactly 64px wide */}

title

Adds an accessible <title> element as the first child inside the SVG, which screen readers announce when they reach the logo. This does not happen automatically - without title (or an aria-label on a wrapping element), the logo is invisible to assistive technology, which is correct when it's purely decorative but wrong when it's the only way to identify a payment method:

<PaymentVisa title="Visa" />

See the Accessibility section on the CSS plugin page for concrete guidance on when a logo needs this and when it should stay aria-hidden instead.

Everything else

Any other prop you pass - class, onClick, style, data-*, and so on - is forwarded as-is to the root <svg> element, exactly like it would be on a plain HTML element:

<PaymentVisa class="rounded shadow-sm" onClick={() => selectMethod('visa')} data-testid="visa-logo" />

provider (dynamic Payment component only)

Required when using Payment instead of a named import. Takes the provider's slug as a string: the component name without the Payment prefix, in kebab-case. For example, PaymentGooglePay"google-pay". Any of the 100+ supported providers works here, not just the ones shown in the examples on this page - see the package README for the full list. See Rendering a provider by name at runtime above.

Available providers

There are over 100 supported providers, each with a Payment<ProviderName> component. See the package README for the full list of provider names and slugs.

On this page

130 sleek illustrations for your startup's visual identity.