# Dispensing

A React block (a whole screen) in [Beamline](https://beamline.io/)'s [Clinic](https://beamline.io/components/apps/clinic) app. Live demo: https://beamline.io/components/dispensing

Dispensing from the shelf by lot. A product is found with its stock and prices (consumables left out unless asked); the quantity is drawn across its lots, earliest expiry first, each lot as long as what is left in it and filled by what is taken, the fill's end a grip with the field as its precise twin. Expired lots are left out and named; a quantity the lots can't cover is said; the lots can be chosen by hand, with a mismatch said. The visit's bill stands beside the line (what is already on it, the pending line and the total so far) and takes the line, with its lots, when it is added; the prescriptions on file for the product show under the line with their refills and expiry. Once on the bill, the line can become a new prescription or a refill of a matching one (no refill left, an expired authorization and a quantity mismatch said; the label apart from private notes). The shelf's lots are kept with their order, receipt, expiry and what is left; a lot's number and expiry are corrected while a used cost stays locked.

## Use it for

- Taking a quantity from stock that is tracked by lot or batch with an expiry: a clinic's or pharmacy's shelf, a lab's reagents, food or cosmetics stock.
- Anywhere expired lots must be left out visibly and the lots behind a dispensed quantity must stay on record.

## Not for

- Counting a delivery in against an order ([purchase-orders](https://beamline.io/components/purchase-orders)).
- One order line's history of shipments ([quantity-river](https://beamline.io/components/quantity-river)).
- Correcting a single count ([count-adjust](https://beamline.io/components/count-adjust)).

## Anatomy

- header: the product's mark, Dispense for the patient (or Stock lots), Dispense or Stock lots
- search: a combobox of products with category, stock, unit and pack prices (out of stock not choosable); Show consumables
- line: the product, how much can be dispensed from how many lots, the quantity field
- lots: one stretch per usable lot, as wide as what is left in it, filled by what is taken (a lot expiring within 60 days on the warning tone), with its number, expiry and what is taken of what is left; the fill's end a grip; expired lots named under it; a shortfall said
- choose the lots by hand: a quantity per lot, a mismatch said, back to earliest expiry first
- bar: what it puts on the bill, Add to the bill; once added, the lots it came from and Make it a prescription
- prescription: Refill or New; prescriptions on file with refills left and validity (expired ones not choosable); prescriber, validity, refills; label and private notes apart
- stock lots: All, Low, Out, Expiring with counts; each product opened into its lots (lot, from, received, expires, left of original, cost with a lock), Edit for number and expiry
- bill: On the bill · <patient>: each line with its detail and amount, the pending line (dashed, Not added yet), the visit total so far; a line added here joins it with its lots
- on file: the product's prescriptions with prescriber, date, quantity, refills left and until when (expired or no refills in the warning tone)

## States

- aggregated search, consumables hidden, out of stock, single lot, multiple lots, manual allocation, quantity mismatch, expired lot excluded, short of stock, added (source-linked billing), add refused
- prescription: new, matching refill, no eligible refill, expired authorization, quantity mismatch, saved
- lots: collapsed, opened, imported lot, ordered lot, expired lot, cost locked, correction saving, not saved
- loading: shaped skeletons
- phone: one column
- right to left: the fill runs from the right
- reduced motion: through the tokens

## Keyboard

- On the grip: Left/Right one unit, Shift ten, Home/End the limits; Escape while dragging puts the quantity back
- Tab through the search, the quantity, the lots by hand, the bar and the prescription

## Motion

A lot's fill grows to what is taken in the fast duration and follows the hand while the grip is held. Nothing runs at rest.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `products` (required) | `Product[]` | — |  |
| `line` | `DispenseLine \| null` | — | The line being dispensed, controlled; or defaultLine. |
| `defaultLine` | `DispenseLine \| null` | — |  |
| `onLineChange` | `((line: DispenseLine \| null) => void)` | — |  |
| `patient` (required) | `string` | — | The animal and visit the line is for, in your words ("Biscuit · visit Nov 2"). |
| `onDispense` | `((line: DispenseLine, allocation: Allocation) => Promise<unknown>)` | — | Add the line to the visit's bill with its lots. Reject with an Error: kept here, the reason said. |
| `prescriptions` | `Prescription[]` | — |  |
| `onPrescribe` | `((draft: PrescriptionDraft) => Promise<unknown>)` | — |  |
| `onSaveLot` | `((productId: string, edit: LotEdit) => Promise<unknown>)` | — |  |
| `bill` | `BillLine[]` | — | What is already on the visit's bill, shown beside the line with the running total; a dispensed line joins it. |
| `defaultView` | `"dispense" \| "stock"` | — |  |
| `today` | `string` | — |  |
| `currency` | `string` | — |  |
| `loading` | `boolean` | — |  |
| `product` | `string` | — |  |
| `className` | `string` | — | Classes on the documented visual root; no override by default. |
| `ref` | `Ref<HTMLDivElement>` | — | Receives the documented native target or imperative handle; omitted by default. |

## Built from

- [Alert](https://beamline.io/components/alert.md)
- [Avatar](https://beamline.io/components/avatar.md)
- [Bottom sheet](https://beamline.io/components/bottom-sheet.md)
- [Button](https://beamline.io/components/button.md)
- [Calendar](https://beamline.io/components/calendar.md)
- [Combobox](https://beamline.io/components/combobox.md)
- [Date picker](https://beamline.io/components/date-picker.md)
- [Input](https://beamline.io/components/input.md)
- [Label](https://beamline.io/components/label.md)
- [Number field](https://beamline.io/components/number-field.md)
- [Segmented control](https://beamline.io/components/segmented-control.md)
- [Select](https://beamline.io/components/select.md)
- [Skeleton](https://beamline.io/components/skeleton.md)
- [Spinner](https://beamline.io/components/spinner.md)
- [Text morph](https://beamline.io/components/text-morph.md)
- [Textarea](https://beamline.io/components/textarea.md)
- [Tooltip](https://beamline.io/components/tooltip.md)
- [Value grip](https://beamline.io/components/value-grip.md)

## Dependencies

`lucide-react`

## Import

```tsx
import { Dispensing } from "@beamline/dispensing";
```

## Get it

Dispensing is part of Beamline UI. Install the parts you need in your React app as compiled packages or editable source. [Get Beamline](https://beamline.io/checkout?pack=complete) · [Connect your agent](https://beamline.io/connect)

## More in Clinic

- [Appointment book](https://beamline.io/components/appointment-book): The desk's day with the appointment editor beside it. The appointment being edited is a block on the day like any other, drawn in the accent while it is…
- [Book an appointment](https://beamline.io/components/client-booking): A client books an appointment on the practice's own site: a service (length and price beside it), who gives it or anyone free, and where; a day with…
- [Services and hours](https://beamline.io/components/booking-setup): A practice's services and the hours its practitioners can be booked, one relation seen from both ends. A service reads as values and changes on demand…
- [Patient overview](https://beamline.io/components/patient-overview): One patient's record on a page. A search finds patients by name, chart number or birth date (recent patients when empty; same names told apart by birth…
- [Patient chart](https://beamline.io/components/patient-chart): A clinic's chart for one client and their animals. The client's header (phone, email, contact preferences, the balance with what it means and as of when…
- [Health questionnaire](https://beamline.io/components/health-questionnaire): A patient's medical history as a versioned questionnaire. Every question takes Yes, No or I don't know, and one not answered says so, never read as No; a…
- [Case workspace](https://beamline.io/components/case-workspace): A patient's clinical cases and how cases work at the practice. A case shows its status, type, teeth, staff, location and start; its checklist counts…
- [Care plan](https://beamline.io/components/care-plan): A client's care plan composed beside what the client will see of it. Every field says who sees it (the care team only, or the client too) and the…
- [Treatment plan](https://beamline.io/components/treatment-plan): A patient's treatment plan in named phases. Each procedure shows its tooth, status and fee beside the patient's and the insurer's estimate (not known…
- [Plan templates](https://beamline.io/components/plan-templates): Reusable treatment-plan templates. A template reads as words at rest and changes on demand: its name edits in place; the status its procedures start as…
- [Plan acceptance](https://beamline.io/components/plan-acceptance): A treatment plan presented for acceptance, from both sides. The practice chooses the agreement (the account's default or this location's own) and how…
- [Plan follow-up](https://beamline.io/components/plan-follow-up): The practice's follow-up lists, for the person who turns accepted treatment into booked chairs. Treatment plans lead with what's at stake: the value…
- [Session notes and tasks](https://beamline.io/components/session-notes): A session's note beside its follow-up tasks, each task tied to the exact words it came from: choose a task and its words light in the note or the…
- [Note templates](https://beamline.io/components/note-templates): A practitioner's note templates in one library with three ways in. My templates lists their own by kind, favourites first, each with when it was last…
- [Probing chart](https://beamline.io/components/probing-chart): A periodontal probing chart. Six sites per tooth (three buccal, three lingual) across both arches as you face the patient, each depth in its cell and…
- [Procedure picker](https://beamline.io/components/procedure-picker): Procedures, conditions and bundles put on a patient's teeth from the chair. The mode (existing, planned, completed) is chosen before adding and each…
- [Results notebook](https://beamline.io/components/results-notebook): A notebook entry's structured results. The entry's text above a bounded results table with typed columns: a sample link, numbers in their unit with their…
- [Insurance claims](https://beamline.io/components/claims-queue): Insurance claims as a queue: every claim at first, in the order a person works them (rejected by the clearinghouse, denied by the payer, partly paid, not…
- [Account ledger](https://beamline.io/components/account-ledger): A patient's account. All transactions or the ones needing attention, each dated with its type in a word, its amount and the running balance; entries that…
- [Record sharing](https://beamline.io/components/record-sharing): Records sent out of a clinic. Several visits' records and their documents (record, invoice, plan, lab result, image) are chosen separately, with how much…
- [Client journal](https://beamline.io/components/client-journal): A client's journal from both ends. The client's side is their home, built around their day: today's goals with how many are done and a mark each, done…

Part of [Beamline UI: polished, editable React components and complete screens for custom applications](https://beamline.io/). [Build your own style from any look; tokens, fonts, radii, motion; not only colours](https://beamline.io/docs/customize).
