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

Item Collection: Enhance API #218

Closed
1 of 4 tasks
emilyrohrbough opened this issue Oct 26, 2017 · 5 comments
Closed
1 of 4 tasks

Item Collection: Enhance API #218

emilyrohrbough opened this issue Oct 26, 2017 · 5 comments

Comments

@emilyrohrbough
Copy link
Contributor

Issue Description

The current prop row takes an array of hashes to generate the list and table displays. This is hard to use and inflexible for future enhancements.

Tech Design Considerations:

Issue Type

  • New Feature
  • Enhancement
  • Bug
  • Other

NOTE: This will be a major version bump.

@emilyrohrbough
Copy link
Contributor Author

emilyrohrbough commented Oct 26, 2017

Tech Design for Item Collection Enhancement

Summary

Tech Design Considerations:

  1. Support Children API
    -Proposal: Create ItemCollection Item Component.
  2. Support Headers and Subheaders Item Collection: Add subheaders to the ItemCollection #216
    -This needs more design input & will be implemented later.
  3. Options between static, single select and multi select rendering
    -Current: Single Select.
    -Proposal: add type prop
  4. Handling column layout Item Collection: Column span should be determined by the row with the most columns #213
    -Current: calculates what elements are present on the first has provided in the rows props and forces remaining to align
    -Proposal: add requiredElements prop. Looping through each child to determine the longest row could be cost/unreasonable if many children are present. Instead allow consumer to provide the expected layout, with the default to show every possible element. At most, 1 start accessory, 8 displays, 1 comment and 1 end accessory will be displayed.

Item Collection API Enhancement

  • Maintain breakpoint, listStyles, tableStyles, and onChange props
  • Deprecate rows prop
  • Add the following props:
Prop Type Default Description Consideration
children node null The items to flex between an list item or a table row. (Later will also include headers and subheaders) 1 & 2
type string static This indicates what type of lists/tables to render. Options include 'static', 'singleSelect', 'multiSelect'. 3
requiredElements shape { startAccessory: true, displays: 8, comment: true, endAccessory: true } Required elements of the collection. This allows to consistent formatting and visual expectation. 3

This component will export the following components: ItemCollection.Item, ItemCollection.Display and ItemCollection.Comment. Later will also export ItemCollection.Header and ItemCollection.Subheader.

Item Component

Summary

This component would handle the rendering of a list item or table row for the ItemCollection. By default, this would render an ListItem with an ItemView as the content. Else it will render a TableRow with the element layout (startAccessory, displays, comment, endAccessory). This component would not handle missing element logic, but provides a clean way to represent an item within the item collection.

Additionally, this component will export the ItemView.Display and ItemView.Comment components as Item.Display & Item.Comment.

React Props:

As a replacement to the rows prop, the pieces of the expected row hash will now be their own prop.

Prop Type Default Description
startAccessory element undefined Element to be placed in the start aligned accessory position.
children array of elements undefined Display elements to be presented.
comment element undefined Comment element to be presented.
endAccessory element undefined Element to be placed in the start aligned accessory position.
itemViewStyles element { layout: 'oneColumn', textEmphasis: 'default', isTruncated: false, accessoryAlignment: 'alignCenter' } The styles to apply to the ItemView when represented as a list item. Styles options are layout, textEmphasis, isTruncated and accessoryAlignment.
  • QUESTION Stephen & I talked and we both felt the use of children in place of ItemView's displays prop would allow for easier implementation. However we could make this displays and match the implementation of ItemView. Opinions??
  • QUESTION There will be a customProp display which will be passed down by the ItemCollection. Would exposing it be valuable to consumers attempting to construct their own lists/tables. Or should Item strictly be utilized by ItemCollection? My vote would be to only support ItemCollection Item within ItemCollection. Thoughts??

Implementation:

<Item
  startAccessory={ <Accessory />}
  comment={ <Item.Comment />}
  endAcessory={ <Accessory />}
  itemViewStyles={{ isTruncated: true }}
>
  <Item.Display />
  <Item.Display />
  <Item.Display />
</Item>

Header & Subheader Component

There are some design/behavior aspects that need to be considered and will land this work in a separate PR/tech design.

New Proposed ItemCollection Implementation

Basic Construction Overview

<ItemCollection {...ItemCollectionProps}>
  <ItemCollection.Item startAccessory={} endAccessory={} comment={}>
    <ItemCollection.Display />
    <ItemCollection.Display />
    <ItemCollection.Display />
  </ItemCollection.Item>
  <ItemCollection.Item />
  <ItemCollection.Item />
</ItemCollection>

Actual Example

# Example
import React form 'terra-item-collection';
import ItemCollection from 'terra-clinical-item-collection';

<ItemCollection
  breakpoint="small"
  type="static"
  tableStyles={{ isPadded: true }}
  listStyles={{ isDivided: true }}
  requiredElements={{ startAccessory: true, endAccessory: true, displays: 3, comment: true }}
>
  <ItemCollection.Item
    startAccessory={<IconAlert />}
    comment={ <ItemCollection.Comment text="Faint red rash appeared at 08-05-2016 13:24:00" />}
    endAcessory={<IconInformation />}
    itemViewStyles={{ isTruncated: true }}
  >
    <ItemCollection.Display icon={<IconPerson />} text="Asif Khan" />
    <ItemCollection.Display text="Care Position: Primary" />
    <ItemCollection.Display text="Room 100A" />
  </ItemCollection.Item>
  <ItemCollection.Item
    endAcessory={<IconInformation />}
    itemViewStyles={{ isTruncated: true }}
  >
    <ItemCollection.Display icon={<IconPerson />} text="John Doe" />
    <ItemCollection.Display text="Care Position: Secondary" />
  </ItemCollection.Item>
</ItemCollection>

@tbiethman
Copy link
Contributor

tbiethman commented Oct 26, 2017

+1. This looks really good.

The one concern I do have is providing an uncontrolled (i.e. internally stateful) Single-/MultiSelect-ItemCollection at all. I'm sure I haven't thought through every scenario, but a majority of the scenarios that I have thought of will require the (consumer) controlled component. It wouldn't necessarily hurt to continue providing uncontrolled components (in addition to controlled), but it may cause confusion among the consumer base unless we can provide documentation that clearly communicates "These are the scenarios in which using the uncontrolled component is possible." I just fear that that list of scenarios will be pretty short (and not justify the cost of development/maintenance/confusion). Maybe we could start with the controlled version and see what consumers ask for?

Regardless, we should develop a canonical example for maintaining selections that people can reference when building their own components. That may just be the current SingleSelectItemCollection (just in a non-released form? I dunno 🤷‍♂️).

@emilyrohrbough
Copy link
Contributor Author

emilyrohrbough commented Oct 27, 2017

Updating requiredElements prop shape to be

{
startAccessoryRequired: PropType.bool,
displaysRequired: PropType.number,
commentRequired: PropType.bool,
endAccessoryRequired: PropType.bool,
}

@mjhenkes
Copy link
Contributor

mjhenkes commented Oct 30, 2017

After some offline discussions with @tbiethman , I support his suggestion to not offer a single-/multiselect item collection initially. While I can see value in providing built in selection functionality there is a concern that we don't know enough yet to implement it correctly. In this case, not doing something is preferred to doing something wrong. After we gather some more feedback on consumers using the uncontrolled item collection we can revisit this topic to see if a controlled single/multiselect makes sense. Adding components later would be passive. Removing them if we make a mistake or they aren't used would be non passive.

@emilyrohrbough
Copy link
Contributor Author

I will be removing the onChange prop until we decide how we want to move forward with offering an internally state-managed Item Collection component.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants