mirror of
https://github.com/bendtherules/completion-viz.git
synced 2026-08-18 21:52:36 +00:00
refactor(completion): Break down Completion Card into sections and forward using context
This commit is contained in:
@@ -1,95 +1,34 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { ICompletionDetail } from "../../logic/completionMapping";
|
import { ICompletionDetail } from "../../logic/completionMapping";
|
||||||
import { CompletionTypes } from "../../types/engine262-stubs";
|
import { getCompletionClassname } from "./utils";
|
||||||
|
|
||||||
import { InlineResultViewer } from "../InlineResultViewer";
|
import { CompletionCardContext } from "./CompletionCardContext";
|
||||||
import { CompletionIcon } from "./CompletionIcon";
|
|
||||||
|
|
||||||
function getCompletionClassname(inputCompletion: ICompletionDetail) {
|
import { CompletionCardFullRecord } from "./CompletionCardFullRecord";
|
||||||
const typeToClassnameMapping: { [key in CompletionTypes]: string } = {
|
import { CompletionCardSourceSnippet } from "./CompletionCardSourceSnippet";
|
||||||
[CompletionTypes.Normal]: "bg-gray-300",
|
import { CompletionCardSummary } from "./CompletionCardSummary";
|
||||||
[CompletionTypes.Return]: "bg-green-200",
|
|
||||||
[CompletionTypes.Continue]: "bg-yellow-100",
|
|
||||||
[CompletionTypes.Break]: "bg-yellow-300",
|
|
||||||
[CompletionTypes.Throw]: "bg-red-300",
|
|
||||||
};
|
|
||||||
|
|
||||||
return typeToClassnameMapping[inputCompletion.completionType];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCodeTextFromCompletion(
|
|
||||||
code: string,
|
|
||||||
completion: ICompletionDetail
|
|
||||||
) {
|
|
||||||
return code.substring(completion.start, completion.end);
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ICompletionCardProps {
|
export interface ICompletionCardProps {
|
||||||
completionDetail: ICompletionDetail;
|
completionDetail: ICompletionDetail;
|
||||||
code: string;
|
code: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CompletionCard(props: ICompletionCardProps) {
|
// TODO: have diff version to be shown as tooltip over source code
|
||||||
|
|
||||||
|
export function CompletionCardFull(props: ICompletionCardProps) {
|
||||||
const { completionDetail, code } = props;
|
const { completionDetail, code } = props;
|
||||||
|
|
||||||
// TODO: have diff version to be shown as tooltip over source code
|
|
||||||
return (
|
return (
|
||||||
<div
|
<CompletionCardContext.Provider value={{ completionDetail, code }}>
|
||||||
className={`px-4 py-1 my-1 rounded-md ${getCompletionClassname(
|
<div
|
||||||
completionDetail
|
className={`px-4 py-1 my-1 rounded-md ${getCompletionClassname(
|
||||||
)}`}
|
completionDetail
|
||||||
>
|
)}`}
|
||||||
<div className="flex items-center my-1">
|
>
|
||||||
<div className="flex-initial flex-shrink-0">
|
<CompletionCardSummary />
|
||||||
<CompletionIcon completionDetail={completionDetail} />
|
<CompletionCardSourceSnippet />
|
||||||
</div>
|
<CompletionCardFullRecord />
|
||||||
<div className="flex-initial min-w-0">
|
|
||||||
<InlineResultViewer
|
|
||||||
className="px-1 rounded"
|
|
||||||
code={completionDetail.completionValueString || "// No value"}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="">
|
</CompletionCardContext.Provider>
|
||||||
<div className="my-1">
|
|
||||||
From source
|
|
||||||
<span role="img" aria-label="See below">
|
|
||||||
⤵️
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<InlineResultViewer
|
|
||||||
className="px-1 py-1 my-1 rounded md:w-fit-content"
|
|
||||||
code={getCodeTextFromCompletion(code, completionDetail)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="">
|
|
||||||
<div className="my-1">
|
|
||||||
Full completion record
|
|
||||||
<span role="img" aria-label="See below">
|
|
||||||
⤵️
|
|
||||||
</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<table className="border border-gray-800">
|
|
||||||
<tr className="border-b border-gray-800">
|
|
||||||
<td className="p-1 border-r border-gray-800">[[Type]]</td>
|
|
||||||
<td className="px-2 py-1">{completionDetail.completionType}</td>
|
|
||||||
</tr>
|
|
||||||
<tr className="border-b border-gray-800">
|
|
||||||
<td className="p-1 border-r border-gray-800">[[Value]]</td>
|
|
||||||
<td className="px-2 py-1">
|
|
||||||
{completionDetail.completionValueString}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr className="border-b border-gray-800">
|
|
||||||
<td className="p-1 border-r border-gray-800">[[Target]]</td>
|
|
||||||
<td className="px-2 py-1">
|
|
||||||
{completionDetail.completionTargetString}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { createContext, useContext } from "react";
|
||||||
|
import { ICompletionDetail } from "../../logic/completionMapping";
|
||||||
|
|
||||||
|
export interface ICompletionCardContext {
|
||||||
|
completionDetail?: ICompletionDetail;
|
||||||
|
code?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialValue: ICompletionCardContext = {};
|
||||||
|
|
||||||
|
export const CompletionCardContext = createContext<ICompletionCardContext>(
|
||||||
|
initialValue
|
||||||
|
);
|
||||||
|
|
||||||
|
export class CompletionCardContextEmptyError extends TypeError {}
|
||||||
|
|
||||||
|
export function useCompletionCardContext() {
|
||||||
|
const contextValue = useContext(CompletionCardContext);
|
||||||
|
const { completionDetail, code } = contextValue;
|
||||||
|
if (completionDetail === undefined || code === undefined) {
|
||||||
|
throw new CompletionCardContextEmptyError(
|
||||||
|
`CompletionCard Context value is not available in consumer. Provider might be missing.\n Value is ${JSON.stringify(
|
||||||
|
contextValue,
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { completionDetail, code };
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { useCompletionCardContext } from "./CompletionCardContext";
|
||||||
|
|
||||||
|
export function CompletionCardFullRecord() {
|
||||||
|
const { completionDetail } = useCompletionCardContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="">
|
||||||
|
<div className="my-1">
|
||||||
|
Full completion record
|
||||||
|
<span role="img" aria-label="See below">
|
||||||
|
⤵️
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<table className="border border-gray-800">
|
||||||
|
<tr className="border-b border-gray-800">
|
||||||
|
<td className="p-1 border-r border-gray-800">[[Type]]</td>
|
||||||
|
<td className="px-2 py-1">{completionDetail.completionType}</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="border-b border-gray-800">
|
||||||
|
<td className="p-1 border-r border-gray-800">[[Value]]</td>
|
||||||
|
<td className="px-2 py-1">
|
||||||
|
{completionDetail.completionValueString}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr className="border-b border-gray-800">
|
||||||
|
<td className="p-1 border-r border-gray-800">[[Target]]</td>
|
||||||
|
<td className="px-2 py-1">
|
||||||
|
{completionDetail.completionTargetString}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { InlineResultViewer } from "../InlineResultViewer";
|
||||||
|
|
||||||
|
import { useCompletionCardContext } from "./CompletionCardContext";
|
||||||
|
import { getCodeTextFromCompletion } from "./utils";
|
||||||
|
|
||||||
|
export function CompletionCardSourceSnippet() {
|
||||||
|
const { completionDetail, code } = useCompletionCardContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="">
|
||||||
|
<div className="my-1">
|
||||||
|
From source
|
||||||
|
<span role="img" aria-label="See below">
|
||||||
|
⤵️
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<InlineResultViewer
|
||||||
|
className="px-1 py-1 my-1 rounded md:w-fit-content"
|
||||||
|
code={getCodeTextFromCompletion(code, completionDetail)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { InlineResultViewer } from "../InlineResultViewer";
|
||||||
|
|
||||||
|
import { CompletionIcon } from "./CompletionIcon";
|
||||||
|
import { useCompletionCardContext } from "./CompletionCardContext";
|
||||||
|
|
||||||
|
export function CompletionCardSummary() {
|
||||||
|
const { completionDetail } = useCompletionCardContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center my-1">
|
||||||
|
<div className="flex-initial flex-shrink-0">
|
||||||
|
<CompletionIcon completionDetail={completionDetail} />
|
||||||
|
</div>
|
||||||
|
<div className="flex-initial min-w-0">
|
||||||
|
<InlineResultViewer
|
||||||
|
className="px-1 rounded"
|
||||||
|
code={completionDetail.completionValueString || "// No value"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
import { CompletionCard } from "./CompletionCard";
|
import { CompletionCardFull } from "./CompletionCard";
|
||||||
|
|
||||||
export { CompletionCard };
|
export { CompletionCardFull };
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { ICompletionDetail } from "../../logic/completionMapping";
|
||||||
|
import { CompletionTypes } from "../../types/engine262-stubs";
|
||||||
|
|
||||||
|
export function getCompletionClassname(inputCompletion: ICompletionDetail) {
|
||||||
|
const typeToClassnameMapping: { [key in CompletionTypes]: string } = {
|
||||||
|
[CompletionTypes.Normal]: "bg-gray-300",
|
||||||
|
[CompletionTypes.Return]: "bg-green-200",
|
||||||
|
[CompletionTypes.Continue]: "bg-yellow-100",
|
||||||
|
[CompletionTypes.Break]: "bg-yellow-300",
|
||||||
|
[CompletionTypes.Throw]: "bg-red-300",
|
||||||
|
};
|
||||||
|
|
||||||
|
return typeToClassnameMapping[inputCompletion.completionType];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCodeTextFromCompletion(
|
||||||
|
code: string,
|
||||||
|
completion: ICompletionDetail
|
||||||
|
) {
|
||||||
|
return code.substring(completion.start, completion.end);
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import React from "react";
|
|||||||
import { ICompletionDetail } from "../../logic/completionMapping";
|
import { ICompletionDetail } from "../../logic/completionMapping";
|
||||||
import { TSourceMapping } from "../../logic/sourceMapping";
|
import { TSourceMapping } from "../../logic/sourceMapping";
|
||||||
|
|
||||||
import { CompletionCard } from "../CompletionCard";
|
import { CompletionCardFull } from "../CompletionCard";
|
||||||
|
|
||||||
export function CompletionViewer(props: {
|
export function CompletionViewer(props: {
|
||||||
code: string;
|
code: string;
|
||||||
@@ -21,10 +21,10 @@ export function CompletionViewer(props: {
|
|||||||
<div className="ml-1 mr-1">
|
<div className="ml-1 mr-1">
|
||||||
{completionDetails.map((tmpCompletion) => (
|
{completionDetails.map((tmpCompletion) => (
|
||||||
// Card for each completion record
|
// Card for each completion record
|
||||||
<CompletionCard
|
<CompletionCardFull
|
||||||
completionDetail={tmpCompletion}
|
completionDetail={tmpCompletion}
|
||||||
code={code}
|
code={code}
|
||||||
></CompletionCard>
|
></CompletionCardFull>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user