fix(RecordList): align action buttons and tint row dividers to color prop

This commit is contained in:
seb
2026-08-09 00:04:30 +02:00
parent f0b622a535
commit 4f0d73e0ea

View File

@@ -48,12 +48,35 @@ import { PanelTile, PanelTileGrid } from '../panels';
* @behaviour Clicking a row calls `onEdit(row)` (only when `onEdit` is provided); the action buttons stop propagation so they do not double-trigger the row click.
* @behaviour The actions column appears only if `onEdit` or `onDelete` is provided.
* @behaviour No data layer: this component never touches storage, routing, toasters, or backend error formatting.
* @behaviour When `color` is a hex value, the row dividers are tinted to a darker shade of it so the horizontal lines fit the tile background.
*/
class RecordList extends Component {
handleRowClick(row) {
this.props.onEdit?.(row);
}
/** Darken a #rrggbb / #rgb hex color by `amount` (0–1); falls back to the divider grey for non-hex colors. */
dividerColor(color, amount = 0.15) {
if (typeof color !== 'string') return 'divider';
const m = color.trim().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
if (!m) return 'divider';
let hex = m[1];
if (hex.length === 3) {
hex = hex
.split('')
.map((c) => c + c)
.join('');
}
const num = parseInt(hex, 16);
const channels = [16, 8, 0].map((shift) => {
const c = (num >> shift) & 0xff;
return Math.max(0, Math.round(c * (1 - amount)));
});
const toHex = (v) => v.toString(16).padStart(2, '0');
return `#${channels.map(toHex).join('')}`;
}
renderLoading() {
return (
<Box sx={{ display: 'flex', justifyContent: 'center', py: 6 }}>
@@ -99,13 +122,22 @@ class RecordList extends Component {
deleteDisabled,
getEditLabel,
getDeleteLabel,
color,
} = this.props;
const hasActions = Boolean(onEdit || onDelete);
const borderColor = this.dividerColor(color);
return (
<TableContainer>
<Table size="small">
<Table
size="small"
sx={{
'& .MuiTableCell-root': {
borderColor,
},
}}
>
<TableHead>
<TableRow>
{columns.map((col) => (
@@ -140,29 +172,31 @@ class RecordList extends Component {
padding="checkbox"
onClick={(e) => e.stopPropagation()}
>
{onEdit ? (
<IconButton
size="small"
aria-label={
getEditLabel?.(row) ?? `„${id}“ bearbeiten`
}
onClick={() => onEdit(row)}
>
<EditOutlinedIcon fontSize="small" />
</IconButton>
) : null}
{onDelete ? (
<IconButton
size="small"
aria-label={
getDeleteLabel?.(row) ?? `„${id}“ löschen`
}
disabled={deleteDisabled}
onClick={() => onDelete(row)}
>
<DeleteOutlinedIcon fontSize="small" />
</IconButton>
) : null}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
{onEdit ? (
<IconButton
size="small"
aria-label={
getEditLabel?.(row) ?? `„${id}“ bearbeiten`
}
onClick={() => onEdit(row)}
>
<EditOutlinedIcon fontSize="small" />
</IconButton>
) : null}
{onDelete ? (
<IconButton
size="small"
aria-label={
getDeleteLabel?.(row) ?? `„${id}“ löschen`
}
disabled={deleteDisabled}
onClick={() => onDelete(row)}
>
<DeleteOutlinedIcon fontSize="small" />
</IconButton>
) : null}
</Box>
</TableCell>
) : null}
</TableRow>