Blueprint: data-* attributes being stripped from certain comopnents

Created on 4 Dec 2018  路  10Comments  路  Source: palantir/blueprint

Right now, passing a data attribute to many blueprint components isn't supported. For example:

<FormGroup data-test="some-unique-testing-id" ... />

will not result in a div in the dom with a data-test attribute.

I think that data-attibutes should be able to be most blueprint components. I don't have an exhaustive list of the components. Here is a sandbox I started to test which components do pass data attributes.

https://codesandbox.io/s/1vo78vp5mq

P2 core enhancement feature request

Most helpful comment

I also arrived here after wanting to use data-* attributes so that my (Cypress) integration tests could use selectors that are less prone to CSS class changes. A couple of work-arounds that might be helpful:

  1. Use the HTML/CSS version of the component instead of the JavaScript one (if possible) so that you can specify the data-* attribute. For example, <ul className={Classes.MENU} data-cy-foo> instead of <Menu>.
  2. Use a classname that is purely for identification and not for styling (e.g., <div className="{...} cy-submit">).

All 10 comments

@tnrich this would only be possible 1) on components that spread all props to a DOM element (which many do not) and 2) if React.HTMLProps allowed arbitrary keys, which it does not.

not really sure how best to solve this issue. not sure there's even a good clean general solution, as supporting data-* attributes essentially amounts to supporting _any_ prop and kinda kills any type safety.

@tnrich do you have an example of a component that _does_ support data-* attributes _in TypeScript_?

No @giladgray I don't have an example but I also haven't dabbled much in using typescript myself. I do know that React allows you to pass data-* elements to any dom component: https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html#data-and-aria-attributes

I second to this. I'm writing integration tests for my app, so to avoid using classes/ids, I wanted to use html5 attributes, like:

<Button data-cy-submit></Button>

And then use something like:

cy.get('[data-cy-submit]')...

Problem is there doesn't seem to be a way to add custom data- props to most Blueprint components.

I understand why it's currently technically not supported but I think some workaround is really needed.

@giladgray the <Button> and <InputGroup> components do support data-* attributes in TypeScript it seems.

I also arrived here after wanting to use data-* attributes so that my (Cypress) integration tests could use selectors that are less prone to CSS class changes. A couple of work-arounds that might be helpful:

  1. Use the HTML/CSS version of the component instead of the JavaScript one (if possible) so that you can specify the data-* attribute. For example, <ul className={Classes.MENU} data-cy-foo> instead of <Menu>.
  2. Use a classname that is purely for identification and not for styling (e.g., <div className="{...} cy-submit">).

@giladgray @warpdesign data-* attributes are supported for

@giladgray Typescript ignores props if they are not valid JS identifiers, so attribute type checking does not error on properties with hyphens (e.g. data-foo).

I think the fix here is to add a filter to removeNonHTMLProps if the property contains a hyphen:
https://github.com/palantir/blueprint/blob/develop/packages/core/src/common/props.ts#L147

https://www.typescriptlang.org/docs/handbook/jsx.html#attribute-type-checking

@justinbhopper that's a great solution suggestion. if you're up for it, a PR would be most welcome.

sadly, my active involvement in Blueprint ended last year, so i'll forward your tag to @adidahiya 馃憢

Agreed, @justinbhopper's proposal would be welcome as a PR

Was this page helpful?
0 / 5 - 0 ratings