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

Feed: add component #363

Merged
merged 16 commits into from
Aug 13, 2016
Merged

Feed: add component #363

merged 16 commits into from
Aug 13, 2016

Conversation

layershifter
Copy link
Member

@layershifter layershifter commented Aug 3, 2016

WIP

http://semantic-ui.com/views/feed.html

  • Components
  • Docs
  • Tests

Fixes #188

@codecov-io
Copy link

codecov-io commented Aug 3, 2016

Current coverage is 94.40% (diff: 100%)

Merging #363 into master will increase coverage by 0.55%

@@             master       #363   diff @@
==========================================
  Files            74         84    +10   
  Lines           960       1055    +95   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits            901        996    +95   
  Misses           59         59          
  Partials          0          0          

Powered by Codecov. Last update 012cba6...d34eb88

@levithomason
Copy link
Member

levithomason commented Aug 4, 2016

Note on docs, I've updated the doc example logic and file naming patterns. Doc files are now organized like so:

/docs
  /app
    /Examples
      /views
        index.js  <--- previously "FeedExamples.js"
        /Types
          index.js <-- (optional, can use root index) previously "FeedTypesExamples.js"

You can still put all the examples in the root index.js, just the filename pattern has been updated. I'll be updating the old doc files to use this new naming pattern. All new components should follow it.

@layershifter
Copy link
Member Author

@levithomason Did I correctly named doc files?

@levithomason
Copy link
Member

The naming is only dictated for the index.js files, so you are good. The other files just need to make sense. I think what you have is OK 👍

@layershifter
Copy link
Member Author

It seems we're ready for initial discussion 😄

  • there are huge amount of subcomponents, it's not looks good;
  • like designed to be used only with like icon, but we use stars in production, so I've made small overhead in <Like>;
<a class="like">
  <i class="like icon"></i> 4 Likes
</a>
  • I'm using imagePropRender() on Label, it produces html with class="ui image", while there are no classes on <img> in SUI docs;
  • TAL on <FeedExtra>: seems prop validation for text is ugly, what about shorthand for images, ideas?
  • seems <Summary> and <Meta> can be shorthands on <Content>, what you think?
  • do we need render with passing object on <Feed>, like:
const events = [
  { content: 'Text' },
  ...
]

() => <Feed events={events}>

Something else? 😄

@levithomason
Copy link
Member

@davezuko and I had an offline discussion regarding similar difficulties with sub components in the Message component PR.

I'm out today but will check back tonight or tomorrow and give an update.

@levithomason
Copy link
Member

there are huge amount of subcomponents, it's not looks good;

Indeed. I'll take any better ideas on how to improve this. Either way, once we get all the components in, we'll revisit these and see if we can optimize them. We may be able to reuse a single set of component parts. I want to get all the components completed with explicit parts before we start to optimize though. This way we can see all the requirements of all the components before making final decisions on how it should be optimized. If you have any ideas or suggestions, please add them to #345 where this is being worked on.

like designed to be used only with like icon, but we use stars in production, so I've made small overhead in <Like>;

Makes sense to me. I think the user should be able to pick the icon as well.

I'm using imagePropRender() on Label, it produces html with class="ui image", while there are no classes on <img> in SUI docs;

It looks like this img does not support any of the <Image /> props nor any classNames (i.e. ui, image, etc.). It is simply an img tag. Because of this, it seems to me we should handle rendering this prop internally in the component. If the prop _.isString() use it as the src for a regular img. If it _.isObject() (an element), use the element itself.

Side note, I plan on improving the icon/prop renderers a bit. Right now they accept either an icon name or image src, or an Icon or Image element. I think it would be good to allow a string (name/src), a plain props object (_.isPlainObject() && !React.isValidElement), or an element (React.isValidElement). I'll probably double back and make these updates a little later. We just need a util to distinguish

TAL on <FeedExtra>: seems prop validation for text is ugly, what about shorthand for images, ideas?

The text prop validation looks correct to me. Can you elaborate on the ugly part you are seeing?

Regarding shorthand for images, we could accept an array of image src strings or image elements. This would make the validation oneOfType([bool, arrayOf(string), arrayOf(node)]).

seems <Summary> and <Meta> can be shorthands on <Content>, what you think?

Makes sense to me. Seems a component is component parts should allow a props to configure those parts.

do we need render with passing object on <Feed>, like:

I also thinks this also makes great sense. Just like <Accordion panels={} />, <Breadcrumb sections={} />, etc.

