Added some initial styles, dependencies, next-auth, and page structure
This commit is contained in:
3
.env.example
Normal file
3
.env.example
Normal file
@@ -0,0 +1,3 @@
|
||||
NEXTAUTH_URL=https://example.com
|
||||
GITHUB_SECRET=""
|
||||
GITHUB_ID=""
|
||||
155
components/DropdownMenu.tsx
Normal file
155
components/DropdownMenu.tsx
Normal file
@@ -0,0 +1,155 @@
|
||||
/** @jsxImportSource theme-ui */
|
||||
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
||||
import { ForwardRefExoticComponent, RefAttributes } from "react";
|
||||
import { keyframes } from "@emotion/react";
|
||||
import { ThemeUIStyleObject, jsx } from "theme-ui";
|
||||
import { theme } from "../theme";
|
||||
|
||||
interface StyledProps {
|
||||
sx?: ThemeUIStyleObject;
|
||||
}
|
||||
|
||||
const Root = DropdownMenu.Root;
|
||||
|
||||
const Trigger = DropdownMenu.Trigger;
|
||||
|
||||
const slideUpAndFade = keyframes({
|
||||
"0%": { opacity: 0, transform: "translateY(2px)" },
|
||||
"100%": { opacity: 1, transform: "translateY(0)" },
|
||||
});
|
||||
|
||||
const slideRightAndFade = keyframes({
|
||||
"0%": { opacity: 0, transform: "translateX(-2px)" },
|
||||
"100%": { opacity: 1, transform: "translateX(0)" },
|
||||
});
|
||||
|
||||
const slideDownAndFade = keyframes({
|
||||
"0%": { opacity: 0, transform: "translateY(-2px)" },
|
||||
"100%": { opacity: 1, transform: "translateY(0)" },
|
||||
});
|
||||
|
||||
const slideLeftAndFade = keyframes({
|
||||
"0%": { opacity: 0, transform: "translateX(2px)" },
|
||||
"100%": { opacity: 1, transform: "translateX(0)" },
|
||||
});
|
||||
|
||||
const bounce = keyframes`
|
||||
from, 20%, 53%, 80%, to {
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
40%, 43% {
|
||||
transform: translate3d(0, -30px, 0);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: translate3d(0, -15px, 0);
|
||||
}
|
||||
|
||||
90% {
|
||||
transform: translate3d(0,-4px,0);
|
||||
}
|
||||
`;
|
||||
|
||||
const animationTypeOne = keyframes({
|
||||
"0%": {
|
||||
opacity: 1,
|
||||
},
|
||||
"20%": {
|
||||
opacity: 0,
|
||||
},
|
||||
"100%": {
|
||||
opacity: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const fadeIn = keyframes({ from: { opacity: 0 }, to: { opacity: 1 } });
|
||||
|
||||
const itemStyles: ThemeUIStyleObject = {
|
||||
all: "unset",
|
||||
fontSize: 1,
|
||||
lineHeight: 1,
|
||||
color: (theme) => theme.rawColors?.modes?.light?.text,
|
||||
borderRadius: 3,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
height: "auto",
|
||||
padding: "10px 5px",
|
||||
position: "relative",
|
||||
paddingLeft: 2,
|
||||
userSelect: "none",
|
||||
"&[data-disabled]": {
|
||||
color: (theme) => theme.rawColors?.modes?.light.muted,
|
||||
pointerEvents: "none",
|
||||
},
|
||||
"&:focus": {
|
||||
backgroundColor: (theme) => theme.rawColors?.modes?.light?.text,
|
||||
color: (theme) => theme.rawColors?.modes?.light?.background,
|
||||
},
|
||||
};
|
||||
|
||||
const Content = (props: DropdownMenu.DropdownMenuContentProps) => (
|
||||
<DropdownMenu.Content
|
||||
{...props}
|
||||
sx={{
|
||||
minWidth: 220,
|
||||
backgroundColor: (theme) => theme.rawColors?.modes?.light?.background,
|
||||
borderRadius: 6,
|
||||
padding: 1,
|
||||
boxShadow:
|
||||
"0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)",
|
||||
"@media (prefers-reduced-motion: no-preference)": {
|
||||
animationDuration: "400ms",
|
||||
animationTimingFunction: "cubic-bezier(0.16, 1, 0.3, 1)",
|
||||
willChange: "transform, opacity",
|
||||
'&[data-state="open"]': {
|
||||
'&[data-side="top"]': {
|
||||
animationName: slideDownAndFade.toString(),
|
||||
},
|
||||
'&[data-side="right"]': {
|
||||
animationName: slideLeftAndFade.toString(),
|
||||
},
|
||||
'&[data-side="bottom"]': {
|
||||
animationName: slideUpAndFade.toString(),
|
||||
},
|
||||
'&[data-side="left"]': {
|
||||
animationName: slideRightAndFade.toString(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
const Item = (props: DropdownMenu.MenuItemProps) => (
|
||||
<DropdownMenu.Item {...props} sx={{ ...itemStyles }} />
|
||||
);
|
||||
|
||||
const Label = (props: DropdownMenu.MenuLabelProps) => (
|
||||
<DropdownMenu.Label {...props} sx={{ ...itemStyles }} />
|
||||
);
|
||||
|
||||
const Group = DropdownMenu.Group;
|
||||
const Separator = DropdownMenu.Separator;
|
||||
|
||||
const Arrow = (props: DropdownMenu.MenuArrowProps) => (
|
||||
<DropdownMenu.Arrow
|
||||
{...props}
|
||||
sx={{
|
||||
fill: (theme) => theme.rawColors?.modes?.light.background,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
const Dropdown = {
|
||||
Root,
|
||||
Label,
|
||||
Trigger,
|
||||
Content,
|
||||
Item,
|
||||
Arrow,
|
||||
Group,
|
||||
Separator,
|
||||
};
|
||||
|
||||
export default Dropdown;
|
||||
31
components/Footer.tsx
Normal file
31
components/Footer.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Box } from "theme-ui";
|
||||
import { useSnapshot } from "valtio";
|
||||
import { state } from "../state";
|
||||
|
||||
const Footer = () => {
|
||||
const snap = useSnapshot(state);
|
||||
return (
|
||||
<Box as="footer" sx={{ display: "flex" }}>
|
||||
<Box
|
||||
as="pre"
|
||||
sx={{
|
||||
borderRadius: "6px",
|
||||
backgroundColor: "#242426",
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
height: "160px",
|
||||
fontFamily: "monospace",
|
||||
fontSize: 0,
|
||||
overflowY: "scroll",
|
||||
py: 3,
|
||||
px: 3,
|
||||
m: 3,
|
||||
}}
|
||||
>
|
||||
{snap.logs.map((log, index) => index + 1 + ": " + log + "\n")}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
73
components/HooksEditor.tsx
Normal file
73
components/HooksEditor.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
/** @jsxImportSource theme-ui */
|
||||
import { useRef } from "react";
|
||||
import { useSnapshot } from "valtio";
|
||||
import Editor from "@monaco-editor/react";
|
||||
import type monaco from "monaco-editor";
|
||||
import { useColorMode } from "@theme-ui/color-modes";
|
||||
import { Button, Box } from "theme-ui";
|
||||
import { ArrowRight } from "phosphor-react";
|
||||
|
||||
import { state } from "../state";
|
||||
import dark from "../theme/editor/amy.json";
|
||||
import light from "../theme/editor/xcode_default.json";
|
||||
|
||||
const HooksEditor = () => {
|
||||
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
|
||||
const [mode, setColorMode] = useColorMode();
|
||||
const snap = useSnapshot(state);
|
||||
return (
|
||||
<Box sx={{ flex: 1, display: "flex", position: "relative" }}>
|
||||
<Editor
|
||||
defaultLanguage={snap.files?.[snap.active]?.language}
|
||||
path={snap.files?.[snap.active]?.name}
|
||||
defaultValue={snap.files?.[snap.active]?.content}
|
||||
beforeMount={(monaco) => {
|
||||
// @ts-expect-error
|
||||
monaco.editor.defineTheme("dark", dark);
|
||||
// @ts-expect-error
|
||||
monaco.editor.defineTheme("light", light);
|
||||
}}
|
||||
onMount={(editor, monaco) => {
|
||||
editorRef.current = editor;
|
||||
editor.updateOptions({
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
});
|
||||
editor.addCommand(
|
||||
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S,
|
||||
() => {
|
||||
if (
|
||||
state.files &&
|
||||
state.files.length > 0 &&
|
||||
state.files[snap.active]
|
||||
) {
|
||||
console.log(
|
||||
`File ${snap.files[snap.active].name} saved successfully ✅`
|
||||
);
|
||||
state.files[snap.active].content = editor.getValue();
|
||||
}
|
||||
}
|
||||
);
|
||||
}}
|
||||
theme={mode === "dark" ? "dark" : "light"}
|
||||
wrapperProps={{ style: { display: "flex", flex: 1 } }}
|
||||
/>
|
||||
<Button
|
||||
sx={{
|
||||
position: "absolute",
|
||||
bottom: 1,
|
||||
left: 3,
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
Compile{" "}
|
||||
<ArrowRight sx={{ mb: "0px", ml: 2 }} weight="bold" size="20px" />
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default HooksEditor;
|
||||
29
components/Logo.tsx
Normal file
29
components/Logo.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
/** @jsxImportSource theme-ui */
|
||||
import { useColorMode } from "theme-ui";
|
||||
|
||||
function Logo(props: React.SVGProps<SVGSVGElement>) {
|
||||
const [mode] = useColorMode();
|
||||
return (
|
||||
<svg
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 28 22"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M19.603 3.87h2.3l-4.786 4.747a4.466 4.466 0 01-6.276 0L6.054 3.871h2.3l3.636 3.605a2.828 2.828 0 003.975 0l3.638-3.605zM8.325 17.069h-2.3l4.816-4.776a4.466 4.466 0 016.276 0l4.816 4.776h-2.3l-3.665-3.635a2.828 2.828 0 00-3.975 0l-3.668 3.635z"
|
||||
sx={{ fill: "text" }}
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M1.556 9.769h4.751v1.555H1.556v10.072H0V0h1.556v9.769zM26.444 9.769h-4.751v1.555h4.751v10.072H28V0h-1.556v9.769z"
|
||||
sx={{ fill: "text" }}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default Logo;
|
||||
127
components/Navigation.tsx
Normal file
127
components/Navigation.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
/** @jsxImportSource theme-ui */
|
||||
import Link from "next/link";
|
||||
import { DownloadSimple, Plus, Share, BookOpen } from "phosphor-react";
|
||||
import {
|
||||
Container,
|
||||
Box,
|
||||
Heading,
|
||||
Button,
|
||||
Spinner,
|
||||
useColorMode,
|
||||
} from "theme-ui";
|
||||
import { useSnapshot } from "valtio";
|
||||
import { Sun, MoonStars } from "phosphor-react";
|
||||
import Image from "next/image";
|
||||
import { useSession, signIn, signOut } from "next-auth/react";
|
||||
import Dropdown from "./DropdownMenu";
|
||||
|
||||
import Stack from "./Stack";
|
||||
import Logo from "./Logo";
|
||||
// import Button from "./Button";
|
||||
import { state } from "../state";
|
||||
|
||||
const Navigation = () => {
|
||||
const snap = useSnapshot(state);
|
||||
const [mode, setColorMode] = useColorMode();
|
||||
const { data: session, status } = useSession();
|
||||
console.log(session);
|
||||
return (
|
||||
<Box
|
||||
as="nav"
|
||||
sx={{
|
||||
display: "flex",
|
||||
height: "60px",
|
||||
bg: "background",
|
||||
// borderBottom: "1px solid",
|
||||
borderColor: "text",
|
||||
}}
|
||||
>
|
||||
<Container sx={{ display: "flex", alignItems: "center", py: 2 }}>
|
||||
<Link href="/" passHref>
|
||||
<Box as="a" sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Logo width="30px" height="30px" />
|
||||
<Heading as="h3" sx={{ fontWeight: "bold", ml: 2 }}>
|
||||
XRPL Hooks
|
||||
</Heading>
|
||||
</Box>
|
||||
</Link>
|
||||
<Box sx={{ ml: 3 }}></Box>
|
||||
<Stack sx={{ ml: 3 }} spacing={2}>
|
||||
{state.loading && "loading"}
|
||||
{snap.files &&
|
||||
snap.files.length > 0 &&
|
||||
snap.files?.map((file, index) => (
|
||||
<Button
|
||||
onClick={() => (state.active = index)}
|
||||
key={file.name}
|
||||
variant={snap.active === index ? "secondary" : "muted"}
|
||||
>
|
||||
{file.name}
|
||||
</Button>
|
||||
))}
|
||||
</Stack>
|
||||
<Stack sx={{ color: "text", ml: "auto" }}>
|
||||
<Plus sx={{ display: "flex" }} size="20px" />
|
||||
<Share sx={{ display: "flex" }} size="20px" />
|
||||
<DownloadSimple sx={{ display: "flex" }} size="20px" />
|
||||
<Box
|
||||
color="text"
|
||||
onClick={(e) => {
|
||||
setColorMode(mode === "light" ? "dark" : "light");
|
||||
}}
|
||||
sx={{
|
||||
display: "flex",
|
||||
marginLeft: "auto",
|
||||
cursor: "pointer",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
mb: 1,
|
||||
}}
|
||||
>
|
||||
{mode === "dark" ? <Sun size="20px" /> : <MoonStars size="20px" />}
|
||||
</Box>
|
||||
{status === "authenticated" && (
|
||||
<Dropdown.Root>
|
||||
<Dropdown.Trigger asChild>
|
||||
<Box sx={{ borderRadius: "100%", overflow: "hidden" }}>
|
||||
<Image
|
||||
src={session?.user?.image || ""}
|
||||
width="30px"
|
||||
height="30px"
|
||||
objectFit="cover"
|
||||
alt="User avatar"
|
||||
/>
|
||||
</Box>
|
||||
</Dropdown.Trigger>
|
||||
<Dropdown.Content>
|
||||
<Dropdown.Item onClick={() => signOut()}>Log out</Dropdown.Item>
|
||||
<Dropdown.Arrow offset={10} />
|
||||
</Dropdown.Content>
|
||||
</Dropdown.Root>
|
||||
)}
|
||||
{status === "unauthenticated" && (
|
||||
<Button
|
||||
sx={{ size: "sm", cursor: "pointer" }}
|
||||
onClick={() => signIn("github")}
|
||||
>
|
||||
Github Login
|
||||
</Button>
|
||||
)}
|
||||
{status === "loading" && <Spinner size="20px" />}
|
||||
{/* <Box
|
||||
sx={{
|
||||
border: "1px solid",
|
||||
borderRadius: "3px",
|
||||
borderColor: "text",
|
||||
p: 1,
|
||||
}}
|
||||
>
|
||||
<BookOpen sx={{ display: "flex" }} size="20px" />
|
||||
</Box> */}
|
||||
</Stack>
|
||||
</Container>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navigation;
|
||||
38
components/Stack.tsx
Normal file
38
components/Stack.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Children } from "react";
|
||||
import { Flex, Box, ThemeUIStyleObject, BoxProps } from "theme-ui";
|
||||
import { useBreakpointIndex } from "@theme-ui/match-media";
|
||||
|
||||
const Stack: React.FC<
|
||||
BoxProps & {
|
||||
spacing?: (number | string | null)[] | string | number;
|
||||
direction?: ("column" | "row") | ("column" | "row" | null)[];
|
||||
sx?: ThemeUIStyleObject;
|
||||
}
|
||||
> = ({ spacing = 3, direction = "row", sx, children, ...rest }) => {
|
||||
const breakpointIndex = useBreakpointIndex();
|
||||
const currentDirection = Array.isArray(direction)
|
||||
? direction[breakpointIndex]
|
||||
: direction;
|
||||
const childrenLength = Array.isArray(children) ? children.length : null;
|
||||
return (
|
||||
<Box
|
||||
{...rest}
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: direction,
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
{Children.map(children, (child, index) => (
|
||||
<Box
|
||||
mt={currentDirection === "column" && index !== 0 ? spacing : 0}
|
||||
ml={currentDirection === "row" && index !== 0 ? spacing : 0}
|
||||
>
|
||||
{child}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Stack;
|
||||
@@ -1,4 +1,7 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
module.exports = {
|
||||
reactStrictMode: true,
|
||||
images: {
|
||||
domains: ['avatars.githubusercontent.com'],
|
||||
},
|
||||
}
|
||||
|
||||
19
package.json
19
package.json
@@ -9,9 +9,24 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "11.1.2",
|
||||
"@mattjennings/react-modal": "^1.0.3",
|
||||
"@monaco-editor/react": "^4.3.1",
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@radix-ui/react-dropdown-menu": "^0.1.1",
|
||||
"@theme-ui/color": "^0.11.3",
|
||||
"@theme-ui/match-media": "^0.11.3",
|
||||
"@wasmer/wasi": "^0.12.0",
|
||||
"@wasmer/wasm-transformer": "^0.12.0",
|
||||
"@wasmer/wasmfs": "^0.12.0",
|
||||
"monaco-editor": "^0.29.1",
|
||||
"next": "^12.0.1",
|
||||
"next-auth": "^4.0.0-beta.5",
|
||||
"octokit": "^1.7.0",
|
||||
"phosphor-react": "^1.3.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2"
|
||||
"react-dom": "17.0.2",
|
||||
"theme-ui": "^0.11.3",
|
||||
"valtio": "^1.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "17.0.31",
|
||||
|
||||
47
pages/[[...index]].tsx
Normal file
47
pages/[[...index]].tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
/** @jsxImportSource theme-ui */
|
||||
import type { GetStaticPaths, GetStaticProps, NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import { Box } from "theme-ui";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
import HooksEditor from "../components/HooksEditor";
|
||||
import { useEffect } from "react";
|
||||
import { fetchFiles } from "../state";
|
||||
import Footer from "../components/Footer";
|
||||
|
||||
const Home: NextPage = () => {
|
||||
const router = useRouter();
|
||||
const index = router.query.index;
|
||||
const gistId = index && Array.isArray(index) ? index[0] : "";
|
||||
useEffect(() => {
|
||||
fetchFiles(gistId);
|
||||
}, [gistId]);
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>XRPL Hooks Playground</title>
|
||||
</Head>
|
||||
|
||||
<main sx={{ display: "flex", flex: 1 }}>
|
||||
<HooksEditor />
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
// ...
|
||||
return { paths: [], fallback: "blocking" };
|
||||
};
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (context) => {
|
||||
// ...
|
||||
return {
|
||||
props: {},
|
||||
revalidate: 60,
|
||||
};
|
||||
};
|
||||
@@ -1,7 +1,22 @@
|
||||
import '../styles/globals.css'
|
||||
import type { AppProps } from 'next/app'
|
||||
/** @jsxImportSource theme-ui */
|
||||
import "../styles/globals.css";
|
||||
import type { AppProps } from "next/app";
|
||||
import { ThemeProvider } from "theme-ui";
|
||||
import { SessionProvider } from "next-auth/react";
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />
|
||||
import { theme } from "../theme";
|
||||
import Navigation from "../components/Navigation";
|
||||
|
||||
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
|
||||
return (
|
||||
<>
|
||||
<SessionProvider session={session}>
|
||||
<ThemeProvider theme={theme}>
|
||||
<Navigation />
|
||||
<Component {...pageProps} />
|
||||
</ThemeProvider>
|
||||
</SessionProvider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
export default MyApp
|
||||
export default MyApp;
|
||||
|
||||
41
pages/_document.tsx
Normal file
41
pages/_document.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import Document, {
|
||||
Html,
|
||||
Head,
|
||||
Main,
|
||||
NextScript,
|
||||
DocumentContext,
|
||||
} from "next/document";
|
||||
|
||||
class MyDocument extends Document {
|
||||
static async getInitialProps(ctx: DocumentContext) {
|
||||
const initialProps = await Document.getInitialProps(ctx);
|
||||
|
||||
return initialProps;
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<Html>
|
||||
<Head>
|
||||
<meta name="description" content="Playground for XRPL Hooks" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link
|
||||
rel="preconnect"
|
||||
href="https://fonts.gstatic.com"
|
||||
crossOrigin=""
|
||||
/>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital@0;1&family=Work+Sans:wght@400;600;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default MyDocument;
|
||||
49
pages/api/auth/[...nextauth].ts
Normal file
49
pages/api/auth/[...nextauth].ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import NextAuth from "next-auth"
|
||||
import GithubProvider from "next-auth/providers/github"
|
||||
|
||||
export default NextAuth({
|
||||
// Configure one or more authentication providers
|
||||
providers: [
|
||||
// GithubProvider({
|
||||
// clientId: process.env.GITHUB_ID,
|
||||
// clientSecret: process.env.GITHUB_SECRET,
|
||||
// // @ts-expect-error
|
||||
// scope: 'user,gist'
|
||||
// }),
|
||||
{
|
||||
id: "github",
|
||||
name: "GitHub",
|
||||
type: "oauth",
|
||||
clientId: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
authorization: "https://github.com/login/oauth/authorize?scope=read:user+user:email+gist",
|
||||
token: "https://github.com/login/oauth/access_token",
|
||||
userinfo: "https://api.github.com/user",
|
||||
profile(profile) {
|
||||
console.log(profile)
|
||||
return {
|
||||
id: profile.id.toString(),
|
||||
name: profile.name || profile.login,
|
||||
email: profile.email,
|
||||
image: profile.avatar_url,
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
// ...add more providers here
|
||||
],
|
||||
callbacks: {
|
||||
async jwt({ token, user, account, profile, isNewUser }) {
|
||||
console.log('jwt', { token, account })
|
||||
if (account && account.access_token) {
|
||||
token.accessToken = account.access_token;
|
||||
}
|
||||
return token
|
||||
},
|
||||
async session({ session, token }) {
|
||||
console.log('session', { token, session })
|
||||
session.accessToken = token.accessToken;
|
||||
return session
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -1,72 +0,0 @@
|
||||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import Image from 'next/image'
|
||||
import styles from '../styles/Home.module.css'
|
||||
|
||||
const Home: NextPage = () => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Head>
|
||||
<title>Create Next App</title>
|
||||
<meta name="description" content="Generated by create next app" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
|
||||
<main className={styles.main}>
|
||||
<h1 className={styles.title}>
|
||||
Welcome to <a href="https://nextjs.org">Next.js!</a>
|
||||
</h1>
|
||||
|
||||
<p className={styles.description}>
|
||||
Get started by editing{' '}
|
||||
<code className={styles.code}>pages/index.js</code>
|
||||
</p>
|
||||
|
||||
<div className={styles.grid}>
|
||||
<a href="https://nextjs.org/docs" className={styles.card}>
|
||||
<h2>Documentation →</h2>
|
||||
<p>Find in-depth information about Next.js features and API.</p>
|
||||
</a>
|
||||
|
||||
<a href="https://nextjs.org/learn" className={styles.card}>
|
||||
<h2>Learn →</h2>
|
||||
<p>Learn about Next.js in an interactive course with quizzes!</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://github.com/vercel/next.js/tree/master/examples"
|
||||
className={styles.card}
|
||||
>
|
||||
<h2>Examples →</h2>
|
||||
<p>Discover and deploy boilerplate example Next.js projects.</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||
className={styles.card}
|
||||
>
|
||||
<h2>Deploy →</h2>
|
||||
<p>
|
||||
Instantly deploy your Next.js site to a public URL with Vercel.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer className={styles.footer}>
|
||||
<a
|
||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Powered by{' '}
|
||||
<span className={styles.logo}>
|
||||
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
|
||||
</span>
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Home
|
||||
6
public/hooks-logo.svg
Normal file
6
public/hooks-logo.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="28" height="22" viewBox="0 0 28 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.6028 3.87061H21.9021L17.1171 8.61699C15.3842 10.3349 12.5747 10.3349 10.8406 8.61699L6.05377 3.87061H8.35492L11.9903 7.47615C12.5199 7.99913 13.2338 8.2923 13.9775 8.2923C14.7211 8.2923 15.435 7.99913 15.9646 7.47615L19.6028 3.87061Z" fill="white"/>
|
||||
<path d="M8.3255 17.0685H6.02466L10.8407 12.2929C12.5736 10.5749 15.3831 10.5749 17.1172 12.2929L21.9332 17.0685H19.6339L15.9675 13.4337C15.4378 12.9107 14.724 12.6175 13.9803 12.6175C13.2367 12.6175 12.5228 12.9107 11.9932 13.4337L8.3255 17.0685Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.5556 9.76858L6.30711 9.76858L6.30711 11.3241L1.5556 11.3241L1.5556 21.396L4.06715e-05 21.396L4.05312e-05 -3.17035e-07L1.5556 -2.38842e-07L1.5556 9.76858Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.4443 9.76858L21.6928 9.76858L21.6928 11.3241L26.4443 11.3241L26.4443 21.396L27.9998 21.396L27.9998 -3.17035e-07L26.4443 -2.38842e-07L26.4443 9.76858Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
105
state.ts
Normal file
105
state.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { proxy } from 'valtio';
|
||||
import { devtools } from 'valtio/utils';
|
||||
import { Octokit } from '@octokit/core';
|
||||
|
||||
const octokit = new Octokit();
|
||||
|
||||
interface Files {
|
||||
name: string,
|
||||
language: string,
|
||||
content: string
|
||||
}
|
||||
|
||||
interface IState {
|
||||
files: {
|
||||
name: string;
|
||||
language: string;
|
||||
content: string;
|
||||
}[] | [],
|
||||
active: number;
|
||||
loading: boolean;
|
||||
logs: string[];
|
||||
}
|
||||
|
||||
const initFiles = [
|
||||
{
|
||||
name: 'hello.c',
|
||||
language: 'c',
|
||||
content: `
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
// printf() displays the string inside quotation
|
||||
printf("Hello, World!");
|
||||
return 0;
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'another.c',
|
||||
language: 'c',
|
||||
content: `
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
/* printf function displays the content that is
|
||||
* passed between the double quotes.
|
||||
*/
|
||||
printf("Hello World");
|
||||
return 0;
|
||||
}
|
||||
`,
|
||||
}
|
||||
];
|
||||
|
||||
const state = proxy<IState>({
|
||||
files: [],
|
||||
active: 0,
|
||||
loading: false,
|
||||
logs: []
|
||||
});
|
||||
|
||||
// state.files = initFiles;
|
||||
|
||||
// const initState = ({ gistId }: { gistId?: string }) => {
|
||||
// if (!gistId) {
|
||||
// return initialState;
|
||||
// }
|
||||
// }
|
||||
|
||||
// const state = initialState;
|
||||
|
||||
export const fetchFiles = (gistId: string) => {
|
||||
if (gistId) {
|
||||
console.log('callling')
|
||||
octokit.request("GET /gists/{gist_id}", { gist_id: gistId }).then(res => {
|
||||
state.logs.push('Fetching files from Github Gists...');
|
||||
|
||||
if (res.data.files && Object.keys(res.data.files).length > 0) {
|
||||
const files = Object.keys(res.data.files).map(filename => ({
|
||||
name: res.data.files?.[filename]?.filename || 'noname.c',
|
||||
language: res.data.files?.[filename]?.language?.toLowerCase() || '',
|
||||
content: res.data.files?.[filename]?.content || ''
|
||||
}))
|
||||
state.files = initFiles
|
||||
state.loading = false;
|
||||
if (files.length > 0) {
|
||||
state.logs.push('Fetched successfully ✅')
|
||||
state.files = files;
|
||||
return
|
||||
}
|
||||
return state.files = initFiles
|
||||
}
|
||||
|
||||
}).catch(err => {
|
||||
state.loading = false;
|
||||
return state.files = initFiles
|
||||
})
|
||||
return
|
||||
}
|
||||
state.loading = false;
|
||||
return state.files = initFiles
|
||||
}
|
||||
|
||||
const unsub = devtools(state, 'Files State')
|
||||
|
||||
export { state };
|
||||
@@ -1,9 +1,11 @@
|
||||
html,
|
||||
body {
|
||||
body,
|
||||
#__next {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
a {
|
||||
|
||||
191
theme/editor/amy.json
Normal file
191
theme/editor/amy.json
Normal file
@@ -0,0 +1,191 @@
|
||||
{
|
||||
"base": "vs-dark",
|
||||
"inherit": true,
|
||||
"rules": [
|
||||
{
|
||||
"background": "200020",
|
||||
"token": ""
|
||||
},
|
||||
{
|
||||
"foreground": "404080",
|
||||
"background": "200020",
|
||||
"fontStyle": "italic",
|
||||
"token": "comment.block"
|
||||
},
|
||||
{
|
||||
"foreground": "999999",
|
||||
"token": "string"
|
||||
},
|
||||
{
|
||||
"foreground": "707090",
|
||||
"token": "constant.language"
|
||||
},
|
||||
{
|
||||
"foreground": "7090b0",
|
||||
"token": "constant.numeric"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"token": "constant.numeric.integer.int32"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"token": "constant.numeric.integer.int64"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold italic",
|
||||
"token": "constant.numeric.integer.nativeint"
|
||||
},
|
||||
{
|
||||
"fontStyle": "underline",
|
||||
"token": "constant.numeric.floating-point.ocaml"
|
||||
},
|
||||
{
|
||||
"foreground": "666666",
|
||||
"token": "constant.character"
|
||||
},
|
||||
{
|
||||
"foreground": "8080a0",
|
||||
"token": "constant.language.boolean"
|
||||
},
|
||||
{
|
||||
"foreground": "008080",
|
||||
"token": "variable.language"
|
||||
},
|
||||
{
|
||||
"foreground": "008080",
|
||||
"token": "variable.other"
|
||||
},
|
||||
{
|
||||
"foreground": "a080ff",
|
||||
"token": "keyword"
|
||||
},
|
||||
{
|
||||
"foreground": "a0a0ff",
|
||||
"token": "keyword.operator"
|
||||
},
|
||||
{
|
||||
"foreground": "d0d0ff",
|
||||
"token": "keyword.other.decorator"
|
||||
},
|
||||
{
|
||||
"fontStyle": "underline",
|
||||
"token": "keyword.operator.infix.floating-point.ocaml"
|
||||
},
|
||||
{
|
||||
"fontStyle": "underline",
|
||||
"token": "keyword.operator.prefix.floating-point.ocaml"
|
||||
},
|
||||
{
|
||||
"foreground": "c080c0",
|
||||
"token": "keyword.other.directive"
|
||||
},
|
||||
{
|
||||
"foreground": "c080c0",
|
||||
"fontStyle": "underline",
|
||||
"token": "keyword.other.directive.line-number"
|
||||
},
|
||||
{
|
||||
"foreground": "80a0ff",
|
||||
"token": "keyword.control"
|
||||
},
|
||||
{
|
||||
"foreground": "b0fff0",
|
||||
"token": "storage"
|
||||
},
|
||||
{
|
||||
"foreground": "60b0ff",
|
||||
"token": "entity.name.type.variant"
|
||||
},
|
||||
{
|
||||
"foreground": "60b0ff",
|
||||
"fontStyle": "italic",
|
||||
"token": "storage.type.variant.polymorphic"
|
||||
},
|
||||
{
|
||||
"foreground": "60b0ff",
|
||||
"fontStyle": "italic",
|
||||
"token": "entity.name.type.variant.polymorphic"
|
||||
},
|
||||
{
|
||||
"foreground": "b000b0",
|
||||
"token": "entity.name.type.module"
|
||||
},
|
||||
{
|
||||
"foreground": "b000b0",
|
||||
"fontStyle": "underline",
|
||||
"token": "entity.name.type.module-type.ocaml"
|
||||
},
|
||||
{
|
||||
"foreground": "a00050",
|
||||
"token": "support.other"
|
||||
},
|
||||
{
|
||||
"foreground": "70e080",
|
||||
"token": "entity.name.type.class"
|
||||
},
|
||||
{
|
||||
"foreground": "70e0a0",
|
||||
"token": "entity.name.type.class-type"
|
||||
},
|
||||
{
|
||||
"foreground": "50a0a0",
|
||||
"token": "entity.name.function"
|
||||
},
|
||||
{
|
||||
"foreground": "80b0b0",
|
||||
"token": "variable.parameter"
|
||||
},
|
||||
{
|
||||
"foreground": "3080a0",
|
||||
"token": "entity.name.type.token"
|
||||
},
|
||||
{
|
||||
"foreground": "3cb0d0",
|
||||
"token": "entity.name.type.token.reference"
|
||||
},
|
||||
{
|
||||
"foreground": "90e0e0",
|
||||
"token": "entity.name.function.non-terminal"
|
||||
},
|
||||
{
|
||||
"foreground": "c0f0f0",
|
||||
"token": "entity.name.function.non-terminal.reference"
|
||||
},
|
||||
{
|
||||
"foreground": "009090",
|
||||
"token": "entity.name.tag"
|
||||
},
|
||||
{
|
||||
"background": "200020",
|
||||
"token": "support.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "400080",
|
||||
"background": "ffff00",
|
||||
"fontStyle": "bold",
|
||||
"token": "invalid.illegal"
|
||||
},
|
||||
{
|
||||
"foreground": "200020",
|
||||
"background": "cc66ff",
|
||||
"token": "invalid.deprecated"
|
||||
},
|
||||
{
|
||||
"background": "40008054",
|
||||
"token": "source.camlp4.embedded"
|
||||
},
|
||||
{
|
||||
"foreground": "805080",
|
||||
"token": "punctuation"
|
||||
}
|
||||
],
|
||||
"colors": {
|
||||
"editor.foreground": "#D0D0FF",
|
||||
"editor.background": "#000000",
|
||||
"editor.selectionBackground": "#ffffff30",
|
||||
"editor.lineHighlightBackground": "#ffffff20",
|
||||
"editorCursor.foreground": "#7070FF",
|
||||
"editorWhitespace.foreground": "#BFBFBF"
|
||||
}
|
||||
}
|
||||
312
theme/editor/sunburst.json
Normal file
312
theme/editor/sunburst.json
Normal file
@@ -0,0 +1,312 @@
|
||||
{
|
||||
"base": "vs-dark",
|
||||
"inherit": true,
|
||||
"rules": [
|
||||
{
|
||||
"background": "000000",
|
||||
"token": ""
|
||||
},
|
||||
{
|
||||
"foreground": "aeaeae",
|
||||
"fontStyle": "italic",
|
||||
"token": "comment"
|
||||
},
|
||||
{
|
||||
"foreground": "3387cc",
|
||||
"token": "constant"
|
||||
},
|
||||
{
|
||||
"foreground": "89bdff",
|
||||
"token": "entity"
|
||||
},
|
||||
{
|
||||
"foreground": "e28964",
|
||||
"token": "keyword"
|
||||
},
|
||||
{
|
||||
"foreground": "99cf50",
|
||||
"token": "storage"
|
||||
},
|
||||
{
|
||||
"foreground": "65b042",
|
||||
"token": "string"
|
||||
},
|
||||
{
|
||||
"foreground": "9b859d",
|
||||
"token": "support"
|
||||
},
|
||||
{
|
||||
"foreground": "3e87e3",
|
||||
"token": "variable"
|
||||
},
|
||||
{
|
||||
"foreground": "fd5ff1",
|
||||
"fontStyle": "italic underline",
|
||||
"token": "invalid.deprecated"
|
||||
},
|
||||
{
|
||||
"foreground": "fd5ff1",
|
||||
"background": "562d56bf",
|
||||
"token": "invalid.illegal"
|
||||
},
|
||||
{
|
||||
"background": "b1b3ba08",
|
||||
"token": "text source"
|
||||
},
|
||||
{
|
||||
"foreground": "9b5c2e",
|
||||
"fontStyle": "italic",
|
||||
"token": "entity.other.inherited-class"
|
||||
},
|
||||
{
|
||||
"foreground": "daefa3",
|
||||
"token": "string.quoted source"
|
||||
},
|
||||
{
|
||||
"foreground": "ddf2a4",
|
||||
"token": "string constant"
|
||||
},
|
||||
{
|
||||
"foreground": "e9c062",
|
||||
"token": "string.regexp"
|
||||
},
|
||||
{
|
||||
"foreground": "cf7d34",
|
||||
"token": "string.regexp constant.character.escape"
|
||||
},
|
||||
{
|
||||
"foreground": "cf7d34",
|
||||
"token": "string.regexp source.ruby.embedded"
|
||||
},
|
||||
{
|
||||
"foreground": "cf7d34",
|
||||
"token": "string.regexp string.regexp.arbitrary-repitition"
|
||||
},
|
||||
{
|
||||
"foreground": "8a9a95",
|
||||
"token": "string variable"
|
||||
},
|
||||
{
|
||||
"foreground": "dad085",
|
||||
"token": "support.function"
|
||||
},
|
||||
{
|
||||
"foreground": "cf6a4c",
|
||||
"token": "support.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "8996a8",
|
||||
"token": "meta.preprocessor.c"
|
||||
},
|
||||
{
|
||||
"foreground": "afc4db",
|
||||
"token": "meta.preprocessor.c keyword"
|
||||
},
|
||||
{
|
||||
"fontStyle": "underline",
|
||||
"token": "entity.name.type"
|
||||
},
|
||||
{
|
||||
"foreground": "676767",
|
||||
"fontStyle": "italic",
|
||||
"token": "meta.cast"
|
||||
},
|
||||
{
|
||||
"foreground": "494949",
|
||||
"token": "meta.sgml.html meta.doctype"
|
||||
},
|
||||
{
|
||||
"foreground": "494949",
|
||||
"token": "meta.sgml.html meta.doctype entity"
|
||||
},
|
||||
{
|
||||
"foreground": "494949",
|
||||
"token": "meta.sgml.html meta.doctype string"
|
||||
},
|
||||
{
|
||||
"foreground": "494949",
|
||||
"token": "meta.xml-processing"
|
||||
},
|
||||
{
|
||||
"foreground": "494949",
|
||||
"token": "meta.xml-processing entity"
|
||||
},
|
||||
{
|
||||
"foreground": "494949",
|
||||
"token": "meta.xml-processing string"
|
||||
},
|
||||
{
|
||||
"foreground": "89bdff",
|
||||
"token": "meta.tag"
|
||||
},
|
||||
{
|
||||
"foreground": "89bdff",
|
||||
"token": "meta.tag entity"
|
||||
},
|
||||
{
|
||||
"foreground": "e0c589",
|
||||
"token": "source entity.name.tag"
|
||||
},
|
||||
{
|
||||
"foreground": "e0c589",
|
||||
"token": "source entity.other.attribute-name"
|
||||
},
|
||||
{
|
||||
"foreground": "e0c589",
|
||||
"token": "meta.tag.inline"
|
||||
},
|
||||
{
|
||||
"foreground": "e0c589",
|
||||
"token": "meta.tag.inline entity"
|
||||
},
|
||||
{
|
||||
"foreground": "e18964",
|
||||
"token": "entity.name.tag.namespace"
|
||||
},
|
||||
{
|
||||
"foreground": "e18964",
|
||||
"token": "entity.other.attribute-name.namespace"
|
||||
},
|
||||
{
|
||||
"foreground": "cda869",
|
||||
"token": "meta.selector.css entity.name.tag"
|
||||
},
|
||||
{
|
||||
"foreground": "8f9d6a",
|
||||
"token": "meta.selector.css entity.other.attribute-name.tag.pseudo-class"
|
||||
},
|
||||
{
|
||||
"foreground": "8b98ab",
|
||||
"token": "meta.selector.css entity.other.attribute-name.id"
|
||||
},
|
||||
{
|
||||
"foreground": "9b703f",
|
||||
"token": "meta.selector.css entity.other.attribute-name.class"
|
||||
},
|
||||
{
|
||||
"foreground": "c5af75",
|
||||
"token": "support.type.property-name.css"
|
||||
},
|
||||
{
|
||||
"foreground": "f9ee98",
|
||||
"token": "meta.property-group support.constant.property-value.css"
|
||||
},
|
||||
{
|
||||
"foreground": "f9ee98",
|
||||
"token": "meta.property-value support.constant.property-value.css"
|
||||
},
|
||||
{
|
||||
"foreground": "8693a5",
|
||||
"token": "meta.preprocessor.at-rule keyword.control.at-rule"
|
||||
},
|
||||
{
|
||||
"foreground": "dd7b3b",
|
||||
"token": "meta.property-value support.constant.named-color.css"
|
||||
},
|
||||
{
|
||||
"foreground": "dd7b3b",
|
||||
"token": "meta.property-value constant"
|
||||
},
|
||||
{
|
||||
"foreground": "8f9d6a",
|
||||
"token": "meta.constructor.argument.css"
|
||||
},
|
||||
{
|
||||
"foreground": "f8f8f8",
|
||||
"background": "0e2231",
|
||||
"fontStyle": "italic",
|
||||
"token": "meta.diff"
|
||||
},
|
||||
{
|
||||
"foreground": "f8f8f8",
|
||||
"background": "0e2231",
|
||||
"fontStyle": "italic",
|
||||
"token": "meta.diff.header"
|
||||
},
|
||||
{
|
||||
"foreground": "f8f8f8",
|
||||
"background": "420e09",
|
||||
"token": "markup.deleted"
|
||||
},
|
||||
{
|
||||
"foreground": "f8f8f8",
|
||||
"background": "4a410d",
|
||||
"token": "markup.changed"
|
||||
},
|
||||
{
|
||||
"foreground": "f8f8f8",
|
||||
"background": "253b22",
|
||||
"token": "markup.inserted"
|
||||
},
|
||||
{
|
||||
"foreground": "e9c062",
|
||||
"fontStyle": "italic",
|
||||
"token": "markup.italic"
|
||||
},
|
||||
{
|
||||
"foreground": "e9c062",
|
||||
"fontStyle": "bold",
|
||||
"token": "markup.bold"
|
||||
},
|
||||
{
|
||||
"foreground": "e18964",
|
||||
"fontStyle": "underline",
|
||||
"token": "markup.underline"
|
||||
},
|
||||
{
|
||||
"foreground": "e1d4b9",
|
||||
"background": "fee09c12",
|
||||
"fontStyle": "italic",
|
||||
"token": "markup.quote"
|
||||
},
|
||||
{
|
||||
"foreground": "fedcc5",
|
||||
"background": "632d04",
|
||||
"token": "markup.heading"
|
||||
},
|
||||
{
|
||||
"foreground": "fedcc5",
|
||||
"background": "632d04",
|
||||
"token": "markup.heading entity"
|
||||
},
|
||||
{
|
||||
"foreground": "e1d4b9",
|
||||
"token": "markup.list"
|
||||
},
|
||||
{
|
||||
"foreground": "578bb3",
|
||||
"background": "b1b3ba08",
|
||||
"token": "markup.raw"
|
||||
},
|
||||
{
|
||||
"foreground": "f67b37",
|
||||
"fontStyle": "italic",
|
||||
"token": "markup comment"
|
||||
},
|
||||
{
|
||||
"foreground": "60a633",
|
||||
"background": "242424",
|
||||
"token": "meta.separator"
|
||||
},
|
||||
{
|
||||
"background": "eeeeee29",
|
||||
"token": "meta.line.entry.logfile"
|
||||
},
|
||||
{
|
||||
"background": "eeeeee29",
|
||||
"token": "meta.line.exit.logfile"
|
||||
},
|
||||
{
|
||||
"background": "751012",
|
||||
"token": "meta.line.error.logfile"
|
||||
}
|
||||
],
|
||||
"colors": {
|
||||
"editor.foreground": "#F8F8F8",
|
||||
"editor.background": "#000000",
|
||||
"editor.selectionBackground": "#DDF0FF33",
|
||||
"editor.lineHighlightBackground": "#FFFFFF0D",
|
||||
"editorCursor.foreground": "#A7A7A7",
|
||||
"editorWhitespace.foreground": "#CAE2FB3D"
|
||||
}
|
||||
}
|
||||
196
theme/editor/vibrant_ink.json
Normal file
196
theme/editor/vibrant_ink.json
Normal file
@@ -0,0 +1,196 @@
|
||||
{
|
||||
"base": "vs-dark",
|
||||
"inherit": true,
|
||||
"rules": [
|
||||
{
|
||||
"background": "000000",
|
||||
"token": ""
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"background": "0f0f0f",
|
||||
"token": "text"
|
||||
},
|
||||
{
|
||||
"background": "000000",
|
||||
"token": "source.ruby.rails.embedded.html"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"background": "101010",
|
||||
"token": "text.html.ruby"
|
||||
},
|
||||
{
|
||||
"foreground": "ccff33",
|
||||
"token": "constant.numeric.ruby"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"background": "000000",
|
||||
"token": "source"
|
||||
},
|
||||
{
|
||||
"foreground": "9933cc",
|
||||
"token": "comment"
|
||||
},
|
||||
{
|
||||
"foreground": "339999",
|
||||
"token": "constant"
|
||||
},
|
||||
{
|
||||
"foreground": "ff6600",
|
||||
"token": "keyword"
|
||||
},
|
||||
{
|
||||
"foreground": "edf8f9",
|
||||
"token": "keyword.preprocessor"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"token": "keyword.preprocessor directive"
|
||||
},
|
||||
{
|
||||
"foreground": "ffcc00",
|
||||
"token": "entity.name.function"
|
||||
},
|
||||
{
|
||||
"foreground": "ffcc00",
|
||||
"token": "storage.type.function.js"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"token": "variable.parameter"
|
||||
},
|
||||
{
|
||||
"foreground": "772cb7",
|
||||
"background": "070707",
|
||||
"token": "source comment.block"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"token": "variable.other"
|
||||
},
|
||||
{
|
||||
"foreground": "999966",
|
||||
"token": "support.function.activerecord.rails"
|
||||
},
|
||||
{
|
||||
"foreground": "66ff00",
|
||||
"token": "string"
|
||||
},
|
||||
{
|
||||
"foreground": "aaaaaa",
|
||||
"token": "string constant.character.escape"
|
||||
},
|
||||
{
|
||||
"foreground": "000000",
|
||||
"background": "cccc33",
|
||||
"token": "string.interpolated"
|
||||
},
|
||||
{
|
||||
"foreground": "44b4cc",
|
||||
"token": "string.regexp"
|
||||
},
|
||||
{
|
||||
"foreground": "cccc33",
|
||||
"token": "string.literal"
|
||||
},
|
||||
{
|
||||
"foreground": "555555",
|
||||
"token": "string.interpolated constant.character.escape"
|
||||
},
|
||||
{
|
||||
"fontStyle": "underline",
|
||||
"token": "entity.name.class"
|
||||
},
|
||||
{
|
||||
"fontStyle": "underline",
|
||||
"token": "support.class.js"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic underline",
|
||||
"token": "entity.other.inherited-class"
|
||||
},
|
||||
{
|
||||
"foreground": "ff6600",
|
||||
"token": "meta.tag.inline.any.html"
|
||||
},
|
||||
{
|
||||
"foreground": "ff6600",
|
||||
"token": "meta.tag.block.any.html"
|
||||
},
|
||||
{
|
||||
"foreground": "99cc99",
|
||||
"fontStyle": "italic",
|
||||
"token": "entity.other.attribute-name"
|
||||
},
|
||||
{
|
||||
"foreground": "dde93d",
|
||||
"token": "keyword.other"
|
||||
},
|
||||
{
|
||||
"foreground": "ff6600",
|
||||
"token": "meta.selector.css"
|
||||
},
|
||||
{
|
||||
"foreground": "ff6600",
|
||||
"token": "entity.other.attribute-name.pseudo-class.css"
|
||||
},
|
||||
{
|
||||
"foreground": "ff6600",
|
||||
"token": "entity.name.tag.wildcard.css"
|
||||
},
|
||||
{
|
||||
"foreground": "ff6600",
|
||||
"token": "entity.other.attribute-name.id.css"
|
||||
},
|
||||
{
|
||||
"foreground": "ff6600",
|
||||
"token": "entity.other.attribute-name.class.css"
|
||||
},
|
||||
{
|
||||
"foreground": "999966",
|
||||
"token": "support.type.property-name.css"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"token": "keyword.other.unit.css"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"token": "constant.other.rgb-value.css"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"token": "constant.numeric.css"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"token": "support.function.event-handler.js"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"token": "keyword.operator.js"
|
||||
},
|
||||
{
|
||||
"foreground": "cccc66",
|
||||
"token": "keyword.control.js"
|
||||
},
|
||||
{
|
||||
"foreground": "ffffff",
|
||||
"token": "support.class.prototype.js"
|
||||
},
|
||||
{
|
||||
"foreground": "ff6600",
|
||||
"token": "object.property.function.prototype.js"
|
||||
}
|
||||
],
|
||||
"colors": {
|
||||
"editor.foreground": "#FFFFFF",
|
||||
"editor.background": "#000000",
|
||||
"editor.selectionBackground": "#35493CE0",
|
||||
"editor.lineHighlightBackground": "#333300",
|
||||
"editorCursor.foreground": "#FFFFFF",
|
||||
"editorWhitespace.foreground": "#404040"
|
||||
}
|
||||
}
|
||||
98
theme/editor/xcode_default.json
Normal file
98
theme/editor/xcode_default.json
Normal file
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"base": "vs",
|
||||
"inherit": true,
|
||||
"rules": [
|
||||
{
|
||||
"background": "FFFFFF",
|
||||
"token": ""
|
||||
},
|
||||
{
|
||||
"foreground": "008e00",
|
||||
"token": "comment"
|
||||
},
|
||||
{
|
||||
"foreground": "7d4726",
|
||||
"token": "meta.preprocessor"
|
||||
},
|
||||
{
|
||||
"foreground": "7d4726",
|
||||
"token": "keyword.control.import"
|
||||
},
|
||||
{
|
||||
"foreground": "df0002",
|
||||
"token": "string"
|
||||
},
|
||||
{
|
||||
"foreground": "3a00dc",
|
||||
"token": "constant.numeric"
|
||||
},
|
||||
{
|
||||
"foreground": "c800a4",
|
||||
"token": "constant.language"
|
||||
},
|
||||
{
|
||||
"foreground": "275a5e",
|
||||
"token": "constant.character"
|
||||
},
|
||||
{
|
||||
"foreground": "275a5e",
|
||||
"token": "constant.other"
|
||||
},
|
||||
{
|
||||
"foreground": "c800a4",
|
||||
"token": "variable.language"
|
||||
},
|
||||
{
|
||||
"foreground": "c800a4",
|
||||
"token": "variable.other"
|
||||
},
|
||||
{
|
||||
"foreground": "c800a4",
|
||||
"token": "keyword"
|
||||
},
|
||||
{
|
||||
"foreground": "c900a4",
|
||||
"token": "storage"
|
||||
},
|
||||
{
|
||||
"foreground": "438288",
|
||||
"token": "entity.name.class"
|
||||
},
|
||||
{
|
||||
"foreground": "790ead",
|
||||
"token": "entity.name.tag"
|
||||
},
|
||||
{
|
||||
"foreground": "450084",
|
||||
"token": "entity.other.attribute-name"
|
||||
},
|
||||
{
|
||||
"foreground": "450084",
|
||||
"token": "support.function"
|
||||
},
|
||||
{
|
||||
"foreground": "450084",
|
||||
"token": "support.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "790ead",
|
||||
"token": "support.type"
|
||||
},
|
||||
{
|
||||
"foreground": "790ead",
|
||||
"token": "support.class"
|
||||
},
|
||||
{
|
||||
"foreground": "790ead",
|
||||
"token": "support.other.variable"
|
||||
}
|
||||
],
|
||||
"colors": {
|
||||
"editor.foreground": "#000000",
|
||||
"editor.background": "#FFFFFF",
|
||||
"editor.selectionBackground": "#B5D5FF",
|
||||
"editor.lineHighlightBackground": "#00000012",
|
||||
"editorCursor.foreground": "#000000",
|
||||
"editorWhitespace.foreground": "#BFBFBF"
|
||||
}
|
||||
}
|
||||
180
theme/index.ts
Normal file
180
theme/index.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import type { Theme } from "theme-ui";
|
||||
import { darken, lighten } from '@theme-ui/color'
|
||||
|
||||
const makeTheme = <T extends Theme>(t: T) => t
|
||||
|
||||
export const theme = makeTheme({
|
||||
config: {
|
||||
initialColorModeName: 'light',
|
||||
},
|
||||
breakpoints: ['40em', '52em', '64em', '78em'],
|
||||
space: [0, 4, 8, 16, 32, 64, 128, 256, 512],
|
||||
fonts: {
|
||||
body: 'Work Sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif',
|
||||
heading: 'Work Sans, sans-serif',
|
||||
monospace: 'Roboto, monospace',
|
||||
},
|
||||
fontSizes: [12, 14, 16, 18, 20, 24, 32, 48, 64, 96],
|
||||
fontWeights: {
|
||||
body: 400,
|
||||
heading: 400,
|
||||
bold: 700,
|
||||
},
|
||||
layout: {
|
||||
container: {
|
||||
maxWidth: "100%",
|
||||
width: "100%",
|
||||
mx: "auto",
|
||||
px: 3
|
||||
}
|
||||
},
|
||||
lineHeights: {
|
||||
body: 1.5,
|
||||
heading: 0.85,
|
||||
},
|
||||
colors: {
|
||||
text: '#000000',
|
||||
background: '#FFFFFF',
|
||||
primary: '#9A52FF',
|
||||
secondary: '#30c',
|
||||
muted: '#C6C6D3',
|
||||
modes: {
|
||||
dark: {
|
||||
text: '#FFFFFF',
|
||||
background: '#000000',
|
||||
primary: '#9A52FF',
|
||||
secondary: '#30c',
|
||||
}
|
||||
}
|
||||
},
|
||||
text: {
|
||||
heading: {
|
||||
fontFamily: 'heading',
|
||||
lineHeight: 'heading',
|
||||
fontWeight: 'heading',
|
||||
},
|
||||
monospace: {
|
||||
fontWeight: 300
|
||||
}
|
||||
},
|
||||
sizes: {
|
||||
"widePlus": 2048,
|
||||
"wide": 1536,
|
||||
"layoutPlus": 1260,
|
||||
"layout": 1024,
|
||||
"copyUltra": 980,
|
||||
"copyPlus": 768,
|
||||
"copy": 680,
|
||||
"narrowPlus": 600,
|
||||
"narrow": 512,
|
||||
sm: {
|
||||
paddingX: 3,
|
||||
paddingY: 1
|
||||
},
|
||||
md: {
|
||||
px: 4,
|
||||
py: 2
|
||||
},
|
||||
lg: {
|
||||
px: 6,
|
||||
py: 4
|
||||
},
|
||||
},
|
||||
buttons: {
|
||||
|
||||
primary: {
|
||||
size: 'md',
|
||||
color: 'white',
|
||||
bg: 'primary',
|
||||
'&:hover': {
|
||||
bg: darken('primary', 0.1),
|
||||
borderColor: darken('primary', 0.1)
|
||||
},
|
||||
fontWeight: 600,
|
||||
borderRadius: '3px',
|
||||
fontSize: 1,
|
||||
border: '1px solid',
|
||||
borderColor: 'primary',
|
||||
},
|
||||
secondary: {
|
||||
color: 'black',
|
||||
bg: 'muted',
|
||||
fontSize: 1,
|
||||
borderRadius: '3px',
|
||||
border: '1px solid',
|
||||
borderColor: 'muted',
|
||||
'&:hover': {
|
||||
bg: darken('muted', 0.1),
|
||||
borderColor: darken('muted', 0.1),
|
||||
},
|
||||
cursor: 'pointer'
|
||||
},
|
||||
muted: {
|
||||
color: 'text',
|
||||
bg: 'background',
|
||||
fontSize: 1,
|
||||
border: '1px solid',
|
||||
borderColor: 'text',
|
||||
borderRadius: '3px',
|
||||
'&:hover': {
|
||||
bg: darken('background', 0.1),
|
||||
},
|
||||
cursor: 'pointer'
|
||||
}
|
||||
},
|
||||
styles: {
|
||||
root: {
|
||||
fontFamily: 'body',
|
||||
lineHeight: 'body',
|
||||
fontWeight: 'body',
|
||||
},
|
||||
h1: {
|
||||
variant: 'text.heading',
|
||||
fontSize: 5,
|
||||
},
|
||||
h2: {
|
||||
variant: 'text.heading',
|
||||
fontSize: 4,
|
||||
},
|
||||
h3: {
|
||||
variant: 'text.heading',
|
||||
fontSize: 3,
|
||||
},
|
||||
h4: {
|
||||
variant: 'text.heading',
|
||||
fontSize: 2,
|
||||
},
|
||||
h5: {
|
||||
variant: 'text.heading',
|
||||
fontSize: 1,
|
||||
},
|
||||
h6: {
|
||||
variant: 'text.heading',
|
||||
fontSize: 0,
|
||||
},
|
||||
pre: {
|
||||
fontFamily: 'monospace',
|
||||
overflowX: 'auto',
|
||||
code: {
|
||||
color: 'inherit',
|
||||
},
|
||||
},
|
||||
code: {
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 'inherit',
|
||||
},
|
||||
table: {
|
||||
width: '100%',
|
||||
borderCollapse: 'separate',
|
||||
borderSpacing: 0,
|
||||
},
|
||||
th: {
|
||||
textAlign: 'left',
|
||||
borderBottomStyle: 'solid',
|
||||
},
|
||||
td: {
|
||||
textAlign: 'left',
|
||||
borderBottomStyle: 'solid',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1,7 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
@@ -12,8 +16,15 @@
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve"
|
||||
"jsx": "preserve",
|
||||
"incremental": true
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user