navigateToLinkDetail(link)}
+ onKeyDown={(event) => handleRowKeyDown(event, link)}
+ tabIndex={0}
+ role="link"
+ aria-label={`Open details for ${link.alias}`}
+ >
{selectable ? (
|
onToggleSelect?.(link.id)}
/>
|
@@ -229,6 +258,7 @@ export default function LinkTable({
rel="noreferrer noopener"
className="alias-pill"
style={{ textDecoration: 'none' }}
+ onClick={stopRowNavigation}
>
#{link.alias}
@@ -239,7 +269,7 @@ export default function LinkTable({
{link.linkType === 'redirect' ? (
link.targetUrl ? (
safeUrl
- ? {link.targetUrl}
+ ? {link.targetUrl}
: Invalid target
) : —
) : markdown}
@@ -248,11 +278,34 @@ export default function LinkTable({
|
-
- {actions && onEdit ? : null}
-
- {actions && onDelete ? : null}
- |
+ {showActionColumn ? (
+
+ {actions && onEdit ? (
+
+ ) : null}
+ {actions && onDelete ? (
+
+ ) : null}
+ |
+ ) : null}
);
})}
@@ -267,13 +320,22 @@ export default function LinkTable({
const selected = selectable && selectedIds?.has(link.id) === true;
const safeUrl = link.linkType === 'redirect' ? safeLinkTargetUrl(link.targetUrl) : null;
return (
-
+
navigateToLinkDetail(link)}
+ onKeyDown={(event) => handleRowKeyDown(event, link)}
+ tabIndex={0}
+ role="link"
+ aria-label={`Open details for ${link.alias}`}
+ >
{selectable ? (
onToggleSelect?.(link.id)}
/>
) : null}
@@ -283,6 +345,7 @@ export default function LinkTable({
rel="noreferrer noopener"
className="alias-pill"
style={{ textDecoration: 'none', fontSize: '0.8125rem' }}
+ onClick={stopRowNavigation}
>
#{link.alias}
@@ -292,7 +355,7 @@ export default function LinkTable({
{link.linkType === 'redirect' && link.targetUrl ? (
{safeUrl
- ? {link.targetUrl}
+ ? {link.targetUrl}
: {link.targetUrl}}
) : null}
@@ -302,11 +365,34 @@ export default function LinkTable({
{new Date(link.updatedAt).toLocaleDateString()}
-
- {actions && onEdit ? : null}
-
- {actions && onDelete ? : null}
-
+ {showActionColumn ? (
+
+ {actions && onEdit ? (
+
+ ) : null}
+ {actions && onDelete ? (
+
+ ) : null}
+
+ ) : null}
);
})}
diff --git a/src/styles.css b/src/styles.css
index 4f77b10..c8c6cf1 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -509,6 +509,12 @@ button.link-action--confirm:hover { background: var(--accent-soft); }
transition: background 0.1s;
}
.link-table tbody tr:hover { background: #F8FAFF; }
+.link-table-row--clickable { cursor: pointer; }
+.link-table-row--clickable:focus-visible {
+ background: #F8FAFF;
+ outline: 2px solid #818CF8;
+ outline-offset: -2px;
+}
.link-table tbody tr:last-child td { border-bottom: none; }
.link-table tr.is-selected { background: var(--accent-soft); }
.link-table tr.is-selected:hover { background: #E0E7FF; }
@@ -588,10 +594,16 @@ button.link-action--confirm:hover { background: var(--accent-soft); }
padding: 0.75rem;
transition: border-color 0.15s, box-shadow 0.15s;
}
+.link-card--clickable { cursor: pointer; }
.link-card:hover {
border-color: #C7D2FE;
box-shadow: 0 4px 16px rgba(99,102,241,0.08);
}
+.link-card--clickable:focus-visible {
+ border-color: #818CF8;
+ box-shadow: 0 0 0 3px rgba(99,102,241,0.18), 0 4px 16px rgba(99,102,241,0.08);
+ outline: none;
+}
.link-card.is-selected { background: var(--accent-soft); border-color: #A5B4FC; }
.link-card-header {