@caratlogic/design-system 0.1.20 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/molecules/CustomCombobox/CustomCombobox.d.ts +1 -1
- package/dist/components/molecules/CustomCombobox/CustomCombobox.d.ts.map +1 -1
- package/dist/components/molecules/CustomCombobox/CustomCombobox.types.d.ts +2 -0
- package/dist/components/molecules/CustomCombobox/CustomCombobox.types.d.ts.map +1 -1
- package/dist/components/molecules/DataEditableTable/DataEditableTable.d.ts +1 -1
- package/dist/components/molecules/DataEditableTable/DataEditableTable.d.ts.map +1 -1
- package/dist/components/molecules/DataEditableTable/DataEditableTable.types.d.ts +2 -0
- package/dist/components/molecules/DataEditableTable/DataEditableTable.types.d.ts.map +1 -1
- package/dist/components/molecules/MetricTile/MetricTile.types.d.ts +1 -1
- package/dist/components/organisms/PartnerShareCard/PartnerShareCard.d.ts +1 -1
- package/dist/components/ui/select.d.ts +3 -1
- package/dist/components/ui/select.d.ts.map +1 -1
- package/dist/index.cjs.js +66 -68
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +66 -68
- package/dist/index.esm.js.map +1 -1
- package/dist/ui.cjs.js +4 -2
- package/dist/ui.cjs.js.map +1 -1
- package/dist/ui.esm.js +4 -2
- package/dist/ui.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -21178,9 +21178,9 @@ function useSelectedComboboxOption(value, options) {
|
|
|
21178
21178
|
}, [normalizedValue, options]);
|
|
21179
21179
|
}
|
|
21180
21180
|
|
|
21181
|
-
function CustomCombobox({ options, placeholder = 'Select option...', value, onChange, className, }) {
|
|
21181
|
+
function CustomCombobox({ options, placeholder = 'Select option...', value, onChange, className, emptyMessage = 'No option found.', }) {
|
|
21182
21182
|
const selectedItem = useSelectedComboboxOption(value, options);
|
|
21183
|
-
return (jsx(SearchableSelect, { selectedItem: selectedItem, onChange: (opt) => onChange(opt.label), getOptionKey: (o) => o.value, getOptionLabel: (o) => o.label, options: options, searchPlaceholder: placeholder, emptyMessage:
|
|
21183
|
+
return (jsx(SearchableSelect, { selectedItem: selectedItem, onChange: (opt) => onChange(opt.label), getOptionKey: (o) => o.value, getOptionLabel: (o) => o.label, options: options, searchPlaceholder: placeholder, emptyMessage: emptyMessage, className: className }));
|
|
21184
21184
|
}
|
|
21185
21185
|
|
|
21186
21186
|
function useExpandableRows() {
|
|
@@ -21579,7 +21579,7 @@ function EditableCellContent({ col, row, value, isEditing, width, onEditValueCha
|
|
|
21579
21579
|
return jsx(Fragment$2, { children: clipToWidth(stringValue, width) });
|
|
21580
21580
|
}
|
|
21581
21581
|
|
|
21582
|
-
function DataEditableTable({ data, columns, onRowClick, enableSelection = false, columnStyles = {}, onEditChange, onSaveRow, sortBy, setSortBy, sortOrder, setSortOrder, saving, selectedRows = [], onSelectionChange, isArchiveView = false, selectionInArchiveView = false, permissionKey = '', columnWidths, onColumnResize, pagination, fetchBusinessContacts, showGrid = true, }) {
|
|
21582
|
+
function DataEditableTable({ data, columns, onRowClick, enableSelection = false, columnStyles = {}, onEditChange, onSaveRow, sortBy, setSortBy, sortOrder, setSortOrder, saving, selectedRows = [], onSelectionChange, isArchiveView = false, selectionInArchiveView = false, permissionKey = '', columnWidths, onColumnResize, pagination, fetchBusinessContacts, showGrid = true, emptyState, }) {
|
|
21583
21583
|
const showSelectionColumn = enableSelection && (!isArchiveView || selectionInArchiveView);
|
|
21584
21584
|
const vBorder = showGrid ? 'border-r' : '';
|
|
21585
21585
|
const { localWidths, draggingKey, tableRef, handleResizeMouseDown } = useColumnResize({
|
|
@@ -21603,77 +21603,73 @@ function DataEditableTable({ data, columns, onRowClick, enableSelection = false,
|
|
|
21603
21603
|
setSortOrder('asc');
|
|
21604
21604
|
}
|
|
21605
21605
|
};
|
|
21606
|
-
return (jsxs("div", { className: "w-full h-full rounded-lg border border-border bg-card flex flex-col overflow-hidden", children: [
|
|
21607
|
-
|
|
21608
|
-
|
|
21609
|
-
|
|
21610
|
-
|
|
21611
|
-
const w = localWidths[col.key];
|
|
21612
|
-
const isDragging = draggingKey === col.key;
|
|
21613
|
-
const isPinnedRight = col.key === 'actions';
|
|
21614
|
-
const thStyle = w || isDragging
|
|
21615
|
-
? {
|
|
21616
|
-
width: `var(--col-w-${col.key})`,
|
|
21617
|
-
minWidth: `var(--col-w-${col.key})`,
|
|
21618
|
-
maxWidth: `var(--col-w-${col.key})`,
|
|
21619
|
-
}
|
|
21620
|
-
: isPinnedRight
|
|
21621
|
-
? { width: '72px', minWidth: '72px', maxWidth: '72px' }
|
|
21622
|
-
: undefined;
|
|
21623
|
-
return (jsxs("th", { className: cn('px-4 py-1.5 relative first:!pl-6 text-left whitespace-nowrap font-semibold text-sm border-b border-solid !border-border', vBorder, isArchiveView && !isPinnedRight && 'pl-1', col.sortable && '!cursor-pointer hover:bg-muted/60', isDragging && 'bg-primary/10', isPinnedRight && pinnedHeaderClass()), style: thStyle, onClick: () => handleColumnClick(col.key, col.sortable), children: [jsxs("div", { className: cn('gap-2', w && 'overflow-hidden', col.sortable && 'flex items-center !cursor-pointer', isPinnedRight && 'flex items-center justify-center'), children: [w && typeof col.header === 'string' ? (jsx("span", { className: "truncate", title: col.header, children: col.header })) : (col.header), col.sortable && (jsx(SortIcon, { active: sortBy === col.key, order: sortOrder }))] }), jsx("div", { className: cn('absolute right-0 top-0 h-full w-1.5 z-20 cursor-col-resize select-none transition-colors hover:bg-primary/40', isDragging && 'bg-primary/40'), onMouseDown: (e) => handleResizeMouseDown(e, col.key), onClick: (e) => e.stopPropagation() })] }, col.key.toString()));
|
|
21624
|
-
})] }) }), jsx("tbody", { children: data.length === 0 ? (jsx("tr", { className: "h-12", children: jsx("td", { colSpan: columns.length +
|
|
21625
|
-
(!isArchiveView ? 1 : 0) +
|
|
21626
|
-
(showSelectionColumn ? 1 : 0), className: "text-center p-6 text-muted-foreground", children: "No data available" }) })) : (data.map((row, rowIndex) => {
|
|
21627
|
-
const isEditing = editingRow === row.id && editingRow !== null;
|
|
21628
|
-
const isSaving = savingRow === row.id;
|
|
21629
|
-
const isSelected = selectedSet.has(row.id);
|
|
21630
|
-
const bgClass = isEditing
|
|
21631
|
-
? 'bg-warning/10 hover:bg-warning/10'
|
|
21632
|
-
: isSelected
|
|
21633
|
-
? 'bg-primary/10 hover:bg-primary/10'
|
|
21634
|
-
: rowIndex % 2 === 0
|
|
21635
|
-
? 'bg-card hover:bg-secondary'
|
|
21636
|
-
: 'bg-background hover:bg-secondary';
|
|
21637
|
-
return (jsxs("tr", { className: cn('group/row h-[46px] transition-colors text-sm text-table-cell', bgClass, onRowClick && 'cursor-pointer'), onClick: () => onRowClick?.(row), children: [isArchiveView ? null : (jsx("td", { className: cn('px-3 py-1.5 text-center first:!pl-6 border-b border-solid !border-border', vBorder), children: jsx(Protected, { module: permissionKey, minLevel: PERMISSIONS.WRITE, children: jsx("button", { onClick: (e) => {
|
|
21638
|
-
e.stopPropagation();
|
|
21639
|
-
handleEditIconClick(row.id, row);
|
|
21640
|
-
}, disabled: isSaving, className: cn('p-1 rounded hover:bg-primary/20 transition-colors !cursor-pointer', isEditing
|
|
21641
|
-
? 'text-success'
|
|
21642
|
-
: 'text-muted-foreground'), children: isSaving ? (jsx(LoaderCircle, { size: 16, className: "animate-spin text-primary" })) : isEditing ? (jsx(Check, { size: 16 })) : (jsx(Pencil, { size: 16 })) }) }) })), showSelectionColumn && (jsx("td", { className: cn('px-3 py-1.5 first:!pl-6 border-b border-solid !border-border', vBorder), onClick: (e) => e.stopPropagation(), children: jsx(Checkbox, { checked: isSelected, onCheckedChange: () => toggleRow(row.id) }) })), columns.map((col) => {
|
|
21643
|
-
const value = isEditing
|
|
21644
|
-
? editValues[col.key]
|
|
21645
|
-
: row[col.key];
|
|
21606
|
+
return (jsxs("div", { className: "w-full h-full rounded-lg border border-border bg-card flex flex-col overflow-hidden", children: [jsxs("div", { className: "overflow-auto flex-1", children: [jsxs("table", { ref: tableRef, className: "min-w-[70vh] w-full text-xs text-center border-separate", style: { borderSpacing: 0 }, children: [jsx("thead", { className: "sticky top-0 z-20 !bg-table-header border-b border-border text-secondary-foreground text-sm", children: jsxs("tr", { className: "h-[40px]", children: [!isArchiveView && (jsx("th", { className: cn('px-3 py-1.5 text-left font-semibold w-8 first:!pl-6 border-b border-solid !border-border', vBorder) })), showSelectionColumn && (jsx("th", { className: cn('px-3 py-1.5 text-center font-semibold first:!pl-6 border-b border-solid !border-border', vBorder), children: jsx(Checkbox, { checked: allSelected
|
|
21607
|
+
? true
|
|
21608
|
+
: someSelected
|
|
21609
|
+
? 'indeterminate'
|
|
21610
|
+
: false, onCheckedChange: toggleSelectAll }) })), columns.map((col) => {
|
|
21646
21611
|
const w = localWidths[col.key];
|
|
21612
|
+
const isDragging = draggingKey === col.key;
|
|
21647
21613
|
const isPinnedRight = col.key === 'actions';
|
|
21648
|
-
const
|
|
21614
|
+
const thStyle = w || isDragging
|
|
21649
21615
|
? {
|
|
21650
21616
|
width: `var(--col-w-${col.key})`,
|
|
21651
21617
|
minWidth: `var(--col-w-${col.key})`,
|
|
21652
21618
|
maxWidth: `var(--col-w-${col.key})`,
|
|
21653
21619
|
}
|
|
21654
21620
|
: isPinnedRight
|
|
21621
|
+
? { width: '72px', minWidth: '72px', maxWidth: '72px' }
|
|
21622
|
+
: undefined;
|
|
21623
|
+
return (jsxs("th", { className: cn('px-4 py-1.5 relative first:!pl-6 text-left whitespace-nowrap font-semibold text-sm border-b border-solid !border-border', vBorder, isArchiveView && !isPinnedRight && 'pl-1', col.sortable && '!cursor-pointer hover:bg-muted/60', isDragging && 'bg-primary/10', isPinnedRight && pinnedHeaderClass()), style: thStyle, onClick: () => handleColumnClick(col.key, col.sortable), children: [jsxs("div", { className: cn('gap-2', w && 'overflow-hidden', col.sortable && 'flex items-center !cursor-pointer', isPinnedRight && 'flex items-center justify-center'), children: [w && typeof col.header === 'string' ? (jsx("span", { className: "truncate", title: col.header, children: col.header })) : (col.header), col.sortable && (jsx(SortIcon, { active: sortBy === col.key, order: sortOrder }))] }), jsx("div", { className: cn('absolute right-0 top-0 h-full w-1.5 z-20 cursor-col-resize select-none transition-colors hover:bg-primary/40', isDragging && 'bg-primary/40'), onMouseDown: (e) => handleResizeMouseDown(e, col.key), onClick: (e) => e.stopPropagation() })] }, col.key.toString()));
|
|
21624
|
+
})] }) }), jsx("tbody", { children: data.map((row, rowIndex) => {
|
|
21625
|
+
const isEditing = editingRow === row.id && editingRow !== null;
|
|
21626
|
+
const isSaving = savingRow === row.id;
|
|
21627
|
+
const isSelected = selectedSet.has(row.id);
|
|
21628
|
+
const bgClass = isEditing
|
|
21629
|
+
? 'bg-warning/10 hover:bg-warning/10'
|
|
21630
|
+
: isSelected
|
|
21631
|
+
? 'bg-primary/10 hover:bg-primary/10'
|
|
21632
|
+
: rowIndex % 2 === 0
|
|
21633
|
+
? 'bg-card hover:bg-secondary'
|
|
21634
|
+
: 'bg-background hover:bg-secondary';
|
|
21635
|
+
return (jsxs("tr", { className: cn('group/row h-[46px] transition-colors text-sm text-table-cell', bgClass, onRowClick && 'cursor-pointer'), onClick: () => onRowClick?.(row), children: [isArchiveView ? null : (jsx("td", { className: cn('px-3 py-1.5 text-center first:!pl-6 border-b border-solid !border-border', vBorder), children: jsx(Protected, { module: permissionKey, minLevel: PERMISSIONS.WRITE, children: jsx("button", { onClick: (e) => {
|
|
21636
|
+
e.stopPropagation();
|
|
21637
|
+
handleEditIconClick(row.id, row);
|
|
21638
|
+
}, disabled: isSaving, className: cn('p-1 rounded hover:bg-primary/20 transition-colors !cursor-pointer', isEditing ? 'text-success' : 'text-muted-foreground'), children: isSaving ? (jsx(LoaderCircle, { size: 16, className: "animate-spin text-primary" })) : isEditing ? (jsx(Check, { size: 16 })) : (jsx(Pencil, { size: 16 })) }) }) })), showSelectionColumn && (jsx("td", { className: cn('px-3 py-1.5 first:!pl-6 border-b border-solid !border-border', vBorder), onClick: (e) => e.stopPropagation(), children: jsx(Checkbox, { checked: isSelected, onCheckedChange: () => toggleRow(row.id) }) })), columns.map((col) => {
|
|
21639
|
+
const value = isEditing
|
|
21640
|
+
? editValues[col.key]
|
|
21641
|
+
: row[col.key];
|
|
21642
|
+
const w = localWidths[col.key];
|
|
21643
|
+
const isPinnedRight = col.key === 'actions';
|
|
21644
|
+
const tdStyle = w || draggingKey === col.key
|
|
21655
21645
|
? {
|
|
21656
|
-
width:
|
|
21657
|
-
minWidth:
|
|
21658
|
-
maxWidth:
|
|
21646
|
+
width: `var(--col-w-${col.key})`,
|
|
21647
|
+
minWidth: `var(--col-w-${col.key})`,
|
|
21648
|
+
maxWidth: `var(--col-w-${col.key})`,
|
|
21659
21649
|
}
|
|
21660
|
-
:
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
|
|
21671
|
-
|
|
21672
|
-
|
|
21673
|
-
|
|
21674
|
-
|
|
21675
|
-
|
|
21676
|
-
|
|
21650
|
+
: isPinnedRight
|
|
21651
|
+
? {
|
|
21652
|
+
width: '72px',
|
|
21653
|
+
minWidth: '72px',
|
|
21654
|
+
maxWidth: '72px',
|
|
21655
|
+
}
|
|
21656
|
+
: undefined;
|
|
21657
|
+
// Pinned cells need an OPAQUE bg matching the row state so the
|
|
21658
|
+
// scrolling content underneath doesn't bleed through — no alpha tints.
|
|
21659
|
+
const pinnedBg = isPinnedRight
|
|
21660
|
+
? isEditing
|
|
21661
|
+
? 'bg-[#FEFCE8] dark:bg-[#422006]'
|
|
21662
|
+
: isSelected
|
|
21663
|
+
? 'bg-[#EFF6FF] dark:bg-[#172554]'
|
|
21664
|
+
: 'bg-card group-hover/row:bg-table-header'
|
|
21665
|
+
: '';
|
|
21666
|
+
return (jsx("td", { className: cn('px-4 py-1.5 first:!pl-6 border-b border-border whitespace-nowrap text-table-cell border-solid !border-border', vBorder, isPinnedRight || col.align === 'center'
|
|
21667
|
+
? 'text-center'
|
|
21668
|
+
: typeof value === 'number'
|
|
21669
|
+
? 'text-right'
|
|
21670
|
+
: 'text-left', isArchiveView && !isPinnedRight && 'pl-2', columnStyles?.[col.key.toString()] || '', draggingKey === col.key && 'bg-primary/5', isPinnedRight && pinnedCellClass(pinnedBg)), style: tdStyle, children: jsx(EditableCellContent, { col: col, row: row, value: value, isEditing: isEditing, width: w, onEditValueChange: handleEditValueChange, fetchBusinessContacts: fetchBusinessContacts }) }, col.key.toString()));
|
|
21671
|
+
})] }, row.id));
|
|
21672
|
+
}) })] }), data.length === 0 && (jsx("div", { className: "sticky left-0 flex w-full items-center justify-center p-6 text-sm text-muted-foreground", children: emptyState ?? 'No data available' }))] }), pagination] }));
|
|
21677
21673
|
}
|
|
21678
21674
|
|
|
21679
21675
|
/**
|
|
@@ -37147,7 +37143,7 @@ function SelectTrigger({ className, size = 'default', children, ...props }) {
|
|
|
37147
37143
|
return (jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("border-input-border cursor-pointer data-[placeholder]:!text-[var(--placeholder)] data-[placeholder]:!text-sm [&_[data-placeholder]]:!text-[var(--placeholder)] [&_[data-placeholder]]:!text-sm [&_span[data-placeholder]]:!text-[var(--placeholder)] [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-full items-center justify-between gap-2 rounded-md border bg-input-background px-3 py-2 text-sm whitespace-nowrap shadow-[0_1px_2px_0_rgba(0,0,0,0.05)] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:bg-muted/50 disabled:text-label data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, jsx(SelectPrimitive.Icon, { asChild: true, children: jsx(ChevronDown, { className: "size-4 text-gray-600" }) })] }));
|
|
37148
37144
|
}
|
|
37149
37145
|
function SelectContent({ className, children, position = 'popper', searchable = true, // default: all selects are searchable
|
|
37150
|
-
searchPlaceholder = 'Search...', ...props }) {
|
|
37146
|
+
searchPlaceholder = 'Search...', emptyMessage = 'No options available', ...props }) {
|
|
37151
37147
|
// Use the shared search context provided by Select root
|
|
37152
37148
|
const searchCtx = useSelectSearchContext();
|
|
37153
37149
|
const searchTerm = searchCtx?.searchTerm ?? '';
|
|
@@ -37159,7 +37155,9 @@ searchPlaceholder = 'Search...', ...props }) {
|
|
|
37159
37155
|
return (jsx(SelectPrimitive.Portal, { children: jsxs(SelectPrimitive.Content, { "data-slot": "select-content", className: cn('bg-card cursor-pointer text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg border border-border shadow-[0_10px_15px_-3px_rgba(0,0,0,0.10),0_4px_6px_-4px_rgba(0,0,0,0.10)]', position === 'popper' &&
|
|
37160
37156
|
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', className), position: position, ...props, children: [searchable && (jsx("div", { className: "p-2 pb-1", children: jsxs("div", { className: "flex h-9 w-full items-center gap-2 rounded-lg bg-secondary px-3", children: [jsx(Search, { className: "h-4 w-4 shrink-0 text-[#737373]", "aria-hidden": "true" }), jsx("input", { type: "search", className: "min-w-0 flex-1 bg-transparent text-sm text-foreground outline-none placeholder:text-placeholder", placeholder: searchPlaceholder, value: searchTerm, onChange: (e) => setSearchTerm?.(e.target.value),
|
|
37161
37157
|
// prevent keys from interfering with Radix keyboard nav
|
|
37162
|
-
onKeyDown: (e) => e.stopPropagation() })] }) })), jsx(SelectScrollUpButton, {}), jsx(SelectPrimitive.Viewport, {
|
|
37158
|
+
onKeyDown: (e) => e.stopPropagation() })] }) })), jsx(SelectScrollUpButton, {}), jsx(SelectPrimitive.Viewport, { "data-slot": "select-viewport", style: {
|
|
37159
|
+
'--select-empty-message': JSON.stringify(searchTerm ? 'No matching options' : emptyMessage),
|
|
37160
|
+
}, className: cn('p-1 max-h-[12.5rem] overflow-y-auto', 'empty:after:block empty:after:px-2 empty:after:py-4 empty:after:text-center empty:after:text-sm empty:after:text-muted-foreground empty:after:content-(--select-empty-message)', position === 'popper' &&
|
|
37163
37161
|
'w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1'), children: children }), jsx(SelectScrollDownButton, {})] }) }));
|
|
37164
37162
|
}
|
|
37165
37163
|
// 👇 Add searchValue + withCheckbox props here
|
|
@@ -37916,7 +37914,7 @@ function InventoryComboBox({ inventoryType, selectedItem, onSelect, fetchGems, f
|
|
|
37916
37914
|
|
|
37917
37915
|
const OwnershipFilter = (props) => (jsx(FilterMultiSelect, { ...props, label: "Ownership", options: [
|
|
37918
37916
|
{ value: 'owned', label: 'Owned' },
|
|
37919
|
-
{ value: '
|
|
37917
|
+
{ value: 'partner', label: 'Partner' },
|
|
37920
37918
|
{ value: 'memo_in', label: 'Memo In' },
|
|
37921
37919
|
] }));
|
|
37922
37920
|
const StockTypeFilter = (props) => (jsx(FilterMultiSelect, { ...props, label: "Stock Type", options: [
|
|
@@ -75514,7 +75512,7 @@ const OwnershipSplitCard = ({ totalAmountLabel, allocationPercentageLabel, total
|
|
|
75514
75512
|
};
|
|
75515
75513
|
|
|
75516
75514
|
/**
|
|
75517
|
-
* One card per partner on the Partner
|
|
75515
|
+
* One card per partner on the Partner Detail page.
|
|
75518
75516
|
* - Header strip: "Partner N" badge + percentage.
|
|
75519
75517
|
* - Identity row: name + subtitle on the left; Contribution / Expenses pair on the right.
|
|
75520
75518
|
* - Optional post-sale block: Profit + share-percentage label + horizontal progress bar.
|