Skip to content

Commit

Permalink
Merge pull request #99 from code-hike/slides
Browse files Browse the repository at this point in the history
Slideshow component
  • Loading branch information
pomber authored Dec 27, 2021
2 parents b790fab + 4abcdea commit 9d682d6
Show file tree
Hide file tree
Showing 12 changed files with 966 additions and 10 deletions.
46 changes: 46 additions & 0 deletions packages/mdx/src/client/slideshow.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.ch-slideshow {
margin: 1rem 0;
}

.ch-slideshow-slide {
display: flex;
flex-flow: row;
gap: 0.5rem;
align-items: stretch;
aspect-ratio: 16 / 9;
}

.ch-slideshow-slide .ch-editor-frame,
.ch-slideshow-slide .ch-code {
flex: 2;
}

.ch-slideshow-preview {
flex: 1;
height: auto;
min-width: 0;
}

.ch-slideshow-range {
display: flex;
flex-flow: row;
gap: 0.5rem;
}

.ch-slideshow-range input {
flex: 1;
}

.ch-slideshow-notes {
border-radius: 0.25rem;
margin-top: 1rem;
padding: 1rem;
border: 1px solid #e3e3e3;
}

.ch-slideshow-note {
min-height: 140px;
max-height: 140px;
padding: 0.05px;
overflow: auto;
}
124 changes: 124 additions & 0 deletions packages/mdx/src/client/slideshow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import React from "react"
import {
EditorProps,
EditorStep,
} from "@code-hike/mini-editor"
import { InnerCode, updateEditorStep } from "./code"
import { Preview, PresetConfig } from "./preview"

export function Slideshow({
children,
editorSteps,
codeConfig,
presetConfig,
code,
}: {
children: React.ReactNode
editorSteps: EditorStep[]
codeConfig: EditorProps["codeConfig"]
presetConfig?: PresetConfig
code?: EditorProps["codeConfig"]
}) {
const stepsChildren = React.Children.toArray(children)

const hasNotes = stepsChildren.some(
(child: any) => child.props?.children
)

const [state, setState] = React.useState({
stepIndex: 0,
step: editorSteps[0],
})
const tab = state.step

function onTabClick(filename: string) {
const newStep = updateEditorStep(
state.step,
filename,
null
)
setState({ ...state, step: newStep })
}

return (
<div
className={`ch-slideshow ${
presetConfig ? "ch-slideshow-with-preview" : ""
}`}
>
<div className="ch-slideshow-slide">
<InnerCode
{...(tab as any)}
codeConfig={{
...codeConfig,
...code,
}}
onTabClick={onTabClick}
/>
{presetConfig && (
<Preview
className="ch-slideshow-preview"
files={tab.files}
presetConfig={presetConfig}
/>
)}
</div>

<div className="ch-slideshow-notes">
<div className="ch-slideshow-range">
<button
onClick={() =>
setState(s => {
const stepIndex = Math.max(
0,
s.stepIndex - 1
)
return {
stepIndex,
step: editorSteps[stepIndex],
}
})
}
>
Prev
</button>
<input
type="range"
min={0}
max={editorSteps.length - 1}
value={state.stepIndex}
step={1}
onChange={e =>
setState({
stepIndex: +e.target.value,
step: editorSteps[+e.target.value],
})
}
/>
<button
onClick={() =>
setState(s => {
const stepIndex = Math.min(
editorSteps.length - 1,
s.stepIndex + 1
)
return {
stepIndex,
step: editorSteps[stepIndex],
}
})
}
>
Next
</button>
</div>

{hasNotes && (
<div className="ch-slideshow-note">
{stepsChildren[state.stepIndex]}
</div>
)}
</div>
</div>
)
}
2 changes: 2 additions & 0 deletions packages/mdx/src/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
import { Code } from "./client/code"
import { Spotlight } from "./client/spotlight"
import { Scrollycoding } from "./client/scrollycoding"
import { Slideshow } from "./client/slideshow"
import {
annotationsMap,
Annotation,
Expand All @@ -20,4 +21,5 @@ export const CH = {
Scrollycoding,
annotations: annotationsMap,
Annotation,
Slideshow,
}
1 change: 1 addition & 0 deletions packages/mdx/src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@import "~@code-hike/mini-browser/dist/index.scss";
@import "./client/spotlight.scss";
@import "./client/scrollycoding.scss";
@import "./client/slideshow.scss";

.ch-code {
border-radius: 6px;
Expand Down
2 changes: 2 additions & 0 deletions packages/mdx/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { transformSections } from "./plugin/section"
import { transformSpotlights } from "./plugin/spotlight"
import { transformScrollycodings } from "./plugin/scrollycoding"
import visit from "unist-util-visit"
import { transformSlideshows } from "./plugin/slideshow"

export function remarkCodeHike({ theme }: { theme: any }) {
return async (tree: Node) => {
Expand All @@ -27,6 +28,7 @@ export function remarkCodeHike({ theme }: { theme: any }) {
try {
await transformScrollycodings(tree, { theme })
await transformSpotlights(tree, { theme })
await transformSlideshows(tree, { theme })
await transformSections(tree, { theme })
await transformEditorNodes(tree, { theme })
await transformCodeNodes(tree, { theme })
Expand Down
42 changes: 42 additions & 0 deletions packages/mdx/src/plugin/slideshow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { visitAsync, toJSX } from "./unist-utils"
import { Node, Parent } from "unist"
import { extractStepsInfo } from "./steps"
import { getPresetConfig } from "./preview"

export async function transformSlideshows(
tree: Node,
config: { theme: any }
) {
await visitAsync(
tree,
"mdxJsxFlowElement",
async node => {
if (node.name === "CH.Slideshow") {
await transformSlideshow(node, config)
}
}
)
}
async function transformSlideshow(
node: Node,
{ theme }: { theme: any }
) {
const editorSteps = await extractStepsInfo(
node as Parent,
{ theme },
"merge step with previous"
)

const presetConfig = await getPresetConfig(
(node as any).attributes
)

toJSX(node, {
props: {
codeConfig: { theme },
editorSteps: editorSteps,
presetConfig,
},
appendProps: true,
})
}
1 change: 1 addition & 0 deletions packages/mini-browser/src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
flex: 1;
padding: 0 10px;
color: #544;
min-width: 5px;
}

.ch-browser-button {
Expand Down
Loading

0 comments on commit 9d682d6

Please sign in to comment.