Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Statistic to v1 API #334

Merged
merged 35 commits into from
Jul 18, 2016

Conversation

layershifter
Copy link
Member

API

Types

Statistic

A statistic can display a value with a label above or below it.

<div class="ui statistic">
  <div class="value">5,550</div>
  <div class="label">Downloads</div>
</div>
<div class="ui statistic">
  <div class="label">Views</div>
  <div class="value">40,509</div>
</div>
<Statistic>
  <Statistic.Value>5,550</Statistic.Value>
  <Statistic.Label>Downloads</Statistic.Label>
</Statistic>
<Statistic>
  <Statistic.Label>Views</Statistic.Label>
  <Statistic.Value>40,509</Statistic.Value>
</Statistic>

Statistic Group

A group of statistics

<div class="ui statistics">
  <div class="statistic">
    <div class="value">22</div>
    <div class="label">Faves</div>
  </div>
  ...
</div>
<Statistic.Group>
  <Statistic>
    <Statistic.Value>22</Statistic.Value>
    <Statistic.Label>Faves</Statistic.Label>
  </Statistic>
  ...
</Statistic.Group>

Content

Value

A statistic can contain a numeric, icon, image, or text value

<div class="statistic">
    <div class="value">22</div>
   <div class="label">Saves</div>
</div>
<div class="statistic">
  <div class="text value">Three<br>Thousand</div>
  <div class="label">Signups</div>
</div>
<div class="statistic">
  <div class="value"><i class="plane icon"></i> 5</div>
  <div class="label">Flights</div>
</div>
<div class="statistic">
    <div class="value">
      <img src="/images/avatar/small/joe.jpg" class="ui circular inline image"> 42
    </div>
    <div class="label">Team Members</div>
</div>
<Statistic>
  <Statistic.Value>22</Statistic.Value>
  <Statistic.Label>Saves</Statistic.Label>
</Statistic>
<Statistic>
  <Statistic.Value text>Three<br>Thousand</Statistic.Value>
  <Statistic.Label>Signups</Statistic.Label>
</Statistic>
<Statistic>
  <Statistic.Value><Icon name='plane' /> 5</Statistic.Value>
  <Statistic.Label>Flights</Statistic.Label>
</Statistic>
<Statistic>
  <Statistic.Value><Image src='/images/avatar/small/joe.jpg' ... /></Statistic.Value>
  <Statistic.Label>Team Members</Statistic.Label>
</Statistic>

Label

A statistic can contain a label to help provide context for the presented value

Already showed

Variations

Horizontal Statistic

A statistic can present its measurement horizontally

<div class="ui horizontal statistic">...</div>
<div class="ui horizontal statistics">...</div>
<Statistic horizontal>...</Statistic>
<Statistic.Group horizontal>...</Statistic.Group>

Colored

A statistic can be formatted to be different colors

<div class="red statistic"></div>
<Statistic color='red'>...</Statistic>

Colors will be used from semanticUtils

Inverted

A statistic can be formatted to fit on a dark background

<div class="ui inverted statistic">...</div>
<Statistic inverted>...</Statistic>

Evenly Divided

A statistic group can have its items divided evenly

Will be taken from #183

Floated

An statistic can sit to the left or right of other content

<div class="ui right floated statistic">...</div>
<Statistic floated='left'>...</Statistic>
<Statistic floated='right'>...</Statistic>

Size

A statistic can vary in size

<Statistic size='mini'>...</Statistic>

There is no medium, big and massive sizes.

@layershifter
Copy link
Member Author

Refers #269

@layershifter
Copy link
Member Author

What about this?

<Statistic label='Faves' value='22' />

@codecov-io
Copy link

codecov-io commented Jul 15, 2016

Current coverage is 92.47%

Merging #334 into master will increase coverage by 0.96%

@@             master       #334   diff @@
==========================================
  Files            62         62          
  Lines           777        797    +20   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits            711        737    +26   
+ Misses           66         60     -6   
  Partials          0          0          

Powered by Codecov. Last updated by c5b0425...c9cc2f2

@levithomason
Copy link
Member

levithomason commented Jul 15, 2016

API looks great. The simplified props version look right as well:

<Statistic label='Faves' value='22' />

We probably just accept the limitation that using props only like this will generate markup with the value on top and the label on bottom. I assume this is the most common configuration.

image

Any intuitive ideas on how to allow reordering label/value with the props API?

@layershifter
Copy link
Member Author

Any intuitive ideas on how to allow reordering label/value with the props API?

What about boolean reverse/labeled/valued prop?

@layershifter
Copy link
Member Author

layershifter commented Jul 17, 2016

What about short syntax for label and value?

<Statistic.Label text='Faves' />
<Statistic.Value text='22' />

UPD:
Oops, text prop is already taken in Statistic.Value, what about content?

@layershifter
Copy link
Member Author

I've implemented all features, added tests and docs. @levithomason wait for feedback 😄

@levithomason
Copy link
Member

What about boolean reverse/labeled/valued prop?

After thinking it through, I think we should just provide a single layout, value on top, label on bottom. If a user wants more control, they can use the sub components. This seems to be the cleanest solution, for now.

Oops, text prop is already taken in Statistic.Value, what about content?

Nice catch, I never saw the text option buried in the docs. We've been using text in many places for shorthand configuration, which as you've noted will not work here. I'd like for shorthand props to be as consistent as possible between all components. My worry is that since content is also a common SUI term, this will have conflicts elsewhere. This makes me think we should not provide shorthand props for label/value sub components here just yet.

