|
7 | 7 | * @flow
|
8 | 8 | */
|
9 | 9 |
|
| 10 | +import {copy} from 'clipboard-js'; |
10 | 11 | import React, {useCallback, useContext} from 'react';
|
11 | 12 | import {TreeDispatcherContext, TreeStateContext} from './TreeContext';
|
12 | 13 | import {BridgeContext, StoreContext} from '../context';
|
@@ -272,6 +273,7 @@ function InspectedElementView({
|
272 | 273 | hooks,
|
273 | 274 | owners,
|
274 | 275 | props,
|
| 276 | + source, |
275 | 277 | state,
|
276 | 278 | } = inspectedElement;
|
277 | 279 |
|
@@ -403,6 +405,54 @@ function InspectedElementView({
|
403 | 405 | ))}
|
404 | 406 | </div>
|
405 | 407 | )}
|
| 408 | + |
| 409 | + {source !== null && ( |
| 410 | + <Source fileName={source.fileName} lineNumber={source.lineNumber} /> |
| 411 | + )} |
| 412 | + </div> |
| 413 | + ); |
| 414 | +} |
| 415 | + |
| 416 | +// This function is based on packages/shared/describeComponentFrame.js |
| 417 | +function formatSourceForDisplay(fileName: string, lineNumber: string) { |
| 418 | + const BEFORE_SLASH_RE = /^(.*)[\\\/]/; |
| 419 | + |
| 420 | + let nameOnly = fileName.replace(BEFORE_SLASH_RE, ''); |
| 421 | + |
| 422 | + // In DEV, include code for a common special case: |
| 423 | + // prefer "folder/index.js" instead of just "index.js". |
| 424 | + if (/^index\./.test(nameOnly)) { |
| 425 | + const match = fileName.match(BEFORE_SLASH_RE); |
| 426 | + if (match) { |
| 427 | + const pathBeforeSlash = match[1]; |
| 428 | + if (pathBeforeSlash) { |
| 429 | + const folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ''); |
| 430 | + nameOnly = folderName + '/' + nameOnly; |
| 431 | + } |
| 432 | + } |
| 433 | + } |
| 434 | + |
| 435 | + return `${nameOnly}:${lineNumber}`; |
| 436 | +} |
| 437 | + |
| 438 | +type SourceProps = {| |
| 439 | + fileName: string, |
| 440 | + lineNumber: string, |
| 441 | +|}; |
| 442 | + |
| 443 | +function Source({fileName, lineNumber}: SourceProps) { |
| 444 | + const handleCopy = () => copy(`${fileName}:${lineNumber}`); |
| 445 | + return ( |
| 446 | + <div className={styles.Source}> |
| 447 | + <div className={styles.SourceHeaderRow}> |
| 448 | + <div className={styles.SourceHeader}>source</div> |
| 449 | + <Button onClick={handleCopy} title="Copy to clipboard"> |
| 450 | + <ButtonIcon type="copy" /> |
| 451 | + </Button> |
| 452 | + </div> |
| 453 | + <div className={styles.SourceOneLiner}> |
| 454 | + {formatSourceForDisplay(fileName, lineNumber)} |
| 455 | + </div> |
406 | 456 | </div>
|
407 | 457 | );
|
408 | 458 | }
|
|
0 commit comments