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

feat(factories): add overrideProps #1428

Merged
merged 18 commits into from
Apr 3, 2017
Merged

Conversation

layershifter
Copy link
Member

Refence: #1424

@layershifter
Copy link
Member Author

@levithomason I've added overrideProps to handle situations like with Menu. It would be great to receive your initial feedback there.

@levithomason
Copy link
Member

I'd like to think about this one a bit.

@layershifter
Copy link
Member Author

@levithomason It will be great receive some feedback from you. Of course, when you will have enough time

@levithomason
Copy link
Member

Whoops, forgot about this thanks! I'm working on the Tabs ATM and also need this feature. Looking now...

return (val, defaultProps) => {
return createShorthand(Component, mapValueToProps, val, defaultProps, generateKey)
return (val, defaultProps, overrideProps) => {
return createShorthand(Component, mapValueToProps, val, defaultProps, overrideProps, generateKey)
Copy link
Member

@levithomason levithomason Mar 25, 2017

Choose a reason for hiding this comment

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

The only comment I have is that the arguments here are getting a little wild. There are cases where you'd want to set generateKey but not defaultProps nor overrideProps. That usage is ugly:

createShorthand(
  Menu, 
  items => ({ items }),
  null, // defaultProps
  null, // overrideProps
  true, // generateKey
)

Perhaps we move these optional arguments to an options object?

createShorthand(
  Menu, 
  items => ({ items }), 
  { generateKey: true }
)

EDIT
Fixed completely incorrect signatures.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't like functions with more that 3 args, so I agree, it will better.

Copy link
Member

Choose a reason for hiding this comment

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

This would also apply to the returned create factory. Instead of:

Menu.create(menu, null /* defaultProps */, () => /* override props */)

We'd have something like:

Menu.create(menu, { overrideProps: () => { ... } })

@layershifter
Copy link
Member Author

I'll rebase it, complete TODOs and update code with your suggestion tomorrow

@levithomason
Copy link
Member

I'd like to try and simplify the factories as we also add more features. There is only one component that currently requires usages of defaultProps as a function (others use a function but do not need to):

Input.js

    const actionElement = Button.create(action, elProps => ({
      className: cx(
        // all action components should have the button className
        !_.includes(elProps.className, 'button') && 'button',
      ),
    }))

This is ensuring the button className is added, but not duplicated. Currently, the factory merges className but does not check for duplicates, it could check first. Then, we can reduce the defaultProps back to a simple object. If we need a function, there is always overrideProps for all other use cases.

I think we should then also remove the option for defaultProps to be a function and instead use a simple object. Then, we update the current merge className logic to only merge unique classNames.

Thoughts?

@codecov-io
Copy link

codecov-io commented Mar 27, 2017

Codecov Report

Merging #1428 into master will decrease coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1428      +/-   ##
==========================================
- Coverage   99.74%   99.74%   -0.01%     
==========================================
  Files         141      141              
  Lines        2384     2383       -1     
==========================================
- Hits         2378     2377       -1     
  Misses          6        6
Impacted Files Coverage Δ
src/modules/Dropdown/DropdownItem.js 100% <ø> (ø) ⬆️
src/collections/Message/Message.js 100% <ø> (ø) ⬆️
src/elements/Button/Button.js 100% <100%> (ø) ⬆️
src/modules/Modal/Modal.js 100% <100%> (ø) ⬆️
src/collections/Breadcrumb/Breadcrumb.js 100% <100%> (ø) ⬆️
src/elements/Input/Input.js 100% <100%> (ø) ⬆️
src/collections/Breadcrumb/BreadcrumbDivider.js 100% <100%> (ø) ⬆️
src/collections/Message/MessageItem.js 100% <100%> (ø) ⬆️
src/collections/Table/TableCell.js 100% <100%> (ø) ⬆️
src/collections/Table/TableRow.js 100% <100%> (ø) ⬆️
... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f796757...28ee505. Read the comment docs.

@levithomason
Copy link
Member

Just ran into an issue over at https://github.com/Semantic-Org/Semantic-UI-React/pull/1508/files#r108559120. We currently only enable support for keys if a create method is instantiated with generateKey set to true.

Although we know which components we need keys for, consumers can also use create in their own code. We should enable key support in all factories so that any user can map over any create method and have support for keys. Otherwise, some factories will be impossible to use in a map.

@levithomason
Copy link
Member

Heads up, I'm gonna push a few changes here.

@levithomason
Copy link
Member

levithomason commented Mar 29, 2017

Heads up, I've got more pushing coming. Working on some of the tests.

@layershifter
Copy link
Member Author

I've pushed some updates, so only 28 tests failed now 👍

@levithomason
Copy link
Member

✔ 7118 tests completed
✖ 6 tests failed

Seems we may have an issue with the BreadcrumbDivider test. The common test for a shorthand prop expects the rendered element to contain the shorthand element. However, the breadcrumb divider uses it's icon props to return an icon with the divider class added.

@levithomason
Copy link
Member

I'll leave this PR alone for now and come back when I can. I also think we'll need to still make overrideProps a function. It would received the merged defaultProps and usersProps. This way, we can wrap an event handler and also still call the user's original event handler.

@layershifter
Copy link
Member Author

layershifter commented Mar 29, 2017

✔ 7124 tests completed 👍

TODO

  • make overrideProps a function
  • update event handlers where we use overrideProps
  • update tests, add tests for overrideProps

return `${k}=${typeof v === 'function' ? v.name || 'func' : v}`
}).join('|')
}
childElements.push(BreadcrumbDivider.create({ content: divider, icon, key }))
Copy link
Member Author

