sales & grn fixers

This commit is contained in:
2026-10-04 15:31:59 +05:30
parent cea433e320
commit 3d3dbbbb59
52 changed files with 20761 additions and 482 deletions
@@ -12,6 +12,19 @@ export interface SuggestOption {
label: string
/** Optional secondary text shown on the right of the suggestion (e.g. a price). */
hint?: string
/** Optional smaller second line under the label (e.g. stock and item details). Not searched. */
detail?: string
/** Optional pill shown on the right, before the hint (e.g. an available stock count). */
badge?: string
badgeTone?: SuggestBadgeTone
}
export type SuggestBadgeTone = "muted" | "success" | "danger"
const badgeToneClass: Record<SuggestBadgeTone, string> = {
muted: "bg-muted text-muted-foreground",
success: "bg-emerald-500/15 text-emerald-700 dark:text-emerald-400",
danger: "bg-destructive/10 text-destructive",
}
interface SuggestInputProps {
@@ -32,6 +45,8 @@ interface SuggestInputProps {
* the list stays open, for adding several options in a row. Click away or press Esc to close. */
keepOpenOnSelect?: boolean
className?: string
/** Extra classes for the suggestion list (it defaults to the input's width), e.g. a wider min-width. */
listClassName?: string
"aria-label"?: string
}
@@ -53,6 +68,7 @@ export function SuggestInput({
browsable = false,
keepOpenOnSelect = false,
className,
listClassName,
...rest
}: SuggestInputProps) {
const [query, setQuery] = React.useState("")
@@ -218,7 +234,7 @@ export function SuggestInput({
id={listId}
role="listbox"
style={{ top: rect.bottom + 4, left: rect.left, width: rect.width }}
className="fixed z-50 max-h-72 min-w-72 overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10"
className={cn("fixed z-50 max-h-72 min-w-72 overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10", listClassName)}
>
{matches.length === 0 ? (
<p className="px-2.5 py-4 text-center text-sm text-muted-foreground">{emptyText}</p>
@@ -241,8 +257,29 @@ export function SuggestInput({
idx === highlight ? "bg-secondary text-secondary-foreground" : "hover:bg-muted"
)}
>
<span className="truncate">{option.label}</span>
{option.hint && <span className="shrink-0 text-xs text-muted-foreground tabular-nums">{option.hint}</span>}
{option.detail ? (
<span className="flex min-w-0 flex-col">
<span className="truncate">{option.label}</span>
<span className="truncate text-xs text-muted-foreground">{option.detail}</span>
</span>
) : (
<span className="truncate">{option.label}</span>
)}
{(option.badge || option.hint) && (
<span className="flex shrink-0 items-center gap-2">
{option.badge && (
<span
className={cn(
"rounded-full px-2 py-0.5 text-xs font-medium tabular-nums",
badgeToneClass[option.badgeTone ?? "muted"],
)}
>
{option.badge}
</span>
)}
{option.hint && <span className="text-xs text-muted-foreground tabular-nums">{option.hint}</span>}
</span>
)}
</button>
))
)}