diff --git a/frontend/src/metabase/internal/components/ComponentsApp.jsx b/frontend/src/metabase/internal/components/ComponentsApp.jsx index a503a0f25831e62822912208d79d1c429bc1542c..045c613dd27619575f26f775e1f505e5f6302914 100644 --- a/frontend/src/metabase/internal/components/ComponentsApp.jsx +++ b/frontend/src/metabase/internal/components/ComponentsApp.jsx @@ -17,73 +17,101 @@ export default class ComponentsApp extends Component { const componentName = slugify(this.props.params.componentName); const exampleName = slugify(this.props.params.exampleName); return ( - <div className="wrapper p4"> - {COMPONENTS.filter( - ({ component, description, examples }) => - !componentName || componentName === slugify(component.name), - ).map(({ component, description, examples }) => ( - <div> - <h2> - <Link - to={`_internal/components/${slugify(component.name)}`} - className="no-decoration" - > - {component.name} - </Link> - </h2> - {description && <p className="my2">{description}</p>} - {component.propTypes && ( - <Section title="Props"> - <div className="border-left border-right border-bottom text-code"> - {Object.keys(component.propTypes).map(prop => ( - <div> - {prop}{" "} - {component.defaultProps && - component.defaultProps[prop] !== undefined - ? "(default: " + - JSON.stringify(component.defaultProps[prop]) + - ")" - : ""} - </div> - ))} - </div> - </Section> - )} - {examples && ( - <Section title="Examples"> - {Object.entries(examples) - .filter( - ([name, element]) => - !exampleName || exampleName === slugify(name), - ) - .map(([name, element]) => ( - <div className="my2"> - <h4 className="my1"> - <Link - to={`_internal/components/${slugify( - component.name, - )}/${slugify(name)}`} - className="no-decoration" - > - {name} - </Link> - </h4> - <div className="flex flex-column"> - <div className="p2 bordered flex align-center flex-full"> - <div className="full">{element}</div> + <div className="flex full"> + <nav + className="full-height border-right p2 pl4" + style={{ flex: "0 0 33.33%" }} + > + <h2 className="my2">Components</h2> + <ul className="py2"> + {COMPONENTS.filter( + ({ component, description, examples }) => + !componentName || componentName === slugify(component.name), + ).map(({ component, description, examples }) => ( + <li> + <a + className="py1 block link h3 text-bold" + href={`/_internal/components#${component.name}`} + > + {component.name} + </a> + </li> + ))} + </ul> + </nav> + <div + className="bg-slate-extra-light flex-full" + style={{ flex: "66.66%" }} + > + <div className="p4"> + {COMPONENTS.filter( + ({ component, description, examples }) => + !componentName || componentName === slugify(component.name), + ).map(({ component, description, examples }) => ( + <div id={component.name}> + <h2> + <Link + to={`_internal/components/${slugify(component.name)}`} + className="no-decoration" + > + {component.name} + </Link> + </h2> + {description && <p className="my2">{description}</p>} + {component.propTypes && ( + <Section title="Props"> + <div className="border-left border-right border-bottom text-code"> + {Object.keys(component.propTypes).map(prop => ( + <div> + {prop}{" "} + {component.defaultProps && + component.defaultProps[prop] !== undefined + ? "(default: " + + JSON.stringify(component.defaultProps[prop]) + + ")" + : ""} </div> - <div className="border-left border-right border-bottom text-code"> - <div className="p1"> - {reactElementToJSXString(element)} + ))} + </div> + </Section> + )} + {examples && ( + <Section title="Examples"> + {Object.entries(examples) + .filter( + ([name, element]) => + !exampleName || exampleName === slugify(name), + ) + .map(([name, element]) => ( + <div className="my2"> + <h4 className="my1"> + <Link + to={`_internal/components/${slugify( + component.name, + )}/${slugify(name)}`} + className="no-decoration" + > + {name} + </Link> + </h4> + <div className="flex flex-column"> + <div className="p2 bordered flex align-center flex-full"> + <div className="full">{element}</div> + </div> + <div className="border-left border-right border-bottom text-code"> + <div className="p1"> + {reactElementToJSXString(element)} + </div> + </div> </div> </div> - </div> - </div> - ))} - </Section> - )} + ))} + </Section> + )} + </div> + ))} </div> - ))} + </div> </div> ); } diff --git a/frontend/src/metabase/internal/routes.js b/frontend/src/metabase/internal/routes.js index c0b6be00dbe4ee4b38336cfa8a01a6044cd2be9a..cefece31d1c9f7cb2c9553ff35041c910c7dbff8 100644 --- a/frontend/src/metabase/internal/routes.js +++ b/frontend/src/metabase/internal/routes.js @@ -11,19 +11,44 @@ const PAGES = { Components: ComponentsApp, }; -const ListApp = () => ( - <ul> - {Object.keys(PAGES).map(name => ( - <li> - <a href={"/_internal/" + name.toLowerCase()}>{name}</a> - </li> - ))} - </ul> -); +const WelcomeApp = () => { + return ( + <div className="wrapper flex flex-column justify-center"> + <div className="my4"> + <h1>Metabase Style Guide</h1> + <p className="text-paragraph"> + Reference and samples for how to make things the Metabase way. + </p> + </div> + </div> + ); +}; + +const InternalLayout = ({ children }) => { + return ( + <div className="flex flex-column full-height"> + <nav className="wrapper flex align-center py3 border-bottom"> + <a className="text-brand-hover" href="/_internal"> + <h4>Style Guide</h4> + </a> + <ul className="flex ml-auto"> + {Object.keys(PAGES).map(name => ( + <li key={name}> + <a className="link mx2" href={"/_internal/" + name.toLowerCase()}> + {name} + </a> + </li> + ))} + </ul> + </nav> + <div className="flex flex-full">{children}</div> + </div> + ); +}; export default ( - <Route> - <IndexRoute component={ListApp} /> + <Route component={InternalLayout}> + <IndexRoute component={WelcomeApp} /> {Object.entries(PAGES).map(([name, Component]) => ( <Route path={name.toLowerCase()} component={Component} /> ))}