Choose a reason for hiding this comment

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

Cruft.

Copy link
Member

@levithomason levithomason Apr 2, 2017

Choose a reason for hiding this comment

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

Darn, this is technically a breaking change. Users who are using objects to define a breadcrumb divider and also not defining a key will now need to add the key. Otherwise, they won't all render.

Copy link
Member

Choose a reason for hiding this comment

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

I misread this initially, we are one using the factory as an object in this case. The key is then required by us, otherwise, we're getting this in the docs for Breadcrumb:

Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using <div>.

_.invoke(predefinedProps, 'onClick', e, buttonProps)
_.invoke(this.props, 'onConfirm', e, this.props)
},
})
Copy link
Member Author

@layershifter layershifter Apr 2, 2017

Choose a reason for hiding this comment

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

We handle there onClick on Buttons, let's allow user to handle own onClick 👍

@@ -26,13 +26,14 @@ function BreadcrumbDivider(props) {
const rest = getUnhandledProps(BreadcrumbDivider, props)
const ElementType = getElementType(BreadcrumbDivider, props)

const iconElement = Icon.create(icon, { ...rest, className: classes })
if (iconElement) return iconElement
if (!_.isNil(icon)) return Icon.create(icon, { defaultProps: { ...rest, className: classes } })
Copy link
Member Author

Choose a reason for hiding this comment

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

Simplified contidition

Copy link
Member Author

@layershifter layershifter left a comment

Choose a reason for hiding this comment

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

@levithomason I've added some tests and performed some cleanups, seems we can go after review 😄

@levithomason
Copy link
Member

levithomason commented Apr 3, 2017

EDIT
I reverted the removal of keys in shorthand for breadcrumb dividers. I had misread that code the first time.

Original
this looks good, I'm just going to revert the removal of generated keys for BreadcrumbDividers to prevent a breaking change, see https://github.com/Semantic-Org/Semantic-UI-React/pull/1428/files#r109309892.

We've got #1533 to remove all manually generated keys. This way we can consolidate our breaking changes for key into one release.

@levithomason levithomason force-pushed the fix/override-factories branch from 845944b to b6a2e57 Compare April 3, 2017 00:26
@levithomason levithomason force-pushed the fix/override-factories branch from b6a2e57 to 52e6685 Compare April 3, 2017 00:28
@levithomason
Copy link
Member

Rebased to master, fixed breadcrumb divider keys. Also tossed in a fix the for "show HTML" button in examples.

Will merge on pass.

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

Successfully merging this pull request may close these issues.

3 participants