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

<KuiButton> needs submit prop #3

Closed
bevacqua opened this issue Oct 23, 2017 · 6 comments
Closed

<KuiButton> needs submit prop #3

bevacqua opened this issue Oct 23, 2017 · 6 comments

Comments

@bevacqua
Copy link
Contributor

bevacqua commented Oct 23, 2017

We're shadowing type='submit' for <button> because type is used to declare primary, secondary, and so on.

<button
disabled={isDisabled}
className={classes}
{...rest}

We should either rename type to something else such as hue='danger', or add a submit prop that results in <button type='submit'>.

Both approaches have their pros and cons. type fits the button "roles" very well, role would also clash with aria props, etc. At the same time, submit={ Boolean } wouldn't fix support for <button type='button'> either.

@snide
Copy link
Contributor

snide commented Oct 23, 2017

There's also the third option of just making a new component that's more direct... ButtonSubmit or whatever. Not a great one either (cuz it'd mostly be a dupe), but that's how it's handled in the current code.

https://github.com/elastic/kibana/blob/master/ui_framework/src/components/button/button.js#L172-L187

@bevacqua
Copy link
Contributor Author

@snide note that there's a bunch of different permutations, so that approach can be problematic:

  • <input type='button'>
  • <button>
  • <button type='button'>
  • <input type='submit'>
  • <button type='submit'>

Probably what we need is to expose a function that given a set of parameters will give you the classes to style any of those elements, for the more advanced use cases. Something along the lines of:

export const getButtonClasses = ({ size, type }) =>
  `kuiButton kuiButton--${ size } kuiButton--${ type }`

@bevacqua
Copy link
Contributor Author

@snide Here's an example from Cloud (there's quite a few cases like this, for normal buttons too) that would be a great consumer example for the above API:

const AddButton = ({ regionId, small = false, ...rest }) => <Link
  { ...rest }
  data-test-id='snapshotRepositories-addBtn'
  className={ cx(`btn btn--success`, { 'btn--sm': small }) }
  to={ createSnapshotRepositoryUrl(regionId) }>
  <FormattedMessage
    id='snapshot-repository-management.add-repository'
    defaultMessage='Add Repository' />
</Link>

With an API like the above, we could do something like

className={ getButtonClasses({ type: 'success', size: small ? 'small' : undefined }) }

@snide
Copy link
Contributor

snide commented Oct 23, 2017

Yep. I agree, I don't think type would need to effect the presentation classes though luckily. I agree type makes better sense for the input type, and theme or even color works fine for the styling.

Normally I'd consider something like this a breaking change because it requires the devs to edit their existing work. We should probably talk a bit (later) about how we'd handle changes like this (release notes, versioning...etc) as we come across more of these.

@cjcenizal
Copy link
Contributor

In Kibana master we changed type to buttonType to avoid this shadowing bug. I think we may have just overlooked this when we created this component in K7. So my suggestion is to rename this prop buttonType, and to apply the same naming pattern to other components which need a "type" property.

In terms of which combination of element and type attribute to support, I think we only need to support <button type="button"> and <button type="submit">. The input element doesn't provide any advantages over button, from what I've read. This would simplify implementation drastically, since we just need to stop shadowing the type prop and All Our Problems Are Magically Solved™.

WRT getButtonClasses, I think this implementation couples the prop values too tightly with the class names:

export const getButtonClasses = ({ size, type }) =>
  `kuiButton kuiButton--${ size } kuiButton--${ type }`

I agree that we'll want these values to be similar/identical to make the code easier to read, but I think decoupling them is just a good defensive programming practice to prevent stuff from accidentally breaking if we decide to tweak CSS class names or acceptable prop values. This also lets you see up-front which types are supported:

const buttonTypeToClassNameMap = {
  basic: 'kuiButton--basic',
  hollow: 'kuiButton--hollow',
  danger: 'kuiButton--danger',
  warning: 'kuiButton--warning',
  primary: 'kuiButton--primary',
  secondary: 'kuiButton--secondary',
};

const getClassName = ({ className, buttonType, hasIcon = false }) =>
  classNames('kuiButton', className, buttonTypeToClassNameMap[buttonType], {
    'kuiButton--iconText': hasIcon,
  });

@bevacqua
Copy link
Contributor Author

bevacqua commented Oct 23, 2017

Yeah, that's a great point. The implementation should definitely be whatever already exists in the components, and then we can expose those bits as a public API as well, so things that depend upon EUI can use the same logic without necessarily knowing about class names

