Skip to content

Commit

Permalink
feat: Migrate ranger docs to v2 layout (#153)
Browse files Browse the repository at this point in the history
* feat: Migrate ranger docs to v2 layout

* Remove useless string literal

* Quick fixes

* Fix v1 redirect list

* Change to v1

* Fix version redirects

* Better redirect
  • Loading branch information
lachlancollins authored Jan 25, 2024
1 parent f1fca89 commit f9b7ff9
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 208 deletions.
71 changes: 70 additions & 1 deletion app/projects/ranger.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,75 @@
import { Link } from '@remix-run/react'
import reactLogo from '~/images/react-logo.svg'
import { FaDiscord, FaGithub } from 'react-icons/fa/index'
import { useDocsConfig } from '~/utils/config'
import type { ConfigSchema, MenuItem } from '~/utils/config'

export const repo = 'tanstack/ranger'

export const v1branch = 'main'
export const latestBranch = 'main'
export const latestVersion = 'v0'
export const availableVersions = ['v0']

export const gradientText =
'inline-block text-transparent bg-clip-text bg-gradient-to-r from-lime-500 to-emerald-500'

const frameworks = {
react: { label: 'React', logo: reactLogo, value: 'react' },
} as const

export type Framework = keyof typeof frameworks

export const createLogo = (version?: string) => (
<>
<Link to="/" className="font-light">
TanStack
</Link>
<Link to=".." className="font-bold">
<span className={`${gradientText}`}>Ranger</span>{' '}
<span className="text-sm align-super">
{version === 'latest' ? latestVersion : version}
</span>
</Link>
</>
)

const localMenu: MenuItem = {
label: 'Menu',
children: [
{
label: 'Home',
to: '..',
},
{
label: (
<div className="flex items-center gap-2">
GitHub <FaGithub className="text-lg opacity-20" />
</div>
),
to: 'https://github.com/tanstack/ranger',
},
{
label: (
<div className="flex items-center gap-2">
Discord <FaDiscord className="text-lg opacity-20" />
</div>
),
to: 'https://tlinz.com/discord',
},
],
}

export function getBranch(argVersion?: string) {
const version = argVersion || latestVersion

return ['latest', latestVersion].includes(version) ? latestBranch : version
}

export const useRangerDocsConfig = (config: ConfigSchema) => {
return useDocsConfig({
config,
frameworks,
localMenu,
availableVersions,
})
}
31 changes: 2 additions & 29 deletions app/routes/ranger.$.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,5 @@
import type { LoaderFunction } from '@remix-run/node'
import { redirect } from '@remix-run/node'

export const loader: LoaderFunction = (context) => {
handleRedirects(context)

return redirect('/ranger/v1')
}

function handleRedirects(context: Parameters<LoaderFunction>[0]) {
const url = new URL(context.request.url)
// prettier-ignore
const reactRangerV1List = [
{from: 'docs/overview',to: 'docs/guide/introduction',},
{from: 'docs/installation',to: 'docs/guide/installation',},
{from: 'examples/basic',to: 'docs/examples/react/basic',},
{from: 'examples/custom-steps',to: 'docs/examples/react/custom-steps',},
{from: 'examples/custom-styles',to: 'docs/examples/react/custom-styles',},
{from: 'examples/logarithmic-interpolator',to: 'docs/examples/react/logarithmic-interpolator',},
{from: 'examples/update-on-drag',to: 'docs/examples/react/update-on-drag',},
{from: '',to: '',},
]

reactRangerV1List.forEach((item) => {
if (url.pathname.startsWith(`/ranger/v1/${item.from}`)) {
throw redirect(
`/ranger/v1/${item.to}?from=reactRangerV1&original=https://react-ranger-v1.tanstack.com/${item.from}`,
301
)
}
})
export const loader = () => {
return redirect('/ranger/latest')
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ import {
FaGithub,
FaTshirt,
} from 'react-icons/fa'
import { Link, useLoaderData } from '@remix-run/react'
import { Link, useLoaderData, useParams } from '@remix-run/react'
import { json } from '@remix-run/node'
import { TbHeartHandshake, TbZoomQuestion } from 'react-icons/tb'
import { VscPreview } from 'react-icons/vsc'
import { RiLightbulbFlashLine } from 'react-icons/ri'
import { gradientText, v1branch } from '~/projects/ranger'
import { gradientText, getBranch } from '~/projects/ranger'
import { Carbon } from '~/components/Carbon'
import { Footer } from '~/components/Footer'
import SponsorPack from '~/components/SponsorPack'
import { getSponsorsForSponsorPack } from '~/server/sponsors'
import type { LoaderFunction } from '@remix-run/node'
import type { Framework } from '~/projects/ranger'

const menu = [
{
Expand Down Expand Up @@ -70,7 +70,7 @@ const menu = [
},
]

export const loader: LoaderFunction = async () => {
export const loader = async () => {
const sponsors = await getSponsorsForSponsorPack()

return json({
Expand All @@ -80,10 +80,9 @@ export const loader: LoaderFunction = async () => {

export default function TanStackRouterRoute() {
const { sponsors } = useLoaderData<typeof loader>()
const [framework] = React.useState<
'react' | 'preact' | 'svelte' | 'vue' | 'solid'
>('react')

const { version } = useParams()
const branch = getBranch(version)
const [framework] = React.useState<Framework>('react')
const [isDark, setIsDark] = React.useState(true)

React.useEffect(() => {
Expand Down Expand Up @@ -317,7 +316,7 @@ export default function TanStackRouterRoute() {
<div className="bg-white dark:bg-black">
<iframe
key={framework}
src={`https://codesandbox.io/embed/github/tanstack/ranger/tree/${v1branch}/examples/${framework}/basic?autoresize=1&fontsize=16&theme=${
src={`https://codesandbox.io/embed/github/tanstack/ranger/tree/${branch}/examples/${framework}/basic?autoresize=1&fontsize=16&theme=${
isDark ? 'dark' : 'light'
}`}
title="tannerlinsley/react-ranger: basic"
Expand Down
44 changes: 44 additions & 0 deletions app/routes/ranger.$version.docs.$.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useLoaderData, useParams } from '@remix-run/react'
import type { LoaderFunctionArgs, MetaFunction } from '@remix-run/node'
import { repo, getBranch } from '~/projects/ranger'
import { DefaultErrorBoundary } from '~/components/DefaultErrorBoundary'
import { seo } from '~/utils/seo'
import { Doc } from '~/components/Doc'
import { loadDocs } from '~/utils/docs'

export const loader = async (context: LoaderFunctionArgs) => {
const { '*': docsPath, version } = context.params
const { url } = context.request

return loadDocs({
repo,
branch: getBranch(version),
docPath: `docs/${docsPath}`,
currentPath: url,
redirectPath: url.replace(/\/docs.*/, '/docs/overview'),
})
}

export const meta: MetaFunction<typeof loader> = ({ data }) => {
return seo({
title: `${data?.title ?? 'Docs'} | TanStack Ranger Docs`,
description: data?.description,
})
}

export const ErrorBoundary = DefaultErrorBoundary

export default function RouteReactRangerDocs() {
const { title, content, filePath } = useLoaderData<typeof loader>()
const { version } = useParams()
const branch = getBranch(version)
return (
<Doc
title={title}
content={content}
repo={repo}
branch={branch}
filePath={filePath}
/>
)
}
File renamed without changes.
45 changes: 45 additions & 0 deletions app/routes/ranger.$version.docs.framework.$framework.$.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { LoaderFunctionArgs, MetaFunction } from '@remix-run/node'
import { repo, getBranch } from '~/projects/ranger'
import { DefaultErrorBoundary } from '~/components/DefaultErrorBoundary'
import { seo } from '~/utils/seo'
import { useLoaderData, useParams } from '@remix-run/react'
import { Doc } from '~/components/Doc'
import { loadDocs } from '~/utils/docs'

export const loader = async (context: LoaderFunctionArgs) => {
const { '*': docsPath, framework, version } = context.params
const { url } = context.request

return loadDocs({
repo,
branch: getBranch(version),
docPath: `docs/framework/${framework}/${docsPath}`,
currentPath: url,
redirectPath: url.replace(/\/docs.*/, '/docs/overview'),
})
}

export const meta: MetaFunction<typeof loader> = ({ data }) => {
return seo({
title: `${data?.title} | TanStack Ranger Docs`,
description: data?.description,
})
}

export const ErrorBoundary = DefaultErrorBoundary

export default function RouteDocs() {
const { title, content, filePath } = useLoaderData<typeof loader>()
const { version } = useParams()
const branch = getBranch(version)

return (
<Doc
title={title}
content={content}
repo={repo}
branch={branch}
filePath={filePath}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { redirect } from '@remix-run/node'
import type { LoaderFunctionArgs } from '@remix-run/node'

export const loader = async (context: LoaderFunctionArgs) => {
throw redirect(context.request.url.replace(/\/docs.*/, '/docs/overview'))
}
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
import * as React from 'react'
import type { LoaderFunctionArgs, MetaFunction } from '@remix-run/node'
import { json } from '@remix-run/node'
import { useLoaderData } from '@remix-run/react'
import { useLoaderData, useParams } from '@remix-run/react'
import { DocTitle } from '~/components/DocTitle'
import { repo, v1branch } from '~/projects/ranger'
import { repo, getBranch } from '~/projects/ranger'
import { seo } from '~/utils/seo'
import { capitalize, slugToTitle } from '~/utils/utils'
import { FaExternalLinkAlt } from 'react-icons/fa'

export const loader = async (context: LoaderFunctionArgs) => {
const { '*': examplePath } = context.params
const [kind, _name] = (examplePath ?? '').split('/')
const [name, search] = _name.split('?')
const { framework, '*': name } = context.params

return json({ kind, name, search: search ?? '' })
return json({ framework, name })
}

export const meta: MetaFunction<typeof loader> = ({ data }) => {
return seo({
title: `${capitalize(data.kind)} Ranger ${slugToTitle(
title: `${capitalize(data.framework)} Ranger ${slugToTitle(
data.name
)} Example | TanStack Ranger Docs`,
description: `An example showing how to implement ${slugToTitle(
data.name
)} in ${capitalize(data.kind)} Ranger`,
)} in ${capitalize(data.framework)} Ranger`,
})
}

export default function RouteReactRangerDocs() {
const { kind, name, search } = useLoaderData<typeof loader>()
const { framework, name } = useLoaderData<typeof loader>()
const { version } = useParams()
const branch = getBranch(version)

const examplePath = [kind, name].join('/')
const examplePath = [framework, name].join('/')

const [isDark, setIsDark] = React.useState(true)

React.useEffect(() => {
setIsDark(window.matchMedia?.(`(prefers-color-scheme: dark)`).matches)
}, [])

const githubUrl = `https://github.com/${repo}/tree/${v1branch}/examples/${examplePath}`
const stackBlitzUrl = `https://stackblitz.com/github/${repo}/tree/${v1branch}/examples/${examplePath}?${search}embed=1&theme=${
const githubUrl = `https://github.com/${repo}/tree/${branch}/examples/${examplePath}`
const stackBlitzUrl = `https://stackblitz.com/github/${repo}/tree/${branch}/examples/${examplePath}?embed=1&theme=${
isDark ? 'dark' : 'light'
}`
const codesandboxUrl = `https://codesandbox.io/s/github/${repo}/tree/${v1branch}/examples/${examplePath}?${search}embed=1&theme=${
const codesandboxUrl = `https://codesandbox.io/s/github/${repo}/tree/${branch}/examples/${examplePath}?embed=1&theme=${
isDark ? 'dark' : 'light'
}`

Expand All @@ -51,7 +51,7 @@ export default function RouteReactRangerDocs() {
<div className="p-4 lg:p-6">
<DocTitle>
<span>
{capitalize(kind)} Example: {slugToTitle(name)}
{capitalize(framework)} Example: {slugToTitle(name)}
</span>
<div className="flex items-center gap-4 flex-wrap font-normal text-xs">
<a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@ import { redirect } from '@remix-run/node'
import type { LoaderFunction } from '@remix-run/node'

export const loader: LoaderFunction = (context) => {
throw redirect(
context.request.url.replace(/\/examples.*/, '/examples/react/basic')
)
throw redirect(context.request.url.replace(/\/examples.*/, '/examples/basic'))
}
55 changes: 55 additions & 0 deletions app/routes/ranger.$version.docs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as React from 'react'
import { Outlet, json, redirect, useLoaderData } from '@remix-run/react'
import {
useRangerDocsConfig,
repo,
getBranch,
createLogo,
} from '~/projects/ranger'
import { seo } from '~/utils/seo'
import { DocsLayout } from '~/components/DocsLayout'
import { getTanstackDocsConfig } from '~/utils/config'
import type { MetaFunction, LoaderFunctionArgs } from '@remix-run/node'
import { availableVersions } from '~/projects/form'

export const loader = async (context: LoaderFunctionArgs) => {
const { version } = context.params
const branch = getBranch(version)

if (!availableVersions.concat('latest').includes(version!)) {
throw redirect(context.request.url.replace(version!, 'latest'))
}

const tanstackDocsConfig = await getTanstackDocsConfig(repo, branch)

return json({
tanstackDocsConfig,
version,
})
}

export const meta: MetaFunction = () => {
return seo({
title: 'TanStack Ranger Docs | React Ranger',
description: 'Modern and headless ranger UI library',
})
}

export default function DocsRoute() {
const { version, tanstackDocsConfig } = useLoaderData<typeof loader>()
let config = useRangerDocsConfig(tanstackDocsConfig)
return (
<DocsLayout
v2={true}
logo={createLogo(version)}
colorFrom={'from-lime-500'}
colorTo={'to-emerald-500'}
textColor={'text-emerald-500'}
config={config}
framework={config.frameworkConfig}
version={config.versionConfig}
>
<Outlet />
</DocsLayout>
)
}
Loading

1 comment on commit f9b7ff9

@vercel
Copy link

@vercel vercel bot commented on f9b7ff9 Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.