OHIF-32: Wrapping React-select with our style requirements (#1529)
* Custom Select component * Including inpot section * Adding missing import sections on docz * Change cursor once is disabled * update date range color font
This commit is contained in:
parent
b183e78f47
commit
b7a72f5225
@ -6,6 +6,7 @@ export {
|
|||||||
DateRange,
|
DateRange,
|
||||||
Icon,
|
Icon,
|
||||||
IconButton,
|
IconButton,
|
||||||
|
Select,
|
||||||
Svg,
|
Svg,
|
||||||
Input,
|
Input,
|
||||||
ThemeWrapper,
|
ThemeWrapper,
|
||||||
|
|||||||
@ -40,6 +40,7 @@
|
|||||||
"react-dates": "^21.8.0",
|
"react-dates": "^21.8.0",
|
||||||
"react-dom": "16.11.0",
|
"react-dom": "16.11.0",
|
||||||
"react-powerplug": "1.0.0",
|
"react-powerplug": "1.0.0",
|
||||||
|
"react-select": "^3.0.8",
|
||||||
"theme-ui": "^0.2.38"
|
"theme-ui": "^0.2.38"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
@apply bg-no-repeat;
|
@apply bg-no-repeat;
|
||||||
}
|
}
|
||||||
.DateInput_input {
|
.DateInput_input {
|
||||||
@apply cursor-pointer border-custom-blue mt-2 bg-black shadow transition duration-300 appearance-none border-t border-l border-r border-b border-solid rounded w-full py-2 px-3 text-sm text-gray-700 leading-tight pl-8;
|
@apply cursor-pointer border-custom-blue mt-2 bg-black shadow transition duration-300 appearance-none border-t border-l border-r border-b border-solid rounded w-full py-2 px-3 text-sm text-white leading-tight pl-8;
|
||||||
}
|
}
|
||||||
.DateInput_input:hover {
|
.DateInput_input:hover {
|
||||||
@apply border-gray-500;
|
@apply border-gray-500;
|
||||||
|
|||||||
@ -10,6 +10,12 @@ import { ICONS } from './getIcon';
|
|||||||
|
|
||||||
# Icon
|
# Icon
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { Icon } from '@ohfi/ui';
|
||||||
|
```
|
||||||
|
|
||||||
## Basic usage
|
## Basic usage
|
||||||
|
|
||||||
<Playground>
|
<Playground>
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import Label from '../Label';
|
|||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
const baseInputClasses =
|
const baseInputClasses =
|
||||||
'shadow transition duration-300 appearance-none border rounded w-full py-2 px-3 text-sm text-gray-700 hover:border-gray-500 leading-tight focus:border-gray-500 focus:outline-none';
|
'shadow transition duration-300 appearance-none border rounded w-full py-2 px-3 text-sm text-white hover:border-gray-500 leading-tight focus:border-gray-500 focus:outline-none';
|
||||||
|
|
||||||
const transparentClasses = {
|
const transparentClasses = {
|
||||||
true: 'bg-transparent',
|
true: 'bg-transparent',
|
||||||
|
|||||||
@ -9,6 +9,12 @@ import Input from './';
|
|||||||
|
|
||||||
# Input
|
# Input
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { Input } from '@ohfi/ui';
|
||||||
|
```
|
||||||
|
|
||||||
## Basic usage
|
## Basic usage
|
||||||
|
|
||||||
<Playground>
|
<Playground>
|
||||||
|
|||||||
@ -9,6 +9,12 @@ import Label from './';
|
|||||||
|
|
||||||
# Label
|
# Label
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { Label } from '@ohfi/ui';
|
||||||
|
```
|
||||||
|
|
||||||
## Basic usage
|
## Basic usage
|
||||||
|
|
||||||
<Playground>
|
<Playground>
|
||||||
|
|||||||
39
platform/ui/src/components/Select/Select.css
Normal file
39
platform/ui/src/components/Select/Select.css
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
.customSelect__wrapper .customSelect__control {
|
||||||
|
@apply bg-black border-custom-blue shadow transition duration-300 border rounded w-full text-sm text-white leading-tight;
|
||||||
|
min-height: 33px;
|
||||||
|
}
|
||||||
|
.customSelect__wrapper .customSelect__control:hover {
|
||||||
|
@apply border-gray-500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customSelect__wrapper .customSelect__control:focus {
|
||||||
|
@apply border-gray-500 outline-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customSelect__wrapper .customSelect__control--menu-is-open {
|
||||||
|
@apply border-gray-500 outline-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customSelect__wrapper .customSelect__indicator-separator {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customSelect__wrapper .customSelect__dropdown-indicator {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customSelect__wrapper .customSelect__option {
|
||||||
|
@apply text-black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customSelect__wrapper .customSelect__single-value {
|
||||||
|
@apply text-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customSelect--is-disabled .customSelect__control--is-disabled {
|
||||||
|
@apply pointer-events-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.customSelect__wrapper.customSelect--is-disabled {
|
||||||
|
@apply cursor-not-allowed pointer-events-auto;
|
||||||
|
}
|
||||||
61
platform/ui/src/components/Select/Select.jsx
Normal file
61
platform/ui/src/components/Select/Select.jsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import ReactSelect from 'react-select';
|
||||||
|
|
||||||
|
import './Select.css';
|
||||||
|
|
||||||
|
const Select = ({
|
||||||
|
autoFocus,
|
||||||
|
className,
|
||||||
|
isDisabled,
|
||||||
|
isMulti,
|
||||||
|
isSearchable,
|
||||||
|
name,
|
||||||
|
onChange,
|
||||||
|
options,
|
||||||
|
placeholder,
|
||||||
|
noOptionsMessage,
|
||||||
|
value,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<ReactSelect
|
||||||
|
autoFocus={autoFocus}
|
||||||
|
className={classnames(
|
||||||
|
className,
|
||||||
|
'flex flex-col flex-1 mt-2 customSelect__wrapper'
|
||||||
|
)}
|
||||||
|
classNamePrefix="customSelect"
|
||||||
|
isDisabled={isDisabled}
|
||||||
|
isMulti={isMulti}
|
||||||
|
isSearchable={isSearchable}
|
||||||
|
name={name}
|
||||||
|
onChange={onChange}
|
||||||
|
options={options}
|
||||||
|
placeholder={placeholder}
|
||||||
|
noOptionsMessage={noOptionsMessage}
|
||||||
|
value={value}
|
||||||
|
></ReactSelect>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Select.propTypes = {
|
||||||
|
autoFocus: PropTypes.bool,
|
||||||
|
className: PropTypes.string,
|
||||||
|
isDisabled: PropTypes.bool,
|
||||||
|
isMulti: PropTypes.bool,
|
||||||
|
isSearchable: PropTypes.bool,
|
||||||
|
name: PropTypes.string,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
options: PropTypes.arrayOf(
|
||||||
|
PropTypes.shape({
|
||||||
|
value: PropTypes.string,
|
||||||
|
label: PropTypes.string,
|
||||||
|
})
|
||||||
|
),
|
||||||
|
placeholder: PropTypes.string,
|
||||||
|
noOptionsMessage: PropTypes.func,
|
||||||
|
value: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Select;
|
||||||
70
platform/ui/src/components/Select/Select.mdx
Normal file
70
platform/ui/src/components/Select/Select.mdx
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
---
|
||||||
|
name: Select
|
||||||
|
menu: Components
|
||||||
|
route: components/select
|
||||||
|
---
|
||||||
|
|
||||||
|
import { Playground, Props } from 'docz';
|
||||||
|
import Select from './';
|
||||||
|
|
||||||
|
# Select
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import { Select } from '@ohfi/ui';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic usage
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<div className="flex flex-col flex-1 p-4 items-center">
|
||||||
|
<div className="w-20">
|
||||||
|
<Select
|
||||||
|
options={[
|
||||||
|
{ value: 'one', label: 'one' },
|
||||||
|
{ value: 'two', label: 'two' },
|
||||||
|
{ value: 'three', label: 'three' },
|
||||||
|
{ value: 'four', label: 'four' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
## Disabled
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<div className="flex flex-col flex-1 p-4 items-center">
|
||||||
|
<div className="w-20">
|
||||||
|
<Select
|
||||||
|
isDisabled
|
||||||
|
options={[
|
||||||
|
{ value: 'one', label: 'one' },
|
||||||
|
{ value: 'two', label: 'two' },
|
||||||
|
{ value: 'three', label: 'three' },
|
||||||
|
{ value: 'four', label: 'four' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
## No Options
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<div className="flex flex-col flex-1 p-4 items-center">
|
||||||
|
<div className="w-20">
|
||||||
|
<Select
|
||||||
|
noOptionsMessage={() => {
|
||||||
|
'No Options';
|
||||||
|
}}
|
||||||
|
options={[]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Playground>
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
<Props of={Select} />
|
||||||
2
platform/ui/src/components/Select/index.js
Normal file
2
platform/ui/src/components/Select/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import Select from './Select';
|
||||||
|
export default Select;
|
||||||
@ -4,6 +4,7 @@ import DateRange from './DateRange';
|
|||||||
import Icon from './Icon';
|
import Icon from './Icon';
|
||||||
import IconButton from './IconButton';
|
import IconButton from './IconButton';
|
||||||
import Input from './Input';
|
import Input from './Input';
|
||||||
|
import Select from './Select';
|
||||||
import Svg from './Svg';
|
import Svg from './Svg';
|
||||||
import ThemeWrapper from './ThemeWrapper/';
|
import ThemeWrapper from './ThemeWrapper/';
|
||||||
import Typography from './Typography';
|
import Typography from './Typography';
|
||||||
@ -15,6 +16,7 @@ export {
|
|||||||
Icon,
|
Icon,
|
||||||
IconButton,
|
IconButton,
|
||||||
Input,
|
Input,
|
||||||
|
Select,
|
||||||
Svg,
|
Svg,
|
||||||
ThemeWrapper,
|
ThemeWrapper,
|
||||||
Typography,
|
Typography,
|
||||||
|
|||||||
@ -39,7 +39,13 @@ const filtersMeta = [
|
|||||||
{
|
{
|
||||||
name: 'modality',
|
name: 'modality',
|
||||||
displayName: 'Modality',
|
displayName: 'Modality',
|
||||||
inputType: 'text',
|
inputType: 'select',
|
||||||
|
selectOptions: [
|
||||||
|
{ value: 'seg', label: 'seg' },
|
||||||
|
{ value: 'ct', label: 'ct' },
|
||||||
|
{ value: 'mr', label: 'mr' },
|
||||||
|
{ value: 'sr', label: 'sr' },
|
||||||
|
],
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
gridCol: 3,
|
gridCol: 3,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
import { Button, Icon, Input, Typography, DateRange } from '@ohif/ui';
|
import { Button, Icon, Input, Typography, Select, DateRange } from '@ohif/ui';
|
||||||
|
|
||||||
const sortIconMap = {
|
const sortIconMap = {
|
||||||
'-1': 'sorting-active-down',
|
'-1': 'sorting-active-down',
|
||||||
@ -127,7 +127,7 @@ const StudyListFilter = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderInput = (inputType, name) => {
|
const renderInput = (inputType, name, { selectOptions }) => {
|
||||||
switch (inputType) {
|
switch (inputType) {
|
||||||
case 'date-range': {
|
case 'date-range': {
|
||||||
return (
|
return (
|
||||||
@ -146,8 +146,10 @@ const StudyListFilter = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case 'select': {
|
||||||
default:
|
return <Select options={selectOptions}></Select>;
|
||||||
|
}
|
||||||
|
case 'text': {
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
className="border-custom-blue mt-2 bg-black"
|
className="border-custom-blue mt-2 bg-black"
|
||||||
@ -157,6 +159,9 @@ const StudyListFilter = ({
|
|||||||
onChange={event => handleFilterValueChange(event, name)}
|
onChange={event => handleFilterValueChange(event, name)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -220,7 +225,14 @@ const StudyListFilter = ({
|
|||||||
<div className="container m-auto relative flex flex-col">
|
<div className="container m-auto relative flex flex-col">
|
||||||
<div className="flex flex-row w-full">
|
<div className="flex flex-row w-full">
|
||||||
{filtersMeta.map(
|
{filtersMeta.map(
|
||||||
({ name, displayName, inputType, isSortable, gridCol }) => {
|
({
|
||||||
|
name,
|
||||||
|
displayName,
|
||||||
|
inputType,
|
||||||
|
isSortable,
|
||||||
|
gridCol,
|
||||||
|
selectOptions,
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={name}
|
key={name}
|
||||||
@ -240,7 +252,7 @@ const StudyListFilter = ({
|
|||||||
onLabelClick={() => handleFilterLabelClick(name)}
|
onLabelClick={() => handleFilterLabelClick(name)}
|
||||||
inputType={inputType}
|
inputType={inputType}
|
||||||
>
|
>
|
||||||
{inputType !== 'none' && renderInput(inputType, name)}
|
{renderInput(inputType, name, { selectOptions })}
|
||||||
</FilterLabel>
|
</FilterLabel>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user