refactor(completion): Break down Completion Card into sections and forward using context

This commit is contained in:
2020-09-28 19:24:54 +05:30
parent f0b0b916e2
commit 05a5278244
8 changed files with 161 additions and 84 deletions
@@ -1,95 +1,34 @@
import React from "react";
import { ICompletionDetail } from "../../logic/completionMapping";
import { CompletionTypes } from "../../types/engine262-stubs";
import { getCompletionClassname } from "./utils";
import { InlineResultViewer } from "../InlineResultViewer";
import { CompletionIcon } from "./CompletionIcon";
import { CompletionCardContext } from "./CompletionCardContext";
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];
}
function getCodeTextFromCompletion(
code: string,
completion: ICompletionDetail
) {
return code.substring(completion.start, completion.end);
}
import { CompletionCardFullRecord } from "./CompletionCardFullRecord";
import { CompletionCardSourceSnippet } from "./CompletionCardSourceSnippet";
import { CompletionCardSummary } from "./CompletionCardSummary";
export interface ICompletionCardProps {
completionDetail: ICompletionDetail;
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;
// TODO: have diff version to be shown as tooltip over source code
return (
<CompletionCardContext.Provider value={{ completionDetail, code }}>
<div
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">
<CompletionIcon completionDetail={completionDetail} />
</div>
<div className="flex-initial min-w-0">
<InlineResultViewer
className="px-1 rounded"
code={completionDetail.completionValueString || "// No value"}
/>
</div>
</div>
<div className="">
<div className="my-1">
From source&nbsp;
<span role="img" aria-label="See below">
</span>
&nbsp;
</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&nbsp;
<span role="img" aria-label="See below">
</span>
&nbsp;
</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>
<CompletionCardSummary />
<CompletionCardSourceSnippet />
<CompletionCardFullRecord />
</div>
</CompletionCardContext.Provider>
);
}
@@ -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&nbsp;
<span role="img" aria-label="See below">
</span>
&nbsp;
</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&nbsp;
<span role="img" aria-label="See below">
</span>
&nbsp;
</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>
);
}
+2 -2
View File
@@ -1,3 +1,3 @@
import { CompletionCard } from "./CompletionCard";
import { CompletionCardFull } from "./CompletionCard";
export { CompletionCard };
export { CompletionCardFull };
+21
View File
@@ -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 { TSourceMapping } from "../../logic/sourceMapping";
import { CompletionCard } from "../CompletionCard";
import { CompletionCardFull } from "../CompletionCard";
export function CompletionViewer(props: {
code: string;
@@ -21,10 +21,10 @@ export function CompletionViewer(props: {
<div className="ml-1 mr-1">
{completionDetails.map((tmpCompletion) => (
// Card for each completion record
<CompletionCard
<CompletionCardFull
completionDetail={tmpCompletion}
code={code}
></CompletionCard>
></CompletionCardFull>
))}
</div>
</div>