Skip to content

Make tabs clickable #86

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion packages/mdx/src/client/code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,26 @@ import { CodeSpring } from "@code-hike/smooth-code"
import {
EditorSpring,
EditorProps,
EditorStep,
} from "@code-hike/mini-editor"

export function Code(props: EditorProps) {
const [step, setStep] = React.useState(props)

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

return <InnerCode {...step} onTabClick={onTabClick} />
}

export function InnerCode({
onTabClick,
...props
}: EditorProps & {
onTabClick?: (filename: string) => void
}) {
if (
!props.southPanel &&
props.files.length === 1 &&
Expand All @@ -19,6 +36,39 @@ export function Code(props: EditorProps) {
/>
)
} else {
return <EditorSpring {...props} />
const frameProps = {
...props?.frameProps,
onTabClick,
}
return (
<EditorSpring {...props} frameProps={frameProps} />
)
}
}

export function updateEditorStep(
step: EditorStep,
filename: string | undefined,
focus: string | null
): EditorStep {
const name = filename || step.northPanel.active
const newFiles = step.files.map((file: any) =>
file.name === name
? {
...file,
focus: focus === null ? file.focus : focus,
}
: file
)

let northPanel = { ...step.northPanel }
let southPanel = step.southPanel && {
...step.southPanel,
}
if (step.northPanel.tabs.includes(name)) {
northPanel.active = name
} else if (southPanel) {
southPanel.active = name
}
return { files: newFiles, northPanel, southPanel }
}
32 changes: 25 additions & 7 deletions packages/mdx/src/client/scrollycoding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
EditorProps,
EditorStep,
} from "@code-hike/mini-editor"
import { Code } from "./code"
import { InnerCode, updateEditorStep } from "./code"
import {
Scroller,
Step as ScrollerStep,
Expand All @@ -25,12 +25,26 @@ export function Scrollycoding({
}) {
const stepsChildren = React.Children.toArray(children)

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

const tab = state.step

function onStepChange(index: number) {
setIndex(index)
setState({ stepIndex: index, step: editorSteps[index] })
}

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

return (
<section
className={`ch-scrollycoding ${
Expand All @@ -44,10 +58,10 @@ export function Scrollycoding({
as="div"
key={i}
index={i}
onClick={() => setIndex(i)}
onClick={() => onStepChange(i)}
className="ch-scrollycoding-step-content"
data-selected={
i === stepIndex ? "true" : undefined
i === state.stepIndex ? "true" : undefined
}
>
{children}
Expand All @@ -56,7 +70,11 @@ export function Scrollycoding({
</Scroller>
</div>
<div className="ch-scrollycoding-sticker">
<Code {...(tab as any)} codeConfig={codeConfig} />
<InnerCode
{...(tab as any)}
codeConfig={codeConfig}
onTabClick={onTabClick}
/>
{presetConfig && (
<Preview
className="ch-scrollycoding-preview"
Expand Down
37 changes: 14 additions & 23 deletions packages/mdx/src/client/section.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react"
import { EditorProps } from "@code-hike/mini-editor"
import { Code } from "./code"
import { InnerCode, updateEditorStep } from "./code"

const SectionContext = React.createContext<{
props: EditorProps
selectedId?: string
setFocus: (x: {
fileName?: string
focus: string
focus: string | null
id: string
}) => void
resetFocus: () => void
Expand All @@ -33,30 +33,14 @@ export function Section({
id,
}: {
fileName?: string
focus: string
focus: string | null
id: string
}) => {
const name = fileName || state.northPanel.active

const newFiles = state.files.map((file: any) =>
file.name === name ? { ...file, focus } : file
)

let northPanel = { ...state.northPanel }
let southPanel = state.southPanel && {
...state.northPanel,
}
if (state.northPanel.tabs.includes(name)) {
northPanel.active = name
} else if (southPanel) {
southPanel.active = name
}
const newStep = updateEditorStep(state, fileName, focus)

setState({
...state,
files: newFiles,
northPanel,
southPanel,
...newStep,
selectedId: id,
})
}
Expand All @@ -78,8 +62,15 @@ export function Section({
}

export function SectionCode() {
const { props } = React.useContext(SectionContext)
return <Code {...props} />
const { props, setFocus } = React.useContext(
SectionContext
)

const onTabClick = (filename: string) => {
setFocus({ fileName: filename, focus: null, id: "" })
}

return <InnerCode {...props} onTabClick={onTabClick} />
}

export function SectionLink({
Expand Down
33 changes: 27 additions & 6 deletions packages/mdx/src/client/spotlight.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
EditorProps,
EditorStep,
} from "@code-hike/mini-editor"
import { Code } from "./code"
import { InnerCode, updateEditorStep } from "./code"
import { Preview, PresetConfig } from "./preview"

export function Spotlight({
Expand All @@ -21,8 +21,20 @@ export function Spotlight({
}) {
const stepsChildren = React.Children.toArray(children)

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

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

const headerElement = stepsChildren[0] as React.ReactElement

Expand All @@ -40,10 +52,15 @@ export function Spotlight({
i === 0 ? null : (
<div
key={i}
onClick={() => setIndex(i)}
onClick={() =>
setState({
stepIndex: i,
step: editorSteps[i],
})
}
className="ch-spotlight-tab"
data-selected={
i === stepIndex ? "true" : undefined
i === state.stepIndex ? "true" : undefined
}
>
{children}
Expand All @@ -52,7 +69,11 @@ export function Spotlight({
)}
</div>
<div className="ch-spotlight-sticker">
<Code {...(tab as any)} codeConfig={codeConfig} />
<InnerCode
{...(tab as any)}
codeConfig={codeConfig}
onTabClick={onTabClick}
/>
{presetConfig && (
<Preview
className="ch-spotlight-preview"
Expand Down
7 changes: 7 additions & 0 deletions packages/mini-editor/src/editor-frame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type EditorFrameProps = {
height?: number
button?: React.ReactNode
classes?: Classes
onTabClick?: (filename: string) => void
} & React.PropsWithoutRef<JSX.IntrinsicElements["div"]>

export const EditorFrame = React.forwardRef<
Expand All @@ -51,6 +52,7 @@ export const EditorFrame = React.forwardRef<
button,
theme,
className,
onTabClick,
...rest
},
ref
Expand All @@ -76,6 +78,7 @@ export const EditorFrame = React.forwardRef<
button={button}
panel="north"
theme={theme}
onTabClick={onTabClick}
/>
}
{...rest}
Expand Down Expand Up @@ -105,6 +108,7 @@ export const EditorFrame = React.forwardRef<
topBorder={true}
panel="south"
theme={theme}
onTabClick={onTabClick}
/>
</div>
<div
Expand All @@ -130,6 +134,7 @@ type TabsContainerProps = {
topBorder?: boolean
panel: "north" | "south"
theme: EditorTheme
onTabClick?: (filename: string) => void
}
function TabsContainer({
tabs,
Expand All @@ -138,6 +143,7 @@ function TabsContainer({
topBorder,
panel,
theme,
onTabClick,
}: TabsContainerProps) {
const c = useClasser("ch-editor-tab")
return (
Expand Down Expand Up @@ -189,6 +195,7 @@ function TabsContainer({
: ColorName.InactiveTabBackground
),
}}
onClick={onTabClick && (() => onTabClick(title))}
>
<div>{title}</div>
</div>
Expand Down
10 changes: 10 additions & 0 deletions packages/playground/content/scrollycoding-demo.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Lorem ipsum dolor sit amet, consectetur adipiscing something about points, sed d

Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus.

<CH.Code>

```js app.js focus=3:10
const { lorem, ipsum } = dolor({
sit: {
Expand Down Expand Up @@ -53,6 +55,14 @@ const { lorem, ipsum } = dolor({
})
```

```css styles.css
.lorem {
color: red;
}
```

</CH.Code>

---

## Step 2
Expand Down
Loading