refactor: clean code editor components and styles

This commit is contained in:
rusconn
2022-04-04 10:45:42 +09:00
parent d410830b7e
commit dfb6461eef
12 changed files with 75 additions and 156 deletions

View File

@@ -1,4 +1,4 @@
import { Paper } from "@mui/material"; import { css, Theme } from "@mui/material/styles";
import { config } from "ace-builds"; import { config } from "ace-builds";
import { ComponentPropsWithoutRef, memo } from "react"; import { ComponentPropsWithoutRef, memo } from "react";
import AceEditor from "react-ace"; import AceEditor from "react-ace";
@@ -12,19 +12,24 @@ config.setModuleUrl(
type Props = ComponentPropsWithoutRef<typeof AceEditor>; type Props = ComponentPropsWithoutRef<typeof AceEditor>;
const editor = (theme: Theme) => css`
box-shadow: ${theme.shadows[1]};
`;
const StyledComponent = (props: Props) => ( const StyledComponent = (props: Props) => (
<Paper> <AceEditor
<AceEditor wrapEnabled
wrapEnabled width="auto"
theme="textmate" height="100%"
showPrintMargin={false} theme="textmate"
highlightActiveLine={false} showPrintMargin={false}
editorProps={{ $blockScrolling: true }} highlightActiveLine={false}
setOptions={{ mergeUndoDeltas: false }} editorProps={{ $blockScrolling: true }}
// eslint-disable-next-line react/jsx-props-no-spreading setOptions={{ mergeUndoDeltas: false }}
{...props} css={editor}
/> // eslint-disable-next-line react/jsx-props-no-spreading
</Paper> {...props}
/>
); );
export const Component = memo(StyledComponent); export const Component = memo(StyledComponent);

View File

@@ -1,26 +0,0 @@
import { useTheme } from "@mui/material/styles";
import { ComponentPropsWithoutRef, memo } from "react";
import { drawerWidth } from "@/components/layout/Drawer";
import { headerHeight } from "@/components/layout/Header";
import CodeEditor from "./CodeEditor";
type Props = Omit<ComponentPropsWithoutRef<typeof CodeEditor>, "width">;
const StyledComponent = (props: Props) => {
const theme = useTheme();
return (
<CodeEditor
height={`calc(100vh - ${headerHeight}px - ${theme.spacing(6 * 2)} - 192px`}
width={`calc(calc(100vw - ${drawerWidth}px - ${theme.spacing(6 * 2)} - 18px) / 2)`}
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
);
};
export const Component = memo(StyledComponent);
export default Component;

View File

@@ -1,26 +0,0 @@
import { Skeleton } from "@mui/material";
import { useTheme } from "@mui/material/styles";
import { ComponentPropsWithoutRef, memo } from "react";
import { drawerWidth } from "@/components/layout/Drawer";
import { headerHeight } from "@/components/layout/Header";
type Props = Omit<ComponentPropsWithoutRef<typeof Skeleton>, "width">;
const StyledComponent = (props: Props) => {
const theme = useTheme();
return (
<Skeleton
variant="rectangular"
height={`calc(100vh - ${headerHeight}px - ${theme.spacing(6 * 2)} - 192px`}
width={`calc(calc(100vw - ${drawerWidth}px - ${theme.spacing(6 * 2)} - 18px) / 2)`}
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
);
};
export const Component = memo(StyledComponent);
export default Component;

View File

@@ -1,24 +1,28 @@
import { Box, Stack, Typography } from "@mui/material"; import { Stack, Typography } from "@mui/material";
import { css, Theme } from "@mui/material/styles"; import { css, Theme } from "@mui/material/styles";
import { memo, PropsWithChildren } from "react"; import { ComponentPropsWithoutRef, memo, PropsWithChildren } from "react";
type Props = PropsWithChildren<{ type Props = PropsWithChildren<
title: string; {
}>; title: string;
} & ComponentPropsWithoutRef<typeof Stack>
>;
const mainTitle = (theme: Theme) => css` const mainTitle = (theme: Theme) => css`
font-size: ${theme.typography.fontSize * 3}px; font-size: ${theme.typography.fontSize * 3}px;
font-weight: 400; font-weight: 400;
margin-bottom: ${theme.spacing(2)};
`; `;
const StyledComponent = ({ children, title }: Props) => ( const StyledComponent = ({ children, title, ...stackProps }: Props) => (
<Box component="main" padding={6}> // eslint-disable-next-line react/jsx-props-no-spreading
<Stack component="main" height="100%" padding={6} spacing={2} {...stackProps}>
<Typography variant="h1" css={mainTitle}> <Typography variant="h1" css={mainTitle}>
{title} {title}
</Typography> </Typography>
<Stack spacing={2}>{children}</Stack> <Stack spacing={2} flexGrow={1}>
</Box> {children}
</Stack>
</Stack>
); );
export const Component = memo(StyledComponent); export const Component = memo(StyledComponent);

View File

@@ -1,17 +1,20 @@
import { Box, Typography } from "@mui/material"; import { Box, Stack, Typography } from "@mui/material";
import { memo, PropsWithChildren } from "react"; import { ComponentPropsWithoutRef, memo, PropsWithChildren } from "react";
type Props = PropsWithChildren<{ type Props = PropsWithChildren<
title: string; {
}>; title: string;
} & ComponentPropsWithoutRef<typeof Stack>
>;
const StyledComponent = ({ children, title }: Props) => ( const StyledComponent = ({ children, title, ...stackProps }: Props) => (
<Box> // eslint-disable-next-line react/jsx-props-no-spreading
<Stack {...stackProps}>
<Typography variant="h6" component="h2"> <Typography variant="h6" component="h2">
{title} {title}
</Typography> </Typography>
{children} <Box flexGrow={1}>{children}</Box>
</Box> </Stack>
); );
export const Component = memo(StyledComponent); export const Component = memo(StyledComponent);

View File

@@ -1,8 +1,7 @@
import CodeEditorHalfLoading from "./CodeEditorHalfLoading";
import Configurations from "./Configurations"; import Configurations from "./Configurations";
import Main from "./Main"; import Main from "./Main";
import MainItem from "./MainItem"; import MainItem from "./MainItem";
import TextField from "./TextField"; import TextField from "./TextField";
import ToolCardGrid from "./ToolCardGrid"; import ToolCardGrid from "./ToolCardGrid";
export { CodeEditorHalfLoading, Configurations, Main, MainItem, TextField, ToolCardGrid }; export { Configurations, Main, MainItem, TextField, ToolCardGrid };

View File

@@ -1,27 +1,27 @@
import { Stack } from "@mui/material"; import { Skeleton, Stack } from "@mui/material";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import { ComponentPropsWithoutRef, memo, useCallback, useState } from "react"; import { ComponentPropsWithoutRef, memo, useCallback, useState } from "react";
import YAML from "yaml"; import YAML from "yaml";
import { CodeEditorHalfLoading, Main, MainItem } from "@/components/common"; import { Main, MainItem } from "@/components/common";
import Configuration, { isSpaces, Spaces } from "./Configuration"; import Configuration, { isSpaces, Spaces } from "./Configuration";
// https://github.com/securingsincity/react-ace/issues/27 // https://github.com/securingsincity/react-ace/issues/27
const CodeEditorHalf = dynamic( const CodeEditor = dynamic(
async () => { async () => {
const ace = await import("@/components/common/CodeEditorHalf"); const ace = await import("@/components/common/CodeEditor");
await Promise.all([ await Promise.all([
import("ace-builds/src-noconflict/mode-json"), import("ace-builds/src-noconflict/mode-json"),
import("ace-builds/src-noconflict/mode-yaml"), import("ace-builds/src-noconflict/mode-yaml"),
]); ]);
return ace; return ace;
}, },
{ ssr: false, loading: () => <CodeEditorHalfLoading /> } { ssr: false, loading: () => <Skeleton variant="rectangular" height="100%" /> }
); );
type CodeValue = NonNullable<ComponentPropsWithoutRef<typeof CodeEditorHalf>["value"]>; type CodeValue = NonNullable<ComponentPropsWithoutRef<typeof CodeEditor>["value"]>;
type OnCodeChange = NonNullable<ComponentPropsWithoutRef<typeof CodeEditorHalf>["onChange"]>; type OnCodeChange = NonNullable<ComponentPropsWithoutRef<typeof CodeEditor>["onChange"]>;
type Props = { type Props = {
json: CodeValue; json: CodeValue;
@@ -42,24 +42,12 @@ const StyledComponent = ({
<MainItem title="Configuration"> <MainItem title="Configuration">
<Configuration {...{ spaces, onSpacesChange }} /> <Configuration {...{ spaces, onSpacesChange }} />
</MainItem> </MainItem>
<Stack direction="row" spacing={2}> <Stack direction="row" spacing={2} height="100%">
<MainItem title="Json"> <MainItem title="Json" height="100%" flexGrow={1}>
<CodeEditorHalf <CodeEditor name="json" mode="json" value={json} tabSize={spaces} onChange={onJsonChange} />
name="json"
mode="json"
value={json}
tabSize={spaces}
onChange={onJsonChange}
/>
</MainItem> </MainItem>
<MainItem title="Yaml"> <MainItem title="Yaml" height="100%" flexGrow={1}>
<CodeEditorHalf <CodeEditor name="yaml" mode="yaml" value={yaml} tabSize={spaces} onChange={onYamlChange} />
name="yaml"
mode="yaml"
value={yaml}
tabSize={spaces}
onChange={onYamlChange}
/>
</MainItem> </MainItem>
</Stack> </Stack>
</Main> </Main>

View File

@@ -1,19 +0,0 @@
import { ComponentPropsWithoutRef, memo } from "react";
import CodeEditor from "@/components/common/CodeEditor";
type Props = Omit<ComponentPropsWithoutRef<typeof CodeEditor>, "height" | "width">;
const StyledComponent = (props: Props) => (
<CodeEditor
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
readOnly
height="160px"
width="100%"
/>
);
export const Component = memo(StyledComponent);
export default Component;

View File

@@ -1,8 +0,0 @@
import { Skeleton } from "@mui/material";
import { memo } from "react";
const StyledComponent = () => <Skeleton variant="rectangular" width="100%" height="160px" />;
export const Component = memo(StyledComponent);
export default Component;

View File

@@ -1,19 +1,18 @@
import { Skeleton } from "@mui/material";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import { ComponentPropsWithoutRef, memo, useCallback, useState } from "react"; import { ComponentPropsWithoutRef, memo, useCallback, useState } from "react";
import { Main, MainItem, TextField } from "@/components/common"; import { Main, MainItem, TextField } from "@/components/common";
import { decode } from "@/libs/jwt"; import { decode } from "@/libs/jwt";
import CodeEditorLoading from "./CodeEditorLoading";
// https://github.com/securingsincity/react-ace/issues/27 // https://github.com/securingsincity/react-ace/issues/27
const CodeEditor = dynamic( const CodeEditor = dynamic(
async () => { async () => {
const ace = await import("./CodeEditor"); const ace = await import("@/components/common/CodeEditor");
await import("ace-builds/src-noconflict/mode-json"); await import("ace-builds/src-noconflict/mode-json");
return ace; return ace;
}, },
{ ssr: false, loading: CodeEditorLoading } { ssr: false, loading: () => <Skeleton variant="rectangular" width="100%" height="160px" /> }
); );
type TextFieldValue = ComponentPropsWithoutRef<typeof TextField>["value"]; type TextFieldValue = ComponentPropsWithoutRef<typeof TextField>["value"];
@@ -33,10 +32,10 @@ const StyledComponent = ({ jwt, header, payload, onJwtChange }: Props) => (
<TextField multiline rows={5} value={jwt} onChange={onJwtChange} /> <TextField multiline rows={5} value={jwt} onChange={onJwtChange} />
</MainItem> </MainItem>
<MainItem title="Header"> <MainItem title="Header">
<CodeEditor name="header" mode="json" value={header} /> <CodeEditor readOnly height="160px" width="100%" name="header" mode="json" value={header} />
</MainItem> </MainItem>
<MainItem title="Payload"> <MainItem title="Payload">
<CodeEditor name="payload" mode="json" value={payload} /> <CodeEditor readOnly height="160px" width="100%" name="payload" mode="json" value={payload} />
</MainItem> </MainItem>
</Main> </Main>
); );

View File

@@ -1,23 +1,23 @@
import { Stack } from "@mui/material"; import { Skeleton, Stack } from "@mui/material";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import { ComponentPropsWithoutRef, memo, useCallback, useState } from "react"; import { ComponentPropsWithoutRef, memo, useCallback, useState } from "react";
import { CodeEditorHalfLoading, Main, MainItem } from "@/components/common"; import { Main, MainItem } from "@/components/common";
import Configuration, { isSpaces, Spaces } from "./Configuration"; import Configuration, { isSpaces, Spaces } from "./Configuration";
// https://github.com/securingsincity/react-ace/issues/27 // https://github.com/securingsincity/react-ace/issues/27
const CodeEditorHalf = dynamic( const CodeEditor = dynamic(
async () => { async () => {
const ace = await import("@/components/common/CodeEditorHalf"); const ace = await import("@/components/common/CodeEditor");
await import("ace-builds/src-noconflict/mode-json"); await import("ace-builds/src-noconflict/mode-json");
return ace; return ace;
}, },
{ ssr: false, loading: () => <CodeEditorHalfLoading /> } { ssr: false, loading: () => <Skeleton variant="rectangular" height="100%" /> }
); );
type CodeValue = NonNullable<ComponentPropsWithoutRef<typeof CodeEditorHalf>["value"]>; type CodeValue = NonNullable<ComponentPropsWithoutRef<typeof CodeEditor>["value"]>;
type OnCodeChange = NonNullable<ComponentPropsWithoutRef<typeof CodeEditorHalf>["onChange"]>; type OnCodeChange = NonNullable<ComponentPropsWithoutRef<typeof CodeEditor>["onChange"]>;
type Props = { type Props = {
json: CodeValue; json: CodeValue;
@@ -30,12 +30,12 @@ const StyledComponent = ({ json, formatted, spaces, onJsonChange, onSpacesChange
<MainItem title="Configuration"> <MainItem title="Configuration">
<Configuration {...{ spaces, onSpacesChange }} /> <Configuration {...{ spaces, onSpacesChange }} />
</MainItem> </MainItem>
<Stack direction="row" spacing={2}> <Stack direction="row" spacing={2} height="100%">
<MainItem title="Input"> <MainItem title="Input" height="100%" flexGrow={1}>
<CodeEditorHalf name="json" mode="json" value={json} tabSize={2} onChange={onJsonChange} /> <CodeEditor name="json" mode="json" value={json} tabSize={2} onChange={onJsonChange} />
</MainItem> </MainItem>
<MainItem title="Output"> <MainItem title="Output" height="100%" flexGrow={1}>
<CodeEditorHalf name="formatted" mode="json" value={formatted} tabSize={spaces} readOnly /> <CodeEditor name="formatted" mode="json" value={formatted} tabSize={spaces} readOnly />
</MainItem> </MainItem>
</Stack> </Stack>
</Main> </Main>

View File

@@ -6,7 +6,7 @@ import { homeTools } from "@/data/tools";
type Props = ComponentPropsWithoutRef<typeof ToolCardGrid>; type Props = ComponentPropsWithoutRef<typeof ToolCardGrid>;
const StyledComponent = ({ tools }: Props) => ( const StyledComponent = ({ tools }: Props) => (
<Main title="All tools"> <Main title="All tools" height="fit-content">
<ToolCardGrid {...{ tools }} /> <ToolCardGrid {...{ tools }} />
</Main> </Main>
); );