Skip to content

Commit 005ff90

Browse files
authored
feat: link to opcode rows (#81)
1 parent 607e9ae commit 005ff90

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

src/components/features/FeatureTable.tsx

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect } from 'react';
1+
import { useState, useEffect, useRef } from 'react';
22
import type { Chain } from '@/../script/index';
33
import { chainLogoUrl, classNames } from '@/lib/utils';
44
import { ExternalLink } from '@/components/layout/ExternalLink';
@@ -9,7 +9,7 @@ import { Copyable } from '@/components/ui/Copyable';
99
import { evmStackAddresses, type EVMStackResult } from '@/../script/checks/evm-stack-addresses';
1010
import { knownOpcodes } from '@/../script/checks/opcodes';
1111
import { getAddress } from 'viem';
12-
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/20/solid';
12+
import { ArrowTopRightOnSquareIcon, LinkIcon } from '@heroicons/react/20/solid';
1313
import Image from 'next/image';
1414
import { BASE_DATA_URL, type Feature } from '@/lib/constants';
1515
import { FormattedAddress } from '@/lib/utils';
@@ -140,15 +140,42 @@ const PrecompilesTable = ({ featureData }: { featureData: Record<string, Precomp
140140
};
141141

142142
const OpcodesTable = ({ featureData }: { featureData: Record<string, Opcodes> }) => {
143+
const opcodeRefs = useRef<Record<string, HTMLTableRowElement | null>>({});
144+
145+
useEffect(() => {
146+
const hash = window.location.hash.substring(1);
147+
if (hash && opcodeRefs.current[hash]) {
148+
opcodeRefs.current[hash]?.scrollIntoView({ behavior: 'smooth', block: 'center' });
149+
}
150+
}, []);
151+
143152
return (
144153
<tbody className={tbodyClasses}>
145154
{Object.keys(knownOpcodes)
146155
.map(Number)
147156
.map((op: number) => (
148-
<tr key={op} className={trClasses}>
149-
<td className={td1Classes}>
150-
{knownOpcodes[op]}
151-
<div className="text-secondary text-sm">{toUppercaseHex(op)}</div>
157+
<tr
158+
key={op}
159+
className={trClasses}
160+
ref={(el) => {
161+
opcodeRefs.current[knownOpcodes[op]] = el;
162+
}}
163+
>
164+
<td className={classNames(td1Classes, 'text-center')}>
165+
<div className="relative inline-block">
166+
<Copyable
167+
content={
168+
<div>
169+
{knownOpcodes[op]}
170+
<div className="text-secondary text-sm">{toUppercaseHex(op)}</div>
171+
</div>
172+
}
173+
Icon={LinkIcon}
174+
textToCopy={`${location.href.replace(location.hash, '')}#${knownOpcodes[op]}`}
175+
// Use negative margin to "center" since the hidden link icon makes it look off-center.
176+
className="ml-2 -mr-2"
177+
/>
178+
</div>
152179
</td>
153180
{Object.keys(featureData).map((chainId) => {
154181
const opcode = featureData[chainId].find((opcode) => Number(opcode.number) === op);

src/components/ui/Copyable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const Copyable = ({
4141
};
4242

4343
return (
44-
<div className={classNames('group group relative flex w-max items-center', className)}>
44+
<div className={classNames('group relative flex w-max items-center', className)}>
4545
<div className="relative flex w-full items-center">
4646
{content}
4747
<Icon

0 commit comments

Comments
 (0)