@d1vij/jassm 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENCE +21 -0
- package/README.md +144 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.js +341 -0
- package/dist/vitePlugin.d.ts +8 -0
- package/dist/vitePlugin.js +14 -0
- package/package.json +75 -0
package/LICENCE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Divij Verma
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Just another static site maker
|
|
2
|
+
|
|
3
|
+
Create content driven sites using mdx (markdown + react) with added support of route safety.
|
|
4
|
+
|
|
5
|
+
## What is this ??
|
|
6
|
+
|
|
7
|
+
JASSM is a simple abstraction layer over [mdx-js](https://mdxjs.com/) and its vite plugin for creating a route/file aware loader for mdx file.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
0. Initialize a react app using vite
|
|
12
|
+
|
|
13
|
+
1. Install jassm
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @d1vij/jassm
|
|
17
|
+
# OR
|
|
18
|
+
pnpm add @d1vij/jassm
|
|
19
|
+
# OR
|
|
20
|
+
bun add @d1vij/jassm
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. Setup vite plugin in vite config
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { defineConfig } from "vite";
|
|
27
|
+
import react from "@vitejs/plugin-react";
|
|
28
|
+
|
|
29
|
+
import jassm from "jassm/plugin";
|
|
30
|
+
|
|
31
|
+
export default defineConfig({
|
|
32
|
+
plugins: [
|
|
33
|
+
jassm(), // Put jassm plugin before react's plugin
|
|
34
|
+
react(),
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
3. Create a folder with `.mdx` assets
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
mkdir assets/mdx
|
|
43
|
+
cd assets/mdx
|
|
44
|
+
echo "# This is a Heading" > sample.mdx
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
4. Setup a mdx registry
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
// src/Registry.tsx
|
|
51
|
+
|
|
52
|
+
import { generateRegistry } from "jassm";
|
|
53
|
+
|
|
54
|
+
export const registry = generateRegistry({
|
|
55
|
+
modules: import.meta.glob("/src/assets/mdx/**/*.mdx"),
|
|
56
|
+
source: "/src/assets/mdx",
|
|
57
|
+
mountOn: "/root",
|
|
58
|
+
records: {
|
|
59
|
+
"/sample": "/example.mdx",
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
5. Setup style classes
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
// src/stylesmap.ts
|
|
68
|
+
import type { StyleClassesMap } from "jassm";
|
|
69
|
+
|
|
70
|
+
// import stylesheet
|
|
71
|
+
import "myStyles.css";
|
|
72
|
+
|
|
73
|
+
export const stylesmap: StyleClassesMap = {
|
|
74
|
+
header: "myHeader",
|
|
75
|
+
paragraph: "pee",
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or using css modules
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import styles from "myStyles.module.css";
|
|
83
|
+
|
|
84
|
+
import type { StyleClassesMap } from "jassm";
|
|
85
|
+
|
|
86
|
+
export const stylesmap: StyleClassesMap = {
|
|
87
|
+
header: styles.myHeader,
|
|
88
|
+
paragraph: styles.pee,
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
6. Using the registry in any other component
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
// importing defined registry
|
|
96
|
+
import { registry } from "./Registry";
|
|
97
|
+
|
|
98
|
+
// importing styles map
|
|
99
|
+
import {stylesmap} from "./stylesmap";
|
|
100
|
+
|
|
101
|
+
import {MDXFromComponent} from "jassm";
|
|
102
|
+
|
|
103
|
+
export default function Content() {
|
|
104
|
+
const Component = registry["/root/sample"];
|
|
105
|
+
return (
|
|
106
|
+
<div>
|
|
107
|
+
<MDXFromComponent
|
|
108
|
+
SourceComponent={Component}
|
|
109
|
+
styles={stylesmap}
|
|
110
|
+
|
|
111
|
+
{/* Optional fallback component for suspense*/}
|
|
112
|
+
fallback={<div>Loading</div>}
|
|
113
|
+
/>
|
|
114
|
+
<div/>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Using `MDXSourceComponent` automatically sets up the required enclosing StyleContext and Suspense component.
|
|
120
|
+
|
|
121
|
+
The setup can also be done manually as follows
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import { StyleContext, Elements } from "jassm";
|
|
125
|
+
|
|
126
|
+
import { registry } from "./Registry";
|
|
127
|
+
import { stylesmap } from "./stylesmap";
|
|
128
|
+
|
|
129
|
+
import { Suspense } from "react";
|
|
130
|
+
|
|
131
|
+
export default function MyLoader() {
|
|
132
|
+
const Component = registry["/root/sample"];
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
<div>
|
|
136
|
+
<StyleContext styles={stylesmap}>
|
|
137
|
+
<Suspense>
|
|
138
|
+
<Component components={Elements} />
|
|
139
|
+
</Suspense>
|
|
140
|
+
</StyleContext>
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { MDXComponents } from "mdx/types";
|
|
2
|
+
declare const Elements: MDXComponents;
|
|
3
|
+
type JSX = React.JSX.Element | null;
|
|
4
|
+
type HeaderLevels = 1 | 2 | 3 | 4 | 5 | 6;
|
|
5
|
+
import { MDXComponents as MDXComponents2, MDXProps } from "mdx/types";
|
|
6
|
+
/**
|
|
7
|
+
* File extension(s) to accept
|
|
8
|
+
*/
|
|
9
|
+
type MDXFile = `${string}.mdx`;
|
|
10
|
+
/**
|
|
11
|
+
* Generated registry type
|
|
12
|
+
*/
|
|
13
|
+
type LazyRegistry<T extends Record<string, MDXFile>> = { readonly [K in keyof T] : React.LazyExoticComponent<React.ComponentType> };
|
|
14
|
+
type Expand<T> = T extends infer O ? { [K in keyof O] : O[K] } : never;
|
|
15
|
+
type MustStartWithSlash<T extends string> = T extends `/${string}` ? T : never;
|
|
16
|
+
type MustNotEndWithSlash<T extends string> = T extends `${string}/` ? never : T;
|
|
17
|
+
/**
|
|
18
|
+
* Function to generate Registry mappings
|
|
19
|
+
* @param MDXRegistryOptions
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
declare function generateRegistry<
|
|
23
|
+
S extends string,
|
|
24
|
+
M extends string,
|
|
25
|
+
R extends Record<string, string>
|
|
26
|
+
>({ modules, source, mountOn, records }: MDXRegistryOptions<S, M, R>): Expand<LazyRegistry<{ [K in keyof typeof records as `${typeof mountOn}${Extract<K, string>}`] : MDXFile }>>;
|
|
27
|
+
/**
|
|
28
|
+
* Options passed to {@link generateRegistry}
|
|
29
|
+
*/
|
|
30
|
+
type MDXRegistryOptions<
|
|
31
|
+
S extends string = string,
|
|
32
|
+
M extends string = string,
|
|
33
|
+
R extends Record<string, string> = Record<string, string>
|
|
34
|
+
> = {
|
|
35
|
+
/**
|
|
36
|
+
* Module object returned from `import.meta.glob`
|
|
37
|
+
* @example import.module.glob("/src/assets/mdx/**\/*.mdx")
|
|
38
|
+
*/
|
|
39
|
+
modules: Record<string, () => Promise<unknown>>;
|
|
40
|
+
/**
|
|
41
|
+
* Directory from which to resolve the source paths in {@link MDXRegistryOptions.records}
|
|
42
|
+
*/
|
|
43
|
+
source: MustNotEndWithSlash<S> & MustStartWithSlash<S>;
|
|
44
|
+
/**
|
|
45
|
+
* Virtual base path on which to mount the key of {@link MDXRegistryOptions.records}
|
|
46
|
+
*/
|
|
47
|
+
mountOn: MustNotEndWithSlash<M> & MustStartWithSlash<M>;
|
|
48
|
+
/**
|
|
49
|
+
* Mappings of virtual path to file paths under {@link MDXRegistryOptions.source}
|
|
50
|
+
*/
|
|
51
|
+
records: { [K in keyof R] : K extends string ? MustNotEndWithSlash<K> & MustStartWithSlash<K> extends never ? never : R[K] extends MustStartWithSlash<R[K]> & MDXFile ? R[K] : never : never };
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* List of default style classes
|
|
55
|
+
*/
|
|
56
|
+
declare const StyleClassesList: readonly ["header", "header_button", "header_1", "header_2", "header_3", "header_4", "header_5", "header_6", "header_icon", "anchor", "button", "bold", "italic", "span", "striked", "paragraph", "code", "preformatted", "blockquote", "horizontal_line", "image", "list", "unordered_list", "ordered_list", "list_item", "table", "table_head", "table_head_cell", "table_body", "table_row", "table_data"];
|
|
57
|
+
type StyleClasses = (typeof StyleClassesList)[number];
|
|
58
|
+
type StyleClassesMap = Partial<{ [K in StyleClasses] : string }>;
|
|
59
|
+
/**
|
|
60
|
+
* Context which defines styles for the loaded component(s)
|
|
61
|
+
*/
|
|
62
|
+
declare const StyleContext: React.Context<StyleClassesMap>;
|
|
63
|
+
/**
|
|
64
|
+
* Hook to get defined style classes map
|
|
65
|
+
* @returns {@link StyleClassesMap}
|
|
66
|
+
*/
|
|
67
|
+
declare function useStyles(): StyleClassesMap;
|
|
68
|
+
type MDXFromComponentProps = {
|
|
69
|
+
SourceComponent: React.ComponentType<MDXProps>;
|
|
70
|
+
styles: StyleClassesMap;
|
|
71
|
+
elements?: MDXComponents2;
|
|
72
|
+
fallback?: React.ReactNode;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Simple way to directly load a component from the Registry
|
|
76
|
+
*/
|
|
77
|
+
declare function MDXFromComponent({ SourceComponent, styles, fallback, elements }: MDXFromComponentProps): JSX;
|
|
78
|
+
export { useStyles, generateRegistry, StyleContext, StyleClassesMap, StyleClassesList, StyleClasses, MDXRegistryOptions, MDXFromComponentProps, MDXFromComponent, MDXFile, LazyRegistry, HeaderLevels, Elements };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
// src/components/Elements/Anchor.tsx
|
|
2
|
+
import { cn } from "@d1vij/shit-i-always-use";
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
4
|
+
|
|
5
|
+
// src/lib/StyleContext.ts
|
|
6
|
+
import { createContext, useContext } from "react";
|
|
7
|
+
var StyleClassesList = [
|
|
8
|
+
"header",
|
|
9
|
+
"header_button",
|
|
10
|
+
"header_1",
|
|
11
|
+
"header_2",
|
|
12
|
+
"header_3",
|
|
13
|
+
"header_4",
|
|
14
|
+
"header_5",
|
|
15
|
+
"header_6",
|
|
16
|
+
"header_icon",
|
|
17
|
+
"anchor",
|
|
18
|
+
"button",
|
|
19
|
+
"bold",
|
|
20
|
+
"italic",
|
|
21
|
+
"span",
|
|
22
|
+
"striked",
|
|
23
|
+
"paragraph",
|
|
24
|
+
"code",
|
|
25
|
+
"preformatted",
|
|
26
|
+
"blockquote",
|
|
27
|
+
"horizontal_line",
|
|
28
|
+
"image",
|
|
29
|
+
"list",
|
|
30
|
+
"unordered_list",
|
|
31
|
+
"ordered_list",
|
|
32
|
+
"list_item",
|
|
33
|
+
"table",
|
|
34
|
+
"table_head",
|
|
35
|
+
"table_head_cell",
|
|
36
|
+
"table_body",
|
|
37
|
+
"table_row",
|
|
38
|
+
"table_data"
|
|
39
|
+
];
|
|
40
|
+
var StyleContext = createContext({});
|
|
41
|
+
function useStyles() {
|
|
42
|
+
return useContext(StyleContext);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/components/Elements/Anchor.tsx
|
|
46
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
47
|
+
function Anchor(props) {
|
|
48
|
+
const selfOrigin = useMemo(() => new URL(window.location.href).origin.toString(), []);
|
|
49
|
+
const styles = useStyles();
|
|
50
|
+
const [target] = useState(() => {
|
|
51
|
+
const href = props.href;
|
|
52
|
+
if (href?.match(/^#.*/)) {
|
|
53
|
+
return "_self";
|
|
54
|
+
}
|
|
55
|
+
const targetOrigin = new URL(props.href ?? "").origin.toString();
|
|
56
|
+
return targetOrigin === selfOrigin ? "_self" : "_blank";
|
|
57
|
+
});
|
|
58
|
+
return /* @__PURE__ */ jsxDEV("a", {
|
|
59
|
+
className: cn(styles.anchor),
|
|
60
|
+
target,
|
|
61
|
+
href: props.href,
|
|
62
|
+
children: props.children
|
|
63
|
+
}, undefined, false, undefined, this);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/components/Elements/BlockQuote.tsx
|
|
67
|
+
import { cn as cn2 } from "@d1vij/shit-i-always-use";
|
|
68
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
69
|
+
function BlockQuote(props) {
|
|
70
|
+
const styles = useStyles();
|
|
71
|
+
return /* @__PURE__ */ jsxDEV2("blockquote", {
|
|
72
|
+
className: cn2(styles.blockquote),
|
|
73
|
+
children: props.children
|
|
74
|
+
}, undefined, false, undefined, this);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/components/Elements/Bold.tsx
|
|
78
|
+
import { cn as cn3 } from "@d1vij/shit-i-always-use";
|
|
79
|
+
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
80
|
+
function Bold(props) {
|
|
81
|
+
const styles = useStyles();
|
|
82
|
+
return /* @__PURE__ */ jsxDEV3("span", {
|
|
83
|
+
className: cn3(styles.bold),
|
|
84
|
+
children: props.children
|
|
85
|
+
}, undefined, false, undefined, this);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/components/Elements/Code.tsx
|
|
89
|
+
import { cn as cn4 } from "@d1vij/shit-i-always-use";
|
|
90
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
91
|
+
function Code(props) {
|
|
92
|
+
const styles = useStyles();
|
|
93
|
+
const lang = /language-(\w+)/.exec(props.className || "")?.[1];
|
|
94
|
+
return /* @__PURE__ */ jsxDEV4("code", {
|
|
95
|
+
className: cn4(styles.code, lang && `language-${lang}`),
|
|
96
|
+
children: props.children
|
|
97
|
+
}, undefined, false, undefined, this);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// src/components/Elements/Heading.tsx
|
|
101
|
+
import { cn as cn5, useClipboardText } from "@d1vij/shit-i-always-use";
|
|
102
|
+
import { useEffect, useRef, useState as useState2 } from "react";
|
|
103
|
+
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
104
|
+
function Header(props) {
|
|
105
|
+
const styles = useStyles();
|
|
106
|
+
const headerRef = useRef(null);
|
|
107
|
+
const [id, setId] = useState2("");
|
|
108
|
+
const { copy } = useClipboardText();
|
|
109
|
+
async function handleClick() {
|
|
110
|
+
const url = new URL(`/#${id}`, window.location.origin).toString();
|
|
111
|
+
console.log("clicked");
|
|
112
|
+
await copy(url);
|
|
113
|
+
}
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (!headerRef.current)
|
|
116
|
+
return;
|
|
117
|
+
const raw = headerRef.current.textContent ?? "";
|
|
118
|
+
const safe = raw.toLowerCase().replace(/[^a-z0-9\s-]/g, "").trim().replace(/\s+/g, "-").slice(0, 30);
|
|
119
|
+
setId(safe);
|
|
120
|
+
}, []);
|
|
121
|
+
return /* @__PURE__ */ jsxDEV5("h1", {
|
|
122
|
+
className: cn5(styles.header, styles[`header_${props.level}`]),
|
|
123
|
+
children: /* @__PURE__ */ jsxDEV5("button", {
|
|
124
|
+
onClick: () => void handleClick(),
|
|
125
|
+
ref: headerRef,
|
|
126
|
+
id,
|
|
127
|
+
className: cn5(styles.header_button),
|
|
128
|
+
type: "button",
|
|
129
|
+
children: props.children
|
|
130
|
+
}, undefined, false, undefined, this)
|
|
131
|
+
}, undefined, false, undefined, this);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// src/components/Elements/HorizontalLine.tsx
|
|
135
|
+
import { cn as cn6 } from "@d1vij/shit-i-always-use";
|
|
136
|
+
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
137
|
+
function HorizontalLine(_) {
|
|
138
|
+
const styles = useStyles();
|
|
139
|
+
return /* @__PURE__ */ jsxDEV6("hr", {
|
|
140
|
+
className: cn6(styles.horizontal_line)
|
|
141
|
+
}, undefined, false, undefined, this);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/components/Elements/Image.tsx
|
|
145
|
+
import { cn as cn7 } from "@d1vij/shit-i-always-use";
|
|
146
|
+
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
147
|
+
function Image(props) {
|
|
148
|
+
const styles = useStyles();
|
|
149
|
+
return /* @__PURE__ */ jsxDEV7("img", {
|
|
150
|
+
className: cn7(styles.image),
|
|
151
|
+
alt: props.alt,
|
|
152
|
+
title: props.title,
|
|
153
|
+
src: props.src
|
|
154
|
+
}, undefined, false, undefined, this);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/components/Elements/Italics.tsx
|
|
158
|
+
import { cn as cn8 } from "@d1vij/shit-i-always-use";
|
|
159
|
+
import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
|
|
160
|
+
function Italics(props) {
|
|
161
|
+
const styles = useStyles();
|
|
162
|
+
return /* @__PURE__ */ jsxDEV8("span", {
|
|
163
|
+
className: cn8(styles.italic),
|
|
164
|
+
children: props.children
|
|
165
|
+
}, undefined, false, undefined, this);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/components/Elements/List.tsx
|
|
169
|
+
import { cn as cn9 } from "@d1vij/shit-i-always-use";
|
|
170
|
+
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
171
|
+
function List(props) {
|
|
172
|
+
const styles = useStyles();
|
|
173
|
+
const L = props.type === "ordered" ? "ol" : "ul";
|
|
174
|
+
return /* @__PURE__ */ jsxDEV9(L, {
|
|
175
|
+
className: cn9(styles.list, props.type === "ordered" && styles.ordered_list, props.type === "unordered" && styles.unordered_list),
|
|
176
|
+
children: props.children
|
|
177
|
+
}, undefined, false, undefined, this);
|
|
178
|
+
}
|
|
179
|
+
function ListItem(props) {
|
|
180
|
+
const styles = useStyles();
|
|
181
|
+
return /* @__PURE__ */ jsxDEV9("li", {
|
|
182
|
+
className: cn9(styles.list_item),
|
|
183
|
+
children: props.children
|
|
184
|
+
}, undefined, false, undefined, this);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// src/components/Elements/Paragraph.tsx
|
|
188
|
+
import { cn as cn10 } from "@d1vij/shit-i-always-use";
|
|
189
|
+
import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
|
|
190
|
+
function Paragraph(props) {
|
|
191
|
+
const styles = useStyles();
|
|
192
|
+
return /* @__PURE__ */ jsxDEV10("p", {
|
|
193
|
+
className: cn10(styles.paragraph),
|
|
194
|
+
children: props.children
|
|
195
|
+
}, undefined, false, undefined, this);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// src/components/Elements/Preformatted.tsx
|
|
199
|
+
import { cn as cn11 } from "@d1vij/shit-i-always-use";
|
|
200
|
+
import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
|
|
201
|
+
function Preformatted(props) {
|
|
202
|
+
const styles = useStyles();
|
|
203
|
+
return /* @__PURE__ */ jsxDEV11("pre", {
|
|
204
|
+
className: cn11(styles.preformatted),
|
|
205
|
+
children: props.children
|
|
206
|
+
}, undefined, false, undefined, this);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/components/Elements/Striked.tsx
|
|
210
|
+
import { cn as cn12 } from "@d1vij/shit-i-always-use";
|
|
211
|
+
import { jsxDEV as jsxDEV12 } from "react/jsx-dev-runtime";
|
|
212
|
+
function Striked(props) {
|
|
213
|
+
const styles = useStyles();
|
|
214
|
+
return /* @__PURE__ */ jsxDEV12("span", {
|
|
215
|
+
className: cn12(styles.striked),
|
|
216
|
+
children: props.children
|
|
217
|
+
}, undefined, false, undefined, this);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/components/Elements/Table.tsx
|
|
221
|
+
import { cn as cn13 } from "@d1vij/shit-i-always-use";
|
|
222
|
+
import { jsxDEV as jsxDEV13 } from "react/jsx-dev-runtime";
|
|
223
|
+
function Table(props) {
|
|
224
|
+
const styles = useStyles();
|
|
225
|
+
return /* @__PURE__ */ jsxDEV13("table", {
|
|
226
|
+
className: cn13(styles.table),
|
|
227
|
+
children: props.children
|
|
228
|
+
}, undefined, false, undefined, this);
|
|
229
|
+
}
|
|
230
|
+
function TableHead(props) {
|
|
231
|
+
const styles = useStyles();
|
|
232
|
+
return /* @__PURE__ */ jsxDEV13("thead", {
|
|
233
|
+
className: cn13(styles.table_head),
|
|
234
|
+
children: props.children
|
|
235
|
+
}, undefined, false, undefined, this);
|
|
236
|
+
}
|
|
237
|
+
function TableBody(props) {
|
|
238
|
+
const styles = useStyles();
|
|
239
|
+
return /* @__PURE__ */ jsxDEV13("tbody", {
|
|
240
|
+
className: cn13(styles.table_body),
|
|
241
|
+
children: props.children
|
|
242
|
+
}, undefined, false, undefined, this);
|
|
243
|
+
}
|
|
244
|
+
function TableRow(props) {
|
|
245
|
+
const styles = useStyles();
|
|
246
|
+
return /* @__PURE__ */ jsxDEV13("tr", {
|
|
247
|
+
className: cn13(styles.table_row),
|
|
248
|
+
children: props.children
|
|
249
|
+
}, undefined, false, undefined, this);
|
|
250
|
+
}
|
|
251
|
+
function TableHeadCell(props) {
|
|
252
|
+
const styles = useStyles();
|
|
253
|
+
return /* @__PURE__ */ jsxDEV13("th", {
|
|
254
|
+
className: cn13(styles.table_head_cell),
|
|
255
|
+
children: props.children
|
|
256
|
+
}, undefined, false, undefined, this);
|
|
257
|
+
}
|
|
258
|
+
function TableData(props) {
|
|
259
|
+
const styles = useStyles();
|
|
260
|
+
return /* @__PURE__ */ jsxDEV13("td", {
|
|
261
|
+
className: cn13(styles.table_data),
|
|
262
|
+
children: props.children
|
|
263
|
+
}, undefined, false, undefined, this);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// src/components/Elements/Elements.tsx
|
|
267
|
+
var Elements = {
|
|
268
|
+
h1: (props) => Header({ ...props, level: 1 }),
|
|
269
|
+
h2: (props) => Header({ ...props, level: 2 }),
|
|
270
|
+
h3: (props) => Header({ ...props, level: 3 }),
|
|
271
|
+
h4: (props) => Header({ ...props, level: 4 }),
|
|
272
|
+
h5: (props) => Header({ ...props, level: 5 }),
|
|
273
|
+
h6: (props) => Header({ ...props, level: 6 }),
|
|
274
|
+
a: Anchor,
|
|
275
|
+
em: Italics,
|
|
276
|
+
del: Striked,
|
|
277
|
+
strong: Bold,
|
|
278
|
+
code: Code,
|
|
279
|
+
blockquote: BlockQuote,
|
|
280
|
+
pre: Preformatted,
|
|
281
|
+
p: Paragraph,
|
|
282
|
+
hr: HorizontalLine,
|
|
283
|
+
ol: (props) => List({ ...props, type: "ordered" }),
|
|
284
|
+
ul: (props) => List({ ...props, type: "unordered" }),
|
|
285
|
+
li: ListItem,
|
|
286
|
+
img: Image,
|
|
287
|
+
table: Table,
|
|
288
|
+
thead: TableHead,
|
|
289
|
+
tbody: TableBody,
|
|
290
|
+
th: TableHeadCell,
|
|
291
|
+
tr: TableRow,
|
|
292
|
+
td: TableData
|
|
293
|
+
};
|
|
294
|
+
// src/components/Loader.tsx
|
|
295
|
+
import { Suspense } from "react";
|
|
296
|
+
|
|
297
|
+
// src/lib/Registry.ts
|
|
298
|
+
import { lazy } from "react";
|
|
299
|
+
function generateRegistry({
|
|
300
|
+
modules,
|
|
301
|
+
source,
|
|
302
|
+
mountOn,
|
|
303
|
+
records
|
|
304
|
+
}) {
|
|
305
|
+
const paths = [];
|
|
306
|
+
for (const [virtual, path] of Object.entries(records)) {
|
|
307
|
+
const src = `${source}${path}`;
|
|
308
|
+
const loader = modules[src];
|
|
309
|
+
if (!loader) {
|
|
310
|
+
throw new Error(`No such file exsits as ${src}`);
|
|
311
|
+
}
|
|
312
|
+
paths.push([`${mountOn}${virtual}`, lazy(loader)]);
|
|
313
|
+
}
|
|
314
|
+
return Object.fromEntries(paths);
|
|
315
|
+
}
|
|
316
|
+
// src/components/Loader.tsx
|
|
317
|
+
import { jsxDEV as jsxDEV14 } from "react/jsx-dev-runtime";
|
|
318
|
+
function MDXFromComponent({
|
|
319
|
+
SourceComponent,
|
|
320
|
+
styles,
|
|
321
|
+
fallback,
|
|
322
|
+
elements = Elements
|
|
323
|
+
}) {
|
|
324
|
+
return /* @__PURE__ */ jsxDEV14(StyleContext, {
|
|
325
|
+
value: styles,
|
|
326
|
+
children: /* @__PURE__ */ jsxDEV14(Suspense, {
|
|
327
|
+
fallback,
|
|
328
|
+
children: /* @__PURE__ */ jsxDEV14(SourceComponent, {
|
|
329
|
+
components: elements
|
|
330
|
+
}, undefined, false, undefined, this)
|
|
331
|
+
}, undefined, false, undefined, this)
|
|
332
|
+
}, undefined, false, undefined, this);
|
|
333
|
+
}
|
|
334
|
+
export {
|
|
335
|
+
useStyles,
|
|
336
|
+
generateRegistry,
|
|
337
|
+
StyleContext,
|
|
338
|
+
StyleClassesList,
|
|
339
|
+
MDXFromComponent,
|
|
340
|
+
Elements
|
|
341
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Options as MDXOptions } from "@mdx-js/rollup";
|
|
2
|
+
import { Plugin } from "vite";
|
|
3
|
+
/**
|
|
4
|
+
* Vite plugin to support MDX conversion.
|
|
5
|
+
* Users wont have to explicitly setup their vite config
|
|
6
|
+
*/
|
|
7
|
+
declare function MDXLoaderPlugin(opts?: MDXOptions): Plugin;
|
|
8
|
+
export { MDXLoaderPlugin as default, MDXLoaderPlugin };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/vitePlugin.ts
|
|
2
|
+
import mdx from "@mdx-js/rollup";
|
|
3
|
+
import remarkGFM from "remark-gfm";
|
|
4
|
+
function MDXLoaderPlugin(opts) {
|
|
5
|
+
return mdx({
|
|
6
|
+
...opts,
|
|
7
|
+
remarkPlugins: [remarkGFM]
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
var vitePlugin_default = MDXLoaderPlugin;
|
|
11
|
+
export {
|
|
12
|
+
vitePlugin_default as default,
|
|
13
|
+
MDXLoaderPlugin
|
|
14
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@d1vij/jassm",
|
|
3
|
+
"description": "Just another static site maker. Create simple content driven sites using MDX and React along with Typescript safety.",
|
|
4
|
+
"version": "0.1.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"module": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"./plugin": {
|
|
19
|
+
"import": "./dist/vitePlugin.js",
|
|
20
|
+
"types": "./dist/vitePlugin.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/d1vij/react-mdx-loader"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/d1vij/react-mdx-loader",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"sideEffects": false,
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "bunup",
|
|
36
|
+
"dev:ui": "cd test/ui && vite",
|
|
37
|
+
"dev": "bunup --watch",
|
|
38
|
+
"prepare": "bun simple-git-hooks",
|
|
39
|
+
"type-check": "tsc --noEmit",
|
|
40
|
+
"prepack": "bun run build",
|
|
41
|
+
"release": "bumpp --commit --push --tag",
|
|
42
|
+
"lint": "biome check --fix && tsc -b",
|
|
43
|
+
"format": "biome format --write"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@biomejs/biome": "^2.4.4",
|
|
47
|
+
"@types/bun": "^1.3.9",
|
|
48
|
+
"@types/mdx": "^2.0.13",
|
|
49
|
+
"@types/react": "^19.2.14",
|
|
50
|
+
"@types/react-dom": "^19.2.3",
|
|
51
|
+
"bumpp": "^10.4.1",
|
|
52
|
+
"bunup": "^0.16.29",
|
|
53
|
+
"simple-git-hooks": "^2.13.1",
|
|
54
|
+
"typescript": "^5.9.3"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"@mdx-js/rollup": "^3.1.1",
|
|
58
|
+
"react": "^19.2.4",
|
|
59
|
+
"react-dom": "^19.2.4",
|
|
60
|
+
"remark-gfm": "^4.0.1",
|
|
61
|
+
"typescript": ">=4.5.0",
|
|
62
|
+
"vite": "^7.3.1"
|
|
63
|
+
},
|
|
64
|
+
"peerDependenciesMeta": {
|
|
65
|
+
"typescript": {
|
|
66
|
+
"optional": true
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@d1vij/shit-i-always-use": "^0.1.3"
|
|
71
|
+
},
|
|
72
|
+
"simple-git-hooks": {
|
|
73
|
+
"pre-commit": "bun run lint && bun run type-check"
|
|
74
|
+
}
|
|
75
|
+
}
|