Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

Commit

Permalink
[clinical-item-view] Add row vs column view prop
Browse files Browse the repository at this point in the history
  • Loading branch information
ry061521 committed Aug 30, 2023
1 parent 2bfc18e commit e91e252
Show file tree
Hide file tree
Showing 101 changed files with 613 additions and 33 deletions.
109 changes: 85 additions & 24 deletions packages/terra-clinical-item-view/src/ItemView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ const AccessoryAlignments = {

const propTypes = {
/**
* The column layout in which to present the displays. One of `oneColumn`, `twoColumn`.
* The visual column layout in which to present the displays. One of `oneColumn`, `twoColumn`.
*/
layout: PropTypes.oneOf(['oneColumn', 'twoColumns']),
/**
* Determines whether the displays are programatically separated by row or as true columns when layout is set to `twoColumns`.
*/
trueColumn: PropTypes.bool,
/**
* The text color emphasis when using two columns. One of `default`, `start`.
*/
Expand Down Expand Up @@ -73,6 +77,7 @@ const propTypes = {

const defaultProps = {
layout: Layouts.ONE_COLUMN,
trueColumn: true,
textEmphasis: TextEmphasisTypes.DEFAULT,
overrideDefaultStyling: false,
isTruncated: false,
Expand Down Expand Up @@ -120,26 +125,65 @@ const defaultEmphasisContentClassesFromIndexes = (rowIndex, rowCount) => {
return [contentSize, contentColor];
};

const startEmphasisContentClassesFromIndexes = (rowIndex, rowCount, columnIndex) => {
if (columnIndex > 0 || rowIndex >= 2) {
const startEmphasisContentClassesFromIndexes = (rowIndex, rowCount, contentIndex) => {
if (contentIndex > 0 || rowIndex >= 2) {
return ['content-secondary-size', 'content-secondary-color'];
}

return defaultEmphasisContentClassesFromIndexes(rowIndex, rowCount);
};

const classesForContent = (rowIndex, rowCount, columnIndex, emphasis) => {
const classesForContent = (rowIndex, rowCount, contentIndex, emphasis) => {
let classes;

if (emphasis === TextEmphasisTypes.START) {
classes = startEmphasisContentClassesFromIndexes(rowIndex, rowCount, columnIndex);
classes = startEmphasisContentClassesFromIndexes(rowIndex, rowCount, contentIndex);
} else {
classes = defaultEmphasisContentClassesFromIndexes(rowIndex, rowCount);
}

return ['content'].concat(classes);
};

const twoColumnGrouping = (displays) => {
let count = 0;
const displayGroups = [];
const primaryColumn = [];
const secondaryColumn = [];

while (displays.length) {
count += 1;

if (count % 2 === 0) {
secondaryColumn.push(displays.splice(0, 1));
} else {
primaryColumn.push(displays.splice(0, 1));
}
}

displayGroups.push(primaryColumn);
displayGroups.push(secondaryColumn);

return displayGroups;
};

const renderRow = (row, rowIndex, rowCount, emphasis) => {
const rowKey = rowIndex;
return (
<div className={cx('row')} key={rowKey}>
{row.map((display, displayIndex) => {
const displayKey = displayIndex;
const contentClasses = classesForContent(rowIndex, rowCount, displayIndex, emphasis);
return (
<div className={cx(contentClasses)} key={displayKey}>
{display}
</div>
);
})}
</div>
);
};

const renderColumn = (displayGroup, displayGroupIndex, emphasis, overrideDefaultStyling) => {
const columnKey = displayGroupIndex;
const displayCount = displayGroup.length;
Expand Down Expand Up @@ -173,31 +217,32 @@ const renderColumn = (displayGroup, displayGroupIndex, emphasis, overrideDefault
);
};

const renderView = (displays, layout, emphasis, overrideDefaultStyling) => {
const renderView = (displays, layout, emphasis, overrideDefaultStyling, trueColumn) => {
if (displays === null || displays === undefined || !displays.length) {
return undefined;
}

const primaryColumn = [];
const displayGroups = [];
let displayGroups = [];
const displaysSlice = displays.slice(0, 8);
const primaryColumn = [];

if (layout === Layouts.TWO_COLUMNS) {
let count = 0;
const secondaryColumn = [];

while (displaysSlice.length) {
count += 1;

if (count % 2 === 0) {
secondaryColumn.push(displaysSlice.splice(0, 1));
} else {
primaryColumn.push(displaysSlice.splice(0, 1));
if (trueColumn) {
displayGroups = twoColumnGrouping(displaysSlice);
} else {
while (displaysSlice.length) {
displayGroups.push(displaysSlice.splice(0, 2));
}
}

displayGroups.push(primaryColumn);
displayGroups.push(secondaryColumn);
return (
<div className={cx('row-container')}>
{displayGroups.map((displayRow, rowIndex) => {
const row = renderRow(displayRow, rowIndex, displayGroups.length, emphasis);
return row;
})}
</div>
);
}
} else {
while (displaysSlice.length) {
primaryColumn.push(displaysSlice.splice(0, 1));
Expand All @@ -216,8 +261,21 @@ const renderView = (displays, layout, emphasis, overrideDefaultStyling) => {
);
};

const isDisplaysTruncated = (displays) => {
const displaysSlice = displays.slice(0, 8);

for (let i = 0; i < displaysSlice.length; i += 1) {
if (displaysSlice[i].props.isTruncated === true) {
return true;
}
}

return false;
};

const ItemView = ({
layout,
trueColumn,
textEmphasis,
overrideDefaultStyling,
isTruncated,
Expand All @@ -231,13 +289,16 @@ const ItemView = ({
...customProps
}) => {
const theme = React.useContext(ThemeContext);
const isTrueTwoColumnView = layout === Layouts.TWO_COLUMNS && trueColumn;
const isTruncatedDisplay = isTruncated || isDisplaysTruncated(displays);
const viewClassNames = classNames(
cx(
'item-view',
{ 'is-truncated': isTruncated },
{ 'one-column': layout === Layouts.ONE_COLUMN },
{ 'two-columns': (layout === Layouts.TWO_COLUMNS && !isTruncated) },
{ 'truncated-two-columns': (layout === Layouts.TWO_COLUMNS && isTruncated) },
{ 'two-columns': isTrueTwoColumnView && !isTruncatedDisplay },
{ 'truncated-two-columns': isTrueTwoColumnView && isTruncatedDisplay },
{ 'two-columns-by-row': layout === Layouts.TWO_COLUMNS && !trueColumn },
theme.className,
),
customProps.className,
Expand All @@ -247,7 +308,7 @@ const ItemView = ({
<div {...customProps} className={viewClassNames} ref={refCallback}>
{renderAccessory(startAccessory, reserveStartAccessorySpace, accessoryAlignment, 'start')}
<div className={cx('body')}>
{renderView(displays, layout, textEmphasis, overrideDefaultStyling)}
{renderView(displays, layout, textEmphasis, overrideDefaultStyling, trueColumn)}
{comment}
</div>
{renderAccessory(endAccessory, false, accessoryAlignment, 'end')}
Expand Down
24 changes: 24 additions & 0 deletions packages/terra-clinical-item-view/src/ItemView.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@
}
}

.row {
display: flex;
width: 100%;
}

.is-truncated,
.is-truncated [data-terra-clinical-item-display-text] {
@include terra-clinical-text-truncate;
Expand All @@ -99,6 +104,25 @@
}
}

.two-columns-by-row {
.content:nth-child(odd) {
flex: 1 1 auto;
float: left;
justify-content: flex-start;
}

.content:nth-child(even) {
@include terra-text-align-end();
flex: 1 0 auto;
float: right;
justify-content: flex-end;
// Set a max-width and disable flexbox-squishing on the right-most displays. This will ensure that they aren't
// prematurely squished and maximize the available space for all labels.
max-width: 60%;
padding-left: 5px;
}
}

.truncated-two-columns {
.primary-column {
flex: 1 1 auto;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Badge } from 'terra-clinical-item-view/package.json?dev-site-package';
import ItemViewStandard from '../example/ItemViewStandard?dev-site-example';
import ItemViewTwoColumn from '../example/ItemViewTwoColumn?dev-site-example';
import ItemViewTwoColumnStart from '../example/ItemViewTwoColumnStart?dev-site-example';
import ItemViewTwoColumnByRow from '../example/ItemViewTwoColumnByRow?dev-site-example';
import ItemViewComment from '../example/ItemViewComment?dev-site-example';
import ItemViewAll from '../example/ItemViewAll?dev-site-example';
import ItemViewAllTopAligned from '../example/ItemViewAllTopAligned?dev-site-example';
Expand Down Expand Up @@ -37,6 +38,10 @@ import ItemView from 'terra-clinical-item-view';
title="ItemView - Two Column Layout"
description="When including icons as part of an '<ItemView.Display />'', it is recommended to use the iconAlignment='inline' prop for best alignment and wrapping with the text."
/>
<ItemViewTwoColumnByRow
title="ItemView - Two Column Layout By Row"
description="When the `trueColumn` prop is set to `false` the displays are split two at a time into rows which are stylized to look like columns instead of true columns. So the ItemView is formatted to look like columns but programatically it's handled by row."
/>
<ItemViewTwoColumnStart title="ItemView - Start Emphasis" />
<ItemViewComment title="ItemView - Comment" />
<ItemViewAll title="ItemView - All Elements" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import IconBriefcase from 'terra-icon/lib/icon/IconBriefcase';
import IconPerson from 'terra-icon/lib/icon/IconPerson';
import ItemView from 'terra-clinical-item-view';

const display1 = <ItemView.Display icon={<IconPerson />} iconAlignment="inline" text="Asif Khan" />;
const display2 = <ItemView.Display icon={<IconBriefcase />} iconAlignment="inline" text="Care Position: Primary" />;
const display3 = <ItemView.Display text="Room 100A" />;
const display4 = <ItemView.Display text="Acuity: 5" />;
const display5 = <ItemView.Display text="Start Time: 08-05-2016 12:00:00" />;
const display6 = <ItemView.Display text="End Time: 08-05-2016 16:00:00" />;
const displays = [display1, display2, display3, display4, display5, display6];

export default () => <ItemView displays={displays} layout="twoColumns" trueColumn={false} />;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import IconAlert from 'terra-icon/lib/icon/IconAlert';
import ItemView from '../../../ItemView';

const display1 = <ItemView.Display icon={<IconAlert />} iconAlignment="inline" text="display1 Text display1 Text display1 Text display1 Text display1 Text display1 Text display1 Text display1 Text" key="123" />;
const display2 = <ItemView.Display icon={<IconAlert />} iconAlignment="inline" text="display2 Text display2 Text display2 Text display2 Text display2 Text display2 Text display2 Text display2 Text display2 Text" key="124" />;
const display3 = <ItemView.Display text="display 3" key="125" />;
const display4 = <ItemView.Display text="display 4" key="126" />;
const display5 = <ItemView.Display text="display 5" key="127" />;
const display6 = <ItemView.Display text="display 6" key="128" />;
const displays = [display1, display2, display3, display4, display5, display6];

const views = () => (
<div>
<h2>Two Column Layout by Row </h2>
<ItemView displays={displays} trueColumn={false} layout="twoColumns" id="test-displays-two-row" />
<br />
<h2>Two Column Layout by Row with Start TextEmphasis </h2>
<ItemView displays={displays} trueColumn={false} layout="twoColumns" textEmphasis="start" id="test-displays-two-row-start" />
</div>
);

export default views;
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ const display4 = <ItemView.Display text="display 4" key="126" />;
const display5 = <ItemView.Display text="display 5" key="127" />;
const display6 = <ItemView.Display text="display 6" key="128" />;
const displays = [display1, display2, display3, display4, display5, display6];
const isTruncatedDisplay1 = <ItemView.Display isTruncated text="display1display1display1display1display1display1display1display1display1display1display1display1display1display1" key="1234" />;
const isTruncatedDisplay2 = <ItemView.Display isTruncated text="display2display2display2display2display2display2display2display2display2display2display2display2display2display2" key="1245" />;
const partialTruncatedDisplays = [isTruncatedDisplay1, isTruncatedDisplay2, display3, display4, display5, display6];
const leftPartialTruncatedDisplays = [isTruncatedDisplay1, display2, display3, display4, display5, display6];
const rightPartialTruncatedDisplays = [display1, isTruncatedDisplay2, display3, display4, display5, display6];

const accessoryStart = id => <IconAlert id={id} />;
const accessoryEnd = id => <IconInformation id={id} />;
Expand All @@ -24,14 +29,26 @@ const views = () => (
<p>Applied width of 900px to show the default vs truncated styling.</p>
<br />
<h2>Full Examples - Default</h2>
<ItemView comment={comment(1)} startAccessory={accessoryStart(5)} endAccessory={accessoryEnd(9)} displays={displays} id="ItemView-one-wrap" />
<ItemView comment={comment(1)} startAccessory={accessoryStart(9)} endAccessory={accessoryEnd(17)} displays={displays} id="ItemView-one-wrap" />
<br />
<ItemView comment={comment(2)} startAccessory={accessoryStart(6)} endAccessory={accessoryEnd(10)} displays={displays} layout="twoColumns" id="ItemView-two-wrap" />
<ItemView comment={comment(2)} startAccessory={accessoryStart(10)} endAccessory={accessoryEnd(18)} displays={displays} layout="twoColumns" id="ItemView-two-wrap" />
<br />
<h2>Full Examples - Truncated</h2>
<ItemView displays={displays} isTruncated comment={comment(3)} startAccessory={accessoryStart(7)} endAccessory={accessoryEnd(11)} textEmphasis="start" id="ItemView-one-truncate" />
<ItemView displays={displays} isTruncated comment={comment(3)} startAccessory={accessoryStart(11)} endAccessory={accessoryEnd(19)} textEmphasis="start" id="ItemView-one-truncate" />
<br />
<ItemView displays={displays} isTruncated comment={comment(4)} startAccessory={accessoryStart(8)} endAccessory={accessoryEnd(12)} layout="twoColumns" textEmphasis="start" id="ItemView-two-truncate" />
<ItemView displays={displays} isTruncated comment={comment(4)} startAccessory={accessoryStart(12)} endAccessory={accessoryEnd(20)} layout="twoColumns" textEmphasis="start" id="ItemView-two-truncate" />
<br />
<h2>Partial Truncation Examples - Single Column</h2>
<ItemView displays={leftPartialTruncatedDisplays} comment={comment(5)} startAccessory={accessoryStart(13)} endAccessory={accessoryEnd(21)} textEmphasis="start" id="ItemView-one-partial-truncate" />
<br />
<h2>Partial Truncation Examples - Two Column Left and Right Truncated</h2>
<ItemView displays={partialTruncatedDisplays} comment={comment(6)} startAccessory={accessoryStart(14)} endAccessory={accessoryEnd(22)} layout="twoColumns" textEmphasis="start" id="ItemView-two-partial-truncate" />
<br />
<h2>Partial Truncation Examples - Two Column Left Truncated</h2>
<ItemView displays={leftPartialTruncatedDisplays} comment={comment(7)} startAccessory={accessoryStart(15)} endAccessory={accessoryEnd(23)} layout="twoColumns" textEmphasis="start" id="ItemView-two-partial-left-truncate" />
<br />
<h2>Partial Truncation Examples - Two Column Right Truncated</h2>
<ItemView displays={rightPartialTruncatedDisplays} comment={comment(8)} startAccessory={accessoryStart(16)} endAccessory={accessoryEnd(24)} layout="twoColumns" textEmphasis="start" id="ItemView-two-partial-right-truncate" />
</div>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';
import IconAlert from 'terra-icon/lib/icon/IconAlert';
import IconInformation from 'terra-icon/lib/icon/IconInformation';
import classNames from 'classnames/bind';
import ItemView from '../../../ItemView';
import styles from './ItemViewCommon.test.module.scss';

const cx = classNames.bind(styles);

const display1 = <ItemView.Display text="display1display1display1display1display1display1display1display1display1display1display1display1display1display1" key="123" />;
const display2 = <ItemView.Display text="display2display2display2display2display2display2display2display2display2display2display2display2display2display2" key="124" />;
const display3 = <ItemView.Display text="display 3" key="125" />;
const display4 = <ItemView.Display text="display 4" key="126" />;
const display5 = <ItemView.Display text="display 5" key="127" />;
const display6 = <ItemView.Display text="display 6" key="128" />;
const displays = [display1, display2, display3, display4, display5, display6];
const isTruncatedDisplay1 = <ItemView.Display isTruncated text="display1display1display1display1display1display1display1display1display1display1display1display1display1display1" key="1234" />;
const isTruncatedDisplay2 = <ItemView.Display isTruncated text="display2display2display2display2display2display2display2display2display2display2display2display2display2display2" key="1245" />;
const partialTruncatedDisplays = [isTruncatedDisplay1, isTruncatedDisplay2, display3, display4, display5, display6];
const leftPartialTruncatedDisplays = [isTruncatedDisplay1, display2, display3, display4, display5, display6];
const rightPartialTruncatedDisplays = [display1, isTruncatedDisplay2, display3, display4, display5, display6];

const accessoryStart = id => <IconAlert id={id} />;
const accessoryEnd = id => <IconInformation id={id} />;
const comment = id => <ItemView.Comment id={id} text="comment1comment1comment1comment1comment1comment1comment1comment1comment1comment1comment1comment1" />;

const views = () => (
<div className={cx('overflow-displays-itemview')}>
<p>Applied width of 900px to show the default vs truncated styling.</p>
<br />
<h2>Default ItemView</h2>
<ItemView trueColumn={false} comment={comment(2)} startAccessory={accessoryStart(10)} endAccessory={accessoryEnd(18)} displays={displays} layout="twoColumns" id="ItemView-by-row-two-wrap" />
<br />
<h2>Truncated ItemView</h2>
<ItemView trueColumn={false} displays={displays} isTruncated comment={comment(4)} startAccessory={accessoryStart(12)} endAccessory={accessoryEnd(20)} layout="twoColumns" textEmphasis="start" id="ItemView-by-row-two-truncate" />
<br />
<p> The next examples include when ItemView has `isTruncated` set to `false` while the ItemDisplays passed in to the ItemView have the `isTruncated` prop set to `true`.</p>
<h2>Left and Right Displays Truncated</h2>
<ItemView trueColumn={false} displays={partialTruncatedDisplays} comment={comment(6)} startAccessory={accessoryStart(14)} endAccessory={accessoryEnd(22)} layout="twoColumns" textEmphasis="start" id="ItemView-by-row-two-partial-truncate" />
<br />
<h2>Left Display Truncated</h2>
<ItemView trueColumn={false} displays={leftPartialTruncatedDisplays} comment={comment(7)} startAccessory={accessoryStart(15)} endAccessory={accessoryEnd(23)} layout="twoColumns" textEmphasis="start" id="ItemView-by-row-two-partial-left-truncate" />
<br />
<h2>Right Display Truncated</h2>
<ItemView trueColumn={false} displays={rightPartialTruncatedDisplays} comment={comment(8)} startAccessory={accessoryStart(16)} endAccessory={accessoryEnd(24)} layout="twoColumns" textEmphasis="start" id="ItemView-by-row-two-partial-right-truncate" />
</div>
);

export default views;
Loading

0 comments on commit e91e252

Please sign in to comment.