Skip to content

Commit ca21b53

Browse files
committed
feat: extract MDXFromChildren to its own component
1 parent 049e8b6 commit ca21b53

File tree

2 files changed

+67
-67
lines changed

2 files changed

+67
-67
lines changed

Diff for: app/work/appdirbebop/page.tsx

+15-67
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,13 @@ import {
88
import PopOver from "@/components/ui/Popover";
99
import type { Metadata } from "next";
1010

11-
import { MDXRemote, MDXRemoteProps } from "next-mdx-remote/rsc";
12-
1311
import { bebopMeta, issMeta } from "../poor_mans_cms";
14-
import { HTMLProps, Suspense } from "react";
1512
import Popover from "@/components/ui/Popover";
16-
import StyledLinkWithIcon from "@/components/ui/StyledLink";
13+
import { MDX } from "@/components/MDX";
1714
import Image from "next/image";
1815

1916
import desktopScreenshot from "@/public/images/projs/bebop/desktop-screenshot.png";
2017
import smartphoneScreenshot from "@/public/images/projs/bebop/smartphone-screenshot.png";
21-
import remarkGfm from "remark-gfm";
22-
import { SerializeOptions } from "next-mdx-remote/dist/types";
23-
import { MDXProvider } from "@mdx-js/react";
2418

2519
const makeSeo = ({
2620
title,
@@ -78,52 +72,6 @@ export const metadata: Metadata = {
7872
},
7973
};
8074

81-
const defaultComponents = {
82-
// @ts-ignore
83-
a: (props) => <StyledLinkWithIcon {...props} />,
84-
h1: (props: HTMLProps<HTMLHeadingElement>) => (
85-
<h1 className="text-2xl text-gray-11 mb-8" {...props} />
86-
),
87-
h2: (props: HTMLProps<HTMLHeadingElement>) => (
88-
<h1 className="text-lg font-bold my-2" {...props} />
89-
),
90-
strong: (props: HTMLProps<HTMLElement>) => (
91-
<strong className="font-bold text-gray-12" {...props} />
92-
),
93-
pre: (props: HTMLProps<HTMLPreElement>) => (
94-
<pre
95-
className="bg-gray-2 rounded p-4 my-2 overflow-x-auto text-sm"
96-
{...props}
97-
/>
98-
),
99-
};
100-
101-
const MDXFromChild = ({
102-
children,
103-
components,
104-
...rest
105-
}: { children: string } & {
106-
// TODO: allow children OR source
107-
options?: SerializeOptions | undefined;
108-
components?: React.ComponentProps<typeof MDXProvider>["components"];
109-
}) => {
110-
return (
111-
// workaround https://beta.nextjs.org/docs/data-fetching/fetching#asyncawait-in-server-components
112-
/* @ts-expect-error Server Component */
113-
<MDXRemote
114-
{...rest}
115-
source={children}
116-
options={{
117-
mdxOptions: {
118-
remarkPlugins: [remarkGfm],
119-
rehypePlugins: [],
120-
},
121-
}}
122-
components={{ ...defaultComponents, ...(components || {}) }}
123-
/>
124-
);
125-
};
126-
12775
export default async function Bebop() {
12876
return (
12977
<>
@@ -156,21 +104,21 @@ export default async function Bebop() {
156104
<h2 className="text-xl font-bold text-gray-11 uppercase mb-2">
157105
Update
158106
</h2>
159-
<MDXFromChild>
107+
<MDX>
160108
{`
161109
On november 2nd 2021 I got a notification on my discord with the amazing news that this project had won the competition with the majority of votes. Now, I bask in the glory!! [I'll leave the screenshot of the announcement here because I'm very proud of this](https://raw.githubusercontent.com/bdsqqq/bebop-webjam/main/docs/img/winner.jpg).
162110
`}
163-
</MDXFromChild>
111+
</MDX>
164112
</ProjectBand>
165113
<ProjectBand headline={{ bold: "01", thin: "Why?" }}>
166-
<MDXFromChild
114+
<MDX
167115
components={{
168116
Popover: (props) => (
169117
<PopOver
170118
content={
171-
<MDXFromChild>
119+
<MDX>
172120
{`The **WebJam** is a hackathon where the participants try to create a website following a prompt and some rules`}
173-
</MDXFromChild>
121+
</MDX>
174122
}
175123
>
176124
{props.children}
@@ -183,37 +131,37 @@ export default async function Bebop() {
183131
<br/>
184132
The challenge for this WebJam was to create a single page/non-scrollable site for a movie of my choosing. The site should work on any screen size and illustrate the movie.
185133
`}
186-
</MDXFromChild>
134+
</MDX>
187135
</ProjectBand>
188136
<ProjectBand headline={{ bold: "02", thin: "Design" }}>
189-
<MDXFromChild>
137+
<MDX>
190138
{`
191139
My choice of movie was Cowboy Bebop, it's one of my favorites and screams personality with its artwork. The mix between Jazz, Noir, Western, and Space is unique and serves as a great source of inspiration for a website.
192140
<br/>
193141
The main constraint for this exercise was space. I took inspiration from types of media with the same limitation such as posters, cover arts, and the TV show itself. After spending an uncomfortable amount of time rewatching the opening of Cowboy Bebop, I figured that I needed to include the iconic shots of silhouettes against bright-colored backgrounds. I even found one of the pieces that inspired the show's artists: the cover art for the film "Tokyo Drifter".
194142
<br/>
195143
At this point, I knew that I wanted something that could be mistaken for a poster when showing it to someone. I made a quick sketch on a piece of paper from my desk and started working.
196144
`}
197-
</MDXFromChild>
145+
</MDX>
198146
</ProjectBand>
199147
<ProjectBand headline={{ bold: "03", thin: "Development" }}>
200-
<MDXFromChild>
148+
<MDX>
201149
{`
202150
Trying to avoid unnecessary complexity, I approached this project from a minimalist perspective, I created a plain HTML file with tailwindcss and made a responsive design with two major blocks, one for the text content and the other for the silhouette; In the second one, I took inspiration from the show's opening where we can find bits of a paragraph overlayed on the solid color to tell a history ending with the ambitious phrase that gives title to the website: "The work, which becomes a new genre itself, will be called... COWBOY BEBOP".
203151
<br/>
204152
It became clear that I would need to create media for this piece. I downloaded Adobe Illustrator for the first time in a couple of years to make figures to layer on my scene. Even though my initial plan to use the silhouette as a "mask" that contained the animated spaceship didn't work, I got the vibe I wanted by using a clip-path element to clip an image of stars I modified into the silhouette. Adding a simple animation to the smoke SVG and a trail to the otherwise boring spaceship gave life to this otherwise static poster.
205153
<br/>
206154
For the final touches, I allowed the title to break its box and overlap with the silhouette container creating that bit of spice the piece was missing. To add to the poster-like feeling I was going for, I added an image of wrinkled paper as an overlay with a CSS filter to make the entire thing look like something you would find glued to a wall and voilá.
207155
`}
208-
</MDXFromChild>
156+
</MDX>
209157
</ProjectBand>
210158
<ProjectBand headline={{ bold: "04", thin: "Results" }}>
211-
<MDXFromChild>
159+
<MDX>
212160
{`
213161
You can see the website [clicking here](https://bebop-webjam.vercel.app/).
214162
or looking at some screenshots:
215163
`}
216-
</MDXFromChild>
164+
</MDX>
217165
<div className="grid grid-cols-4 items-center min-h-0 gap-2 my-1">
218166
<div className="col-start-1 col-end-2">
219167
<Image
@@ -236,13 +184,13 @@ export default async function Bebop() {
236184
/>
237185
</div>
238186
</div>
239-
<MDXFromChild>
187+
<MDX>
240188
{`
241189
After working on this project I'm more confident in my ability to create a cool design and translate it to code. As well as working with design tools such as Adobe Illustrator and Photoshop when needed. I also had a chance to learn a new animation library called motion one and enjoyed every second of it.
242190
<br/>
243191
I liked the WebJam experience and will be looking forward to its future installments.
244192
`}
245-
</MDXFromChild>
193+
</MDX>
246194
</ProjectBand>
247195
</ProjectLayout>
248196
</ProjectContainer>

Diff for: components/MDX.tsx

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import remarkGfm from "remark-gfm";
2+
import { SerializeOptions } from "next-mdx-remote/dist/types";
3+
import { MDXProvider } from "@mdx-js/react";
4+
import { MDXRemote, MDXRemoteProps } from "next-mdx-remote/rsc";
5+
import StyledLinkWithIcon from "@/components/ui/StyledLink";
6+
import { HTMLProps } from "react";
7+
8+
const defaultComponents = {
9+
// @ts-ignore
10+
a: (props) => <StyledLinkWithIcon {...props} />,
11+
h1: (props: HTMLProps<HTMLHeadingElement>) => (
12+
<h1 className="text-2xl text-gray-11 mb-8" {...props} />
13+
),
14+
h2: (props: HTMLProps<HTMLHeadingElement>) => (
15+
<h1 className="text-lg font-bold my-2" {...props} />
16+
),
17+
strong: (props: HTMLProps<HTMLElement>) => (
18+
<strong className="font-bold text-gray-12" {...props} />
19+
),
20+
pre: (props: HTMLProps<HTMLPreElement>) => (
21+
<pre
22+
className="bg-gray-2 rounded p-4 my-2 overflow-x-auto text-sm"
23+
{...props}
24+
/>
25+
),
26+
};
27+
28+
export const MDX = ({
29+
children,
30+
components,
31+
...rest
32+
}: { children: string } & {
33+
// TODO: allow children OR source
34+
options?: SerializeOptions | undefined;
35+
components?: React.ComponentProps<typeof MDXProvider>["components"];
36+
}) => {
37+
return (
38+
// workaround https://beta.nextjs.org/docs/data-fetching/fetching#asyncawait-in-server-components
39+
/* @ts-expect-error Server Component */
40+
<MDXRemote
41+
{...rest}
42+
source={children}
43+
options={{
44+
mdxOptions: {
45+
remarkPlugins: [remarkGfm],
46+
rehypePlugins: [],
47+
},
48+
}}
49+
components={{ ...defaultComponents, ...(components || {}) }}
50+
/>
51+
);
52+
};

0 commit comments

Comments
 (0)