Inventory
A stock table where merchants edit quantities in place and save adjustments. Handles live orders, edits from another device and oversold or untracked stock.
Inventory is the stock table for one location. Each row is a variant with its thumbnail, title and SKU. The columns follow Shopify: Unavailable, Committed, Available, On hand and Incoming. On hand is always Available plus Committed plus Unavailable, so editing one of them moves the other by the same amount.
Click a quantity, press Enter or start typing to open the editor. Adjust by adds or removes stock and Set to enters a count, with a live preview such as 42 → 47. The arrow keys step by 1, or by 10 with Shift. Enter keeps the change in a draft and moves down a row, and Escape cancels. Edited cells get a dot and show their delta, and a save bar collects the batch with one reason, such as Received or Cycle count.
Saving sends adjustments, not overwrites. Each one carries its delta, the quantity it was based on and the result, so an order placed while you were typing isn’t lost. A row the server rejects stays in the draft with its message, such as “Quantity changed to 40 by another device”, and Reapply sends it again on top of the new quantity.
When new items arrive, changed numbers roll digit by digit and flash briefly. Rows don’t re-sort while you’re working in the table. The toolbar has search by title or SKU, Low stock, Out of stock and Incoming filters, sorting by Available, and bulk Set to 0 or Adjust by for selected rows. Loading, an empty location, no results, untracked variants, oversold stock and an all-locations read-only view are covered too, and every row has its adjustment history in a sheet.
Procurez-vous HextaUI Pro
Un seul paiement débloque tous les blocs, y compris les prochains. Voir les tarifs.
Ajouter le registre Pro à components.json
components.json Ajouter votre token
Créez un token sur votre page de compte et placez-le dans
.env.localsous le nomHEXTAUI_PRO_TOKEN.Ajouter le block
pnpm dlx shadcn@latest add @hextaui-pro/inventory
Save to Shopify
Send each batch to inventoryAdjustQuantities with the delta and changeFromQuantity. Shopify rejects a change when the quantity moved since you loaded it, and those user errors come back as failed rows that the merchant can reapply.
Medusa inventory levels
Map Medusa location levels to items: stocked minus reserved is Available, and reserved is Committed. Each adjustment posts the new stocked quantity for that inventory item and location.
Map a CSV import
previewCsvImport matches rows to variants by SKU and turns each count into an adjustment against the current quantity. It also lists unknown SKUs and bad rows so you can show them before anything is saved.
Anatomie
Les parties à composer, de l’extérieur vers l’intérieur.
| Partie | Description |
|---|---|
InventoryTable | Toolbar, editable grid, quantity editor, history sheet and save bar. |
QuantityEditor | The Adjust by / Set to popover with a stepper and a before → after preview. |
InventoryHistorySheet | A side sheet listing who changed a row, when, why, by how much and the resulting quantity. |
buildAdjustments, draftDelta, onHand, stockStatus | Pure helpers for adjustments, deltas, on-hand math and stock states. They work on the server too. |
InventoryTable
Also takes div props.
| Prop | Type | Par défaut |
|---|---|---|
itemsVariants at the current location. Pass new arrays as orders come in, and changed numbers roll and flash in place. | InventoryItem[] | – |
onSaveApply the batch, update items, then resolve. Return { failed } to keep those rows in the draft with a message, or throw to fail the whole batch. | (adjustments: InventoryAdjustment[]) => Promise<InventorySaveResult | void> | – |
loadingShows skeleton rows. | boolean | false |
locationNameUsed in the empty state, the history sheet and labels. | string | – |
readOnlyTurns off editing and selection, for example when showing all locations. | boolean | false |
lowStockThresholdAvailable at or below this counts as low stock. | number | 5 |
defaultReasonThe reason preselected in the save bar. | InventoryReason | "correction" |
onTrackShows a Track button on untracked rows. | (item: InventoryItem) => Promise<void> | – |
onLoadHistoryLoads the adjustment history when the sheet opens. Throw to show a retry state. | (item: InventoryItem) => Promise<InventoryHistoryEntry[]> | – |
onDirtyChangeCalled when unsaved changes appear or clear, for navigation guards. | (dirty: boolean) => void | – |
localeLocale for numbers and dates. | Intl.LocalesArgument | "en-US" |
labelsColumn names, filters, save bar and empty-state words. | Partial<InventoryTableLabels> | – |
| Prop | Type | Par défaut |
|---|---|---|
idYour inventory item or variant id. It comes back in each adjustment. | string | – |
productTitle, variantTitle, sku, imageWhat the row shows. Search matches the title, variant and SKU. | string, string, string, { src; alt? } | – |
availableSellable stock. Can be negative when overselling is allowed. | number | – |
committedStock in unfulfilled orders. | number | – |
unavailableCounted in On hand but not sellable, with a breakdown popover. | { damaged?; qualityControl?; safetyStock?; reserved? } | – |
incomingTransfers and purchase orders on the way. Past dates show as overdue. | { id; quantity; expectedOn?; source? }[] | – |
trackedfalse shows Not tracked instead of numbers. | boolean | true |
| Prop | Type | Par défaut |
|---|---|---|
itemIdThe row that changed. | string | – |
fieldWhich quantity was edited. Both move by the same delta. | "available" | "onHand" | – |
deltaThe change to apply. Send this to the server, not the result. | number | – |
compareQuantityThe quantity the change was based on, for compare-and-set checks. | number | – |
quantityThe expected result. | number | – |
reasoncorrection, received, damaged, theft_or_loss, returned or cycle_count. | InventoryReason | – |
| Touche | Action |
|---|---|
| ArrowUpArrowDownArrowLeftArrowRight | Moves between cells like a spreadsheet. In the editor, Up and Down step the quantity. |
| ShiftArrowUp | Steps the quantity by 10 in the editor. |
| Enter | Opens the editor on a quantity. In the editor, keeps the change and moves down a row. |
| 0-9 | Starts editing with that digit. + and − start an Adjust by. |
| Escape | Cancels the editor, or clears the selection in the grid. |
| Backspace | Removes the unsaved change on the focused row. |
| Space | Selects or clears the row when its checkbox has focus. |
| ModS | Saves the draft. |
- The grid uses one tab stop that moves with the arrow keys. Every cell has a name such as “Available for Ring Vase, Sand / Medium, 47, changed by +5, not saved”.
- A polite live region announces each change kept in the draft, selection counts and “Saved 3 changes”. Save failures go to an alert region, and the failed row links to its message.
- Stock states are never shown by color alone. Low stock, Out of stock and Oversold are written out, oversold numbers get a warning icon, and edited cells show their delta as text.
- Rows don’t move while focus is in the table or a popover is open, so live updates never pull the row out from under a screen reader or keyboard user. Number rolls and flashes are turned off for reduced motion.
Construit avec
Les composants HextaUI gratuits dont Inventory est constitué. Chacun s’installe séparément.
Code
9 fichiers, ajoutés à components/blocks/inventory.