Pre-built UI components for OMS e-commerce sites
npm install @instockng/storefront-uiPre-built React UI components for building e-commerce storefronts with the OMS (Order Management System) API. Built with React, TypeScript, Tailwind CSS, and shadcn/ui.
``bash`
npm install @instockng/storefront-ui @tanstack/react-query lucide-react
- ✅ Drop-in Components - Fully functional UI out of the box
- ✅ Fully Typed - TypeScript support with auto-generated API types
- ✅ Customizable - Override styles with className props
- ✅ Theme Support - Pass custom colors, fonts, and styling
- ✅ Responsive - Mobile-first design
- ✅ Accessible - Built with accessibility in mind
`bash`
npm install @instockng/storefront-uior
pnpm add @instockng/storefront-ui
`bash`
npm install react react-dom @tanstack/react-query lucide-react
#### Option A: If your project already uses Tailwind CSS (Recommended)
Add storefront-ui to your Tailwind config's content array:
`ts`
// tailwind.config.ts
export default {
content: [
'./app/*/.{js,ts,jsx,tsx}',
'./node_modules/@instockng/storefront-ui/src/*/.{js,ts,jsx,tsx}', // Add this
],
// ... rest of your config
}
#### Option B: If your project doesn't use Tailwind CSS
Import the pre-built CSS file:
`tsx`
// app/layout.tsx or _app.tsx
import '@instockng/storefront-ui/styles.css';
Wrap your app with providers:
`tsx
import { ApiClientProvider } from '@instockng/storefront-ui';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
function App() {
return (
);
}
`
#### ProductGrid - Product Catalog
`tsx
import { ProductGrid } from '@instockng/storefront-ui';
function ProductCatalog() {
return (
onAddToCart={(variantId, quantity) => {
console.log('Adding to cart:', variantId, quantity);
}}
columns={3}
showStock={true}
/>
);
}
`
#### ShoppingCart - Cart Sidebar with Integrated Checkout
The ShoppingCart component now includes an integrated Checkout modal - no need to handle onCheckout unless you want custom behavior!
`tsx
import { ShoppingCart, CartProvider } from '@instockng/storefront-ui';
function MyApp() {
const [isCartOpen, setIsCartOpen] = useState(false);
return (
{/ Your app content /}
{/ Cart with integrated checkout - no onCheckout needed! /}
onClose={() => setIsCartOpen(false)}
onOrderSuccess={(orderId) => {
console.log('Order placed:', orderId);
// Optionally navigate or show success message
}}
showDiscountCode={true}
/>
);
}
`
Custom Checkout Handler (Optional)
If you need custom behavior, you can still pass onCheckout:
`tsx`
onClose={() => setIsCartOpen(false)}
onCheckout={() => navigate('/custom-checkout')} // Custom behavior
showDiscountCode={true}
/>
#### CheckoutSummary - Checkout Page
`tsx
import { CheckoutSummary } from '@instockng/storefront-ui';
function CheckoutPage() {
const navigate = useNavigate();
return (
brandId="brand-uuid"
onSuccess={(orderId, token) => {
navigate(/order-confirmation/${orderId}/${token});`
}}
cartSummary={{
subtotal: 100.00,
discountAmount: 10.00,
discountCode: 'SAVE10',
deliveryFee: 5.00,
total: 95.00
}}
/>
);
}
#### OrderConfirmation - Confirmation Page
`tsx
import { OrderConfirmation } from '@instockng/storefront-ui';
function OrderPage() {
const { orderId, token } = useParams();
return (
token={token}
onConfirm={(orderNumber) => {
console.log('Order confirmed:', orderNumber);
}}
/>
);
}
`
#### Customization
`tsx
token={token}
// Custom styling
className="bg-white"
headerClassName="text-brand-blue"
buttonClassName="bg-brand-primary hover:bg-brand-primary-dark"
cardClassName="shadow-lg border-brand-gray"
// Custom locale & currency
currency="USD"
locale="en-US"
// Custom WhatsApp support
whatsappHelpLink="https://wa.me/1234567890"
whatsappHelpNumber="+1 (234) 567-890"
// Callbacks
onConfirm={(orderNumber) => {
// Track analytics
analytics.track('Order Confirmed', { orderNumber });
// Redirect
router.push('/thank-you');
}}
onError={(error) => {
// Show toast notification
toast.error('Failed to confirm order');
}}
/>
`
- ProductGrid - Grid of products with add to cart, filtering, and customization
- ProductCard - Individual product with variants, images, stock status, and quantity selector
- ShoppingCart - Full cart display with items, discount codes, and checkout button
- CartItem - Individual cart item with quantity controls and remove button
- DiscountCodeInput - Standalone discount code input with validation
- CheckoutSummary - Complete checkout form with customer info, delivery, and payment
- DeliveryZoneSelector - Delivery zone dropdown grouped by state
- OrderConfirmation - Order confirmation page for confirming prospect orders
All components accept className props for custom styling:
`tsx`
headerClassName="text-brand-color" // Header section
buttonClassName="bg-brand-primary" // Buttons
cardClassName="border-brand-gray" // Card components
/>
The components are built with Tailwind CSS. Make sure your tailwind.config.js includes the package:
`js`
module.exports = {
content: [
'./src/*/.{js,ts,jsx,tsx}',
'./node_modules/@instockng/storefront-ui/*/.{js,ts,jsx,tsx}',
],
// ... your config
}
All @oms/api-client hooks are re-exported for convenience:
`tsx`
import {
useGetOrder,
useConfirmOrder,
useGetProducts,
useGetCart,
useCheckout,
// ... all other hooks
} from '@instockng/storefront-ui';
Access underlying UI components for custom layouts:
`tsx`
import {
Button,
Card,
CardContent,
CardHeader,
CardTitle,
Badge,
} from '@instockng/storefront-ui';
Helper functions for formatting:
`tsx
import {
formatCurrency,
formatDate,
formatDateTime,
getStatusColor,
cn, // Tailwind class merger
} from '@instockng/storefront-ui';
// Usage
formatCurrency(1999.99, 'USD', 'en-US'); // "$1,999.99"
formatDate('2024-01-15'); // "January 15, 2024"
formatDateTime('2024-01-15T10:30:00'); // "January 15, 2024 at 10:30 AM"
getStatusColor('shipped'); // "bg-blue-100 text-blue-800"
cn('base-class', { 'conditional': true }); // Merges Tailwind classes
`
All components are fully typed with TypeScript:
`tsx
import type { OrderConfirmationProps } from '@instockng/storefront-ui';
const config: OrderConfirmationProps = {
orderId: '123',
token: 'abc',
// TypeScript will autocomplete and validate all props
};
`
`tsx
import { OrderConfirmation } from '@instockng/storefront-ui';
export default function OrderPage({ orderId, token }) {
return
}
`
`tsx
import { OrderConfirmation } from '@instockng/storefront-ui';
export default function BrandedOrderPage({ orderId, token }) {
return (
token={token}
className="bg-gray-50 font-inter"
headerClassName="text-purple-600"
buttonClassName="bg-purple-600 hover:bg-purple-700"
cardClassName="border-purple-200"
currency="USD"
locale="en-US"
/>
);
}
`
`tsx
import { OrderConfirmation } from '@instockng/storefront-ui';
import { analytics } from './analytics';
export default function TrackedOrderPage({ orderId, token }) {
return (
token={token}
onConfirm={(orderNumber) => {
analytics.track('Order Confirmed', {
orderNumber,
orderId,
});
// Redirect to thank you page
window.location.href = '/thank-you';
}}
onError={(error) => {
analytics.track('Order Confirmation Failed', {
error: error.message,
orderId,
});
}}
/>
);
}
`
This package is part of the OMS monorepo. When the backend API changes:
`bashRegenerate types
cd packages/types
pnpm run generate
ISC