@farming-labs/theme 0.0.2-beta.13 → 0.0.2-beta.14

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.
@@ -34,6 +34,7 @@ function hasChildPages(dir) {
34
34
  function buildTree(config) {
35
35
  const docsDir = path.join(process.cwd(), "app", config.entry);
36
36
  const icons = config.icons;
37
+ const ordering = config.ordering;
37
38
  const rootChildren = [];
38
39
  if (fs.existsSync(path.join(docsDir, "page.mdx"))) {
39
40
  const data = readFrontmatter(path.join(docsDir, "page.mdx"));
@@ -44,52 +45,87 @@ function buildTree(config) {
44
45
  icon: resolveIcon(data.icon, icons)
45
46
  });
46
47
  }
47
- /**
48
- * Recursively scan a directory and return tree nodes.
49
- *
50
- * - If a subdirectory has its own children (nested pages), it becomes a
51
- * **folder** node with collapsible children. Its own `page.mdx` becomes
52
- * the folder's `index` page.
53
- * - Otherwise it becomes a simple **page** node.
54
- */
55
- function scan(dir, baseSlug) {
48
+ function buildNode(dir, name, baseSlug, slugOrder) {
49
+ const full = path.join(dir, name);
50
+ if (!fs.statSync(full).isDirectory()) return null;
51
+ const pagePath = path.join(full, "page.mdx");
52
+ if (!fs.existsSync(pagePath)) return null;
53
+ const data = readFrontmatter(pagePath);
54
+ const slug = [...baseSlug, name];
55
+ const url = `/${config.entry}/${slug.join("/")}`;
56
+ const icon = resolveIcon(data.icon, icons);
57
+ const displayName = data.title ?? name.replace(/-/g, " ");
58
+ if (hasChildPages(full)) {
59
+ const folderChildren = scanDir(full, slug, slugOrder);
60
+ return {
61
+ type: "folder",
62
+ name: displayName,
63
+ icon,
64
+ index: {
65
+ type: "page",
66
+ name: displayName,
67
+ url,
68
+ icon
69
+ },
70
+ children: folderChildren
71
+ };
72
+ }
73
+ return {
74
+ type: "page",
75
+ name: displayName,
76
+ url,
77
+ icon
78
+ };
79
+ }
80
+ function scanDir(dir, baseSlug, slugOrder) {
56
81
  if (!fs.existsSync(dir)) return [];
57
- const nodes = [];
58
82
  const entries = fs.readdirSync(dir).sort();
59
- for (const name of entries) {
60
- const full = path.join(dir, name);
61
- if (!fs.statSync(full).isDirectory()) continue;
62
- const pagePath = path.join(full, "page.mdx");
63
- if (!fs.existsSync(pagePath)) continue;
64
- const data = readFrontmatter(pagePath);
65
- const slug = [...baseSlug, name];
66
- const url = `/${config.entry}/${slug.join("/")}`;
67
- const icon = resolveIcon(data.icon, icons);
68
- const displayName = data.title ?? name.replace(/-/g, " ");
69
- if (hasChildPages(full)) {
70
- const folderChildren = scan(full, slug);
71
- nodes.push({
72
- type: "folder",
73
- name: displayName,
74
- icon,
75
- index: {
76
- type: "page",
77
- name: displayName,
78
- url,
79
- icon
80
- },
81
- children: folderChildren
83
+ if (slugOrder) {
84
+ const nodes = [];
85
+ const slugMap = /* @__PURE__ */ new Map();
86
+ for (const item of slugOrder) slugMap.set(item.slug, item);
87
+ for (const item of slugOrder) {
88
+ if (!entries.includes(item.slug)) continue;
89
+ const node = buildNode(dir, item.slug, baseSlug, item.children);
90
+ if (node) nodes.push(node);
91
+ }
92
+ for (const name of entries) {
93
+ if (slugMap.has(name)) continue;
94
+ const node = buildNode(dir, name, baseSlug);
95
+ if (node) nodes.push(node);
96
+ }
97
+ return nodes;
98
+ }
99
+ if (ordering === "numeric") {
100
+ const nodes = [];
101
+ for (const name of entries) {
102
+ const full = path.join(dir, name);
103
+ if (!fs.statSync(full).isDirectory()) continue;
104
+ const pagePath = path.join(full, "page.mdx");
105
+ if (!fs.existsSync(pagePath)) continue;
106
+ const data = readFrontmatter(pagePath);
107
+ const order = typeof data.order === "number" ? data.order : Infinity;
108
+ const node = buildNode(dir, name, baseSlug);
109
+ if (node) nodes.push({
110
+ order,
111
+ node
82
112
  });
83
- } else nodes.push({
84
- type: "page",
85
- name: displayName,
86
- url,
87
- icon
113
+ }
114
+ nodes.sort((a, b) => {
115
+ if (a.order === b.order) return 0;
116
+ return a.order - b.order;
88
117
  });
118
+ return nodes.map((n) => n.node);
119
+ }
120
+ const nodes = [];
121
+ for (const name of entries) {
122
+ const node = buildNode(dir, name, baseSlug);
123
+ if (node) nodes.push(node);
89
124
  }
90
125
  return nodes;
91
126
  }
92
- rootChildren.push(...scan(docsDir, []));
127
+ const rootSlugOrder = Array.isArray(ordering) ? ordering : void 0;
128
+ rootChildren.push(...scanDir(docsDir, [], rootSlugOrder));
93
129
  return {
94
130
  name: "Docs",
95
131
  children: rootChildren
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/theme",
3
- "version": "0.0.2-beta.13",
3
+ "version": "0.0.2-beta.14",
4
4
  "description": "Theme package for @farming-labs/docs — layout, provider, MDX components, and styles",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",
@@ -74,7 +74,7 @@
74
74
  "next": ">=14.0.0",
75
75
  "tsdown": "^0.20.3",
76
76
  "typescript": "^5.9.3",
77
- "@farming-labs/docs": "0.0.2-beta.13"
77
+ "@farming-labs/docs": "0.0.2-beta.14"
78
78
  },
79
79
  "peerDependencies": {
80
80
  "@farming-labs/docs": ">=0.0.1",
@@ -186,6 +186,12 @@ code:not(pre code) {
186
186
  border-top: none;
187
187
  }
188
188
 
189
+ /* Last item: bottom border */
190
+ .dark aside .overscroll-contain > div > a[data-active]:last-child,
191
+ .dark aside .overscroll-contain > div > div:last-child {
192
+ border-bottom: 1px solid hsl(0 0% 12%);
193
+ }
194
+
189
195
  /* ── Sidebar links (all levels) ──────────────────────────────────── */
190
196
 
191
197
  .dark aside a[data-active] {