Perhaps add a TODO in each component to find a shorthand prop for each that is not text but that is also consistent with shorthand props in other components. Then, once we get through the v1 updates, we can scan through the components and find the most appropriate prop name.

@levithomason
Copy link
Member

Some more ideas on props for Statistic sub components. The Statistic already accepts label and value shorthand props. We could allow these props on the subcomponents:

<Statistic.Value value={99} />
<Statistic.Label label='Likes' />

Regarding label/value order for Statistic shorthand props, React props are order dependent. As noted in the React docs:

NOTE:
Order matters. By putting the {...other} before your JSX props you ensure that the consumer of your component can't override them. In the example above we have guaranteed that the input will be of type "checkbox".

So we could simply do this:

<Statistic label='Label first' value={3} />
<Statistic value={99} label='Label last' />

See it in action here: http://www.react.run/HJxagQKP/2

return (<div className={classes} {...rest}>
<Statistic.Value text={text}>{value}</Statistic.Value>
<Statistic.Label>{label}</Statistic.Label>
</div>)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since props are applied in order, we need to spread the rest before applying the className. The classes includes the user's className values. If we apply the rest after the classes, then their classNames will override the classes we've built up.

Also, I think the linter should have caught this but let's return multiline JSX like this:

return (
  <div {...rest} className={classes}>
    <Statistic.Value text={text}>{value}</Statistic.Value>
    <Statistic.Label>{label}</Statistic.Label>
  </div>
)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

itemsJSX.push(<Statistic key={key} {...item} />)
})

return <div className={classes} {...rest}>{itemsJSX}</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted in Statistic, spread before applying className to prevent user's className from overriding the className build up.

Conformance tests ensure props are spread, I should add a test to ensure className is not override during spread ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have to correct myself here, while this is true regarding prop order rest actually does not include className in this example. That is because the className prop is being handled in the propTypes, so getUnhandledProps is returning an object of props that does not include className.

Let's still spread them first, and I'm adding the common test now. I just wanted to point out that this would actually work as is and my original comment was incorrect.

@layershifter
Copy link
Member Author

Okay, here is some problems:

  • common.isConformant(StatisticGroup) fails, seems test might be updated:
    image
  • common.propValueOnlyToClassName(StatisticGroup, 'widths') fails, seems there needed new test in commonTests:
    image

import StatisticGroup from 'src/views/Statistic/StatisticGroup'

describe('StatisticGroup', () => {
common.isConformant(StatisticGroup)
common.hasUIClassName(StatisticGroup)
common.rendersChildren(StatisticGroup)
common.propKeyOnlyToClassName(StatisticGroup, 'horizontal')
common.propValueOnlyToClassName(StatisticGroup, 'widths')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is mostly accurate, but not entirely. Consider when a user passes widths='3', the value '3' is not actually added to the className, the word three is.

We should likely add a common test for implementsNumberToWordProp(Statistic, 'widths'). This test would assert that the numberToWord value is added to the className. It would also assert that it works with numbers, strings, and number words (i.e. 'two').

The reason I think we should allow the second param to this common tests is that on other components, like FormFields, the numerToWord prop is width. This way, we can point this test to a specific prop name.

@layershifter
Copy link
Member Author

layershifter commented Jul 17, 2016

I've made sort, seems it make all ugly 😿

image

@layershifter
Copy link
Member Author

I've created implementsNumberToWordProp, take a look

Need fix for common.isConformant(StatisticGroup) and decision for props order

@levithomason
Copy link
Member

I've made sort, seems it make all ugly

Oh boy, yep. That isn't good nor intuitive. Let's not sort.

@levithomason
Copy link
Member

I'll be tied up the next couple hours. Will check on the rest then. Thanks much for all the refactors and rapid responses!

@layershifter
Copy link
Member Author

It seems that componentClassName definition in componentInfo needs to be modified for #203

@levithomason
Copy link
Member

Whoops, missed this one. Checking...

@levithomason
Copy link
Member

Rebase and give this a shot. TechnologyAdvice/stardust@c5b0425

Tested on this branch and master. It uses the plural name of the parent for componentClassName on sub component groups. So, statistics for StatisticGroup.

@layershifter
Copy link
Member Author

Seems it works 👍 Waiting for review

@levithomason
Copy link
Member

On it

@levithomason levithomason merged commit 9fcaae2 into Semantic-Org:master Jul 18, 2016
jhchill666 pushed a commit to jhchill666/stardust that referenced this pull request Jul 19, 2016
* (feat) Rail Semantic-Org#181

* (feat) Rail Semantic-Org#181

* (feat) Rail docs Semantic-Org#181

* (fix) Sort Rail props Semantic-Org#181

* (fix) Rail review fixes Semantic-Org#181

* (fix) Rail review fixes Semantic-Org#181

* (fix) Rail review fixes Semantic-Org#181

* (fix) Rail sizes Semantic-Org#181

* (fix) Rail sizes in docs Semantic-Org#181

* (fix) Statistic

* (feat) Statistic Item

* (feat) Statistic Label and Value

* (feat) Statistic Group

* (fix) Statistic fix sizes

* (fix) Statistic functionality

* (fix) Statistic docs

* (fix) Statistic lint fixes

* (fix) Statistic tests

* (Statistic) Remove shorthands

* (utils) Update numberToWord

* (Statistic) Fix returned JSX

* (utils) Update numberToWord, fix imports

* (Statistic) Update widths usage

* (Statistic) Fix JSDoc

* (Statistic) Update `rest` prop

* (utils) implementsNumberToWordProp test

* (Statistic) Test update

* fix(Statistic) Fix example
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants