Game UI

Checkout bar

The total on an accent band, the receipt above, the confirm under.

stablev0.5.0 Chromium 103 ui-scale safe

Install

Copies the file into components/ds/, with its registry dependencies and npm packages. See Installation for the one-time setup.
bunx shadcn@3 add @fastrp/checkout-bar

Examples

Default

Open alone
Toplam$45+ vergi
Toplam$3.638

API

<CheckoutBar />

The foot of a shop: the total on an accent band, the confirm block under it. The only accent fill a menu shows besides the wallet — what it costs, and the way to pay it. TAB takes the cursor to the confirm block when it sits in a `MenuScreen`.

PropTypeDefaultNotes
total*ReactNode—The figure: "$240".
confirmDisabledboolean—
confirmLabelReactNodeOnaylaThe confirm block's text: "ONAYLA", "SATIN AL".
labelReactNodeToplamOver the total, left: "TOPLAM".
lines{ label: ReactNode; value: ReactNode; }[]—What the total is made of, above it: Parçalar, %10 indirim, Vergi.
noteReactNode—Beside the figure, small: "+ VERGİ".
onConfirm(() => void)—

Dependencies

npm

  • None

Registry

Source

components/ds/checkout-bar.tsxShow
'use client';

import type * as React from 'react';
import { useUiSound } from '@/components/ds/ui-sounds';
import { cn } from '@/lib/utils';

// @fast-ds [email protected]

export type CheckoutBarProps = Omit<React.ComponentProps<'div'>, 'onClick'> & {
  /** Over the total, left: "TOPLAM". */
  label?: React.ReactNode;
  /** The figure: "$240". */
  total: React.ReactNode;
  /** Beside the figure, small: "+ VERGİ". */
  note?: React.ReactNode;
  /** What the total is made of, above it: Parçalar, %10 indirim, Vergi. */
  lines?: { label: React.ReactNode; value: React.ReactNode }[];
  /** The confirm block's text: "ONAYLA", "SATIN AL". */
  confirmLabel?: React.ReactNode;
  onConfirm?: () => void;
  confirmDisabled?: boolean;
};

/**
 * The foot of a shop: the total on an accent band, the confirm block under it. The only accent
 * fill a menu shows besides the wallet — what it costs, and the way to pay it. TAB takes the
 * cursor to the confirm block when it sits in a `MenuScreen`.
 */
function CheckoutBar({
  label = 'Toplam',
  total,
  note,
  lines,
  confirmLabel = 'Onayla',
  onConfirm,
  confirmDisabled,
  className,
  ...props
}: CheckoutBarProps) {
  const sound = useUiSound();

  return (
    <div
      data-slot="checkout-bar"
      className={cn('flex w-full select-none flex-col', className)}
      {...props}
    >
      {lines && lines.length > 0 && (
        <dl className="menu-block mb-menu-gap px-4 py-2 font-menu text-menu-hint text-foreground text-hud">
          {lines.map((line, index) => (
            // biome-ignore lint/suspicious/noArrayIndexKey: positional lines of a receipt
            <div key={index} className="flex items-center justify-between gap-4 py-1">
              <dt className="text-foreground/70">{line.label}</dt>
              <dd className="tabular-nums">{line.value}</dd>
            </div>
          ))}
        </dl>
      )}
      <div className="flex h-14 items-center justify-between gap-4 rounded-t-menu bg-primary px-4 text-primary-foreground">
        <span className="font-menu text-menu-hint">{label}</span>
        <span className="flex items-baseline gap-1.5">
          <span className="font-menu text-menu-figure tabular-nums">{total}</span>
          {note && <span className="font-menu text-xs opacity-80">{note}</span>}
        </span>
      </div>
      <button
        type="button"
        data-slot="checkout-confirm"
        onClick={() => {
          sound('select');
          onConfirm?.();
        }}
        disabled={confirmDisabled}
        data-sfx-hover="navigate"
        className="menu-block h-14 rounded-t-none font-menu text-menu-tab text-foreground text-hud outline-none transition-[background-color,color,transform] duration-fast active:scale-[0.99] hover:bg-foreground hover:text-background hover:[text-shadow:none] focus-visible:bg-foreground focus-visible:text-background focus-visible:[text-shadow:none] disabled:cursor-not-allowed disabled:opacity-40"
      >
        {confirmLabel}
      </button>
    </div>
  );
}

export { CheckoutBar };