Files
zooqueen f31a87bf93 style: draw every state in the monochrome palette
State now reads through shape, weight and tone rather than hue: the
active editor step and selected file carry a filled mark and heavier
label, recipients are told apart by six neutral tones, and status icons
lean on the clock/check/file glyphs they already draw. Red stays as the
one accent, reserved for destructive and rejected.

Drops the unreferenced --new-* ramps and the dawn/water scales, points
the stock Tailwind ring at --ring, and desaturates the sign scale so the
PDF certificate, audit log and email templates match the app.
2026-08-14 01:59:50 -07:00

92 lines
2.8 KiB
TypeScript

import { Plural } from '@lingui/react/macro';
import { useCurrentEnvelopeRender } from '@hanzo/esign-lib/client-only/providers/envelope-render-provider';
import { cn } from '@hanzo/esign-ui/lib/utils';
type EnvelopeItemSelectorProps = {
number: number;
primaryText: React.ReactNode;
secondaryText: React.ReactNode;
isSelected: boolean;
buttonProps: React.ButtonHTMLAttributes<HTMLButtonElement>;
};
export const EnvelopeItemSelector = ({
number,
primaryText,
secondaryText,
isSelected,
buttonProps,
}: EnvelopeItemSelectorProps) => {
return (
<button
title={typeof primaryText === 'string' ? primaryText : undefined}
className={`flex h-fit max-w-72 flex-shrink-0 cursor-pointer items-center space-x-3 rounded-lg border px-4 py-3 transition-colors ${
isSelected
? 'border-foreground/30 bg-muted text-foreground'
: 'border-border bg-muted/50 hover:bg-muted/70'
}`}
{...buttonProps}
>
{/* The selected file's number is filled, the rest are outlined. */}
<div
className={`flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full text-xs font-medium ${
isSelected ? 'bg-foreground text-background' : 'bg-muted text-muted-foreground'
}`}
>
{number}
</div>
<div className="min-w-0 text-left">
<div className={cn('truncate text-sm', isSelected ? 'font-semibold' : 'font-medium')}>
{primaryText}
</div>
<div className="text-xs text-muted-foreground">{secondaryText}</div>
</div>
<div
className={cn('h-2 w-2 flex-shrink-0 rounded-full', {
'bg-foreground': isSelected,
})}
></div>
</button>
);
};
type EnvelopeRendererFileSelectorProps = {
fields: { envelopeItemId: string }[];
className?: string;
secondaryOverride?: React.ReactNode;
};
export const EnvelopeRendererFileSelector = ({
fields,
className,
secondaryOverride,
}: EnvelopeRendererFileSelectorProps) => {
const { envelopeItems, currentEnvelopeItem, setCurrentEnvelopeItem } = useCurrentEnvelopeRender();
return (
<div className={cn('flex h-fit flex-shrink-0 space-x-2 overflow-x-auto p-4', className)}>
{envelopeItems.map((doc, i) => (
<EnvelopeItemSelector
key={doc.id}
number={i + 1}
primaryText={doc.title}
secondaryText={
secondaryOverride ?? (
<Plural
one="1 Field"
other="# Fields"
value={fields.filter((field) => field.envelopeItemId === doc.id).length}
/>
)
}
isSelected={currentEnvelopeItem?.id === doc.id}
buttonProps={{
onClick: () => setCurrentEnvelopeItem(doc.id),
}}
/>
))}
</div>
);
};