wip on switching from docz to docusaurus
This commit is contained in:
1 parent
69e36106e3
commit
09469e6ac5
97 files changed
+1505
-7132
No files matched your search
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: AboutModal
|
||||
menu: General
|
||||
route: components/aboutModal
|
||||
---
|
||||
|
||||
import { AboutModal } from '@ohif/ui';
|
||||
|
||||
# AboutModal
|
||||
|
||||
AboutModal are used to show application version information.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { AboutModal } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<AboutModal />
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
@@ -0,0 +1,444 @@
|
||||
---
|
||||
name: Button
|
||||
menu: General
|
||||
route: components/button
|
||||
---
|
||||
|
||||
import { Button, IconButton, Icon } from '@ohif/ui';
|
||||
|
||||
# Button
|
||||
|
||||
Buttons are used to execute actions when users interacts with them.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Button } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Outlined Buttons
|
||||
|
||||
````jsx live
|
||||
<div className="p-4">
|
||||
<Button variant="outlined" className="m-1">
|
||||
Default
|
||||
</Button>
|
||||
<Button variant="outlined" color="primary" className="m-1">
|
||||
Primary
|
||||
</Button>
|
||||
<Button variant="outlined" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button variant="outlined" color="white" className="m-1">
|
||||
White
|
||||
</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Contained Buttons
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Button variant="contained" className="m-1">
|
||||
Default
|
||||
</Button>
|
||||
<Button variant="contained" color="primary" className="m-1">
|
||||
Primary
|
||||
</Button>
|
||||
<Button variant="contained" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button variant="contained" color="white" className="m-1">
|
||||
White
|
||||
</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Text Buttons
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Button variant="text" className="m-1">
|
||||
Default
|
||||
</Button>
|
||||
<Button variant="text" color="primary" className="m-1">
|
||||
Primary
|
||||
</Button>
|
||||
<Button variant="text" color="secondary" className="m-1">
|
||||
Secondary
|
||||
</Button>
|
||||
<Button variant="text" color="white" className="m-1">
|
||||
White
|
||||
</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Rounded Buttons
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<div className="mb-2">
|
||||
<Button variant="contained" rounded="none" className="m-1">
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="small" className="m-1">
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="medium" className="m-1">
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="large" className="m-1">
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="full" className="m-1">
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="none"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="small"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="medium"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="large"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="full"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="none"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="small"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="medium"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="large"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="full"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<Button variant="contained" rounded="none" color="white" className="m-1">
|
||||
Non Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="small" color="white" className="m-1">
|
||||
Small Rounded
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
rounded="medium"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Medium Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="large" color="white" className="m-1">
|
||||
Large Rounded
|
||||
</Button>
|
||||
<Button variant="contained" rounded="full" color="white" className="m-1">
|
||||
Full Rounded
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Sizes
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<div>
|
||||
<Button variant="contained" size="small" className="m-1">
|
||||
Small
|
||||
</Button>
|
||||
<Button variant="contained" size="medium" className="m-1">
|
||||
Medium
|
||||
</Button>
|
||||
<Button variant="contained" size="large" className="m-1">
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="small"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Small
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="medium"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="large"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
>
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="small"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Small
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="medium"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Medium
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="large"
|
||||
color="secondary"
|
||||
className="m-1"
|
||||
>
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="small"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Small
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="medium"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Medium
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="large"
|
||||
color="white"
|
||||
className="m-1"
|
||||
>
|
||||
Large
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
## Buttons with icons
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex">
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
startIcon={<Icon name="settings" />}
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className="m-1"
|
||||
endIcon={<Icon name="settings" />}
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
rounded="full"
|
||||
color="default"
|
||||
className="m-1"
|
||||
endIcon={<Icon name="settings" />}
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Icon Buttons
|
||||
|
||||
Icon buttons are generally used in toolbars.
|
||||
|
||||
```javascript
|
||||
import { IconButton } from '@ohif/ui';
|
||||
````
|
||||
|
||||
````jsx live
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<div className="">
|
||||
<IconButton className="m-2">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="text">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="primary">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="primary" variant="text">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="primary" variant="outlined">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="secondary">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="secondary" variant="text">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="secondary" variant="outlined">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="white">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="text" color="white">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined" color="white">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<div className="">
|
||||
<IconButton className="m-2">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="text">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="primary">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="primary" variant="text">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="primary" variant="outlined">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="secondary">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="secondary" variant="text">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" color="secondary" variant="outlined">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div>
|
||||
<IconButton className="m-2" color="white">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="text" color="white">
|
||||
<Icon name="launch-arrow" />
|
||||
</IconButton>
|
||||
<IconButton className="m-2" variant="outlined" color="white">
|
||||
<Icon name="cancel" />
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Button} />
|
||||
````
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
name: ButtonGroup
|
||||
menu: General
|
||||
route: components/buttonGroup
|
||||
---
|
||||
|
||||
import { ButtonGroup, Button, IconButton, Icon } from '@ohif/ui';
|
||||
|
||||
# ButtonGroup
|
||||
|
||||
Group Button display buttons together sharing its configurations
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ButtonGroup } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic button group
|
||||
|
||||
````jsx live
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<ButtonGroup color="primary" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Tree</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup color="primary" variant="contained" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Tree</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup color="primary" variant="text" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Tree</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Group sizes and colorss
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<ButtonGroup color="default" size="small" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Tree</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup color="primary" size="medium" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Tree</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup color="secondary" size="large" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Tree</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Group orientation
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex flex-row justify-center">
|
||||
<ButtonGroup orientation="vertical" color="primary" className="m-2">
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Tree</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup
|
||||
orientation="vertical"
|
||||
color="primary"
|
||||
variant="contained"
|
||||
className="m-2"
|
||||
>
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Tree</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup
|
||||
orientation="vertical"
|
||||
color="primary"
|
||||
variant="text"
|
||||
className="m-2"
|
||||
>
|
||||
<Button>One</Button>
|
||||
<Button>Two</Button>
|
||||
<Button>Tree</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Split Button
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<ButtonGroup color="primary" className="m-2">
|
||||
<Button>Options</Button>
|
||||
<IconButton className="mr-2">
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ButtonGroup} />
|
||||
````
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
name: CinePlayer
|
||||
menu: General
|
||||
route: components/CinePlayer
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { CinePlayer } from '@ohif/ui';
|
||||
|
||||
# Input Text
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { CinePlayer } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
return (
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<CinePlayer
|
||||
cineMinFrameRate={1}
|
||||
cineMaxFrameRate={90}
|
||||
cineStepFrameRate={1}
|
||||
cineFrameRate={24}
|
||||
isPlaying={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={CinePlayer} />
|
||||
```
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: Context Menu
|
||||
menu: General
|
||||
route: components/contextMenu
|
||||
---
|
||||
|
||||
import { ContextMenu } from '@ohif/ui';
|
||||
|
||||
# Context Menu
|
||||
|
||||
...
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ContextMenu } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const items = [
|
||||
{
|
||||
label: 'Delete measurement',
|
||||
actionType: 'Delete',
|
||||
action: () => alert('Delete'),
|
||||
},
|
||||
{
|
||||
label: 'Relabel',
|
||||
actionType: 'setLabel',
|
||||
action: () => alert('Relabel'),
|
||||
},
|
||||
{
|
||||
label: 'Add Description',
|
||||
actionType: 'setDescription',
|
||||
action: () => alert('Add Description'),
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div className="p-4">
|
||||
<ContextMenu items={items} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ContextMenu} />
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: Date Range
|
||||
menu: Form
|
||||
route: components/date-range
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { DateRange } from '@ohif/ui';
|
||||
|
||||
# Date Range
|
||||
|
||||
Date Range is used to select a range of dates.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { DateRange } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Date Range
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const [dates, setDates] = useState({
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
return (
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<DateRange
|
||||
startDate={dates.startDate}
|
||||
endDate={dates.endDate}
|
||||
onChange={({ startDate, endDate }) =>
|
||||
setDates({ startDate, endDate })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={DateRange} />
|
||||
```
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
name: Dropdown
|
||||
menu: General
|
||||
route: components/dropdown
|
||||
---
|
||||
|
||||
import { Dropdown, IconButton, Icon } from '@ohif/ui';
|
||||
|
||||
# Dropdown
|
||||
|
||||
This component is used when there are more than a few options to choose from. By
|
||||
hovering or clicking on the trigger, a dropdown menu will appear, which allows
|
||||
you to choose an option and execute the relevant action.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Dropdown } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const handleClick = () => {
|
||||
alert('Clicked');
|
||||
};
|
||||
return (
|
||||
<div className="py-4">
|
||||
<Dropdown
|
||||
showDropdownIcon={false}
|
||||
list={[
|
||||
{
|
||||
title: 'Option 1',
|
||||
icon: 'info',
|
||||
onClick: handleClick,
|
||||
},
|
||||
{
|
||||
title: 'Option 2',
|
||||
icon: 'settings',
|
||||
onClick: handleClick,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
className="text-primary-active"
|
||||
>
|
||||
<Icon name="settings" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
className="text-primary-active"
|
||||
>
|
||||
<Icon name="chevron-down" />
|
||||
</IconButton>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Dropdown} />
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: Empty Studies
|
||||
menu: Data Display
|
||||
route: components/empty-studies
|
||||
---
|
||||
|
||||
import { EmptyStudies } from '@ohif/ui';
|
||||
|
||||
# Empty Studies
|
||||
|
||||
This component can be used to display a message when there are no studies.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { EmptyStudies } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<EmptyStudies />
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={EmptyStudies} />
|
||||
```
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
name: Error Boundary
|
||||
menu: Data Display
|
||||
route: components/errorBoundary
|
||||
---
|
||||
|
||||
import { ErrorBoundary } from '@ohif/ui';
|
||||
|
||||
# Error Boundary
|
||||
|
||||
This component can be used to display a message or handle unhandled errors.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ErrorBoundary } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
````jsx live
|
||||
<div className="p-4">
|
||||
<ErrorBoundary context="Somewhere">
|
||||
{() => {
|
||||
throw new Error('Error!');
|
||||
return <p></p>;
|
||||
}}
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Custom error fallback
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
const CustomFallback = ({ error, componentStack, resetErrorBoundary }) => {
|
||||
return (
|
||||
<div>
|
||||
<p>This is a custom fallback!</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="p-4">
|
||||
<ErrorBoundary context="Somewhere" fallbackComponent={CustomFallback}>
|
||||
{() => {
|
||||
throw new Error('Error!');
|
||||
return <p></p>;
|
||||
}}
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ErrorBoundary} />
|
||||
````
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
name: Expandable Toolbar Button
|
||||
menu: General
|
||||
route: components/expandableToolbarButton
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { ExpandableToolbarButton, ListMenu } from '@ohif/ui';
|
||||
|
||||
# Toolbar Button
|
||||
|
||||
Expandable Toolbar Buttons are used to populate the Toolbar.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ExpandableToolbarButton, ListMenu } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const props = {
|
||||
content: ListMenu,
|
||||
contentProps: {
|
||||
options: [
|
||||
{
|
||||
value: 'windowLevelPreset1',
|
||||
title: 'Soft tissue',
|
||||
subtitle: '400 / 40',
|
||||
},
|
||||
{
|
||||
value: 'windowLevelPreset2',
|
||||
title: 'Lung',
|
||||
subtitle: '1500 / -600',
|
||||
},
|
||||
{ value: 'windowLevelPreset3', title: 'Liver', subtitle: '150 / 90' },
|
||||
{ value: 'windowLevelPreset4', title: 'Bone', subtitle: '80 / 40' },
|
||||
{
|
||||
value: 'windowLevelPreset5',
|
||||
title: 'Brain',
|
||||
subtitle: '2500 / 480',
|
||||
},
|
||||
],
|
||||
renderer: ({ title, subtitle, isActive, index }) => (
|
||||
<>
|
||||
<div>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-white',
|
||||
'mr-2 text-base'
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-aqua-pale',
|
||||
'font-thin text-sm'
|
||||
)}
|
||||
>
|
||||
{subtitle}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-primary-active',
|
||||
'text-sm'
|
||||
)}
|
||||
>
|
||||
{index + 1}
|
||||
</span>
|
||||
</>
|
||||
),
|
||||
},
|
||||
};
|
||||
return (
|
||||
<div className="py-10 flex justify-center">
|
||||
<ExpandableToolbarButton {...props} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ExpandableToolbarButton} />
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: Input
|
||||
menu: Form
|
||||
route: components/input
|
||||
---
|
||||
|
||||
import { Input } from '@ohif/ui';
|
||||
|
||||
# Input
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Input } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const [inputValue, setInputValue] = React.useState('');
|
||||
return (
|
||||
<div className="p-4">
|
||||
<Input
|
||||
transparent
|
||||
containerClassName="mb-3"
|
||||
label="Label"
|
||||
placeholder="With Label"
|
||||
/>
|
||||
<Input placeholder="Without label" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Input} />
|
||||
```
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: InputDateRange
|
||||
menu: Form
|
||||
route: components/InputDateRange
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { InputDateRange } from '@ohif/ui';
|
||||
|
||||
# Input Date Range
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { InputDateRange } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const [dates, setDates] = useState({
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
return (
|
||||
<div className="p-4 flex flex-col items-center">
|
||||
<div className="w-56">
|
||||
<InputDateRange
|
||||
label="Dates"
|
||||
value={dates}
|
||||
onChange={dates => setDates(dates)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={InputDateRange} />
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
name: InputGroup
|
||||
menu: Form
|
||||
route: components/InputGroup
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { InputGroup } from '@ohif/ui';
|
||||
|
||||
# Input Group
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { InputGroup } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const [filterValues, setFilterValues] = useState({
|
||||
patient: '',
|
||||
studyDate: {
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
modality: [],
|
||||
});
|
||||
const [filterSorting, setFilterSorting] = useState({
|
||||
sortBy: '',
|
||||
sortDirection: 'none',
|
||||
});
|
||||
const filtersMeta = [
|
||||
{
|
||||
name: 'patient',
|
||||
displayName: 'Patient Name',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 6,
|
||||
},
|
||||
{
|
||||
name: 'studyDate',
|
||||
displayName: 'Study date',
|
||||
inputType: 'DateRange',
|
||||
isSortable: true,
|
||||
gridCol: 6,
|
||||
},
|
||||
{
|
||||
name: 'modality',
|
||||
displayName: 'Modality',
|
||||
inputType: 'MultiSelect',
|
||||
inputProps: {
|
||||
options: [
|
||||
{ value: 'SEG', label: 'SEG' },
|
||||
{ value: 'CT', label: 'CT' },
|
||||
{ value: 'MR', label: 'MR' },
|
||||
{ value: 'SR', label: 'SR' },
|
||||
],
|
||||
},
|
||||
isSortable: true,
|
||||
gridCol: 6,
|
||||
},
|
||||
{
|
||||
name: 'numberOfInstance',
|
||||
displayName: 'Number of Instances',
|
||||
inputType: 'None',
|
||||
isSortable: true,
|
||||
gridCol: 6,
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div className="py-4">
|
||||
<InputGroup
|
||||
inputMeta={filtersMeta}
|
||||
values={filterValues}
|
||||
onValuesChange={setFilterValues}
|
||||
sorting={filterSorting}
|
||||
onSortingChange={setFilterSorting}
|
||||
isSortingEnable={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={InputGroup} />
|
||||
```
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: InputMultiSelect
|
||||
menu: Form
|
||||
route: components/InputMultiSelect
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { InputMultiSelect } from '@ohif/ui';
|
||||
|
||||
# Input Multi Select
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { InputMultiSelect } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const [values, setValues] = useState([]);
|
||||
return (
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<InputMultiSelect
|
||||
label="Modality"
|
||||
options={[
|
||||
{ value: 'SEG', label: 'SEG' },
|
||||
{ value: 'CT', label: 'CT' },
|
||||
{ value: 'MR', label: 'MR' },
|
||||
{ value: 'SR', label: 'SR' },
|
||||
]}
|
||||
value={values}
|
||||
onChange={values => {
|
||||
setValues(values);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={InputMultiSelect} />
|
||||
```
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
name: InputText
|
||||
menu: Form
|
||||
route: components/InputText
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { InputText } from '@ohif/ui';
|
||||
|
||||
# Input Text
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { InputText } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const [text, setText] = useState('');
|
||||
return (
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<InputText
|
||||
label="Name"
|
||||
value={text}
|
||||
onChange={value => {
|
||||
setText(value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={InputText} />
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: Label
|
||||
menu: Form
|
||||
route: components/label
|
||||
---
|
||||
|
||||
import { Label } from '@ohif/ui';
|
||||
|
||||
# Label
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Label } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
return (
|
||||
<div className="p-4">
|
||||
<Label text="Label" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Label} />
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
name: List Menu
|
||||
menu: General
|
||||
route: components/listMenu
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { ListMenu, ToolbarButton } from '@ohif/ui';
|
||||
|
||||
# List Menu
|
||||
|
||||
List Menus are used to populate expandable Toolbar.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ListMenu, ToolbarButton } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
return (
|
||||
<ToolbarButton
|
||||
items={[
|
||||
{
|
||||
value: 'windowLevelPreset1',
|
||||
title: 'Soft tissue',
|
||||
subtitle: '400 / 40',
|
||||
},
|
||||
{
|
||||
value: 'windowLevelPreset2',
|
||||
title: 'Lung',
|
||||
subtitle: '1500 / -600',
|
||||
},
|
||||
{ value: 'windowLevelPreset3', title: 'Liver', subtitle: '150 / 90' },
|
||||
{ value: 'windowLevelPreset4', title: 'Bone', subtitle: '80 / 40' },
|
||||
{
|
||||
value: 'windowLevelPreset5',
|
||||
title: 'Brain',
|
||||
subtitle: '2500 / 480',
|
||||
},
|
||||
]}
|
||||
renderer={({ title, subtitle, isActive, index }) => (
|
||||
<>
|
||||
<div>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-white',
|
||||
'mr-2 text-base'
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</span>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-aqua-pale',
|
||||
'font-thin text-sm'
|
||||
)}
|
||||
>
|
||||
{subtitle}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
className={classnames(
|
||||
isActive ? 'text-black' : 'text-primary-active',
|
||||
'text-sm'
|
||||
)}
|
||||
>
|
||||
{index + 1}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ListMenu} />
|
||||
```
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
name: Measurement Table
|
||||
menu: Data Display
|
||||
route: components/measurementTable
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { MeasurementTable } from '@ohif/ui';
|
||||
|
||||
# Measurement Table
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { MeasurementTable } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
````jsx live
|
||||
{() => {
|
||||
const [activeMeasurementItem, setActiveMeasurementItem] = useState(null);
|
||||
const measurementTableData = {
|
||||
title: 'Measurements',
|
||||
amount: 10,
|
||||
data: new Array(10).fill({}).map((el, i) => ({
|
||||
id: i + 1,
|
||||
label: 'Label short description',
|
||||
displayText: ['24.0 x 24.0 mm (S:4, I:22)'],
|
||||
isActive: activeMeasurementItem === i + 1,
|
||||
})),
|
||||
onClick: id => setActiveMeasurementItem(s => (s === id ? null : id)),
|
||||
onEdit: id => alert(`Edit: ${id}`),
|
||||
};
|
||||
return (
|
||||
<div className="p-4 w-80">
|
||||
<MeasurementTable {...measurementTableData} />
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Empty Data
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
return (
|
||||
<div className="p-4 w-80">
|
||||
<MeasurementTable title="Measurements" />
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={MeasurementTable} />
|
||||
````
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
name: NavBar
|
||||
menu: Navigation
|
||||
route: components/navBar
|
||||
---
|
||||
|
||||
import { NavBar, Typography } from '@ohif/ui';
|
||||
|
||||
# NavBar
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { NavBar } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<NavBar className="justify-center">
|
||||
<Typography variant="h3" className="m-2">
|
||||
Header content
|
||||
</Typography>
|
||||
</NavBar>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={NavBar} />
|
||||
```
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
name: Notification
|
||||
menu: Feedback
|
||||
route: components/notification
|
||||
---
|
||||
|
||||
import { Notification } from '@ohif/ui';
|
||||
|
||||
# Notification
|
||||
|
||||
A notification displays a short message in a way that attracts the user's
|
||||
attention without interrupting the user's task.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Notification } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
return (
|
||||
<div className="p-4 w-full lg:w-2/3">
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
window.alert(value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Notification} />
|
||||
```
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: Segmentation Table
|
||||
menu: Data Display
|
||||
route: components/segmentationTable
|
||||
---
|
||||
|
||||
import { SegmentationTable } from '@ohif/ui';
|
||||
|
||||
# Segmentation Table
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { SegmentationTable } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const tableData = {
|
||||
title: 'Segments',
|
||||
amount: 12,
|
||||
data: new Array(12).fill(''),
|
||||
};
|
||||
return (
|
||||
<div className="p-4 w-80">
|
||||
<SegmentationTable {...tableData} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={SegmentationTable} />
|
||||
```
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
name: Select
|
||||
menu: Form
|
||||
route: components/select
|
||||
---
|
||||
|
||||
import { Select } from '@ohif/ui';
|
||||
|
||||
# Select
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Select } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
````jsx live
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<Select
|
||||
options={[
|
||||
{ value: 'ONE', label: 'ONE' },
|
||||
{ value: 'TWO', label: 'TWO' },
|
||||
{ value: 'THREE', label: 'THREE' },
|
||||
{ value: 'FOUR', label: 'FOUR' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Disabled
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<Select
|
||||
isDisabled
|
||||
options={[
|
||||
{ value: 'ONE', label: 'ONE' },
|
||||
{ value: 'TWO', label: 'TWO' },
|
||||
{ value: 'THREE', label: 'THREE' },
|
||||
{ value: 'FOUR', label: 'FOUR' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## No Options
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-col flex-1 p-4 items-center">
|
||||
<div className="w-56">
|
||||
<Select
|
||||
noOptionsMessage={() => {
|
||||
'No Options';
|
||||
}}
|
||||
options={[]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Select} />
|
||||
````
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
name: SidePanel
|
||||
menu: General
|
||||
route: components/sidePanel
|
||||
---
|
||||
|
||||
import { SidePanel } from '@ohif/ui';
|
||||
|
||||
# SidePanel
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { SidePanel } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
````jsx live
|
||||
<div
|
||||
className="flex flex-row flex-no-wrap flex-1 items-stretch overflow-hidden w-full"
|
||||
style={{ height: '500px' }}
|
||||
>
|
||||
<SidePanel
|
||||
side="left"
|
||||
childComponents={{
|
||||
iconName: "group-layers",
|
||||
iconLabel: "Studies",
|
||||
name: "studies",
|
||||
label: "Studies",
|
||||
content: <div className="flex justify-center text-white p-2">panel content</div>,
|
||||
}}
|
||||
/>
|
||||
<div className="flex flex-1 h-100 overflow-hidden bg-primary-main items-center justify-center text-white">
|
||||
CONTENT
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
## Multiple panels
|
||||
|
||||
```jsx live
|
||||
<div
|
||||
className="flex flex-row flex-no-wrap flex-1 items-stretch overflow-hidden w-full"
|
||||
style={{ height: '500px' }}
|
||||
>
|
||||
<SidePanel
|
||||
side="left"
|
||||
childComponents={[{
|
||||
iconName: "group-layers",
|
||||
iconLabel: "Studies",
|
||||
name: "studies",
|
||||
label: "Studies",
|
||||
content: <div className="flex justify-center text-white p-2">studies panel content</div>,
|
||||
},
|
||||
{
|
||||
iconName: "list-bullets",
|
||||
iconLabel: "Measure",
|
||||
name: "measurements",
|
||||
label: "Measurements",
|
||||
content: <div className="flex justify-center text-white p-2">measure panel content</div>,
|
||||
}]}
|
||||
/>
|
||||
<div className="flex flex-1 h-100 overflow-hidden bg-primary-main items-center justify-center text-white">
|
||||
CONTENT
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={SidePanel} />
|
||||
````
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
name: Split Button
|
||||
menu: General
|
||||
route: components/splitButton
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { SplitButton, WindowLevelMenuItem } from '@ohif/ui';
|
||||
|
||||
# Split Button
|
||||
|
||||
Split Buttons are used to populate the Toolbar.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { SplitButton, WindowLevelMenuItem } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const mockedProps = {
|
||||
bState: {
|
||||
primaryToolId: 'WWWC',
|
||||
toggles: {},
|
||||
},
|
||||
primary: {
|
||||
tooltip: 'W/L',
|
||||
type: 'tool',
|
||||
icon: 'tool-window-level',
|
||||
onClick: args => console.debug('Primary click!', args),
|
||||
},
|
||||
secondary: {
|
||||
icon: 'chevron-down',
|
||||
label: '',
|
||||
isActive: true,
|
||||
tooltip: 'More Measure Tools',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
id: '1',
|
||||
icon: 'tool-layout',
|
||||
label: 'Layout',
|
||||
onClick: args => console.debug('Item click!', args),
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
icon: 'tool-window-level',
|
||||
label: 'W/L',
|
||||
onClick: args => console.debug('Item click!', args),
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
icon: 'tool-length',
|
||||
label: 'Length',
|
||||
onClick: args => console.debug('Item click!', args),
|
||||
},
|
||||
],
|
||||
onClick: args => console.debug('Any click!', args),
|
||||
};
|
||||
return (
|
||||
<div className="mb-2">
|
||||
<div className="flex flex-row w-full justify-center items-center bg-secondary-dark">
|
||||
<SplitButton {...mockedProps} isRadio />
|
||||
<SplitButton
|
||||
{...mockedProps}
|
||||
isAction
|
||||
renderer={WindowLevelMenuItem}
|
||||
items={[
|
||||
{ id: '1', value: 1, title: 'Soft tissue', subtitle: '400 / 40' },
|
||||
{ id: '2', value: 2, title: 'Lung', subtitle: '1500 / -600' },
|
||||
{ id: '3', value: 3, title: 'Liver', subtitle: '150 / 90' },
|
||||
{ id: '4', value: 4, title: 'Bone', subtitle: '80 / 40' },
|
||||
{ id: '5', value: 5, title: 'Brain', subtitle: '2500 / 480' },
|
||||
]}
|
||||
/>
|
||||
<SplitButton {...mockedProps} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={SplitButton} />
|
||||
```
|
||||
@@ -0,0 +1,113 @@
|
||||
---
|
||||
name: StudyBrowser
|
||||
menu: General
|
||||
route: components/studyBrowser
|
||||
---
|
||||
|
||||
import { StudyBrowser } from '@ohif/ui';
|
||||
|
||||
# StudyBrowser
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyBrowser } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const studyWithSR = {
|
||||
studyInstanceUid: '1',
|
||||
date: '07-Sept-2010',
|
||||
description: 'CHEST/ABD/PELVIS W/CONTRAST',
|
||||
numInstances: 902,
|
||||
modalities: 'CT,SR',
|
||||
displaySets: [
|
||||
{
|
||||
displaySetInstanceUID: 'f69f6asdasd48c-223e-db7f-c4af-b8906641a66e',
|
||||
description: 'Multiple line image series description lorem sit',
|
||||
seriesNumber: 1,
|
||||
numInstances: 68,
|
||||
componentType: 'thumbnailTracked',
|
||||
viewportIdentificator: 'A',
|
||||
isTracked: true,
|
||||
},
|
||||
{
|
||||
displaySetInstanceUID: 'f69f648c-223e-db7f-c4asdasdaf-b8906641a66e',
|
||||
description: 'Multiple line image series description lorem sit',
|
||||
seriesNumber: 1,
|
||||
numInstances: 68,
|
||||
componentType: 'thumbnailTracked',
|
||||
viewportIdentificator: 'B',
|
||||
},
|
||||
{
|
||||
displaySetInstanceUID: 'f69f648c-223e-dasdasdb7f-c4af-b8906641a66e',
|
||||
description: 'Multiple line image series description lorem sit',
|
||||
seriesNumber: 1,
|
||||
numInstances: 68,
|
||||
componentType: 'thumbnailTracked',
|
||||
},
|
||||
{
|
||||
displaySetInstanceUID: 'f69f648c-223e-db7f-c4afas-b8906asd641a66e',
|
||||
description: 'Multiple line description lorem ipsum dolor sit amet',
|
||||
modality: 'SR',
|
||||
componentType: 'thumbnailNoImage',
|
||||
seriesDate: '07-Sept-2010',
|
||||
},
|
||||
],
|
||||
};
|
||||
const studySimple = {
|
||||
studyInstanceUid: '2',
|
||||
date: '07-Sept-2010',
|
||||
description: 'CHEST/ABD/PELVIS W/CONTRAST',
|
||||
numInstances: 902,
|
||||
modalities: 'CT',
|
||||
displaySets: [
|
||||
{
|
||||
displaySetInstanceUID: 'f69f648c-223e-db7f-c4af-b8906641a66e',
|
||||
description: 'Multiple line image series description lorem sit',
|
||||
seriesNumber: 1,
|
||||
numInstances: 68,
|
||||
componentType: 'thumbnailTracked',
|
||||
},
|
||||
],
|
||||
};
|
||||
const tabs = [
|
||||
{
|
||||
name: 'primary',
|
||||
label: 'Primary',
|
||||
studies: [studySimple],
|
||||
},
|
||||
{
|
||||
name: 'recent',
|
||||
label: 'Recent',
|
||||
studies: [studyWithSR, studySimple],
|
||||
},
|
||||
{
|
||||
name: 'all',
|
||||
label: 'All',
|
||||
studies: [studySimple, studyWithSR],
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div className="flex flex-1" style={{ height: '400px' }}>
|
||||
<div className="overflow-hidden w-64">
|
||||
<StudyBrowser
|
||||
tabs={tabs}
|
||||
activeTabName="primary"
|
||||
expandedStudyInstanceUIDs={[]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={StudyBrowser} />
|
||||
```
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
name: StudyItem
|
||||
menu: General
|
||||
route: components/studyItem
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { StudyItem } from '@ohif/ui';
|
||||
|
||||
# StudyItem
|
||||
|
||||
Used to expose study information as a card
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyItem } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const [studyActive, setStudyActive] = useState(null);
|
||||
return (
|
||||
<div className="flex flex-1 items-center justify-center p-4">
|
||||
<div className="w-56">
|
||||
<StudyItem
|
||||
studyInstanceUid="1"
|
||||
date="07-Sept-2010"
|
||||
description="CHEST/ABD/PELVIS W/CONTRAST"
|
||||
numInstances={902}
|
||||
modalities="CT,SR"
|
||||
isActive={studyActive}
|
||||
onClick={() => setStudyActive(studyActive === '1' ? null : '1')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={StudyItem} />
|
||||
```
|
||||
@@ -0,0 +1,124 @@
|
||||
---
|
||||
name: Study List Filter
|
||||
menu: Data Display
|
||||
route: components/studyListFilter
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { StudyListFilter, Modal } from '@ohif/ui';
|
||||
import { ModalProvider } from '@ohif/ui';
|
||||
|
||||
# Study List Filter
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyListFilter, ModalProvider, Modal } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const defaultFilterValues = {
|
||||
patientName: '',
|
||||
mrn: '',
|
||||
studyDate: {
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
description: '',
|
||||
modality: undefined,
|
||||
accession: '',
|
||||
sortBy: '',
|
||||
sortDirection: 'none',
|
||||
page: 0,
|
||||
resultsPerPage: 25,
|
||||
};
|
||||
const [filterValues, setFilterValues] = useState(defaultFilterValues);
|
||||
const filtersMeta = [
|
||||
{
|
||||
name: 'patientName',
|
||||
displayName: 'Patient Name',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'mrn',
|
||||
displayName: 'MRN',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 2,
|
||||
},
|
||||
{
|
||||
name: 'studyDate',
|
||||
displayName: 'Study date',
|
||||
inputType: 'DateRange',
|
||||
isSortable: true,
|
||||
gridCol: 5,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
displayName: 'Description',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'modality',
|
||||
displayName: 'Modality',
|
||||
inputType: 'MultiSelect',
|
||||
inputProps: {
|
||||
options: [
|
||||
{ value: 'SEG', label: 'SEG' },
|
||||
{ value: 'CT', label: 'CT' },
|
||||
{ value: 'MR', label: 'MR' },
|
||||
{ value: 'SR', label: 'SR' },
|
||||
],
|
||||
},
|
||||
isSortable: true,
|
||||
gridCol: 3,
|
||||
},
|
||||
{
|
||||
name: 'accession',
|
||||
displayName: 'Accession',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'instances',
|
||||
displayName: 'Instances',
|
||||
inputType: 'None',
|
||||
isSortable: true,
|
||||
gridCol: 2,
|
||||
},
|
||||
];
|
||||
const isFiltering = (filterValues, defaultFilterValues) => {
|
||||
return Object.keys(defaultFilterValues).some(name => {
|
||||
return filterValues[name] !== defaultFilterValues[name];
|
||||
});
|
||||
};
|
||||
return (
|
||||
<ModalProvider modal={Modal}>
|
||||
<StudyListFilter
|
||||
numOfStudies={100}
|
||||
filtersMeta={filtersMeta}
|
||||
filterValues={filterValues}
|
||||
onChange={setFilterValues}
|
||||
clearFilters={() => setFilterValues(defaultFilterValues)}
|
||||
isFiltering={isFiltering(filterValues, defaultFilterValues)}
|
||||
/>
|
||||
</ModalProvider>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={StudyListFilter} />
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: Study List Pagination
|
||||
menu: Navigation
|
||||
route: components/studyListPagination
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { StudyListPagination } from '@ohif/ui';
|
||||
|
||||
# StudyListPagination
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyListPagination } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [perPage, setPerPage] = useState(25);
|
||||
const onChangePage = page => {
|
||||
setCurrentPage(page);
|
||||
};
|
||||
const onChangePerPage = perPage => {
|
||||
setPerPage(perPage);
|
||||
setCurrentPage(1);
|
||||
};
|
||||
return (
|
||||
<StudyListPagination
|
||||
onChangePage={onChangePage}
|
||||
onChangePerPage={onChangePerPage}
|
||||
currentPage={currentPage}
|
||||
perPage={perPage}
|
||||
/>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={StudyListPagination} />
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
name: Study List Table
|
||||
menu: Data Display
|
||||
route: components/studyListTable
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { StudyListTable } from '@ohif/ui';
|
||||
|
||||
# StudyListTable
|
||||
|
||||
This component is used to display a studies list.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { StudyListTable } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
const studies = new Array(10).fill('');
|
||||
const [expandedRows, setExpandedRows] = useState([]);
|
||||
const tableDataSource = studies.map((study, key) => {
|
||||
const rowKey = key + 1;
|
||||
const isExpanded = expandedRows.some(k => k === rowKey);
|
||||
return {
|
||||
row: [
|
||||
{ key: 'Cell 01', content: 'Cell 01', gridCol: 2 },
|
||||
{ key: 'Cell 02', content: 'Cell 02', gridCol: 4 },
|
||||
{ key: 'Cell 03', content: 'Cell 03', gridCol: 4 },
|
||||
{ key: 'Cell 04', content: 'Cell 04', gridCol: 4 },
|
||||
],
|
||||
expandedContent: (
|
||||
<td className="w-full p-8">
|
||||
Custom expanded content for row {rowKey}
|
||||
</td>
|
||||
),
|
||||
onClickRow: () =>
|
||||
setExpandedRows(rows =>
|
||||
isExpanded ? rows.filter(n => rowKey !== n) : [...rows, rowKey]
|
||||
),
|
||||
isExpanded,
|
||||
};
|
||||
});
|
||||
return (
|
||||
<div className="py-4">
|
||||
<StudyListTable
|
||||
tableDataSource={tableDataSource}
|
||||
numOfStudies={studies.length}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={StudyListTable} />
|
||||
```
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
name: Table
|
||||
menu: Data Display
|
||||
route: components/table
|
||||
---
|
||||
|
||||
import { Table, TableHead, TableBody, TableRow, TableCell } from '@ohif/ui';
|
||||
|
||||
# Table
|
||||
|
||||
Tables display sets of data.
|
||||
|
||||
_The Table component and its components in the tree are built using divs._
|
||||
|
||||
## Import
|
||||
|
||||
Check the given example below to see how to import each component to create a
|
||||
table.
|
||||
|
||||
```javascript
|
||||
import { Table, TableBody, TableCell, TableHead, TableRow } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Item 01</TableCell>
|
||||
<TableCell>Item 02</TableCell>
|
||||
<TableCell>Item 03</TableCell>
|
||||
<TableCell>Item 04</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{new Array(25).fill('').map(row => (
|
||||
<TableRow>
|
||||
<TableCell>Content 01</TableCell>
|
||||
<TableCell>Content 02</TableCell>
|
||||
<TableCell>Content 03</TableCell>
|
||||
<TableCell>Content 04</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Table width
|
||||
|
||||
Table has full width by default. If you want to change its width, you will have
|
||||
to set the `fullWidth` prop to `false` and then define your own table width by
|
||||
passing a `className` or `style`.
|
||||
|
||||
## Properties
|
||||
|
||||
### Table Props
|
||||
|
||||
<Props of={Table} />
|
||||
|
||||
### TableHead Props
|
||||
|
||||
<Props of={TableHead} />
|
||||
|
||||
### TableBody Props
|
||||
|
||||
<Props of={TableBody} />
|
||||
|
||||
### TableRow Props
|
||||
|
||||
<Props of={TableRow} />
|
||||
|
||||
### TableCell Props
|
||||
|
||||
<Props of={TableCell} />
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Thumbnail
|
||||
menu: General
|
||||
route: components/thumbnail
|
||||
---
|
||||
|
||||
|
||||
import { Thumbnail } from '../';
|
||||
|
||||
# Thumbnail
|
||||
|
||||
Used to expose a display set showing some information about the group of images
|
||||
and a thumbnail
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Thumbnail } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-1 items-center justify-center p-4">
|
||||
<div className="w-56">
|
||||
<Thumbnail
|
||||
imageAltText="DisplaySet thumbnail image"
|
||||
description="Multiple line image series description lorem sit"
|
||||
seriesNumber={4}
|
||||
numInstances={902}
|
||||
onClick={() => alert('Thumbnail was clicked!')}
|
||||
isActive={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Thumbnail} />
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
name: ThumbnailNoImage
|
||||
menu: General
|
||||
route: components/ThumbnailNoImage
|
||||
---
|
||||
|
||||
|
||||
import { ThumbnailNoImage } from '../';
|
||||
|
||||
# ThumbnailNoImage
|
||||
|
||||
Used to expose
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Thumbnail } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-1 items-center justify-center p-4">
|
||||
<div className="w-64">
|
||||
<ThumbnailNoImage
|
||||
modality={'SR'}
|
||||
seriesDate="13-Mar-1999"
|
||||
description="Multiple line image series description lorem sit"
|
||||
onClick={() => alert('ThumbnailNoImage was clicked!')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ThumbnailNoImage} />
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: ThumbnailTracked
|
||||
menu: General
|
||||
route: components/ThumbnailTracked
|
||||
---
|
||||
|
||||
|
||||
import { ThumbnailTracked } from '../';
|
||||
|
||||
# ThumbnailTracked
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ThumbnailTracked } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="flex flex-1 items-center justify-center p-4">
|
||||
<div className="w-64">
|
||||
<ThumbnailTracked
|
||||
imageAltText="DisplaySet thumbnail image"
|
||||
description="Multiple line image series description lorem sit"
|
||||
seriesNumber={4}
|
||||
numInstances={902}
|
||||
onClick={() => alert('Thumbnail was clicked!')}
|
||||
viewportIdentificator={["A"]}
|
||||
isTracked={true}
|
||||
isActive={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ThumbnailTracked} />
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: Toolbar Button
|
||||
menu: General
|
||||
route: components/toolbarButton
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { ToolbarButton } from '@ohif/ui';
|
||||
|
||||
# Toolbar Button
|
||||
|
||||
Toolbar Buttons are used to populate the Toolbar.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ToolbarButton } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function ToolbarButtonExample(props) {
|
||||
// const [isActive, setIsActive] = useState(false);
|
||||
const tool = {
|
||||
id: 'Zoom',
|
||||
label: 'Zoom',
|
||||
icon: 'tool-zoom',
|
||||
type: null,
|
||||
commandName: 'setToolActive',
|
||||
commandOptions: { toolName: 'Zoom' },
|
||||
//onClick: () => setIsActive(true),
|
||||
isActive: true,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="py-10 flex justify-center">
|
||||
<ToolbarButton {...tool} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ToolbarButton} />
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Tooltip
|
||||
menu: Data Display
|
||||
route: components/tooltip
|
||||
---
|
||||
|
||||
import { Tooltip, Typography } from '@ohif/ui';
|
||||
|
||||
# Tooltip
|
||||
|
||||
Tooltips display informative content when users hover over, focus on, or tap an
|
||||
element.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Tooltip } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
function TooltipExample(props) {
|
||||
const tooltips = ['bottom', 'bottom-left', 'bottom-right', 'left', 'right'];
|
||||
return (
|
||||
<div className="py-10 flex flex-col items-center justify-center">
|
||||
{tooltips.map(tooltip => (
|
||||
<div className="mb-16">
|
||||
<Tooltip content="Tooltip content" position={tooltip}>
|
||||
<Typography>Tooltip {tooltip}</Typography>
|
||||
</Tooltip>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Tooltip} />
|
||||
```
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: TooltipClipboard
|
||||
menu: Data Display
|
||||
route: components/tooltipClipboard
|
||||
---
|
||||
|
||||
import { TooltipClipboard } from '@ohif/ui';
|
||||
|
||||
# Tooltip Clipboard
|
||||
|
||||
Tooltips display informative content when users hover over, focus on, or tap an
|
||||
element.
|
||||
|
||||
## Import
|
||||
|
||||
```jsx live
|
||||
import { TooltipClipboard } from '@ohif/ui';
|
||||
|
||||
<div className="p-4">
|
||||
<TooltipClipboard>Text to be copied</TooltipClipboard>
|
||||
</div>;
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={TooltipClipboard} />
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
name: Typography
|
||||
menu: General
|
||||
route: components/typography
|
||||
---
|
||||
|
||||
import { Typography } from '@ohif/ui';
|
||||
|
||||
# Typography
|
||||
|
||||
Use typography to display text using the available props for customizing your
|
||||
content.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Typography } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
````jsx live
|
||||
<div className="p-4">
|
||||
<Typography variant="h1">
|
||||
h1. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h2">
|
||||
h2. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h3">
|
||||
h3. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h4">
|
||||
h4. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h5">
|
||||
h5. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="h6">
|
||||
h6. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="subtitle">
|
||||
subtitle. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
<Typography variant="body">
|
||||
body. The five boxing wizards jump quickly.
|
||||
</Typography>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Changing the HTML element
|
||||
|
||||
There are different semantic elements to be used in the Typography component.
|
||||
You can use the prop `component` to associate the component to be rendered with
|
||||
a semantic element. The style of a Typography is independent of the semantic
|
||||
element.
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Typography variant="h1" component="h2">
|
||||
This is a h2 using the h1 styles.
|
||||
</Typography>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Typography} />
|
||||
````
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
name: Viewport
|
||||
menu: Data Display
|
||||
route: components/viewport
|
||||
---
|
||||
|
||||
import { Viewport } from '@ohif/ui';
|
||||
|
||||
# Viewport
|
||||
|
||||
Viewport component to be used in the ViewportGrid.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Viewport } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-screen">
|
||||
<Viewport
|
||||
viewportIndex={0}
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: true,
|
||||
isLocked: false,
|
||||
isRehydratable: false,
|
||||
studyDate: '07-Sep-2011',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'CT',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '5.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<div className="flex justify-center items-center h-full">CONTENT</div>
|
||||
</Viewport>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Viewport} />
|
||||
```
|
||||
@@ -0,0 +1,136 @@
|
||||
---
|
||||
name: Viewport Action Bar
|
||||
menu: Data Display
|
||||
route: components/viewportActionBar
|
||||
---
|
||||
|
||||
import { ViewportActionBar } from '@ohif/ui';
|
||||
|
||||
# Viewport Action Bar
|
||||
|
||||
Used to display an Action Bar in the viewer.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ViewportActionBar } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
````jsx live
|
||||
<div className="p-4 h-64">
|
||||
<ViewportActionBar
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: true,
|
||||
isLocked: false,
|
||||
isRehydratable: false,
|
||||
studyDate: '07-Sep-2010',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'CT',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '2.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-64">
|
||||
<ViewportActionBar
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: false,
|
||||
isLocked: false,
|
||||
isRehydratable: true,
|
||||
studyDate: '07-Sep-2010',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'CT',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '2.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-64">
|
||||
<ViewportActionBar
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: false,
|
||||
isLocked: false,
|
||||
isRehydratable: false,
|
||||
studyDate: '07-Sep-2010',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'SR',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '2.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
```
|
||||
```jsx live
|
||||
<div className="p-4 h-64">
|
||||
<ViewportActionBar
|
||||
onSeriesChange={direction => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: false,
|
||||
isLocked: false,
|
||||
isRehydratable: true,
|
||||
studyDate: '07-Sep-2010',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'SR',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '2.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
```
|
||||
</>
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ViewportActionBar} />
|
||||
````
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: ViewportGrid
|
||||
menu: General
|
||||
route: components/viewportGrid
|
||||
---
|
||||
|
||||
import { DragAndDropProvider, ViewportGrid } from '@ohif/ui';
|
||||
|
||||
# ViewportGrid
|
||||
|
||||
Used to display viewports in the viewer page.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ViewportGrid } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<DragAndDropProvider>
|
||||
<div className="p-4 h-56">
|
||||
<ViewportGrid numRows={1} numCols={2}>
|
||||
<div className="flex items-center justify-center h-full text-white">
|
||||
Viewport1
|
||||
</div>
|
||||
<div className="flex items-center justify-center h-full text-white">
|
||||
Viewport2
|
||||
</div>
|
||||
</ViewportGrid>
|
||||
</div>
|
||||
</DragAndDropProvider>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ViewportGrid} />
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: ViewportPane
|
||||
menu: General
|
||||
route: components/viewport-pane
|
||||
---
|
||||
|
||||
|
||||
import { ViewportGrid, ViewportPane, DragAndDropProvider } from '@ohif/ui';
|
||||
|
||||
# ViewportPane
|
||||
|
||||
Used to display viewports in the viewer page.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { ViewportPane } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4 h-56">
|
||||
<DragAndDropProvider>
|
||||
<ViewportGrid numRows={1} numCols={2}>
|
||||
<ViewportPane onDrop={() => {}} isActive={true}><h3>Hello</h3></ViewportPane>
|
||||
<ViewportPane onDrop={() => {}} isActive={false}><h3>World</h3></ViewportPane>
|
||||
</ViewportGrid>
|
||||
</DragAndDropProvider>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={ViewportPane} />
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
name: Window Level Menu Item
|
||||
menu: General
|
||||
route: components/windowLevelMenuItem
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { ListMenu, WindowLevelMenuItem } from '@ohif/ui';
|
||||
|
||||
# Window Level Menu Item
|
||||
|
||||
Window Level Menu Item are used as renderer of the ListMenu.
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { WindowLevelMenuItem, ListMenu } from '@ohif/ui';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
{
|
||||
() => {
|
||||
return (
|
||||
<div className="py-10 flex justify-center">
|
||||
<ListMenu renderer={WindowLevelMenuItem} items={[]} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={WindowLevelMenuItem} />
|
||||
```
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
name: Icon
|
||||
menu: General
|
||||
route: components/icon
|
||||
---
|
||||
|
||||
import { Icon, ICONS } from '@ohif/ui';
|
||||
|
||||
# Icon
|
||||
|
||||
## Import
|
||||
|
||||
```javascript
|
||||
import { Icon } from '@ohif/ui';
|
||||
```
|
||||
|
||||
## Basic usage
|
||||
|
||||
```jsx live
|
||||
<div className="p-4">
|
||||
<Icon name="series-active" className="text-primary-light m-4" />
|
||||
</div>
|
||||
```
|
||||
|
||||
## All Icons
|
||||
|
||||
<div className="p-4 flex flex-wrap items-center bg-black py-8">
|
||||
{Object.keys(ICONS)
|
||||
.sort()
|
||||
.map((name, i) => {
|
||||
return (
|
||||
<React.Fragment key={i}>
|
||||
<div className="flex flex-col items-center w-48 py-4">
|
||||
<div className="flex items-center justify-center rounded border border-primary-light p-4 m-2 w-20 h-20">
|
||||
<Icon name={name} className="text-primary-light w-6" />
|
||||
</div>
|
||||
<div className="break-normal text-white">{name}</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
## Properties
|
||||
|
||||
<Props of={Icon} />
|
||||
|
||||
The `Icon` component takes a single prop of `name`, which indicates which Icon
|
||||
should be displayed. The icon inherit the component text/font styles.
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
@@ -0,0 +1,117 @@
|
||||
---
|
||||
name: ModalProvider
|
||||
route: customHooks/modalProvider
|
||||
---
|
||||
|
||||
import { ModalComponent, ModalProvider } from '@ohif/ui';
|
||||
|
||||
# Modal Context Provider
|
||||
|
||||
This is a context provider that allow the application to share the modal
|
||||
component across all application.
|
||||
|
||||
## ModalProvider
|
||||
|
||||
Properties:
|
||||
|
||||
<Props of={ModalProvider} />
|
||||
|
||||
Usage example:
|
||||
|
||||
```javascript
|
||||
import { ModalProvider } from '@ohif/ui';
|
||||
import YourModalComponent from 'your-modal-component';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<ModalProvider modal={YourModalComponent}>
|
||||
/** You app content */
|
||||
</ModalComponent>;
|
||||
)
|
||||
};
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
## useModal
|
||||
|
||||
Used for React Functional Components. Should be used in the body of the
|
||||
functional component to get access to the context together with the `show/hide`
|
||||
functions.
|
||||
|
||||
Usage example:
|
||||
|
||||
```javascript
|
||||
import { withModal } from '@ohif/ui';
|
||||
|
||||
const SampleComponent = () => {
|
||||
const { show, hide } = useModal();
|
||||
|
||||
const openModal = () => {
|
||||
show({
|
||||
content: <div> Modal Content </div>,
|
||||
title: 'Modal title',
|
||||
});
|
||||
}
|
||||
|
||||
const closeModal = () => {
|
||||
hide();
|
||||
}
|
||||
|
||||
return (
|
||||
<button onClick={openModal}>
|
||||
Open modal
|
||||
</button>
|
||||
<button onClick={closeModal}>
|
||||
Close modal
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default SampleComponent;
|
||||
```
|
||||
|
||||
## withModal
|
||||
|
||||
Used for React Class Components. This function show receive a Component as a
|
||||
property and this component will have access to the context through its own
|
||||
properties.
|
||||
|
||||
Usage example:
|
||||
|
||||
```javascript
|
||||
import { withModal } from '@ohif/ui';
|
||||
import React from 'react';
|
||||
|
||||
class SampleComponent extends React.Component {
|
||||
openModal() {
|
||||
this.props.modal.show({
|
||||
content: <div> Modal Content </div>,
|
||||
title: 'Modal title',
|
||||
});
|
||||
}
|
||||
|
||||
closeModal() = {
|
||||
this.props.modal.hide();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<button onClick={this.openModal}>
|
||||
Open modal
|
||||
</button>
|
||||
<button onClick={this.closeModal}>
|
||||
Close modal
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withModal(SampleComponent);
|
||||
```
|
||||
|
||||
## Modal Properties
|
||||
|
||||
The Modal Properties that can be override are:
|
||||
|
||||
<Props of={ModalComponent} />
|
||||
@@ -0,0 +1,183 @@
|
||||
---
|
||||
name: ViewportDialogProvider
|
||||
route: customHooks/viewportDialogProvider
|
||||
---
|
||||
|
||||
<!-- This is a workaround to import things from ohif/core as docz does not allow us to access window element and @ohif/core does use it once we import to instanciate cornerstone -->
|
||||
<!-- import UIViewportDialogService from './../../../core/src/services/UIViewportDialogService';
|
||||
import ServicesManager from './../../../core/src/services/ServicesManager'; !-->
|
||||
|
||||
import {
|
||||
Dialog,
|
||||
Button,
|
||||
Notification,
|
||||
ViewportDialogProvider,
|
||||
useViewportDialog,
|
||||
} from '@ohif/ui';
|
||||
|
||||
# Viewport Dialog Provider
|
||||
|
||||
This is a context provider that allow the application to share the modal
|
||||
component across all application.
|
||||
|
||||
## Sample
|
||||
|
||||
````jsx live
|
||||
{() => {
|
||||
const ViewportNotification = ({ hide }) => {
|
||||
return (
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.alert(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
const ViewportActionButtons = () => {
|
||||
const [dialogState, dialogApi] = useViewportDialog();
|
||||
return (
|
||||
<Button onClick={() => dialogApi.show({ content: ViewportNotification })}>
|
||||
Open Dialog
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="w-full flex flex-row p-4" style={{height: '400px'}}>
|
||||
<div className="flex flex-1 items-center justify-center h-full w-full bg-black text-white border border-primary-main">
|
||||
<ViewportDialogProvider dialog={Dialog}>
|
||||
<div className="flex flex-1 flex-col items-center justify-center h-full">
|
||||
<ViewportActionButtons />
|
||||
<span>CONTENT 1</span>
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
<div className="flex flex-1 items-center justify-center h-full w-full bg-black text-white border border-primary-main">
|
||||
<ViewportDialogProvider dialog={Dialog}>
|
||||
<div className="flex flex-1 flex-col items-center justify-center h-full">
|
||||
<ViewportActionButtons />
|
||||
<span>CONTENT 1</span>
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Example using UIViewportDialogService
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
const ViewportNotification = ({ hide }) => {
|
||||
return (
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.alert(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
// Creating servicesManager and register services should be in the root of your app
|
||||
const servicesManager = new ServicesManager();
|
||||
servicesManager.registerServices([UIViewportDialogService]);
|
||||
// Get service instance
|
||||
const _UIViewportDialogService =
|
||||
servicesManager.services.UIViewportDialogService;
|
||||
console.log(_UIViewportDialogService);
|
||||
return (
|
||||
<div className="w-full flex flex-col p-4" style={{height: '400px'}}>
|
||||
<div className="flex flex-2">
|
||||
<Button
|
||||
className="mr-4 mb-4"
|
||||
onClick={() =>
|
||||
_UIViewportDialogService.show({
|
||||
content: ViewportNotification,
|
||||
viewportIndex: 0,
|
||||
})
|
||||
}
|
||||
>
|
||||
Open dialog on 0
|
||||
</Button>
|
||||
<Button
|
||||
className="mr-4 mb-4"
|
||||
onClick={() =>
|
||||
_UIViewportDialogService.show({
|
||||
content: ViewportNotification,
|
||||
viewportIndex: 1,
|
||||
})
|
||||
}
|
||||
>
|
||||
Open dialog on 1
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex flex-1 w-full flex-row">
|
||||
<ViewportDialogProvider
|
||||
dialog={Dialog}
|
||||
service={_UIViewportDialogService}
|
||||
viewportIndex={0}
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center h-full bg-black text-white border border-primary-main">
|
||||
CONTENT 0
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
<ViewportDialogProvider
|
||||
dialog={Dialog}
|
||||
service={_UIViewportDialogService}
|
||||
viewportIndex={1}
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center h-full bg-black text-white border border-primary-main">
|
||||
CONTENT 1
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Properties:
|
||||
|
||||
<Props of={ViewportDialogProvider} />
|
||||
````
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
---
|
||||
name: ViewportDialogProvider
|
||||
route: customHooks/viewportDialogProvider
|
||||
---
|
||||
|
||||
|
||||
|
||||
<!-- This is a workaround to import things from ohif/core as docz does not allow us to access window element and @ohif/core does use it once we import to instanciate cornerstone -->
|
||||
import UIViewportDialogService from './../../../core/src/services/UIViewportDialogService';
|
||||
import ServicesManager from './../../../core/src/services/ServicesManager';
|
||||
|
||||
import { Dialog, Button, Notification, ViewportDialogProvider, useViewportDialog } from '@ohif/ui';
|
||||
|
||||
# Viewport Dialog Provider
|
||||
|
||||
This is a context provider that allow the application to share the modal
|
||||
component across all application.
|
||||
|
||||
## Sample
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
const ViewportNotification = ({ hide }) => {
|
||||
return (
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.alert(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
const ViewportActionButtons = () => {
|
||||
const [dialogState, dialogApi] = useViewportDialog();
|
||||
return (
|
||||
<Button onClick={() => dialogApi.show({ content: ViewportNotification })}>
|
||||
Open Dialog
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div className="w-full flex flex-row p-4" style={{height: '400px'}}>
|
||||
<div className="flex flex-1 items-center justify-center h-full w-full bg-black text-white border border-primary-main">
|
||||
<ViewportDialogProvider dialog={Dialog}>
|
||||
<div className="flex flex-1 flex-col items-center justify-center h-full">
|
||||
<ViewportActionButtons />
|
||||
<span>CONTENT 1</span>
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
<div className="flex flex-1 items-center justify-center h-full w-full bg-black text-white border border-primary-main">
|
||||
<ViewportDialogProvider dialog={Dialog}>
|
||||
<div className="flex flex-1 flex-col items-center justify-center h-full">
|
||||
<ViewportActionButtons />
|
||||
<span>CONTENT 1</span>
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Example using UIViewportDialogService
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
const ViewportNotification = ({ hide }) => {
|
||||
return (
|
||||
<Notification
|
||||
message="Track all measurement for this series?"
|
||||
type="info"
|
||||
actions={[
|
||||
{
|
||||
type: 'cancel',
|
||||
text: 'No',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
type: 'secondary',
|
||||
text: 'No, do not ask again',
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
type: 'primary',
|
||||
text: 'Yes',
|
||||
value: 1,
|
||||
},
|
||||
]}
|
||||
onSubmit={value => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.alert(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
// Creating servicesManager and register services should be in the root of your app
|
||||
const servicesManager = new ServicesManager();
|
||||
servicesManager.registerServices([UIViewportDialogService]);
|
||||
// Get service instance
|
||||
const _UIViewportDialogService =
|
||||
servicesManager.services.UIViewportDialogService;
|
||||
console.log(_UIViewportDialogService);
|
||||
return (
|
||||
<div className="w-full flex flex-col p-4" style={{height: '400px'}}>
|
||||
<div className="flex flex-2">
|
||||
<Button
|
||||
className="mr-4 mb-4"
|
||||
onClick={() =>
|
||||
_UIViewportDialogService.show({
|
||||
content: ViewportNotification,
|
||||
viewportIndex: 0,
|
||||
})
|
||||
}
|
||||
>
|
||||
Open dialog on 0
|
||||
</Button>
|
||||
<Button
|
||||
className="mr-4 mb-4"
|
||||
onClick={() =>
|
||||
_UIViewportDialogService.show({
|
||||
content: ViewportNotification,
|
||||
viewportIndex: 1,
|
||||
})
|
||||
}
|
||||
>
|
||||
Open dialog on 1
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex flex-1 w-full flex-row">
|
||||
<ViewportDialogProvider
|
||||
dialog={Dialog}
|
||||
service={_UIViewportDialogService}
|
||||
viewportIndex={0}
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center h-full bg-black text-white border border-primary-main">
|
||||
CONTENT 0
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
<ViewportDialogProvider
|
||||
dialog={Dialog}
|
||||
service={_UIViewportDialogService}
|
||||
viewportIndex={1}
|
||||
>
|
||||
<div className="flex flex-1 items-center justify-center h-full bg-black text-white border border-primary-main">
|
||||
CONTENT 1
|
||||
</div>
|
||||
</ViewportDialogProvider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
|
||||
## Properties:
|
||||
|
||||
<Props of={ViewportDialogProvider} />
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
name: Colors
|
||||
route: system/colors
|
||||
---
|
||||
|
||||
import BackgroundColor from '@ohif/ui';
|
||||
|
||||
# Color System
|
||||
|
||||
`@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
|
||||
all the default colors from Tailwind, besides our custom colors too.
|
||||
|
||||
# How to use
|
||||
|
||||
To apply color in your element, you will use the same way Tailwind does.
|
||||
|
||||
- Background - `bg-primary-main`
|
||||
- Border - `border-primary-main`
|
||||
- Text - `text-primary-main`
|
||||
- Placeholder - `placeholder-primary-main`
|
||||
|
||||
Check [Tailwind's documentation](https://tailwindcss.com/docs) to see more
|
||||
details about color classes.
|
||||
|
||||
# Examples
|
||||
|
||||
## Text
|
||||
|
||||
````jsx live
|
||||
<div className="p-8">
|
||||
<p className="text-common-bright">text-common-bright</p>
|
||||
<p className="text-common-light">text-common-light</p>
|
||||
<p className="text-common-main">text-common-main</p>
|
||||
<p className="text-common-dark">text-common-dark</p>
|
||||
<p className="text-common-active">text-common-active</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Background
|
||||
|
||||
<div className="flex">
|
||||
<div className="mr-8">
|
||||
<BackgroundColor color="primary-light" />
|
||||
<BackgroundColor color="primary-main" />
|
||||
<BackgroundColor color="primary-dark" />
|
||||
<BackgroundColor color="primary-active" />
|
||||
</div>
|
||||
<div>
|
||||
<BackgroundColor color="secondary-light" />
|
||||
<BackgroundColor color="secondary-main" />
|
||||
<BackgroundColor color="secondary-dark" />
|
||||
<BackgroundColor color="secondary-active" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
# Color palette
|
||||
|
||||
```javascript
|
||||
primary: {
|
||||
light: '#5acce6',
|
||||
main: '#0944b3',
|
||||
dark: '#090c29',
|
||||
active: '#348cfd',
|
||||
},
|
||||
|
||||
secondary: {
|
||||
light: '#3a3f99',
|
||||
main: '#2b166b',
|
||||
dark: '#041c4a',
|
||||
active: '#1f1f27',
|
||||
},
|
||||
|
||||
common: {
|
||||
bright: '#e1e1e1',
|
||||
light: '#a19fad',
|
||||
main: '#fff',
|
||||
dark: '#726f7e',
|
||||
active: '#2c3074',
|
||||
},
|
||||
````
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: Getting Started
|
||||
route: /
|
||||
---
|
||||
|
||||
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';
|
||||
```
|
||||
|
||||
```jsx live
|
||||
<div className="p-8">
|
||||
<Button onClick={() => alert('Hello!')}>Click here!</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
In the **Examples** section you can check many examples on how to build your
|
||||
application using `@ohif/ui` components.
|
||||
|
||||
...
|
||||
@@ -0,0 +1,346 @@
|
||||
---
|
||||
name: Study List
|
||||
menu: Views
|
||||
route: examples/studyList
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
import {
|
||||
Icon,
|
||||
StudyListExpandedRow,
|
||||
Button,
|
||||
NavBar,
|
||||
Svg,
|
||||
IconButton,
|
||||
EmptyStudies,
|
||||
StudyListTable,
|
||||
StudyListPagination,
|
||||
StudyListFilter
|
||||
} from '@ohif/ui';
|
||||
import utils from '../../utils';
|
||||
|
||||
|
||||
import classnames from 'classnames';
|
||||
import moment from 'moment';
|
||||
|
||||
# Study List
|
||||
|
||||
This example shows you how you can build a Study List page using the available
|
||||
components.
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
const defaultFilterValues = {
|
||||
patientName: '',
|
||||
mrn: '',
|
||||
studyDate: {
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
description: '',
|
||||
modality: undefined,
|
||||
accession: '',
|
||||
sortBy: '',
|
||||
sortDirection: 'none',
|
||||
page: 0,
|
||||
resultsPerPage: 25,
|
||||
};
|
||||
const [filterValues, setFilterValues] = useState(defaultFilterValues);
|
||||
const [studies, setStudies] = useState([]);
|
||||
const numOfStudies = studies.length;
|
||||
const [expandedRows, setExpandedRows] = useState([]);
|
||||
const filtersMeta = [
|
||||
{
|
||||
name: 'patientName',
|
||||
displayName: 'Patient Name',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'mrn',
|
||||
displayName: 'MRN',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 2,
|
||||
},
|
||||
{
|
||||
name: 'studyDate',
|
||||
displayName: 'Study date',
|
||||
inputType: 'DateRange',
|
||||
isSortable: true,
|
||||
gridCol: 5,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
displayName: 'Description',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'modality',
|
||||
displayName: 'Modality',
|
||||
inputType: 'MultiSelect',
|
||||
inputProps: {
|
||||
options: [
|
||||
{ value: 'SEG', label: 'SEG' },
|
||||
{ value: 'CT', label: 'CT' },
|
||||
{ value: 'MR', label: 'MR' },
|
||||
{ value: 'SR', label: 'SR' },
|
||||
],
|
||||
},
|
||||
isSortable: true,
|
||||
gridCol: 3,
|
||||
},
|
||||
{
|
||||
name: 'accession',
|
||||
displayName: 'Accession',
|
||||
inputType: 'Text',
|
||||
isSortable: true,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
name: 'instances',
|
||||
displayName: 'Instances',
|
||||
inputType: 'None',
|
||||
isSortable: true,
|
||||
gridCol: 2,
|
||||
},
|
||||
];
|
||||
const isFiltering = (filterValues, defaultFilterValues) => {
|
||||
return Object.keys(defaultFilterValues).some((name) => {
|
||||
return filterValues[name] !== defaultFilterValues[name];
|
||||
});
|
||||
};
|
||||
const tableDataSource = studies.map((study, key) => {
|
||||
const rowKey = key + 1;
|
||||
const isExpanded = expandedRows.some((k) => k === rowKey);
|
||||
const {
|
||||
AccessionNumber,
|
||||
Modalities,
|
||||
Instances,
|
||||
StudyDescription,
|
||||
PatientId,
|
||||
PatientName,
|
||||
StudyDate,
|
||||
series,
|
||||
} = study;
|
||||
const seriesTableColumns = {
|
||||
description: 'Description',
|
||||
seriesNumber: 'Series',
|
||||
modality: 'Modality',
|
||||
Instances: 'Instances',
|
||||
};
|
||||
const seriesTableDataSource = series.map((seriesItem) => {
|
||||
const { SeriesNumber, Modality, instances } = seriesItem;
|
||||
return {
|
||||
description: 'Patient Protocol',
|
||||
seriesNumber: SeriesNumber,
|
||||
modality: Modality,
|
||||
Instances: instances.length,
|
||||
};
|
||||
});
|
||||
return {
|
||||
row: [
|
||||
{
|
||||
key: 'patientName',
|
||||
content: PatientName,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
key: 'mrn',
|
||||
content: PatientId,
|
||||
gridCol: 2,
|
||||
},
|
||||
{
|
||||
key: 'studyDate',
|
||||
content: (
|
||||
<div>
|
||||
<span className="mr-4">
|
||||
{moment(StudyDate).format('MMM-DD-YYYY')}
|
||||
</span>
|
||||
<span>{moment(StudyDate).format('hh:mm A')}</span>
|
||||
</div>
|
||||
),
|
||||
gridCol: 5,
|
||||
},
|
||||
{
|
||||
key: 'description',
|
||||
content: StudyDescription,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
key: 'modality',
|
||||
content: Modalities,
|
||||
gridCol: 3,
|
||||
},
|
||||
{
|
||||
key: 'accession',
|
||||
content: AccessionNumber,
|
||||
gridCol: 4,
|
||||
},
|
||||
{
|
||||
key: 'instances',
|
||||
content: (
|
||||
<>
|
||||
<Icon
|
||||
name="group-layers"
|
||||
className={classnames('inline-flex mr-2 w-4', {
|
||||
'text-primary-active': isExpanded,
|
||||
'text-secondary-light': !isExpanded,
|
||||
})}
|
||||
/>
|
||||
{Instances}
|
||||
</>
|
||||
),
|
||||
gridCol: 4,
|
||||
},
|
||||
],
|
||||
expandedContent: (
|
||||
<StudyListExpandedRow
|
||||
seriesTableColumns={seriesTableColumns}
|
||||
seriesTableDataSource={seriesTableDataSource}
|
||||
>
|
||||
<Button
|
||||
rounded="full"
|
||||
variant="contained"
|
||||
className="mr-4 font-bold"
|
||||
endIcon={
|
||||
<Icon name="launch-arrow" style={{ color: '#21a7c6' }} />
|
||||
}
|
||||
>
|
||||
Basic Viewer
|
||||
</Button>
|
||||
<Button
|
||||
rounded="full"
|
||||
variant="contained"
|
||||
className="mr-4 font-bold"
|
||||
endIcon={
|
||||
<Icon name="launch-arrow" style={{ color: '#21a7c6' }} />
|
||||
}
|
||||
>
|
||||
Segmentation
|
||||
</Button>
|
||||
<Button
|
||||
rounded="full"
|
||||
variant="outlined"
|
||||
endIcon={<Icon name="launch-info" />}
|
||||
className="font-bold"
|
||||
>
|
||||
Module 3
|
||||
</Button>
|
||||
<div className="ml-5 text-lg text-common-bright inline-flex items-center">
|
||||
<Icon
|
||||
name="notificationwarning-diamond"
|
||||
className="mr-2 w-5 h-5"
|
||||
/>
|
||||
Feedback text lorem ipsum dolor sit amet
|
||||
</div>
|
||||
</StudyListExpandedRow>
|
||||
),
|
||||
onClickRow: () =>
|
||||
setExpandedRows((s) =>
|
||||
isExpanded ? s.filter((n) => rowKey !== n) : [...s, rowKey]
|
||||
),
|
||||
isExpanded,
|
||||
};
|
||||
});
|
||||
const handleStudyList = (number) => {
|
||||
const studies = utils.getMockedStudies(number);
|
||||
setStudies(studies);
|
||||
setCurrentPage(1);
|
||||
};
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [perPage, setPerPage] = useState(25);
|
||||
const totalPages = Math.floor(numOfStudies / perPage);
|
||||
const onChangePage = (page) => {
|
||||
if (page > totalPages) {
|
||||
return;
|
||||
}
|
||||
setCurrentPage(page);
|
||||
};
|
||||
const onChangePerPage = (perPage) => {
|
||||
setPerPage(perPage);
|
||||
setCurrentPage(1);
|
||||
};
|
||||
const hasStudies = numOfStudies > 0;
|
||||
return (
|
||||
<div>
|
||||
<div className="bg-white p-4">
|
||||
<Button className="mr-2" onClick={() => handleStudyList(0)}>
|
||||
0 Studies
|
||||
</Button>
|
||||
<Button className="mr-2" onClick={() => handleStudyList(50)}>
|
||||
50 Studies
|
||||
</Button>
|
||||
<Button className="mr-2" onClick={() => handleStudyList(100)}>
|
||||
100 Studies
|
||||
</Button>
|
||||
<Button className="mr-2" onClick={() => handleStudyList(1000)}>
|
||||
1000 Studies
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
className={classnames('bg-black h-full', {
|
||||
'h-screen': !hasStudies,
|
||||
})}
|
||||
>
|
||||
<NavBar className="justify-between border-b-4 border-black" isSticky>
|
||||
<div className="flex items-center">
|
||||
<div className="mx-3">
|
||||
<Svg name="logo-ohif" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="mr-3 text-common-light text-lg">
|
||||
FOR INVESTIGATIONAL USE ONLY
|
||||
</span>
|
||||
<IconButton
|
||||
variant="text"
|
||||
color="inherit"
|
||||
className="text-primary-active"
|
||||
onClick={() => {}}
|
||||
>
|
||||
<React.Fragment>
|
||||
<Icon name="settings" />
|
||||
<Icon name="chevron-down" />
|
||||
</React.Fragment>
|
||||
</IconButton>
|
||||
</div>
|
||||
</NavBar>
|
||||
<StudyListFilter
|
||||
numOfStudies={numOfStudies}
|
||||
filtersMeta={filtersMeta}
|
||||
filterValues={filterValues}
|
||||
onChange={setFilterValues}
|
||||
clearFilters={() => setFilterValues(defaultFilterValues)}
|
||||
isFiltering={isFiltering(filterValues, defaultFilterValues)}
|
||||
/>
|
||||
{hasStudies ? (
|
||||
<>
|
||||
<StudyListTable
|
||||
tableDataSource={tableDataSource.slice(
|
||||
(currentPage - 1) * perPage,
|
||||
(currentPage - 1) * perPage + perPage
|
||||
)}
|
||||
numOfStudies={numOfStudies}
|
||||
filtersMeta={filtersMeta}
|
||||
/>
|
||||
<StudyListPagination
|
||||
onChangePage={onChangePage}
|
||||
onChangePerPage={onChangePerPage}
|
||||
currentPage={currentPage}
|
||||
perPage={perPage}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex flex-col items-center justify-center pt-48">
|
||||
<EmptyStudies />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
```
|
||||
@@ -0,0 +1,178 @@
|
||||
---
|
||||
name: Viewer
|
||||
menu: Views
|
||||
route: examples/viewer
|
||||
---
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import {
|
||||
NavBar,
|
||||
SidePanel,
|
||||
Svg,
|
||||
SegmentationTable,
|
||||
ButtonGroup,
|
||||
Button,
|
||||
Icon,
|
||||
IconButton,
|
||||
StudyBrowser,
|
||||
ViewportActionBar,
|
||||
Notification,
|
||||
Viewport,
|
||||
ViewportGrid,
|
||||
ViewportPane,
|
||||
StudySummary,
|
||||
MeasurementTable,
|
||||
Header,
|
||||
DragAndDropProvider,
|
||||
} from '@ohif/ui';
|
||||
|
||||
import { tabs } from './studyBrowserMockData';
|
||||
|
||||
# Viewer
|
||||
|
||||
```jsx live
|
||||
{() => {
|
||||
const [activeMeasurementItem, setActiveMeasurementItem] = useState(null);
|
||||
const descriptionData = {
|
||||
date: '07-Sep-2010',
|
||||
modality: 'CT',
|
||||
description: 'CHEST/ABD/PELVIS W CONTRAST',
|
||||
};
|
||||
const measurementTableData = {
|
||||
title: 'Measurements',
|
||||
amount: 10,
|
||||
data: new Array(10).fill({}).map((el, i) => ({
|
||||
id: i + 1,
|
||||
label: 'Label short description',
|
||||
displayText: '24.0 x 24.0 mm (S:4, I:22)',
|
||||
isActive: activeMeasurementItem === i + 1,
|
||||
})),
|
||||
onClick: (id) => setActiveMeasurementItem((s) => (s === id ? null : id)),
|
||||
onEdit: (id) => alert(`Edit: ${id}`),
|
||||
};
|
||||
const [activeViewportIndex, setActiveViewportIndex] = useState(0);
|
||||
return (
|
||||
<DragAndDropProvider>
|
||||
<Header />
|
||||
<div
|
||||
className="flex flex-row flex-no-wrap items-stretch overflow-hidden w-full"
|
||||
style={{ height: 'calc(100vh - 52px' }}
|
||||
>
|
||||
{/* LEFT SIDEPANELS */}
|
||||
<SidePanel
|
||||
side="left"
|
||||
defaultComponentOpen='studies'
|
||||
childComponents={{
|
||||
iconName: 'group-layers',
|
||||
iconLabel: 'Studies',
|
||||
label: 'Studies',
|
||||
name: 'studies',
|
||||
content: <StudyBrowser tabs={tabs} />
|
||||
}}
|
||||
/>
|
||||
{/* TOOLBAR + GRID */}
|
||||
<div className="flex flex-col flex-1 h-full">
|
||||
<div className="flex flex-2 w-100 border-b border-transparent h-12">
|
||||
{/* <ViewportToolbar /> Secondary Toolbar */}
|
||||
</div>
|
||||
{/* VIEWPORT GRID CONTAINER */}
|
||||
<div className="flex flex-1 h-full overflow-hidden bg-black items-center justify-center pb-2 pt-1">
|
||||
<ViewportGrid numRows={1} numCols={2}>
|
||||
{[0, 1].map(viewportIndex => (
|
||||
<ViewportPane key={viewportIndex} className="m-1" isActive={false} onDrop={() => {}}>
|
||||
<Viewport
|
||||
viewportIndex={viewportIndex}
|
||||
onSeriesChange={(direction) => alert(`Series ${direction}`)}
|
||||
studyData={{
|
||||
label: 'A',
|
||||
isTracked: true,
|
||||
isLocked: false,
|
||||
isRehydratable: false,
|
||||
studyDate: '07-Sep-2011',
|
||||
currentSeries: 1,
|
||||
seriesDescription:
|
||||
'Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit Series description lorem ipsum dolor sit ',
|
||||
modality: 'CT',
|
||||
patientInformation: {
|
||||
patientName: 'Smith, Jane',
|
||||
patientSex: 'F',
|
||||
patientAge: '59',
|
||||
MRN: '10000001',
|
||||
thickness: '5.0mm',
|
||||
spacing: '1.25mm',
|
||||
scanner: 'Aquilion',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<div className="flex justify-center items-center h-full">
|
||||
CONTENT
|
||||
</div>
|
||||
</Viewport>
|
||||
</ViewportPane>)
|
||||
)}
|
||||
</ViewportGrid>
|
||||
</div>
|
||||
</div>
|
||||
<SidePanel
|
||||
side="right"
|
||||
defaultComponentOpen="measurements"
|
||||
childComponents={{
|
||||
iconName: 'list-bullets',
|
||||
iconLabel: 'Measure',
|
||||
label: 'Measurements',
|
||||
name: 'measurements',
|
||||
content: (
|
||||
<>
|
||||
<div className="overflow-x-hidden overflow-y-auto invisible-scrollbar">
|
||||
<StudySummary
|
||||
date={descriptionData.date}
|
||||
modality={descriptionData.modality}
|
||||
description={descriptionData.description}
|
||||
/>
|
||||
<MeasurementTable
|
||||
title="Measurements"
|
||||
amount={measurementTableData.data.length}
|
||||
data={measurementTableData.data}
|
||||
onClick={() => {}}
|
||||
onEdit={id => alert(`Edit: ${id}`)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-center p-4">
|
||||
<React.Fragment>
|
||||
<ButtonGroup onClick={() => alert('Export')}>
|
||||
<Button
|
||||
className="text-white border-primary-main bg-black text-base py-2 px-2"
|
||||
size="initial"
|
||||
color="inherit"
|
||||
>
|
||||
Export
|
||||
</Button>
|
||||
<IconButton
|
||||
className="bg-black border-primary-main px-2 text-white px-2"
|
||||
color="inherit"
|
||||
size="initial"
|
||||
>
|
||||
<Icon name="arrow-down" />
|
||||
</IconButton>
|
||||
</ButtonGroup>
|
||||
<Button
|
||||
className="text-white border border-primary-main bg-black text-base py-2 px-2 ml-2"
|
||||
variant="outlined"
|
||||
size="initial"
|
||||
color="inherit"
|
||||
onClick={() => alert('Create Report')}
|
||||
>
|
||||
Create Report
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</DragAndDropProvider>
|
||||
);
|
||||
}}
|
||||
```
|
||||
@@ -72,6 +72,7 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
// },
|
||||
themes: ['@docusaurus/theme-live-codeblock'],
|
||||
plugins: [
|
||||
path.resolve(__dirname, './pluginOHIFWebpackConfig.js'),
|
||||
'plugin-image-zoom', // 3rd party plugin for image click to pop
|
||||
[
|
||||
'@docusaurus/plugin-client-redirects',
|
||||
@@ -80,10 +81,13 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
redirects: [
|
||||
{
|
||||
// we need this for https://cloud.google.com/healthcare/docs/how-tos/dicom-viewers
|
||||
to: "/deployment/recipes/google-cloud-healthcare",
|
||||
from: ['/connecting-to-image-archives/google-cloud-healthcare', '/connecting-to-image-archives/google-cloud-healthcare.html']
|
||||
}
|
||||
]
|
||||
to: '/deployment/recipes/google-cloud-healthcare',
|
||||
from: [
|
||||
'/connecting-to-image-archives/google-cloud-healthcare',
|
||||
'/connecting-to-image-archives/google-cloud-healthcare.html',
|
||||
],
|
||||
},
|
||||
],
|
||||
// createRedirects: function(path) {
|
||||
// // redirect to /docs from /docs/introduction,
|
||||
// // as introduction has been made the home doc
|
||||
@@ -275,8 +279,18 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
srcDark: 'img/ohif-logo.svg',
|
||||
},
|
||||
items: [
|
||||
{ to: 'https://ohif.org/get-started', label: 'Get Started', target: '_self', position: 'left' },
|
||||
{ to: 'https://ohif.org/examples', label: 'Examples', target: '_self', position: 'left' },
|
||||
{
|
||||
to: 'https://ohif.org/get-started',
|
||||
label: 'Get Started',
|
||||
target: '_self',
|
||||
position: 'left',
|
||||
},
|
||||
{
|
||||
to: 'https://ohif.org/examples',
|
||||
label: 'Examples',
|
||||
target: '_self',
|
||||
position: 'left',
|
||||
},
|
||||
{
|
||||
position: 'left',
|
||||
to: '/',
|
||||
@@ -284,8 +298,18 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
docId: 'Introduction',
|
||||
label: 'Docs',
|
||||
},
|
||||
{ to: 'https://ohif.org/community', label: 'Community', target: '_self', position: 'left' },
|
||||
{ to: 'next/help', activeBaseRegex: '(^/help$)|(/next/help)', label: 'Help', position: 'right' },
|
||||
{
|
||||
to: 'https://ohif.org/community',
|
||||
label: 'Community',
|
||||
target: '_self',
|
||||
position: 'left',
|
||||
},
|
||||
{
|
||||
to: 'next/help',
|
||||
activeBaseRegex: '(^/help$)|(/next/help)',
|
||||
label: 'Help',
|
||||
position: 'right',
|
||||
},
|
||||
// { to: 'https://react.ohif.org/', label: 'UI Component Library', position: 'left' },
|
||||
// {to: 'showcase', label: 'Showcase', position: 'left'},
|
||||
// right
|
||||
@@ -299,7 +323,8 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
position: 'right',
|
||||
dropdownItemsAfter: [
|
||||
{
|
||||
to: 'next/viewer/internationalization#contributing-with-new-languages',
|
||||
to:
|
||||
'next/viewer/internationalization#contributing-with-new-languages',
|
||||
label: 'Help Us Translate',
|
||||
},
|
||||
],
|
||||
@@ -308,12 +333,11 @@ const isI18nStaging = process.env.I18N_STAGING === 'true';
|
||||
to: 'https://github.com/OHIF/Viewers',
|
||||
position: 'right',
|
||||
className: 'header-github-link',
|
||||
'aria-label': 'GitHub Repository'
|
||||
'aria-label': 'GitHub Repository',
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
|
||||
style: 'dark',
|
||||
links: [
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ohif/ui": "^2.0.0",
|
||||
"@docusaurus/core": "2.0.0-beta.3",
|
||||
"@docusaurus/plugin-client-redirects": "2.0.0-beta.3",
|
||||
"@docusaurus/plugin-ideal-image": "2.0.0-beta.3",
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
module.exports = function(context, options) {
|
||||
return {
|
||||
name: 'plugin-ohif-webpack-config',
|
||||
configureWebpack(config, isServer, utils) {
|
||||
return {
|
||||
resolve: {
|
||||
fallback: {
|
||||
fs: false,
|
||||
path: false,
|
||||
},
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.m?jsx?$/,
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import * as ui from '@ohif/ui';
|
||||
|
||||
// Add react-live imports you need here
|
||||
const ReactLiveScope = {
|
||||
React,
|
||||
...React,
|
||||
...ui,
|
||||
};
|
||||
|
||||
export default ReactLiveScope;
|
||||
Reference in new issue
Block a user