diff --git a/packages/libs/coreui/src/components/containers/NoteBox.tsx b/packages/libs/coreui/src/components/containers/NoteBox.tsx new file mode 100644 index 0000000000..86ccd763c2 --- /dev/null +++ b/packages/libs/coreui/src/components/containers/NoteBox.tsx @@ -0,0 +1,71 @@ +import { css } from '@emotion/react'; +import React, { ReactNode } from 'react'; +import { error, warning, mutedBlue } from '../../definitions/colors'; +import { Error, Info, Warning } from '@material-ui/icons'; + +export interface Props { + type: 'info' | 'warning' | 'error'; + showIcon?: boolean; + children: ReactNode; +} + +const baseCss = css` + border-left: 0.35em solid var(--note-box-border-color); + border-radius: 0.25em; + padding: 1em 3em; + background: var(--note-box-bg-color); + gap: 1em; + margin-bottom: 1em; + position: relative; +`; + +const infoCss = css` + --note-box-bg-color: ${mutedBlue[100]}; + --note-box-border-color: ${mutedBlue[600]}; + ${baseCss}; +`; + +const warningCss = css` + --note-box-bg-color: ${warning[100]}; + --note-box-border-color: ${warning[600]}; + font-weight: 500; + ${baseCss}; +`; + +const errorCss = css` + --note-box-bg-color: ${error[100]}; + --note-box-border-color: ${error[600]}; + font-weight: 500; + ${baseCss}; +`; + +const iconCss = css` + position: absolute; + left: 0.5em; + font-size: 1.5em; +`; + +export function NoteBox(props: Props) { + const finalCss = + props.type === 'warning' + ? warningCss + : props.type === 'error' + ? errorCss + : infoCss; + + const Icon = + props.showIcon === true + ? props.type === 'info' + ? Info + : props.type === 'warning' + ? Warning + : props.type === 'error' + ? Error + : null + : null; + return ( +
+ {Icon ? : null} {props.children} +
+ ); +} diff --git a/packages/libs/coreui/src/index.ts b/packages/libs/coreui/src/index.ts index 3dca9af1b5..a4cb9293e9 100644 --- a/packages/libs/coreui/src/index.ts +++ b/packages/libs/coreui/src/index.ts @@ -30,6 +30,7 @@ export { default as SelectTree } from './components/inputs/SelectTree/SelectTree export { default as SearchBox } from './components/inputs/SearchBox/SearchBox'; export { default as CheckboxList } from './components/inputs/checkboxes/CheckboxList'; export { default as CheckboxTree } from './components/inputs/checkboxes/CheckboxTree/CheckboxTree'; +export { NoteBox } from './components/containers/NoteBox'; export { default as styles } from './styleDefinitions'; export { default as colors } from './definitions/colors'; diff --git a/packages/libs/coreui/src/stories/containers/NoteBox.stories.tsx b/packages/libs/coreui/src/stories/containers/NoteBox.stories.tsx new file mode 100644 index 0000000000..4f6ff41314 --- /dev/null +++ b/packages/libs/coreui/src/stories/containers/NoteBox.stories.tsx @@ -0,0 +1,156 @@ +import React from 'react'; +import { NoteBox, Props } from '../../components/containers/NoteBox'; +import { Story, Meta } from '@storybook/react/types-6-0'; +import { UIThemeProvider } from '../../components/theming'; +import { mutedGreen, mutedMagenta } from '../../definitions/colors'; + +export default { + title: 'Containers/NoteBox', + component: NoteBox, +} as Meta; + +const Template: Story = function Template(props) { + return ( +
+ + + +
+ ); +}; + +export const InfoWithoutIcon = Object.assign(Template.bind({}), { + args: { + type: 'info', + showIcon: false, + children: ( +
+ This is some general information about the content that follows on the + page. +
+ ), + }, +}); + +export const WarningWithoutIcon = Object.assign(Template.bind({}), { + args: { + type: 'warning', + showIcon: false, + children: ( +
This is a warning about the content that follows on the page.
+ ), + }, +}); + +export const ErrorWithoutIcon = Object.assign(Template.bind({}), { + args: { + type: 'error', + showIcon: false, + children: ( +
+ This is an error message about the content that follows on the page. +
+ ), + }, +}); + +export const LongContentWithoutIcon = Object.assign(Template.bind({}), { + args: { + type: 'info', + showIcon: false, + children: ( +
+ Lorem ipsum odor amet, consectetuer adipiscing elit. Faucibus morbi ac + ultrices purus urna tristique mattis consequat. Posuere volutpat + facilisi natoque dictumst dignissim magna dapibus. Taciti vel a etiam + curabitur velit torquent. Fusce interdum dictum vulputate sollicitudin + nulla. Orci placerat congue odio aptent enim mauris. Turpis nec rhoncus + eleifend eleifend eget. Auctor sed nullam vestibulum quisque egestas; + nullam aenean ante. +
+ ), + }, +}); + +export const InfoWithIcon = Object.assign(Template.bind({}), { + args: { + type: 'info', + showIcon: true, + children: ( +
+ This is some general information about the content that follows on the + page. +
+ ), + }, +}); + +export const WarningWithIcon = Object.assign(Template.bind({}), { + args: { + type: 'warning', + showIcon: true, + children: ( +
This is a warning about the content that follows on the page.
+ ), + }, +}); + +export const ErrorWithIcon = Object.assign(Template.bind({}), { + args: { + type: 'error', + showIcon: true, + children: ( +
+ This is an error message about the content that follows on the page. +
+ ), + }, +}); + +export const LongContentWithIcon = Object.assign(Template.bind({}), { + args: { + type: 'info', + showIcon: true, + children: ( +
+ Lorem ipsum odor amet, consectetuer adipiscing elit. Faucibus morbi ac + ultrices purus urna tristique mattis consequat. Posuere volutpat + facilisi natoque dictumst dignissim magna dapibus. Taciti vel a etiam + curabitur velit torquent. Fusce interdum dictum vulputate sollicitudin + nulla. Orci placerat congue odio aptent enim mauris. Turpis nec rhoncus + eleifend eleifend eget. Auctor sed nullam vestibulum quisque egestas; + nullam aenean ante. +
+ ), + }, +}); + +export const ExpandableContentWithIcon = Object.assign(Template.bind({}), { + args: { + type: 'info', + showIcon: true, + children: ( +
+ + There are some interesting things about this... + +

+ Lorem ipsum odor amet, consectetuer adipiscing elit. Faucibus morbi ac + ultrices purus urna tristique mattis consequat. Posuere volutpat + facilisi natoque dictumst dignissim magna dapibus. Taciti vel a etiam + curabitur velit torquent. Fusce interdum dictum vulputate sollicitudin + nulla. Orci placerat congue odio aptent enim mauris. Turpis nec + rhoncus eleifend eleifend eget. Auctor sed nullam vestibulum quisque + egestas; nullam aenean ante. +

+
+ ), + }, +}); diff --git a/packages/libs/wdk-client/src/Views/Records/RecordTable/RecordTableDescription.jsx b/packages/libs/wdk-client/src/Views/Records/RecordTable/RecordTableDescription.jsx index 2351870a9b..d48f81183a 100644 --- a/packages/libs/wdk-client/src/Views/Records/RecordTable/RecordTableDescription.jsx +++ b/packages/libs/wdk-client/src/Views/Records/RecordTable/RecordTableDescription.jsx @@ -1,17 +1,7 @@ import PropTypes from 'prop-types'; import React, { useState } from 'react'; import { safeHtml, wrappable } from '../../../Utils/ComponentUtils'; - -const containerStyle = { - display: 'flex', - flexWrap: 'wrap', - borderLeft: '.2em solid #79a3d7', - borderRight: '.2em solid #79a3d7', - padding: '.5em 1em', - background: '#ebf4ff', - gap: '1em', - marginBottom: '1em', -}; +import { NoteBox } from '@veupathdb/coreui'; function RecordTableDescription(props) { const { description } = props.table; @@ -21,7 +11,7 @@ function RecordTableDescription(props) { if (!description) return null; return ( -
+ {safeHtml( description, { @@ -30,7 +20,7 @@ function RecordTableDescription(props) { return; } if ( - el.clientWidth >= el.scrollWidth || + el.clientWidth >= el.scrollWidth && el.clientHeight >= el.scrollHeight ) { setIsOverflowing(false); @@ -51,15 +41,23 @@ function RecordTableDescription(props) { 'div' )} {isOverflowing && ( - + <> + + )} -
+ ); } diff --git a/packages/sites/ortho-site/webapp/wdkCustomization/js/client/records/Sequences.tsx b/packages/sites/ortho-site/webapp/wdkCustomization/js/client/records/Sequences.tsx index 1efea4f282..db2ed1a9c4 100644 --- a/packages/sites/ortho-site/webapp/wdkCustomization/js/client/records/Sequences.tsx +++ b/packages/sites/ortho-site/webapp/wdkCustomization/js/client/records/Sequences.tsx @@ -31,6 +31,7 @@ import { PfamDomain } from 'ortho-client/components/pfam-domains/PfamDomain'; import { FilledButton, FloatingButton, + NoteBox, OutlinedButton, SelectList, Undo, @@ -637,7 +638,7 @@ export function RecordTable_Sequences( if (filteredRows == null) return null; - const warningText = + const errorText = numSequences >= MIN_SEQUENCES_FOR_TREE && (filteredRows.length > MAX_SEQUENCES_FOR_TREE || filteredRows.length < MIN_SEQUENCES_FOR_TREE) ? ( @@ -662,23 +663,7 @@ export function RecordTable_Sequences( } as CSSProperties } > - {warningText && ( -
- {warningText} -
- )} + {errorText && {errorText}}