Skip to content
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

✨ Refactor layout for Remix docs #3

Merged
merged 10 commits into from
Aug 1, 2024
2 changes: 1 addition & 1 deletion library/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pheralb/toast",
"version": "0.2.0",
"version": "0.2.2",
"author": "@pheralb_",
"keywords": [
"react",
Expand Down
17 changes: 15 additions & 2 deletions library/src/components/toast-functions.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
import { ToastPropsWithVariant } from '../types/toast.types';
import type { ToastPropsWithVariant } from '../types/toast.types';
import { openToast } from './toaster';

export const toast = {
interface ToastFunctions {
default: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
success: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
error: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
warning: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
info: (data: ToastPropsWithVariant) => ToastPropsWithVariant;
}

export const toast: ToastFunctions = {
default: (data: ToastPropsWithVariant) => {
openToast({ ...data });
return data;
},
success: (data: ToastPropsWithVariant) => {
openToast({ ...data, variant: 'success' });
return data;
},
error: (data: ToastPropsWithVariant) => {
openToast({ ...data, variant: 'error' });
return data;
},
warning: (data: ToastPropsWithVariant) => {
openToast({ ...data, variant: 'warning' });
return data;
},
info: (data: ToastPropsWithVariant) => {
openToast({ ...data, variant: 'info' });
return data;
},
};
4 changes: 3 additions & 1 deletion library/src/components/toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@ export const Toaster = ({
);
};

export const openToast = (data: ToastPropsWithVariant) => openToastGlobal(data);
export const openToast = (data: ToastPropsWithVariant): void => {
openToastGlobal(data);
};
12 changes: 1 addition & 11 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

104 changes: 51 additions & 53 deletions website/app/root.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import type {
LinksFunction,
LoaderFunctionArgs,
MetaFunction,
import {
type LinksFunction,
type LoaderFunctionArgs,
type MetaFunction,
} from '@vercel/remix';
import type { ReactNode } from 'react';

import {
isRouteErrorResponse,
Link,
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
useLoaderData,
useRouteError,
} from '@remix-run/react';
import { getLatestVersion } from 'fast-npm-meta';
import { eslogan, siteTitle, siteUrl, siteUrlImages } from './globals';
Expand All @@ -31,21 +29,18 @@ import { proseClasses } from './ui/prose';
import { Toaster } from '@pheralb/toast';
import {
PreventFlashOnWrongTheme,
Theme,
ThemeProvider,
useTheme,
} from 'remix-themes';
import { themeSessionResolver } from './sessions.server';

// MDX Components:
import { MDXProvider } from '@mdx-js/react';
import { mdxComponents } from './components/mdx';

// Stores:
import { useDocsStore } from './store';

// Other:
import { Logo } from './components/icons';
import { buttonVariants } from './ui/button';
import { themeSessionResolver } from './sessions.server';

// Links:
export const links: LinksFunction = () => [
Expand Down Expand Up @@ -97,6 +92,7 @@ export const meta: MetaFunction = ({ matches }) => {
];
};

// Get theme from loader:
export async function loader({ request }: LoaderFunctionArgs) {
const { getTheme } = await themeSessionResolver(request);
const metadata = await getLatestVersion('@pheralb/toast');
Expand All @@ -106,21 +102,18 @@ export async function loader({ request }: LoaderFunctionArgs) {
};
}

export default function AppWithProviders() {
const data = useLoaderData<typeof loader>();
return (
<ThemeProvider specifiedTheme={data.theme} themeAction="/action/set-theme">
<App />
</ThemeProvider>
);
}

function App() {
// App global layout:
function Layout({ children }: { children: ReactNode }) {
const data = useLoaderData<typeof loader>();
const [theme] = useTheme();
const { toastPosition, toastTheme } = useDocsStore();
return (
<html lang="en" className={cn(theme, 'scroll-smooth focus:scroll-auto')}>
<html
lang="en"
data-theme={theme}
className={cn(theme ?? '', 'scroll-smooth focus:scroll-auto')}
style={{ colorScheme: theme ?? '' }}
>
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
Expand Down Expand Up @@ -149,10 +142,11 @@ function App() {
<meta name="twitter:title" content={siteTitle} />
{/* App Meta Function */}
<Meta />
<PreventFlashOnWrongTheme ssrTheme={Boolean(data.theme)} />
<PreventFlashOnWrongTheme ssrTheme={Boolean(data?.theme)} />
<Links />
</head>
<body
suppressHydrationWarning
className={cn(
'font-sans antialiased',
'bg-neutral-50 dark:bg-neutral-900',
Expand All @@ -171,7 +165,7 @@ function App() {
proseClasses,
)}
>
<Outlet />
{children}
</article>
</MDXProvider>
</main>
Expand All @@ -187,35 +181,39 @@ function App() {
);
}

// App with providers:
function AppWithProviders({ children }: { children: ReactNode }) {
const data = useLoaderData<typeof loader>();
return (
<ThemeProvider
specifiedTheme={data?.theme as Theme}
themeAction="/action/set-theme"
>
<Layout>{children}</Layout>
</ThemeProvider>
);
}

export default function App() {
return (
<AppWithProviders>
<Outlet />
</AppWithProviders>
);
}

export function ErrorBoundary() {
const error = useRouteError();
return (
<html lang="en" className="dark">
<head>
<title>Oops! - @pheralb/toast</title>
<Meta />
<Links />
</head>
<body className="flex h-screen flex-col items-center justify-center space-y-4 bg-neutral-900 font-sans text-white">
<Logo className="h-12 w-12" />
<h1 className="text-2xl font-medium tracking-tight">
{isRouteErrorResponse(error)
? `${error.status} ${error.statusText}`
: error instanceof Error
? error.message
: 'Unknown Error'}
</h1>
<Link
to="/"
className={buttonVariants({
variant: 'outline',
})}
>
Go back home
</Link>
<p className="font-mono text-sm">@pheralb/toast</p>
<Scripts />
</body>
</html>
<AppWithProviders>
<h2>Error</h2>
</AppWithProviders>
);
}

export function HydrateFallback() {
return (
<AppWithProviders>
<h1>Loading...</h1>
</AppWithProviders>
);
}
3 changes: 2 additions & 1 deletion website/app/routes/action.set-theme.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { unstable_defineAction as defineAction } from '@vercel/remix';
import { createThemeAction } from 'remix-themes';
import { themeSessionResolver } from '@/sessions.server';

export const action = createThemeAction(themeSessionResolver);
export const action = defineAction(createThemeAction(themeSessionResolver));
Loading