Skip to content

d1vij/jassm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Just another static site maker

Create content driven sites using mdx (markdown + react) with added support typescript based autocompletion for the pages.

What is this ??

JASSM is a simple abstraction layer over mdx-js and its vite plugin for creating a route/file aware loader for mdx file.

Each page is configured at a single source of truth (registry) and thereby provides typesafe access throughout.

(ps the DX is similar to that of TanstackRouter or Elysia)

Usage

  1. Initialize a react app using vite

  2. Install jassm

npm install @d1vij/jassm
# OR
pnpm add @d1vij/jassm
# OR
bun add @d1vij/jassm
  1. Setup vite plugin in vite config
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

import jassm from "@d1vij/jassm/plugin";

export default defineConfig({
    plugins: [
        jassm(), // Put jassm plugin before react's plugin
        react(),
    ],
});
  1. Create a folder with .mdx assets
mkdir assets/mdx
cd assets/mdx
echo "# This is a Heading" > sample.mdx
  1. Setup a mdx registry
// src/Registry.tsx

import { Registry } from "@d1vij/jassm";

export const registry = new Registry({
    modules: import.meta.glob("/src/assets/mdx/**/*.mdx"),
    source: "/src/assets/mdx",
    mountOn: "/root",
    records: {
        "/sample": "/example.mdx",
    },
});
  1. Setup style classes
// src/stylesmap.ts
import type { StyleClassesMap } from "jassm";

// import stylesheet
import "myStyles.css";

export const stylesmap: StyleClassesMap = {
    header: "myHeader",
    paragraph: "pee",
};

Or using css modules

import styles from "myStyles.module.css";

import type { StyleClassesMap } from "jassm";

export const stylesmap: StyleClassesMap = {
    header: styles.myHeader,
    paragraph: styles.pee,
};
  1. Using the registry in any other component
// importing defined registry
import { registry } from "./Registry";

// importing styles map
import {stylesmap} from "./stylesmap";

import {MDXFromComponent} from "jassm";

import {use} from "react";

type ExportType = {
    meta: {
        title: string
    }
};

export default function Content() {
    const Component = registry.getComponent("/root/sample");
    const exports = use(registry.getExport<ExportType>("/root/sample")) // consuming the 'import' promise using use
    return (
        <div>
            {exports.meta.title}
            <MDXFromComponent
                SourceComponent={Component}
                styles={stylesmap}

                {/* Optional fallback component for suspense*/}
                fallback={<div>Loading</div>}
            />
        <div/>
    )
}

Using MDXSourceComponent automatically sets up the required enclosing StyleContext and Suspense component.

The setup can also be done manually as follows

import { StyleContext, Elements } from "@d1vij/jassm";

import { registry } from "./Registry";
import { stylesmap } from "./stylesmap";

import { Suspense } from "react";

export default function MyLoader() {
    const Component = registry["/root/sample"];

    return (
        <div>
            <StyleContext styles={stylesmap}>
                <Suspense>
                    <Component components={Elements} />
                </Suspense>
            </StyleContext>
        </div>
    );
}

About

A just another static site maker

Resources

License

Stars

Watchers

Forks