feat: Custom Menu Structure (#1605)
This commit is contained in:
parent
ba5e1497bf
commit
f8bbee22b7
@ -1,4 +1,14 @@
|
||||
export default {
|
||||
title: '@ohif/ui',
|
||||
menu: ['Getting Started', 'Readme', 'Components', 'Views'],
|
||||
menu: [
|
||||
'Getting Started',
|
||||
// COMPONENTS ARE DEFINED JUST TO CUSTOMIZE THEIR SORTING
|
||||
'General',
|
||||
'Form',
|
||||
'Navigation',
|
||||
// 'Feedback',
|
||||
// 'Other',
|
||||
'Data Display',
|
||||
],
|
||||
ignore: ['README.md'],
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Button
|
||||
menu: Components
|
||||
menu: General
|
||||
route: components/button
|
||||
---
|
||||
|
||||
@ -180,20 +180,10 @@ import { Button } from '@ohif/ui';
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="none"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
<Button variant="contained" rounded="none" color="white" className="m-1">
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="small"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
<Button variant="contained" rounded="small" color="white" className="m-1">
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button
|
||||
@ -204,20 +194,10 @@ import { Button } from '@ohif/ui';
|
||||
>
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="large"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
<Button variant="contained" rounded="large" color="white" className="m-1">
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="full"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
<Button variant="contained" rounded="full" color="white" className="m-1">
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
@ -344,7 +324,7 @@ import { IconButton } from '@ohif/ui';
|
||||
<IconButton className="m-2" variant="text">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined" >
|
||||
<IconButton className="m-2" variant="outlined">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
</div>
|
||||
@ -390,7 +370,7 @@ import { IconButton } from '@ohif/ui';
|
||||
<IconButton className="m-2">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined" >
|
||||
<IconButton className="m-2" variant="outlined">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="text">
|
||||
@ -433,7 +413,6 @@ import { IconButton } from '@ohif/ui';
|
||||
</div>
|
||||
</Playground>
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Button} />
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: ButtonGroup
|
||||
menu: Components
|
||||
menu: General
|
||||
route: components/buttonGroup
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Date Range
|
||||
menu: Components
|
||||
menu: Form
|
||||
route: components/date-range
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Empty Studies
|
||||
menu: Components
|
||||
menu: Data Display
|
||||
route: components/empty-studies
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Icon
|
||||
menu: Components
|
||||
menu: General
|
||||
route: components/icon
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Input
|
||||
menu: Components
|
||||
menu: Form
|
||||
route: components/input
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: InputDateRange
|
||||
menu: Components
|
||||
menu: Form
|
||||
route: components/InputDateRange
|
||||
---
|
||||
|
||||
@ -30,7 +30,7 @@ import { InputDateRange } from '@ohif/ui';
|
||||
<InputDateRange
|
||||
label="Dates"
|
||||
value={dates}
|
||||
onChange={dates => setDates(dates)}
|
||||
onChange={(dates) => setDates(dates)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: InputGroup
|
||||
menu: Components
|
||||
menu: Form
|
||||
route: components/InputGroup
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: InputMultiSelect
|
||||
menu: Components
|
||||
menu: Form
|
||||
route: components/InputMultiSelect
|
||||
---
|
||||
|
||||
@ -33,7 +33,7 @@ import { InputMultiSelect } from '@ohif/ui';
|
||||
{ value: 'SR', label: 'SR' },
|
||||
]}
|
||||
value={values}
|
||||
onChange={values => {
|
||||
onChange={(values) => {
|
||||
setValues(values);
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: InputText
|
||||
menu: Components
|
||||
menu: Form
|
||||
route: components/InputText
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Label
|
||||
menu: Components
|
||||
menu: Form
|
||||
route: components/label
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: NavBar
|
||||
menu: Components
|
||||
menu: Navigation
|
||||
route: components/navBar
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Select
|
||||
menu: Components
|
||||
menu: Form
|
||||
route: components/select
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Study List Pagination
|
||||
menu: Components
|
||||
menu: Navigation
|
||||
route: components/studyListPagination
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Study List Table
|
||||
menu: Components
|
||||
menu: Data Display
|
||||
route: components/studyListTable
|
||||
---
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Table
|
||||
menu: Components
|
||||
menu: Data Display
|
||||
route: components/table
|
||||
---
|
||||
|
||||
@ -36,7 +36,7 @@ import { Table, TableBody, TableCell, TableHead, TableRow } from '@ohif/ui';
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{new Array(25).fill('').map(row => (
|
||||
{new Array(25).fill('').map((row) => (
|
||||
<TableRow>
|
||||
<TableCell>Content 01</TableCell>
|
||||
<TableCell>Content 02</TableCell>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Typography
|
||||
menu: Components
|
||||
menu: General
|
||||
route: components/typography
|
||||
---
|
||||
|
||||
|
||||
@ -15,12 +15,13 @@ export const Layout = ({ children }) => {
|
||||
const nav = useRef();
|
||||
|
||||
const handleSidebarToggle = () => {
|
||||
setSidebarOpen(s => !s);
|
||||
setSidebarOpen((s) => !s);
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseLayout sx={{ '& > div': { flex: '1 1 auto' } }} data-testid="layout">
|
||||
<Main
|
||||
id="main-layout"
|
||||
sx={styles.main}
|
||||
className={classnames({
|
||||
'overflow-hidden h-screen lg:overflow-auto': sidebarOpen,
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
/** @jsx jsx */
|
||||
import { jsx } from 'theme-ui';
|
||||
import React from 'react';
|
||||
import { useCurrentDoc } from 'docz';
|
||||
|
||||
import * as styles from 'gatsby-theme-docz/src/components/NavGroup/styles';
|
||||
import { NavLink } from 'gatsby-theme-docz/src/components/NavLink';
|
||||
import { NavGroup as DoczNavGroup } from 'gatsby-theme-docz/src/components/NavGroup';
|
||||
import { ChevronDown } from 'gatsby-theme-docz/src/components/Icons';
|
||||
|
||||
export const NavGroup = ({ item, sidebarRef }) => {
|
||||
const currentDoc = useCurrentDoc();
|
||||
const currentDocRef = React.useRef();
|
||||
const { name, menu } = item;
|
||||
const [subheadingsVisible, setShowsubheadings] = React.useState(
|
||||
currentDoc.menu === name
|
||||
);
|
||||
const toggleSubheadings = () => setShowsubheadings(!subheadingsVisible);
|
||||
React.useEffect(() => {
|
||||
if (sidebarRef.current && currentDocRef.current) {
|
||||
sidebarRef.current.scrollTo(0, currentDocRef.current.offsetTop);
|
||||
}
|
||||
}, [sidebarRef]);
|
||||
return (
|
||||
<div sx={styles.wrapper} data-testid="nav-group">
|
||||
<div sx={styles.title} onClick={toggleSubheadings}>
|
||||
{item.name}
|
||||
<ChevronDown sx={styles.chevron({ active: subheadingsVisible })} />
|
||||
</div>
|
||||
<div sx={styles.sublinkWrapper} data-testid="nav-group-links">
|
||||
{menu &&
|
||||
subheadingsVisible &&
|
||||
menu.map((menu) => {
|
||||
if (currentDoc.route === menu.route) {
|
||||
return (
|
||||
<NavLink key={menu.id} item={menu} ref={currentDocRef}>
|
||||
{menu.name}
|
||||
</NavLink>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<NavLink key={menu.id} item={menu}>
|
||||
{menu.name}
|
||||
</NavLink>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -15,7 +15,7 @@ export const Sidebar = React.forwardRef((props, ref) => {
|
||||
const menus = useMenus({ query });
|
||||
const currentDoc = useCurrentDoc();
|
||||
const currentDocRef = useRef();
|
||||
const handleChange = ev => {
|
||||
const handleChange = (ev) => {
|
||||
setQuery(ev.target.value);
|
||||
};
|
||||
useEffect(() => {
|
||||
@ -24,6 +24,47 @@ export const Sidebar = React.forwardRef((props, ref) => {
|
||||
}
|
||||
}, [ref]);
|
||||
|
||||
const customMenus = {
|
||||
Components: [],
|
||||
System: [],
|
||||
Examples: [],
|
||||
};
|
||||
|
||||
const MENU_CATEGORIES = {
|
||||
Components: [
|
||||
'General',
|
||||
'Form',
|
||||
'Navigation',
|
||||
'Feedback',
|
||||
'Data Display',
|
||||
'Other',
|
||||
],
|
||||
Examples: ['Views'],
|
||||
System: ['Colors'],
|
||||
};
|
||||
|
||||
const renderMenuCategories = () => {
|
||||
return Object.keys(customMenus).map((menuName) => {
|
||||
return (
|
||||
<div key={menuName}>
|
||||
<h2 className="pl-2 border-l-8 -ml-4 border-secondary-active">
|
||||
{menuName}
|
||||
</h2>
|
||||
{customMenus[menuName].map((item) => item)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const getMenuCategory = (menuName) => {
|
||||
return Object.keys(MENU_CATEGORIES).find((category) => {
|
||||
if (MENU_CATEGORIES[category].includes(menuName)) {
|
||||
return category;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{props.sidebarOpen && (
|
||||
@ -56,11 +97,26 @@ export const Sidebar = React.forwardRef((props, ref) => {
|
||||
onChange={handleChange}
|
||||
/>
|
||||
{menus &&
|
||||
menus.map(menu => {
|
||||
if (!menu.route)
|
||||
menus.map((menu) => {
|
||||
const isGroup = !!menu.menu;
|
||||
const Component = isGroup ? NavGroup : NavLink;
|
||||
const menuCategory = getMenuCategory(menu.name) || null;
|
||||
|
||||
if (menuCategory) {
|
||||
customMenus[menuCategory].push(
|
||||
<Component key={menu.id} item={menu} sidebarRef={ref}>
|
||||
{!isGroup && menu.name}
|
||||
</Component>
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!menu.route) {
|
||||
return (
|
||||
<NavGroup key={menu.id} item={menu} sidebarRef={ref} />
|
||||
);
|
||||
}
|
||||
|
||||
if (menu.route === currentDoc.route) {
|
||||
return (
|
||||
<NavLink key={menu.id} item={menu} ref={currentDocRef}>
|
||||
@ -74,6 +130,7 @@ export const Sidebar = React.forwardRef((props, ref) => {
|
||||
</NavLink>
|
||||
);
|
||||
})}
|
||||
{renderMenuCategories()}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@ -4,6 +4,9 @@
|
||||
|
||||
[data-testid='live-preview'] {
|
||||
background: #000;
|
||||
}
|
||||
|
||||
#main-layout {
|
||||
@apply font-sans;
|
||||
}
|
||||
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Getting Started
|
||||
route: /
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
Design systems enable teams to build better products faster by making design reusable—reusability makes scale possible. This is the heart and primary value of design systems. A design system is a collection of reusable components, guided by clear standards, that can be assembled together to build any number of applications.
|
||||
|
||||
Regardless of the technologies and tools behind them, a successful design system follows these guiding principles:
|
||||
|
||||
- **It’s consistent**. The way components are built and managed follows a predictable pattern.
|
||||
- **It’s self-contained**. Your design system is treated as a standalone dependency.
|
||||
- **It’s reusable**. You’ve built components so they can be reused in many contexts.
|
||||
- **It’s accessible**. Applications built with your design system are usable by as many people as possible, no matter how they access the web.
|
||||
- **It’s robust**. No matter the product or platform to which your design system is applied, it should perform with grace and minimal bugs.
|
||||
|
||||
## Consistency
|
||||
|
||||
Your first, most important task when starting out is to define the rules of your system, document them, and ensure that everyone follows them. When you have clearly documented code standards and best practices in place, designers and developers from across your organization can easily use and, more importantly, contribute to your design system.
|
||||
47
platform/ui/src/pages/getting-started.mdx
Normal file
47
platform/ui/src/pages/getting-started.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
---
|
||||
name: Getting Started
|
||||
route: /
|
||||
---
|
||||
|
||||
import { Playground } from 'docz';
|
||||
import { Button } from '@ohif/ui';
|
||||
|
||||
# Getting Started
|
||||
|
||||
`@ohif/ui` is a collection of components and utilities that power OHIF's
|
||||
zero-footprint DICOM viewer.
|
||||
|
||||
It's maintained in a monorepo, in the
|
||||
[OHIF's repository](https://github.com/OHIF/Viewers/).
|
||||
|
||||
## Installation
|
||||
|
||||
Install `@ohif/ui` from your terminal:
|
||||
|
||||
```bash
|
||||
// with npm
|
||||
npm i @ohif/ui --save-exact
|
||||
|
||||
// with yarn
|
||||
yarn add @ohif/ui --exact
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
// Import and use components
|
||||
import { Button } from '@ohif/ui';
|
||||
```
|
||||
|
||||
<Playground className="p-8" style={{ padding: 8 }}>
|
||||
<div className="p-8">
|
||||
<Button onClick={() => alert('Hello!')}>Click here!</Button>
|
||||
</div>
|
||||
</Playground>
|
||||
|
||||
## Examples
|
||||
|
||||
In the **Examples** section you can check many examples on how to build your
|
||||
application using `@ohif/ui` components.
|
||||
|
||||
...
|
||||
@ -1,6 +1,5 @@
|
||||
---
|
||||
name: Colors
|
||||
menu: System
|
||||
route: system/colors
|
||||
---
|
||||
|
||||
@ -9,9 +8,9 @@ import BackgroundColor from './BackgroundColor';
|
||||
|
||||
# Color System
|
||||
|
||||
**@ohif/ui** offers a color system with a handful of color utility classes.
|
||||
`@ohif/ui` offers a color system with a handful of color utility classes.
|
||||
|
||||
As **@ohif/ui** uses Tailwind as a base styling library, you will be able to use
|
||||
As `@ohif/ui` uses Tailwind as a base styling library, you will be able to use
|
||||
all the default colors from Tailwind, besides our custom colors too.
|
||||
|
||||
# How to use
|
||||
|
||||
Loading…
Reference in New Issue
Block a user