Creditcard
<loomi-creditcard> — a flippable credit-card input. The front face holds the card
number, cardholder name, and expiry; an edge button flips the card to its back to enter
the CVC. The network logo (Visa, Mastercard, American Express, Discover, Diners Club,
JCB, UnionPay, Maestro) is detected live from the number’s prefix, and a
contactless-payment glyph sits in the front’s top-right corner.
npm install @loomidev/creditcard litimport "@loomidev/creditcard";Basic Usage
Section titled “Basic Usage”<loomi-creditcard cardholder-name="Emma Reid"></loomi-creditcard>Typing a number auto-detects and shows the matching network logo, auto-groups the digits
(4-6-5 for Amex, 4-4-4-4 for most others), and caps the length to that network’s real
card-number length.
Flipping to the CVC
Section titled “Flipping to the CVC”Click the small round button on the card’s right edge to flip to the back and focus the
CVC field (Amex shows 4 digits, every other network shows 3). The same button flips back;
Escape while flipped does too.
<loomi-creditcard flipped></loomi-creditcard>document.querySelector("loomi-creditcard").addEventListener("flip", (e) => { console.log(e.detail.flipped);});Reading the value
Section titled “Reading the value”Not form-associated by design — card data is sensitive and is typically handed to a
payment provider’s tokenization SDK rather than posted through a plain HTML form. Read
the structured value from the value getter, or listen for input/change:
const el = document.querySelector("loomi-creditcard");el.addEventListener("change", (e) => { const { number, numberDigits, cardholderName, expiryMonth, expiryYear, cvc, brand } = e.detail; // hand off to your payment SDK});console.log(el.value); // same shape, read on demandPre-filling fields
Section titled “Pre-filling fields”number, cardholder-name, expiry-month, expiry-year, and cvc are all plain
attributes/properties. number accepts either raw digits or a masked saved-card value
such as **** **** **** 4242:
<loomi-creditcard cardholder-name="Emma Reid" number="4242424242424242" expiry-month="07" expiry-year="28"></loomi-creditcard>Forcing a network logo
Section titled “Forcing a network logo”Leave brand unset to auto-detect from number. Set it explicitly to override (e.g. a
saved card where you already know the network but don’t want to show the full number):
<loomi-creditcard brand="visa" number="•••• •••• •••• 4242"></loomi-creditcard>Theming
Section titled “Theming”Like every loomi component, color picks the gradient from the shared palette and
recolors instantly from plain page CSS — no rebuild:
<loomi-creditcard color="success"></loomi-creditcard>:root { --loomi-success-600: #15803d; --loomi-success-700: #166534;}Set variant="outline" for a bare card silhouette instead of the full-color gradient
face — a soft gray border with no background fill, for light or minimal UIs:
<loomi-creditcard variant="outline" cardholder-name="Emma Reid"></loomi-creditcard>Inline Card Information
Section titled “Inline Card Information”Use variant="inline" for the compact card-information layout: card number on the
first row, expiry and CVC on the second row, with no cardholder-name field.
<loomi-creditcard variant="inline"></loomi-creditcard>Validation
Section titled “Validation”validate() checks that every field is complete (full-length number for the detected
network, a non-blank name, a non-expired MM/YY, and a full-length CVC) when required
is set, and returns whether it passed:
<loomi-creditcard required show-error-inline error-message="Complete the card details to continue"></loomi-creditcard>
<script type="module"> const el = document.querySelector("loomi-creditcard"); payButton.addEventListener("click", () => { if (!el.validate()) return; // proceed });</script>Accessibility
Section titled “Accessibility”For the library-wide baseline, see Foundations — Accessibility.
Responsive behavior
Section titled “Responsive behavior”For the shared container and viewport rules, see Foundations — Responsive behavior.
Dark mode
Section titled “Dark mode”- Filled card faces keep brand accent gradients with
--loomi-text-on-primarylabels.
For theme activation, token overrides, and contrast guidance, see Foundations — Dark mode.
Attributes
Section titled “Attributes”| Attribute | Default | Description |
|---|---|---|
name | (blank) | Targeting class only (see LoomiElement) — not a form field, since this component doesn’t submit. |
cardholder-name | (blank) | Name printed on the card. |
number | (blank) | Card number, auto-grouped per network as the user types. Masked saved-card values like **** **** **** 4242 are preserved for edit screens. |
expiry-month | (blank) | Two-digit month, "01"–"12". |
expiry-year | (blank) | Two-digit year. |
cvc | (blank) | Security code (3 digits, 4 for Amex). |
brand | (auto-detected) | Force a network logo: visa, mastercard, amex, discover, diners, jcb, unionpay, maestro. |
color | "primary" | Gradient color, from the shared loomi palette. Ignored in outline variant. |
variant | "gradient" | "gradient" for the full-color accent face, "outline" for a bare silhouette, or "inline" for card number, expiry, and CVC fields only. |
locale | (blank) | Overrides the global locale for this instance. |
flipped | false | Shows the back face. (boolean) |
disabled | false | Disables every field and the flip button. (boolean) |
readonly | false | Read-only fields. (boolean) |
required | false | Fails validate() while any field is incomplete. (boolean) |
error-message | (blank) | Message shown when validation fails. |
show-error-inline | false | Render the error beneath the card. (boolean) |
no-clearing | false | Remove the default bottom margin. (boolean) |
Properties: value (read-only LoomiCreditcardValue), activeBrand (read-only,
the currently displayed LoomiCardBrand).
Methods: validate().
Parts: front, back, number, name, expiry, cvc, flip-button.
Events
Section titled “Events”| Event | Description |
|---|---|
change | Fired when the value is committed or changed. |
input | Fired while the value is edited. |
loomi-flip | Fired when the visible card face changes. |
Full Example
Section titled “Full Example”<loomi-creditcard cardholder-name="Emma Reid" number="5555555555554444" expiry-month="11" expiry-year="27" color="secondary" required></loomi-creditcard>Framework integration
Section titled “Framework integration”<loomi-creditcard> is a standard custom element, so the browser can use it in plain HTML, Blade, React, Vue, Angular, Svelte, Astro, and most other frameworks. The important beginner rule is: install the package, import it once before the tag is rendered, then write the Loomi tag in your template.
Where to run commands
Section titled “Where to run commands”Run install commands from the app where you want to use this component. That means the folder that contains that app’s package.json. Do not run these install commands from packages/creditcard unless you are editing LoomiUI itself.
cd /path/to/your-appnpm install @loomidev/creditcard litIf you are contributing to LoomiUI itself, first move to the top-level components folder. That is where the main package.json for all packages lives, and pnpm --filter ... commands should be run from there:
cd /path/to/your-copy-of-loomiui/componentspnpm --filter @loomidev/creditcard buildpnpm --filter @loomidev/creditcard typecheckChoose your framework
Section titled “Choose your framework”Use the CDN version for prototypes, documentation pages, or a quick reproduction. The import map tells the browser where to find Lit, which Loomi components use internally.
<script type="importmap"> { "imports": { "lit": "https://esm.sh/lit@3.3.3", "lit/": "https://esm.sh/lit@3.3.3/" } }</script><script type="module" src="https://esm.sh/@loomidev/creditcard"></script>
<loomi-creditcard cardholder-name="Emma Reid"></loomi-creditcard>In Vite, Webpack, Parcel, Rollup, or a framework build pipeline, install the package and import it once in your main app JavaScript file. After that, you can use the Loomi tag anywhere in your app.
import "@loomidev/creditcard";This component does not submit through a native <form> — read its value getter or listen for input/change instead (see “Reading the value” above).
Run the install command from your Laravel project root, then import the component in resources/js/app.js. If your project uses Laravel Vite, npm run dev and npm run build should also be run from the Laravel project root.
cd /path/to/your-laravel-appnpm install @loomidev/creditcard litnpm run devimport "@loomidev/creditcard";<loomi-creditcard cardholder-name="{{ $name }}"></loomi-creditcard>React can render Loomi tags directly. If you are on React 18, or if you need to pass arrays, objects, or functions, use a ref and assign those values after the component mounts.
import "@loomidev/creditcard";
export function LoomiExample() { return ( <loomi-creditcard cardholder-name="Emma Reid"></loomi-creditcard> );}If TypeScript does not recognize the Loomi tag in JSX, add it to your app’s JSX type declarations.
Import the package in the component that uses it, or once in your main Vue file. Vue templates can use Loomi tags directly. For arrays, objects, or functions, pass the value as a JavaScript property instead of as plain text.
<script setup>import "@loomidev/creditcard";</script>
<template> <loomi-creditcard cardholder-name="Emma Reid"></loomi-creditcard></template>If Vue warns that the tag is an unknown component, configure compilerOptions.isCustomElement for tags that start with loomi- in your Vite or Vue config.
Import the package once and tell Angular to allow custom HTML tags with CUSTOM_ELEMENTS_SCHEMA. For NgModule apps, add the schema to the module instead of the standalone component.
import { CUSTOM_ELEMENTS_SCHEMA, Component } from "@angular/core";import "@loomidev/creditcard";
@Component({ selector: "app-root", standalone: true, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: ` <loomi-creditcard cardholder-name="Emma Reid"></loomi-creditcard> `,})export class AppComponent {}Svelte can import the package inside a component script. Astro can import it in the frontmatter of the page or layout where the tag appears.
<script> import "@loomidev/creditcard";</script>
<loomi-creditcard cardholder-name="Emma Reid"></loomi-creditcard>---import "@loomidev/creditcard";---
<loomi-creditcard cardholder-name="Emma Reid"></loomi-creditcard>Server-side rendering notes
Section titled “Server-side rendering notes”Frameworks such as Next.js, Nuxt, SvelteKit, and Astro sometimes render HTML on the server before browser-only code runs. If your framework complains, move the Loomi import to client-side code. In Next.js, that usually means a component with "use client"; in Nuxt, it often means a .client.ts plugin.
Dependencies
Section titled “Dependencies”@loomidev/core@loomidev/theme