Something else?

Probably! 😄 This is a really great start though, let's keep momentum and just tackle these items for now.

}

Feed._meta = {
library: META.library.semanticUI,
Copy link
Member

Choose a reason for hiding this comment

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

Heads up, I've deprecated library as of today in #380. See that PR for rationale. There is also a failing test for including it now.

@layershifter
Copy link
Member Author

layershifter commented Aug 8, 2016

It looks like this img does not support any of ...

Updated.

Can you elaborate on the ugly part you are seeing?

Nevermind 😄

Regarding shorthand for images, we could accept an array of image src strings or image elements.

There is problem with key handling. TAL on FeedExtra.js, any ideas?

@levithomason
Copy link
Member

Sorry, not sure what TAL is and I need a little more info to help on this one. Can you describe the issue with key handling?

}

const imagesJSX = images.map((image, index) => {
const key = `${index}`
Copy link
Member Author

Choose a reason for hiding this comment

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

What might be key for image, when image is string? And what when is object?

Copy link
Member

Choose a reason for hiding this comment

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

How about the image src as it is required and will be unique?

Copy link
Member Author

Choose a reason for hiding this comment

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

In docs src's are same (/images/wireframe/image.png), so I have:
image


How I can deal with this, when I have element at input?

const images = [<img src='http://semantic-ui.com/images/wireframe/image.png' />, ...];
const imagesJSX = images.map(image => {
  return _.isString(image) ? <img key={image} src={image} /> : image
})

I think that React.cloneElement(image, {key: image.src}) is smelly solution.

Copy link
Member

@levithomason levithomason Aug 8, 2016

Choose a reason for hiding this comment

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

Hm, I see.

/cc @davezuko we we're just talking about weak-key, here we have an array of objects with possibly no unique key/value pairs. Ideas for generating unique React keys?

EDIT

I prefer not to add the polyfill for WeakMaps...

@layershifter
Copy link
Member Author

layershifter commented Aug 8, 2016

Seems, docs and components finished. I'll start writting test after review. So, feedback is welcome 😄

@@ -39,7 +39,7 @@ const Date = () => {
<Feed.Label image={imageSrc} />
<Feed.Content
date='3 days ago'
summary={<span>You added <a>Jenny Hess</a> to your <a>coworker</a> group.</span>}
summary='You added Jenny Hess to your coworker group.'
Copy link
Member

Choose a reason for hiding this comment

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

Reduced all shorthand props, except icon/image, to strings only.

Copy link
Member

Choose a reason for hiding this comment

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

Renders a simple read only feed like so:

image

@levithomason
Copy link
Member

Updated, take a look at the last commit and comments.

@layershifter
Copy link
Member Author

Thanks for review, all is nice, I'll fix it soon and add tests.

@layershifter
Copy link
Member Author

Oh, I missed that you've already applied all 😸 Working on tests, seems we can merge it today.

@levithomason
Copy link
Member

Awesome, I've got the Modal updates and docs done. It was blocked by the Image, so finishing that up as well.


if (Array.isArray(images)) {
const imagesJSX = images.map((image, i) => {
return _.isString(image) ? <img key={i} src={image} /> : image
Copy link
Member Author

Choose a reason for hiding this comment

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

@levithomason It seems that you like antipattern with key more than I 😆

I think:

  • allow pass only string, not nodes;
  • use pair of index and src.

Better ideas?

Copy link
Member

Choose a reason for hiding this comment

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

@levithomason It seems that you like antipattern with key more than I 😆

I must admit, I once took it very lightly :S

  • allow pass only string, not nodes;
  • use pair of index and src.

There is a chance that the strings might be the same, for instance a placeholder image for multiple images. Also, adding index into the string will affectively do the same thing as having an index only, since the key changes when the child order changes. We would need to accept objects in order to accept a key: images={[{key: 'foo', src: '...'}]}.

I think for now, we allow a string only and fix the duplicate image src string edge case if it arises.

@layershifter
Copy link
Member Author

I think I blurted out too much about today 😢
I've finish with tests tomorrow and will wait for final review.

@levithomason
Copy link
Member

No worries, I'll review once tests are in then. Thanks.

@levithomason
Copy link
Member

Heads up, I've done some heavy utils refactoring in #388. I left many comments there to help get up to speed. That PR greatly improved things and unblocks the Image and Modal work. Really glad with the results and I think you will be too after updating.

LMK if you have any questions. I'll leave comments on this PR where it needs updated to meet the new refactors later tonight.

@levithomason
Copy link
Member

I updated this PR to use the new utils. It might be a good idea to familiarize yourself with the changes made in the last commit. I also fixed tests and lint issues.

I'm not sure why PhantomJS is crashing in watch mode though. The branch was doing that before the updates. Master branch does not crash. Looking into it.

@levithomason
Copy link
Member

Suddenly after the rebase test watching is working again. LMK if you have any issues.

@layershifter
Copy link
Member Author

Suddenly after the rebase test watching is working again.

Offtop: Did you have issues with PhantomJS's crash, too?


Feed.js

I've updated key prop handling as we discussed.

const eventsJSX = events.map(eventProps => {
    const { childKey, date, meta, summary, ...eventData } = eventProps
    const finalKey = childKey || `${date}-${meta}-${summary}`

    return <FeedEvent
      date={date}
      key={finalKey}
      meta={meta}
      summary={summary}
      {...eventData}
    />
  })

FeedExtra.js

  1. Only array of string can be passed now.
- PropTypes.arrayOf(PropTypes.node),
+ PropTypes.arrayOf(PropTypes.string),
  1. Updated key prop (better ideas?) and used new factory.
const imagesJSX = images.map((image, index) => {
  const key = [index, image].join('-')

  return createImg(image, {key})
})

FeedLabel-test.js

Are tests for image prop correct (createImg factory)?


Tests are ready. Show must go on 👻

@levithomason
Copy link
Member

Did you have issues with PhantomJS's crash, too?

Indeed, not sure what fixed it in the rebase but it seems to be fine now?

I've updated key prop handling as we discussed.

We'll have to pick a different prop name as key won't work, see here: https://github.com/TechnologyAdvice/stardust/pull/390#discussion_r74691048

date={date}
key={finalKey}
meta={meta}
summary={summary}
{...eventData}
/>
/>)
Copy link
Member

Choose a reason for hiding this comment

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

Indent issue here, needs some new lines inserted.

@levithomason
Copy link
Member

FeedExtra 👍

FeedLabel-test 👍 though, we'll need to update the key prop to another name then update the factories to apply our standard key prop name to the key prop.

@layershifter
Copy link
Member Author

Indeed, not sure what fixed it in the rebase but it seems to be fine now?

Yep.

We'll have to pick a different prop name as key won't work, see here: #390 (comment)

events: customPropTypes.every([
  PropTypes.arrayOf(PropTypes.shape({
    childKey: PropTypes.string,
  })),
]),

childKey will be applied to FeedEvent as it might be, or not?

we'll need to update the key prop to another name then update the factories to apply our standard key prop name to the key prop.

??? Not understand you there.

@levithomason
Copy link
Member

What you've done for FeedEvent is correct. My comment was in regard to passing a childKey prop to the image prop:

// on an element
const image = <img childKey='...' src='...' />
<FeedLabel image={image} />

// or a props object (this is a new feature of our factories)

<FeedLabel image={{ childKey='...', src='...' }}

Our factories are responsible for merging those props by default. Currently, they will simply pass the childKey prop since onto the final element. We need to map childKey to the key prop for the final element in the createFactory.js mergePropsAndClassName().

This work can be done on a separate PR though to keep this one moving.

@levithomason
Copy link
Member

Anything else to update here? Looks great. I'd like to merge and make any updates on future PRs.

@layershifter
Copy link
Member Author

No, we can go 🚗

@levithomason levithomason merged commit 6cfa43e into master Aug 13, 2016
@levithomason levithomason deleted the feature/feed branch August 13, 2016 21:15
@levithomason
Copy link
Member

💥 Released in stardust@0.34.0

layershifter added a commit that referenced this pull request Aug 14, 2016
* feat(Feed) Initial commit

* feat(Feed) Docs and components update

* feat(Feed) Docs and components update

* feat(Feed) More docs and components

* feat(Feed) Remove meta.library

* feat(Feed) Update prop handling

* feat(Feed) Update prop handling

* feat(Feed) More shorthands

* refactor(Feed): use string shorthand props

* feat(Feed) Update prop handling and tests

* fix(Feed) More tests

* refactor(Feed): update to refactored utils

* fix(Feed) Fixes and more tests

* fix(Feed) Lint issues

* fix(Feed) Update lint issues
@levithomason levithomason changed the title Add Feed component Feed: add component Aug 18, 2016
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