shadcn.io is not affiliated with official shadcn/ui
Tip Calculator Dialog Block for React
A café terminal's pay screen with a tip popover shown open beside it: the bill, a tip of 15, 18, 20 or 25 percent or your own, how many people share it, a switch that rounds each share up to a dollar, and four lines that add it up.
Installation
Overview
Let people add a tip and split it without leaving the pay screen, with this tip-calculator popover for React with Base UI. It opens from the pay screen of Tabcloth, a café payments terminal: the page's header holds an outline Add tip Button, and the terminal's screen, an amount, the bill, a tip row and a Pay button, is drawn in a hairline frame with a plus mark on each corner, with the card beside it. It isn't modal, so the screen stays readable. The card has the bill and the number of people in two Fields with an Input each, a Toggle Group for the tip, 15, 18, 20, 25 or Custom, which turns on a percent field, and a Switch that rounds each share up to a whole dollar. Under them four lines work it out in whole cents: the tip, what the rounding adds, the total and what each person pays. Add tip to bill, the only Shine Button, writes the tip and the new total on the drawn screen. For preview the card is drawn open in place when the page loads; the header button opens the real Popover, with the same fields and the same state. For cafés, restaurants, taxi and delivery apps and any payment that takes a tip.
FAQ
Why is the card already open, and what do I keep?
So you can see it without a click. On load the card is a copy drawn in place beside the screen: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Add tip button opens the real card as a non-modal Popover that hangs from the button; Escape closes it and focus goes back to the button, and the copy stays closed until a reload. Both show the same TipFields component and share the block's state, so a tip chosen in the copy is there in the real one. In your app keep the Popover and drop the copy: the "in-place" state and the dialog element beside the screen.
How are the four lines worked out?
In whole cents. The tip is the bill times the percent, rounded to a cent. The tip and the bill are shared by the people, and each share is rounded up: to the next cent normally, or to the next whole dollar when the switch is on. Rounding adds is what those round-ups come to (what the shares add up to, minus the bill and the tip), the total is the bill, the tip and the rounding, and each person pays the rounded share. A share is never less than its part of the total, so the rounding line is how you see what was added. While a field is wrong the lines show dashes instead of numbers.
How does Custom work, and what is checked?
Custom turns on the percent field beside the Tip label and moves focus into it; it is always on the card, only switched off until you choose Custom, so choosing it moves nothing. The bill must look like 62.50, the percent can be from 0 to 100 with up to two decimals, and people from 1 to 12. The first problem shows in one slot under the fields, which is always there, when you press Add tip to bill, with focus on the field; once it shows it follows your typing and clears as soon as it is fixed.
Does it pay anything, and how do I wire it up?
No. Add tip to bill writes the tip and the total on the drawn screen, closes the card and says in a polite status message that nothing was paid. The header sentence and the trigger follow it: Change tip replaces Add tip. In your app pass the real bill into the card, send the chosen tip and the number of people to your payment provider when the customer pays, and let the server recompute the figures; the rounding here is a display choice, not a payment rule.
How does it look on a phone?
The drawn screen keeps its top, the amount, and the copy shown on load docks over the lower part of the frame with the actions inside it. The real popover is the same card, hung from the button and held inside the screen's width.
Is it accessible from the keyboard?
Yes. The card is named by its title and described by its sentence, focus starts in the bill field, and Escape closes it and returns focus to the button. The trigger is passed to PopoverTrigger through render, and the popover is controlled with open and onOpenChange. The tips are a group you move through with the arrow keys, each field's problem is tied to it with aria-describedby, the switch is named for what it does, and one polite status message reports the result. The copy shown on load moves no focus; Escape inside it closes it and puts focus on the header button.
Related
- Pro
Split Bill Dialog
Payments and plansA group-dining app's open check with a dialog that splits it by item: each item has a row of initials that toggle who shared it, and beside them what each person pays, reconciled to the cent, with the tax and tip spread fairly.
- Pro
Split Payment Dialog
Payments and plansA point-of-sale ticket with its split-payment dialog shown open: methods added from a select, an amount for each, a running total with a bar by method, and Pay held back until the remainder is exactly zero.
- Pro
A hardware shop's quantity dialog shown open: a number field with a button on each side over a four-tier price ladder that follows it, a hint to the next tier and totals worked out in whole cents.
- Pro
Quick Calculator Dialog
Media and widgetsA contractor's quote with a calculator dialog shown open: a display with the sum above its result, a four by five keypad, memory keys, a history of the last five sums, working keyboard keys and a Use result button that writes the figure on the quote.
- Pro
App Rating Dialog
Drawers and popoversA water tracker's Today screen with its rating drawer shown open over a drawn phone: five stars with a word each, then a branch, where four or five stars offers the store and one to three asks what could be better, with topics and a note.
- Pro
Audio Player Dialog
Drawers and popoversAn ambient-sound library's page with its mini player shown open over it: a floating panel with the track, a seek slider and its time, Previous, Play and Next, and a volume slider with mute. It isn't modal, so the page stays usable, and nothing really plays.