feat: enhanced notifications and toolbar hover states (#3032)
* fix: button hover state and overlay colors in tmtv * fix: styles for notificaionts
This commit is contained in:
1 parent
be6b8629be
commit
bbfdda7fe7
18 files changed
+185
-88
No files matched your search
@@ -64,6 +64,6 @@
|
||||
"postcss": "^8.3.5",
|
||||
"postcss-loader": "^6.1.1",
|
||||
"prop-types": "15.7.2",
|
||||
"tailwindcss": "3.1.8"
|
||||
"tailwindcss": "3.2.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path d="M24 11.794c.017 6.667-5.333 12.108-12 12.205a11.823 11.823 0 0 1-12-11.79C-.019 5.541 5.331.1 12 .001a11.824 11.824 0 0 1 12 11.793z" fill="#B70D11"/>
|
||||
<g stroke="#FFF" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
|
||||
<path d="M11.494 17.158a.245.245 0 0 0-.241.255.254.254 0 0 0 .253.245h0a.246.246 0 0 0 .241-.255.253.253 0 0 0-.244-.245h-.005M11.503 13V6"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 566 B |
@@ -0,0 +1,8 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<circle fill="#0944B3" cx="12" cy="12" r="12"/>
|
||||
<g stroke="#FFF" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12.538 17.423V11.5a.846.846 0 0 0-.846-.846H10M11.27 6.423a.423.423 0 1 1 0 .846.423.423 0 0 1 0-.846M10 17.425h5.077"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 425 B |
@@ -0,0 +1,6 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path d="M24 11.794c.017 6.667-5.333 12.108-12 12.205a11.823 11.823 0 0 1-12-11.79C-.019 5.541 5.331.1 12 .001a11.824 11.824 0 0 1 12 11.793z" fill="#61C840"/>
|
||||
<path d="m17.5 7.5-7 9.5-5-4" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 428 B |
@@ -0,0 +1,8 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path d="M24 11.794c.017 6.667-5.333 12.108-12 12.205a11.823 11.823 0 0 1-12-11.79C-.019 5.541 5.331.1 12 .001a11.824 11.824 0 0 1 12 11.793z" fill="#F1CC1B"/>
|
||||
<g stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
|
||||
<path d="M11.494 17.158a.245.245 0 0 0-.241.255.254.254 0 0 0 .253.245h0a.246.246 0 0 0 .241-.255.253.253 0 0 0-.244-.245h-.005M11.503 13V6"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 566 B |
@@ -53,6 +53,10 @@ import tabSegmentation from './../../assets/icons/tab-segmentation.svg';
|
||||
import uiArrowDown from './../../assets/icons/ui-arrow-down.svg';
|
||||
import uiArrowUp from './../../assets/icons/ui-arrow-up.svg';
|
||||
import loadingOHIFMark from './../../assets/icons/loading-ohif-mark.svg';
|
||||
import notificationsInfo from './../../assets/icons/notifications-info.svg';
|
||||
import notificationsWarning from './../../assets/icons/notifications-warning.svg';
|
||||
import notificationsError from './../../assets/icons/notifications-error.svg';
|
||||
import notificationsSuccess from './../../assets/icons/notifications-success.svg';
|
||||
|
||||
/** Tools */
|
||||
import toolZoom from './../../assets/icons/tool-zoom.svg';
|
||||
@@ -152,6 +156,10 @@ const ICONS = {
|
||||
'checkbox-checked': checkboxChecked,
|
||||
'checkbox-unchecked': checkboxUnchecked,
|
||||
'loading-ohif-mark': loadingOHIFMark,
|
||||
'notifications-info': notificationsInfo,
|
||||
'notifications-error': notificationsError,
|
||||
'notifications-success': notificationsSuccess,
|
||||
'notifications-warning': notificationsWarning,
|
||||
|
||||
/** Tools */
|
||||
'tool-zoom': toolZoom,
|
||||
|
||||
@@ -42,19 +42,11 @@
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.sb-title {
|
||||
@apply break-normal text-lg font-bold;
|
||||
}
|
||||
|
||||
.sb-message {
|
||||
@apply break-normal text-base;
|
||||
}
|
||||
|
||||
.sb-item {
|
||||
animation: fadein 1s;
|
||||
box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.2), 0 1px 18px 0 rgba(0, 0, 0, 0.12),
|
||||
0 3px 5px -1px rgba(0, 0, 0, 0.14);
|
||||
@apply relative p-5 text-white overflow-hidden rounded-md transition-height ease-in-out duration-300;
|
||||
@apply relative p-3 text-white overflow-hidden rounded-md transition-height ease-in-out duration-300;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import SnackbarItem from './SnackbarItem'
|
||||
import SnackbarItem from './SnackbarItem';
|
||||
import { useSnackbar } from '../../contextProviders/SnackbarProvider';
|
||||
|
||||
import './Snackbar.css';
|
||||
@@ -8,11 +8,7 @@ const SnackbarContainer = () => {
|
||||
const { snackbarItems, hide } = useSnackbar();
|
||||
|
||||
const renderItem = item => (
|
||||
<SnackbarItem
|
||||
key={item.itemId}
|
||||
options={item}
|
||||
onClose={hide}
|
||||
/>
|
||||
<SnackbarItem key={item.itemId} options={item} onClose={hide} />
|
||||
);
|
||||
|
||||
const renderItems = () => {
|
||||
@@ -26,23 +22,27 @@ const SnackbarContainer = () => {
|
||||
};
|
||||
|
||||
snackbarItems.forEach(item => items[item.position].push(item));
|
||||
return (
|
||||
snackbarItems && (
|
||||
<div>
|
||||
{Object.keys(items).map(pos => {
|
||||
if (!items[pos].length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return snackbarItems && (
|
||||
<div>
|
||||
{Object.keys(items).map(pos => {
|
||||
if (!items[pos].length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={pos} className={`fixed z-50 p-6 box-border h-auto sb-${pos}`}>
|
||||
{items[pos].map((item, index) => (
|
||||
<div key={item.id + index}>{renderItem(item)}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
return (
|
||||
<div
|
||||
key={pos}
|
||||
className={`fixed z-50 p-6 box-border h-auto sb-${pos}`}
|
||||
>
|
||||
{items[pos].map((item, index) => (
|
||||
<div key={item.id + index}>{renderItem(item)}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import Icon from '../Icon';
|
||||
import IconButton from '../IconButton';
|
||||
|
||||
import SnackbarTypes from './SnackbarTypes';
|
||||
|
||||
const iconClasses = {
|
||||
[SnackbarTypes.INFO]: 'notifications-info',
|
||||
[SnackbarTypes.WARNING]: 'notifications-warning',
|
||||
[SnackbarTypes.SUCCESS]: 'notifications-success',
|
||||
[SnackbarTypes.ERROR]: 'notifications-error',
|
||||
};
|
||||
|
||||
const SnackbarItem = ({ options, onClose }) => {
|
||||
const handleClose = () => onClose(options.id);
|
||||
|
||||
@@ -15,10 +21,10 @@ const SnackbarItem = ({ options, onClose }) => {
|
||||
}, []);
|
||||
|
||||
const typeClasses = {
|
||||
[SnackbarTypes.INFO]: 'bg-primary-active',
|
||||
[SnackbarTypes.WARNING]: 'bg-yellow-600',
|
||||
[SnackbarTypes.SUCCESS]: 'bg-green-600',
|
||||
[SnackbarTypes.ERROR]: 'bg-red-600',
|
||||
[SnackbarTypes.INFO]: 'bg-[#bed1db]',
|
||||
[SnackbarTypes.WARNING]: 'bg-[#ebe5c4]',
|
||||
[SnackbarTypes.SUCCESS]: 'bg-[#c6d9bf]',
|
||||
[SnackbarTypes.ERROR]: 'bg-[#dabdbe]',
|
||||
};
|
||||
|
||||
const hidden =
|
||||
@@ -31,17 +37,28 @@ const SnackbarItem = ({ options, onClose }) => {
|
||||
typeClasses[options.type]
|
||||
)}
|
||||
>
|
||||
{/* <span className="sb-closeBtn" onClick={handleClose}> */}
|
||||
{/* <span className="sb-closeIcon">x</span> */}
|
||||
<div
|
||||
onClick={handleClose}
|
||||
className="w-5 h-5 rounded-full absolute bg-white flex items-center justify-center right-0 top-0 mr-2 mt-2"
|
||||
>
|
||||
<Icon name="close" className="w-4 text-black" />
|
||||
<div className="flex ">
|
||||
<div
|
||||
onClick={handleClose}
|
||||
className="w-5 h-5 rounded-full absolute flex items-center justify-center right-0 top-0 mr-2 mt-2 text-[#0944b3]"
|
||||
>
|
||||
<Icon name="close" className="w-5 h-5 text-black" />
|
||||
</div>
|
||||
<Icon name={iconClasses[options.type]} className="w-5 h-5 mt-[1px]" />
|
||||
<div className="flex-col ml-2">
|
||||
{/* </span> */}
|
||||
{options.title && (
|
||||
<div className="break-normal text-lg font-bold text-black">
|
||||
{options.title}
|
||||
</div>
|
||||
)}
|
||||
{options.message && (
|
||||
<div className="break-normal text-base text-black">
|
||||
{options.message}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* </span> */}
|
||||
{options.title && <div className="sb-title">{options.title}</div>}
|
||||
{options.message && <div className="sb-message">{options.message}</div>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,14 +8,14 @@ import { Icon, Tooltip, ListMenu } from '../';
|
||||
|
||||
const baseClasses = {
|
||||
Button:
|
||||
'flex items-center rounded-md border-transparent border-2 cursor-pointer',
|
||||
'flex items-center rounded-md border-transparent border-2 cursor-pointer group/button',
|
||||
Primary:
|
||||
'h-full flex flex-1 items-center rounded-md rounded-tr-none rounded-br-none',
|
||||
'h-full flex flex-1 items-center rounded-md rounded-tr-none rounded-br-none group/primary',
|
||||
Secondary:
|
||||
'h-full flex items-center justify-center rounded-tr-md rounded-br-md w-4',
|
||||
'h-full flex items-center justify-center rounded-tr-md rounded-br-md w-4 group/secondary',
|
||||
PrimaryIcon: 'w-5 h-5',
|
||||
SecondaryIcon: 'w-4 h-full stroke-1',
|
||||
Separator: 'border-l pt-2 pb-2',
|
||||
Separator: 'border-l py-2.5',
|
||||
Content: 'absolute z-10 top-0 mt-12',
|
||||
};
|
||||
|
||||
@@ -49,8 +49,10 @@ const classes = {
|
||||
PrimaryIcon: ({ primary, isExpanded }) =>
|
||||
classNames(
|
||||
baseClasses.PrimaryIcon,
|
||||
!primary.isActive &&
|
||||
'group-hover/primary:text-primary-light group-hover/secondary:text-primary-light group-hover/button:text-primary-light',
|
||||
primary.isActive && !isExpanded
|
||||
? 'text-primary-dark'
|
||||
? 'text-primary-dark '
|
||||
: 'text-common-bright'
|
||||
),
|
||||
SecondaryIcon: ({ isExpanded }) =>
|
||||
@@ -58,7 +60,7 @@ const classes = {
|
||||
baseClasses.SecondaryIcon,
|
||||
isExpanded
|
||||
? 'text-primary-dark'
|
||||
: 'text-primary-active hover:text-common-bright'
|
||||
: 'text-[#348cfd] group-hover/secondary:text-primary-light'
|
||||
),
|
||||
Separator: ({ primary, isExpanded, isHovering }) =>
|
||||
classNames(
|
||||
|
||||
@@ -3,38 +3,46 @@ import classnames from 'classnames';
|
||||
|
||||
import './ViewportOverlay.css';
|
||||
|
||||
const ViewportOverlay = props => {
|
||||
const topLeft = 'top-viewport left-viewport';
|
||||
const topRight = 'top-viewport right-viewport-scrollbar';
|
||||
const bottomRight = 'bottom-viewport right-viewport-scrollbar';
|
||||
const bottomLeft = 'bottom-viewport left-viewport';
|
||||
const overlay = 'absolute pointer-events-none';
|
||||
const classes = {
|
||||
topLeft: 'top-viewport left-viewport',
|
||||
topRight: 'top-viewport right-viewport-scrollbar',
|
||||
bottomRight: 'bottom-viewport right-viewport-scrollbar',
|
||||
bottomLeft: 'bottom-viewport left-viewport',
|
||||
};
|
||||
|
||||
const ViewportOverlay = ({
|
||||
topLeft,
|
||||
topRight,
|
||||
bottomRight,
|
||||
bottomLeft,
|
||||
color,
|
||||
}) => {
|
||||
const overlay = 'absolute pointer-events-none';
|
||||
return (
|
||||
<div className="text-primary-light">
|
||||
<div className={classnames(color ? color : 'text-primary-light')}>
|
||||
<div
|
||||
data-cy={'viewport-overlay-top-left'}
|
||||
className={classnames(overlay, topLeft)}
|
||||
className={classnames(overlay, classes.topLeft)}
|
||||
>
|
||||
{props.topLeft}
|
||||
{topLeft}
|
||||
</div>
|
||||
<div
|
||||
data-cy={'viewport-overlay-top-right'}
|
||||
className={classnames(overlay, topRight)}
|
||||
className={classnames(overlay, classes.topRight)}
|
||||
>
|
||||
{props.topRight}
|
||||
{topRight}
|
||||
</div>
|
||||
<div
|
||||
data-cy={'viewport-overlay-bottom-right'}
|
||||
className={classnames(overlay, bottomRight)}
|
||||
className={classnames(overlay, classes.bottomRight)}
|
||||
>
|
||||
{props.bottomRight}
|
||||
{bottomRight}
|
||||
</div>
|
||||
<div
|
||||
data-cy={'viewport-overlay-bottom-left'}
|
||||
className={classnames(overlay, bottomLeft)}
|
||||
className={classnames(overlay, classes.bottomLeft)}
|
||||
>
|
||||
{props.bottomLeft}
|
||||
{bottomLeft}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user