docstra 1.0.1 → 1.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/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # **Docstra**
2
+
3
+ Docstra is a modern documentation framework for Next.js. It's built with Tailwind CSS and MDX, making it easy to create beautiful and responsive documentation sites.
4
+
5
+ > Documentation of Docstra is coming soon. Stay tuned!
6
+
7
+ ## Features
8
+
9
+ - MDX support
10
+ - Custom content directories
11
+ - Works in monorepos
12
+ - Beautiful sidebar + TOC
13
+ - Edit-on-GitHub links
14
+ - Search coming soon
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ npm install docstra
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ```ts
25
+ // docstra.config.ts
26
+ export default defineDocstraConfig({
27
+ siteName: 'Docstra Site',
28
+ githubRepo: 'https://github.com/sudhucodes/test',
29
+ editOnGithub: true,
30
+ formSyncFormID: 'FORM_ID',
31
+ navbar: {
32
+ logo: {
33
+ link: '/docs'
34
+ },
35
+ links: [{ name: 'Guides', href: '/docs/guides' }]
36
+ },
37
+ sidebar: {
38
+ // sidebar links
39
+ }
40
+ });
41
+ ```
42
+
43
+ > Created and maintained with 💙 by [SudhuCodes](https://github.com/sudhucodes)
@@ -269,7 +269,7 @@ function DocstraSidebar() {
269
269
  "aside",
270
270
  {
271
271
  className: cn(
272
- "sticky md:top-18 h-[calc(100svh-72px)] scrollbar-y w-screen z-21 md:w-72 pb-10 text-base md:text-sm shrink-0 border-r border-gray-200 p-4 max-md:fixed bg-white overflow-y-auto transition-all duration-300",
272
+ "sticky md:top-18 h-[calc(100svh-72px)] scrollbar-y w-screen max-md:rounded-t-lg z-21 md:w-72 pb-10 text-base md:text-sm shrink-0 border-r border-gray-200 p-4 max-md:fixed bg-white overflow-y-auto transition-all duration-300",
273
273
  openSidebar ? "top-32" : "top-full"
274
274
  ),
275
275
  children: [
@@ -277,7 +277,7 @@ function DocstraSidebar() {
277
277
  "div",
278
278
  {
279
279
  className: "flex items-center gap-2 cursor-pointer mt-6 mb-4 p-2.5 text-gray-500 border border-gray-200 rounded-lg hover:bg-gray-50",
280
- onClick: () => import_react_toast_msg2.toast.success("Docstra: Search is coming soon!"),
280
+ onClick: () => import_react_toast_msg2.toast.warning("Search is not available yet!"),
281
281
  children: [
282
282
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.SearchIcon, { className: "size-4.5" }),
283
283
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "Search" }),
@@ -298,7 +298,7 @@ function DocstraSidebar() {
298
298
  href: link.href,
299
299
  onNavigate: () => openSidebar && setOpenSidebar(false),
300
300
  className: cn(
301
- "flex items-center gap-2 text-gray-500 hover:bg-gray-100 py-2 px-2.5 rounded-lg text-sm",
301
+ "flex items-center gap-2 text-gray-500 hover:bg-gray-100 py-2 px-2.5 rounded-lg",
302
302
  pathname === link.href && "bg-gray-100 text-gray-800"
303
303
  ),
304
304
  children: [
@@ -664,7 +664,10 @@ function DocstraTOC({ mdxFilePath, rawMdxContent }) {
664
664
  const observerRef = (0, import_react6.useRef)(null);
665
665
  const pathname = (0, import_navigation5.usePathname)();
666
666
  const baseUrlOfGithub = docstraConfig?.githubRepo || "https://github.com/sudhucodes/docstra";
667
- const githubLink = baseUrlOfGithub + "/edit/main" + mdxFilePath.split("app")[1];
667
+ const normalized = mdxFilePath.replace(/\\/g, "/");
668
+ const match = normalized.match(/\/docs\/(.+)$/);
669
+ const relativePath = match ? match[1] : "";
670
+ const githubLink = `${baseUrlOfGithub}/edit/main/docs/${relativePath}`;
668
671
  (0, import_react6.useEffect)(() => {
669
672
  const onScroll = () => {
670
673
  const currentY = window.scrollY;
@@ -227,7 +227,7 @@ function DocstraSidebar() {
227
227
  "aside",
228
228
  {
229
229
  className: cn(
230
- "sticky md:top-18 h-[calc(100svh-72px)] scrollbar-y w-screen z-21 md:w-72 pb-10 text-base md:text-sm shrink-0 border-r border-gray-200 p-4 max-md:fixed bg-white overflow-y-auto transition-all duration-300",
230
+ "sticky md:top-18 h-[calc(100svh-72px)] scrollbar-y w-screen max-md:rounded-t-lg z-21 md:w-72 pb-10 text-base md:text-sm shrink-0 border-r border-gray-200 p-4 max-md:fixed bg-white overflow-y-auto transition-all duration-300",
231
231
  openSidebar ? "top-32" : "top-full"
232
232
  ),
233
233
  children: [
@@ -235,7 +235,7 @@ function DocstraSidebar() {
235
235
  "div",
236
236
  {
237
237
  className: "flex items-center gap-2 cursor-pointer mt-6 mb-4 p-2.5 text-gray-500 border border-gray-200 rounded-lg hover:bg-gray-50",
238
- onClick: () => toast.success("Docstra: Search is coming soon!"),
238
+ onClick: () => toast.warning("Search is not available yet!"),
239
239
  children: [
240
240
  /* @__PURE__ */ jsx5(SearchIcon2, { className: "size-4.5" }),
241
241
  /* @__PURE__ */ jsx5("p", { children: "Search" }),
@@ -256,7 +256,7 @@ function DocstraSidebar() {
256
256
  href: link.href,
257
257
  onNavigate: () => openSidebar && setOpenSidebar(false),
258
258
  className: cn(
259
- "flex items-center gap-2 text-gray-500 hover:bg-gray-100 py-2 px-2.5 rounded-lg text-sm",
259
+ "flex items-center gap-2 text-gray-500 hover:bg-gray-100 py-2 px-2.5 rounded-lg",
260
260
  pathname === link.href && "bg-gray-100 text-gray-800"
261
261
  ),
262
262
  children: [
@@ -622,7 +622,10 @@ function DocstraTOC({ mdxFilePath, rawMdxContent }) {
622
622
  const observerRef = useRef(null);
623
623
  const pathname = usePathname5();
624
624
  const baseUrlOfGithub = docstraConfig?.githubRepo || "https://github.com/sudhucodes/docstra";
625
- const githubLink = baseUrlOfGithub + "/edit/main" + mdxFilePath.split("app")[1];
625
+ const normalized = mdxFilePath.replace(/\\/g, "/");
626
+ const match = normalized.match(/\/docs\/(.+)$/);
627
+ const relativePath = match ? match[1] : "";
628
+ const githubLink = `${baseUrlOfGithub}/edit/main/docs/${relativePath}`;
626
629
  useEffect4(() => {
627
630
  const onScroll = () => {
628
631
  const currentY = window.scrollY;
@@ -38,10 +38,16 @@ interface FileContent {
38
38
  mdxFilePath: string;
39
39
  }
40
40
 
41
- declare function getFilePath(slug: Slug): string;
42
- declare function getFileContents(slug: Slug): FileContent;
41
+ declare function getFilePath({ slug, CONTENT_DIR }: {
42
+ slug: Slug;
43
+ CONTENT_DIR?: string;
44
+ }): string;
45
+ declare function getFileContents({ slug, CONTENT_DIR }: {
46
+ slug: Slug;
47
+ CONTENT_DIR?: string;
48
+ }): FileContent;
43
49
 
44
- declare function defineDocstraConfig(config: DocstraConfig): DocstraConfig;
50
+ declare function defineDocstraConfig<T extends DocstraConfig>(config: T): T;
45
51
 
46
52
  declare function DocstraMDXCompiler({ mdxContent, components }: {
47
53
  mdxContent: string;
@@ -38,10 +38,16 @@ interface FileContent {
38
38
  mdxFilePath: string;
39
39
  }
40
40
 
41
- declare function getFilePath(slug: Slug): string;
42
- declare function getFileContents(slug: Slug): FileContent;
41
+ declare function getFilePath({ slug, CONTENT_DIR }: {
42
+ slug: Slug;
43
+ CONTENT_DIR?: string;
44
+ }): string;
45
+ declare function getFileContents({ slug, CONTENT_DIR }: {
46
+ slug: Slug;
47
+ CONTENT_DIR?: string;
48
+ }): FileContent;
43
49
 
44
- declare function defineDocstraConfig(config: DocstraConfig): DocstraConfig;
50
+ declare function defineDocstraConfig<T extends DocstraConfig>(config: T): T;
45
51
 
46
52
  declare function DocstraMDXCompiler({ mdxContent, components }: {
47
53
  mdxContent: string;
@@ -41,24 +41,26 @@ module.exports = __toCommonJS(server_exports);
41
41
  var import_fs = __toESM(require("fs"));
42
42
  var import_path = __toESM(require("path"));
43
43
  var import_gray_matter = __toESM(require("gray-matter"));
44
- var CONTENT_DIR = import_path.default.join(process.cwd(), "app", "docs", "content");
45
- function getFilePath(slug) {
44
+ var DEFAULT_CONTENT_DIR = import_path.default.join(process.cwd(), "app", "docs", "content");
45
+ function getFilePath({ slug, CONTENT_DIR }) {
46
46
  const slugArray = Array.isArray(slug) && slug.length > 0 ? slug : ["index"];
47
+ const USER_CONTENT_DIR = process.cwd() + CONTENT_DIR;
48
+ const DIR = USER_CONTENT_DIR || DEFAULT_CONTENT_DIR;
47
49
  const possiblePaths = [
48
- import_path.default.join(CONTENT_DIR, ...slugArray) + ".mdx",
49
- import_path.default.join(CONTENT_DIR, ...slugArray) + ".md",
50
- import_path.default.join(CONTENT_DIR, ...slugArray, "index.mdx"),
51
- import_path.default.join(CONTENT_DIR, ...slugArray, "index.md")
50
+ import_path.default.join(DIR, ...slugArray) + ".mdx",
51
+ import_path.default.join(DIR, ...slugArray) + ".md",
52
+ import_path.default.join(DIR, ...slugArray, "index.mdx"),
53
+ import_path.default.join(DIR, ...slugArray, "index.md")
52
54
  ];
53
55
  for (const filePath of possiblePaths) {
54
56
  if (import_fs.default.existsSync(filePath)) {
55
57
  return filePath;
56
58
  }
57
59
  }
58
- throw new Error(`\u274C MDX file not found for slug: ${slugArray.join("/")} `);
60
+ throw new Error(`\u274C MDX file not found in: ${DIR} `);
59
61
  }
60
- function getFileContents(slug) {
61
- const filePath = getFilePath(slug);
62
+ function getFileContents({ slug, CONTENT_DIR }) {
63
+ const filePath = getFilePath({ slug, CONTENT_DIR: CONTENT_DIR || DEFAULT_CONTENT_DIR });
62
64
  const rawFile = import_fs.default.readFileSync(filePath, "utf-8");
63
65
  const { data, content } = (0, import_gray_matter.default)(rawFile);
64
66
  return {
@@ -2,24 +2,26 @@
2
2
  import fs from "fs";
3
3
  import path from "path";
4
4
  import matter from "gray-matter";
5
- var CONTENT_DIR = path.join(process.cwd(), "app", "docs", "content");
6
- function getFilePath(slug) {
5
+ var DEFAULT_CONTENT_DIR = path.join(process.cwd(), "app", "docs", "content");
6
+ function getFilePath({ slug, CONTENT_DIR }) {
7
7
  const slugArray = Array.isArray(slug) && slug.length > 0 ? slug : ["index"];
8
+ const USER_CONTENT_DIR = process.cwd() + CONTENT_DIR;
9
+ const DIR = USER_CONTENT_DIR || DEFAULT_CONTENT_DIR;
8
10
  const possiblePaths = [
9
- path.join(CONTENT_DIR, ...slugArray) + ".mdx",
10
- path.join(CONTENT_DIR, ...slugArray) + ".md",
11
- path.join(CONTENT_DIR, ...slugArray, "index.mdx"),
12
- path.join(CONTENT_DIR, ...slugArray, "index.md")
11
+ path.join(DIR, ...slugArray) + ".mdx",
12
+ path.join(DIR, ...slugArray) + ".md",
13
+ path.join(DIR, ...slugArray, "index.mdx"),
14
+ path.join(DIR, ...slugArray, "index.md")
13
15
  ];
14
16
  for (const filePath of possiblePaths) {
15
17
  if (fs.existsSync(filePath)) {
16
18
  return filePath;
17
19
  }
18
20
  }
19
- throw new Error(`\u274C MDX file not found for slug: ${slugArray.join("/")} `);
21
+ throw new Error(`\u274C MDX file not found in: ${DIR} `);
20
22
  }
21
- function getFileContents(slug) {
22
- const filePath = getFilePath(slug);
23
+ function getFileContents({ slug, CONTENT_DIR }) {
24
+ const filePath = getFilePath({ slug, CONTENT_DIR: CONTENT_DIR || DEFAULT_CONTENT_DIR });
23
25
  const rawFile = fs.readFileSync(filePath, "utf-8");
24
26
  const { data, content } = matter(rawFile);
25
27
  return {
package/dist/styles.css CHANGED
@@ -996,6 +996,12 @@
996
996
  overflow: hidden;
997
997
  }
998
998
  }
999
+ .max-md\:rounded-t-lg {
1000
+ @media (width < 48rem) {
1001
+ border-top-left-radius: var(--radius-lg);
1002
+ border-top-right-radius: var(--radius-lg);
1003
+ }
1004
+ }
999
1005
  .max-md\:px-4 {
1000
1006
  @media (width < 48rem) {
1001
1007
  padding-inline: calc(var(--spacing) * 4);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docstra",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "A Modern Documentation Framework for Next.js",
5
5
  "keywords": [
6
6
  "next",
@@ -32,7 +32,7 @@
32
32
  "./styles.css": "./dist/styles.css"
33
33
  },
34
34
  "scripts": {
35
- "build": "npm run prettier && npm run build:ts && npm run build:css",
35
+ "build": "npm run build:ts && npm run build:css",
36
36
  "build:ts": "tsup",
37
37
  "build:css": "npx @tailwindcss/cli -i ./src/styles/input.css -o ./dist/styles.css",
38
38
  "prettier": "prettier --write src"