cjcenizal added a commit to cjcenizal/eui that referenced this issue Jan 28, 2018
nreese added a commit that referenced this issue May 1, 2018
…ox (#698)

* add clear icon

* use shallow render in tests to avoid cascading diff changes when underlying componenets change

* update change log

* Added `onClear` prop to `EuiFormControlLayout` (#3)

* Added `onClear` prop to `EuiFormControlLayout`

This will allow these extras to properly position according to what is visible and allow for other inputs to utilize it as well.

* Adding `isClearable` back in

* Adding onClose/onOpen back in and allowing a

`onIconClick` prop on the EuiFormControlLayout that will then wrap the icon in a button.

* set isClearable to true for example

* move readme comment to master

* remove rebase garbage from changelog
@andreadelrio andreadelrio mentioned this issue Mar 31, 2020
8 tasks
cee-chen pushed a commit that referenced this issue Oct 28, 2021
…to` (#5281)

* Remove isHeightSame check

* Remove same height check from shouldComponentUpdate

- if we're not checking for sameHeight in componentDidUpdate, we also likely don't need this anymore, and all dynamic user changes appear to work without this code

* [Proposed refactors]

- Rename `recalculateRowHeight` to `setAutoRowHeight`

- DRY out setAutoRowHeight to be reusable by both the resize observer and during props update (NB: This leads to some repetition with the height being obtained twice, but will not be an issue shortly as I'll be refactoring/removing the cell wrapper observer in a future PR)

- Refactor rowHeightUtils.isAutoHeight to accept an undefined rowHeightsOptions

* Improve unit tests

* Add changelog entry

* [PR feedback] Fix `isAutoHeight` false positive
- occurs if the `defaultHeight` is auto but a specific `rowHeights` line override is not auto

TODO: Write a unit test for this in the future

* [PR feedback/Discover testing] Trigger component update when rowHeightsOptions changes

* [cleanup] Remove now-unused compareHeights util

+ clean up mock rowHeightUtils as well

* [revert] rename setAutoRowHeight back to recalculateRowHeight

- lineCount in #5284 will shortly be using the row height cache in addition to auto, so I'm making the fn name less specific again

* Add enqueue/timeout to recalculateRowHeight updates

- to avoid race conditions with cache being cleared

* Remove clearHeightsCache completely

* Unset row+column height values on unmount (#3)

* Add unit test for new unsetRowHeight

+ add optional isAutoHeight check

* Remove hidden columns from row height cache

* Early return in getRowHeight

Co-authored-by: Chandler Prall <chandler.prall@gmail.com>
ym pushed a commit to ym/eui that referenced this issue Oct 29, 2021
…to` (elastic#5281)

* Remove isHeightSame check

* Remove same height check from shouldComponentUpdate

- if we're not checking for sameHeight in componentDidUpdate, we also likely don't need this anymore, and all dynamic user changes appear to work without this code

* [Proposed refactors]

- Rename `recalculateRowHeight` to `setAutoRowHeight`

- DRY out setAutoRowHeight to be reusable by both the resize observer and during props update (NB: This leads to some repetition with the height being obtained twice, but will not be an issue shortly as I'll be refactoring/removing the cell wrapper observer in a future PR)

- Refactor rowHeightUtils.isAutoHeight to accept an undefined rowHeightsOptions

* Improve unit tests

* Add changelog entry

* [PR feedback] Fix `isAutoHeight` false positive
- occurs if the `defaultHeight` is auto but a specific `rowHeights` line override is not auto

TODO: Write a unit test for this in the future

* [PR feedback/Discover testing] Trigger component update when rowHeightsOptions changes

* [cleanup] Remove now-unused compareHeights util

+ clean up mock rowHeightUtils as well

* [revert] rename setAutoRowHeight back to recalculateRowHeight

- lineCount in elastic#5284 will shortly be using the row height cache in addition to auto, so I'm making the fn name less specific again

* Add enqueue/timeout to recalculateRowHeight updates

- to avoid race conditions with cache being cleared

* Remove clearHeightsCache completely

* Unset row+column height values on unmount (elastic#3)

* Add unit test for new unsetRowHeight

+ add optional isAutoHeight check

* Remove hidden columns from row height cache

* Early return in getRowHeight

Co-authored-by: Chandler Prall <chandler.prall@gmail.com>
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

No branches or pull requests

3 participants