@@ -4,30 +4,16 @@ import { Outlet } from 'react-router';
44import { Sidebar } from '~/_components/sidebar/sidebar' ;
55import {
66 getFileFromContentDir ,
7+ getFilesFromContentDir ,
78 getFoldersInContentDir ,
89} from '~/_utils/files.server' ;
10+ import { generateFromMdx } from '~/_utils/generate-from-mdx' ;
911import i18n from '~/i18next.server' ;
1012import type { Route } from './+types/layout' ;
1113import classes from './layout.module.css' ;
1214
1315export { ErrorBoundary } from '~/root' ;
1416
15- // Maps to store unique entries per category
16- const categoryMaps = new Map <
17- string ,
18- Map < string , { title : string ; url : string } >
19- > ( ) ;
20- const getStartedMap = new Map < string , { title : string ; url : string } > ( ) ;
21-
22- const cats : {
23- [ key : string ] : {
24- title : string ;
25- url : string ;
26- } [ ] ;
27- } = {
28- getStarted : [ ] ,
29- } ;
30-
3117export const loader = async ( {
3218 params : { lang } ,
3319 request,
@@ -45,77 +31,110 @@ export const loader = async ({
4531
4632 const t = await i18n . getFixedT ( lang ) ;
4733
48- if ( ! cats . getStarted . length ) {
49- categoryMaps . clear ( ) ;
50- getStartedMap . clear ( ) ;
51-
52- /* read all folders in content/components */
53- const folders = getFoldersInContentDir ( '/components' ) ;
54-
55- await Promise . all (
56- folders . map ( async ( folder ) => {
57- const metadataJson = getFileFromContentDir (
58- join ( 'components' , folder , 'metadata.json' ) ,
59- ) ;
60-
61- if ( ! metadataJson ) {
62- const category = 'components' ;
63- if ( ! categoryMaps . has ( category ) ) {
64- categoryMaps . set ( category , new Map ( ) ) ;
65- }
66- const categoryMap = categoryMaps . get ( category ) ;
67- if ( categoryMap ) {
68- categoryMap . set ( `/${ lang } /components/${ folder } ` , {
69- title : folder ,
70- url : `/${ lang } /components/${ folder } ` ,
71- } ) ;
72- }
73- return ;
74- }
75-
76- const parsedMetadata = JSON . parse ( metadataJson ) ;
77- const category = parsedMetadata . category || 'components' ;
78-
79- const component = {
80- title : parsedMetadata [ lang ] . title || folder ,
81- url : `/${ lang } /components/${ folder } ` ,
82- } ;
83-
84- if ( ! categoryMaps . has ( category ) ) {
85- categoryMaps . set ( category , new Map ( ) ) ;
86- }
87- const categoryMap = categoryMaps . get ( category ) ;
88- if ( categoryMap ) {
89- categoryMap . set ( component . url , component ) ;
90- }
91- } ) ,
92- ) ;
34+ const cats : {
35+ getStarted : {
36+ title : string ;
37+ url : string ;
38+ order : number ;
39+ } [ ] ;
40+ [ key : string ] : {
41+ title : string ;
42+ url : string ;
43+ } [ ] ;
44+ } = {
45+ getStarted : [ ] ,
46+ } ;
9347
94- getStartedMap . set ( `/${ lang } /changelog` , {
48+ // Get started items (added first)
49+ const getStartedItems = [
50+ {
9551 title : t ( 'components.changelog.title' ) ,
96- url : `/${ lang } /changelog` ,
52+ url : `/${ lang } /components/changelog` ,
53+ order : 1 ,
54+ } ,
55+ ] ;
56+
57+ const getStartedFolders = getFilesFromContentDir (
58+ join ( 'components-docs' , lang ) ,
59+ ) ;
60+
61+ for ( const file of getStartedFolders ) {
62+ const fileContent = getFileFromContentDir (
63+ join ( 'components-docs' , lang , `${ file . relativePath } ` ) ,
64+ ) ;
65+ const result = await generateFromMdx ( fileContent ) ;
66+
67+ getStartedItems . push ( {
68+ title :
69+ result . frontmatter . sidebar_title ||
70+ file . relativePath . replace ( '.mdx' , '' ) ,
71+ url : `/${ lang } /components/${ file . relativePath . replace ( '.mdx' , '' ) } ` ,
72+ order : parseInt ( result . frontmatter . order , 10 ) || 9999 ,
9773 } ) ;
74+ }
9875
99- for ( const [ category , map ] of categoryMaps . entries ( ) ) {
100- cats [ category ] = Array . from ( map . values ( ) ) . sort ( ( a , b ) =>
101- a . title . localeCompare ( b . title ) ,
76+ cats . getStarted = getStartedItems ;
77+
78+ /* read all folders in content/components */
79+ const folders = getFoldersInContentDir ( '/components' ) ;
80+
81+ const components = await Promise . all (
82+ folders . map ( async ( folder ) => {
83+ const metadataJson = getFileFromContentDir (
84+ join ( 'components' , folder , 'metadata.json' ) ,
10285 ) ;
86+
87+ if ( ! metadataJson ) {
88+ return {
89+ category : 'components' ,
90+ title : folder ,
91+ url : `/${ lang } /components/docs/${ folder } ` ,
92+ } ;
93+ }
94+
95+ const parsedMetadata = JSON . parse ( metadataJson ) ;
96+ const category = parsedMetadata . category || 'components' ;
97+
98+ return {
99+ category,
100+ title : parsedMetadata [ lang ] . title || folder ,
101+ url : `/${ lang } /components/docs/${ folder } ` ,
102+ } ;
103+ } ) ,
104+ ) ;
105+
106+ // Group components by category
107+ const componentCategories = new Set < string > ( ) ;
108+ for ( const component of components ) {
109+ const { category, ...item } = component ;
110+ componentCategories . add ( category ) ;
111+ if ( ! cats [ category ] ) {
112+ cats [ category ] = [ ] ;
103113 }
104- cats . getStarted = Array . from ( getStartedMap . values ( ) ) ;
114+ cats [ category ] . push ( item ) ;
115+ }
116+
117+ // Sort each category
118+ for ( const category in cats ) {
119+ cats [ category ] . sort ( ( a , b ) => a . title . localeCompare ( b . title ) ) ;
105120 }
106121
107122 const trimmedUrl = request . url . endsWith ( '/' )
108- ? request . url . slice ( 0 , - 1 )
109- : request . url ;
110- const compPage = trimmedUrl . split ( '/' ) . pop ( ) ;
123+ ? request . url . slice ( 0 , - 1 ) . split ( '/' )
124+ : request . url . split ( '/' ) ;
125+ const compPage = trimmedUrl [ trimmedUrl . length - 1 ] ;
111126
112- const isComponentPage = request . url . includes ( '/components/' ) ;
127+ const isComponentPage = request . url . includes ( '/components/docs/ ' ) ;
113128
114129 const sidebarSuffix : { [ key : string ] : string } = { } ;
115- for ( const category of categoryMaps . keys ( ) ) {
116- sidebarSuffix [ category ] = isComponentPage ? '/' + compPage : '/overview' ;
130+ for ( const category of componentCategories ) {
131+ sidebarSuffix [ category ] = isComponentPage ? `/ ${ compPage } ` : '/overview' ;
117132 }
118133
134+ cats . getStarted . sort ( ( a , b ) => {
135+ return a . order - b . order ;
136+ } ) ;
137+
119138 return {
120139 lang,
121140 cats,
0 commit comments