Repository navigation
React SDK 0.11.0
·
20 commits
to main
since this release
Breaking
- Components no longer read Tailwind classes, host CSS or shadcn's
--primary,--primary-foregroundand--bordervariables. Pass your colours asappearance.variablesinstead (for examplecolorPrimary: "var(--primary)"). Without anappearance, components use thelightlook: primary#4f46e5. The billing portal's green accent (#526949) is gone; setcolorPrimaryor the older--nozle-portal-accentto keep it. @tanstack/react-query(v5) is a required peer dependency.usePlansnow runs on TanStack Query throughBillingProvider's query client and keeps its return shape, plusrefetch.PricingTableno longer marks a plan "Custom" because its name or code contains "enterprise" or "custom". List the codes of plans sold on request incontactSalesPlans; their card shows "Custom" and a "Contact Sales" button that opensenterpriseEmail.PlanCardtakesplan(a catalog plan) withisCurrent,returnUrl,onSelectand the optionalfeatures. It no longer takesid,name,monthlyPrice,annualPrice,description,isAnnualorchildren, and thePlantype export is removed.PlanComparisontakesplans(catalog plans) and the optionalfeatures. A plan that lacks an entitlement shows a cross.featuresrows are keyed by plancode, notid.
Added
appearanceonBillingProviderand on every component that renders UI. It takes athemefrom@nozle-js/react/themes(light,dark,minimal,neobrutal,nozleornozleDark; an array stacks them, last wins), your ownvariables, and per-elementelements, where a string adds a class name and an object adds inline styles. Every part has a fixednozle-<key>class, such asnozle-pricingTableornozle-planCard__price. A component's ownappearancegoes on top of the provider's. Components render without Tailwind or host CSS; they read--nozle-*CSS variables, and the older--nozle-portal-*and--nozle-pricing-*names still work.Checkoutpasses the resolved theme to Stripe's Payment Element (Stripe'snighttheme on a dark background).useAppearanceand theAppearance,Theme,Variables,Elements,ElementKey,UseAppearanceandElementPropstypes are exported.PricingTabletakeshighlightStyle:outline(default) draws the highlighted card's border incolorHighlight;filledpaints the card incolorHighlightand its text and button incolorHighlightForeground. Both variables default to the primary colours.highlightLabelsets the badge on the highlighted card (default "Most Popular";nullshows no badge).- Two more themes,
nozleandnozleDark, give the Nozle dashboard look (flat cards, a hard ink shadow on buttons, Nunito). New variablesbuttonRadiusandbuttonBorderWidth(every button),buttonBorderColorandbuttonShadow(primary buttons only),colorSecondaryandcolorInput(secondary buttons), andlabelFont,labelTextTransform,labelLetterSpacingandfontFamilyNumbersfor table headers, status labels and numbers; a theme'splanCardLayout: "panel"lays plan cards out like the dashboard, withACTIVEon the current plan.neobrutalprimary buttons get a black border and offset shadow. - Text roles. New variables
fontTitle,fontHeading,fontMetric,fontBody,fontMetaandfontAction(CSSfontshorthands, written as--nozle-font-titleand so on) set the type of every element, withlabelFontas the label role; each defaults to a size infontFamily(fontMetricinfontFamilyNumberswhen set, in tabular figures). Every component root sets the body role, so no text takes its size, font or colour from the host page, including thePricingTabletoggle, theUsageAlertdismiss button, theCheckoutButtonstatus and error,Checkout, the billing portal and its dialogs.nozleandnozleDarkset the dashboard scale (title 20/900, heading 14/900, price 24/800 in Nunito, body 13, meta 11.5, buttons 14/800);neobrutalsets bolder titles and headings. - Customer billing hooks built on TanStack Query:
useSubscription(withpast_due),useEntitlement(featureCode),useCreditBalance(creditSystemCode?),useCreditHistory()(paged,operationsready forCreditHistory),useUsage({ period })(current period forUsageBreakdown, past periods forUsageTrend),useUpgradePreview(planCode),useInvoices({ page }),useInvoiceDownload()(resolves an invoice's PDF URL, ornullwhile it is generated) anduseBillingRefresh(). They read your backend route set asBillingProvider billingEndpoint(withbillingHeadersfor a CSRF token), served bycreateBillingHandlerfrom@nozle-js/node, so the browser holds no secret key and sees only the signed-in customer.BillingProvidertakes an optionalqueryClientto share your app's cache; the hooks pass their client explicitly and never replace yourQueryClientProvider. Failed requests throwBillingRequestError(status,code,requestId); a 4xx is not retried. CurrentPlanshows the customer's plan, status, price, scheduled change, usage against the plan's limits and a near-limit notice, and an alert when the subscription is past due. It reads the billing hooks by default;subscription,usage,detailsandactionscan be passed instead.currentPlanMeters(entitlements, usage)returns its meter rows for your own layout.PricingTable,PlanCardandPlanComparisonread what each plan gives from the public catalog: entitlements, credit grants and the usage prices of every charge model exceptcustomanddynamic.PricingTableaccepts an optionalfeatures(an array aligned to the rendered plans, or an object keyed by plan code),PlanCardan optionalfeatureslist andPlanComparisonoptionalfeaturesrows. When passed, they replace the generated lines.planFeatures(plan)andcomparisonRows(plans)return the same lines and rows for your own layout. TheCatalogEntitlement,CatalogCreditGrantRule,CatalogCharge,CatalogPrivilegeandComparisonRowtypes are exported, andCatalogPlanandPricingPlandeclare the optionalentitlements,credit_grant_rulesandchargesfields.PricingTableandPlanComparisonsort plans by base price, cheapest first (PricingTableputscontactSalesPlanslast), instead of showing the catalog's newest-first order. Plans in different currencies stay grouped, and ties keep the catalog order. Passsortto use your own order.sortPlansByPrice(plans)is exported. Afeaturesarray is aligned to the sorted order.CreditBalanceandCreditHistoryrender the SDK's credit balance and credit operations (CreditBalanceData,CreditOperationData), each with loading, error and empty states;CreditHistoryhas a load-more button for the SDK'snext_cursor.usageItems(entitlements, results)buildsUsageDashboardrows from a plan's metered entitlements andcan()results.UsageDashboardtakeserrorandemptyMessage, andUsageMeterandUsageDashboardaccept anullor missinglimitand showUnlimited.UsageBreakdown(a table of each feature's units and amount for one period, with the total) andUsageTrend(a bar chart of the amount, or the units of onefeatureCode, per period) render the usage your backend reads from Core'scurrent_usageandpast_usage(CustomerUsageData,ChargeUsageData). Both have loading, error and empty states and no chart library.PricingTable,PlanComparison,CurrentPlan,Checkout,UpgradeModalandBillingPortalshow "Powered by" and the Nozle logo when the merchant's Nozle plan keeps the branding (meta.nozle_brandingin the publishable-key catalog,nozleBrandingin the portal). Only the outermost of nested components shows it.useNozleBranding()andPoweredByNozleare exported for your own UI. The portal's plain "Powered by Nozle" footer is replaced.PricingTableandusePlansshare one cached catalog request.- Changing plan in
PlanChangeControl(and the billing portal) lists the plans as choices with price, upgrade or downgrade, and, inside aBillingProvider, each plan's description and features from the catalog; the confirmation step has a Back button.UpgradeModaltakesonBack. The portal subscription card puts View usage, Change plan and Cancel subscription in one action row.
Changed
PricingTablegives plans priced above the current plan the primary button and the current and cheaper plans the plain one (without a current plan, only the highlighted plan gets the primary button).- Tables (
CreditHistory,UsageBreakdown,PlanComparisonand the billing portal's usage and invoice tables) follow the Nozle dashboard table: a bordered frame, a tinted header band, 20px cell padding, one-line cells and right-aligned numbers in tabular figures; each theme styles the header labels its own way. The billing portal's invoice search is a single search field with an icon. UsageDashboardhas the same card frame as the other data components. AUsageMetervalue is in the text colour below 80% and turns to the warning colour at 80% and the danger colour at 95%, instead of always taking the bar colour.- Muted text follows
colorForeground. WhencolorMutedForegroundis not set it iscolorForegroundmixed 62% intocolorCardinstead of a fixed#6b7280; thelightanddarkthemes use the same mix. Error and success text use contrast-adjusted colours like warning text already did. Sizes are now the same for the same kind of text across components, so the default look changes slightly: plan names are 16px, prices and balances 28px, buttons 14px, badges and status pills use the label role. The panel plan card no longer hard-codes the dashboard sizes; the themes supply them.
Deprecated
nozlePreset(@nozle-js/react/styles/preset) has no effect on the components, which no longer use Tailwind. It is kept so existing imports still build. Theme the components withappearanceinstead.
Fixed
- The built package keeps
"use client"on the main entry, so a Next.js server component can render the components without a wrapper; before, it failed with "createContext only works in Client Components".@nozle-js/react/themesstays importable from server components. useUsage()is typed per period:CustomerUsageData | nullfor the current period andCustomerUsageData[]with{ period: "past" }, so its data passes toUsageBreakdownandUsageTrendwithout a cast.PricingPlan.descriptionacceptsnull, sousePlans().planspasses toPricingTable,PlanCardandPlanComparisonas is.PoweredByNozleused on its own takes the theme's colours.- Component buttons (
UpgradePrompt,PlanCard,PricingTableand its toggle,UsageAlertdismiss,PaymentMethodDisplay) aretype="button", so they no longer submit a form they sit inside. PricingTableshows the real billing interval (/quarter,/week,/6 months) instead of/monthfor every plan that is not yearly.PlanCardprints the plan's own currency instead of$for every plan.- The annual toggle no longer shows a hard-coded "Save 20%".