JedWatson / react-select

The Select Component for React.js
https://react-select.com/
MIT License
27.63k stars 4.13k forks source link

[v2] Pass down data attributes to container/nested elements #3149

Closed RIP21 closed 3 years ago

RIP21 commented 6 years ago

I want easily select react-select using data-testid attribute selector for e2e test using cypress

Please pass down data attributes to the, at least, container, or come up with more advanced API for such use cases for easy selection of internal elements using CSS selectors.

So we can easily type, click etc. Some additions to the docs "how to test" will be a nice thing to have too.

RIP21 commented 5 years ago

Is this project dead? :) I understand that there is hundreds of Issues and PRs etc. But, dunno, maybe it's time to give control over this project to some fellow OSS contributors that will be happy to review and clean up the mess at least a little bit? :)

MikaelCarpenter commented 5 years ago

I'm running into this issue as well, wanting to pass a data-* attribute to the select components. Right now I have a solution, it just doesn't feel particularly great.

Gist: https://gist.github.com/MikaelCarpenter/1fe226967b00eea82e6a4760b244ada1

It works for when you're already passing custom components. You can also use it to add the data attribute to a component you're not necessarily trying to replace, but this approach for that use case sort of feels heavy handed. It would be cool to have a better API for handling this sort of use case, but not sure what that should look like.

gwyneplaine commented 5 years ago

Hi @RIP21, we provide you with a classNamePrefix prop which replaces the emotion uids with more semantic selectors with the specified classNamePrefix value as a prefix, this should be what you're after. At the moment we don't provide a way to pass data-attributes to the rendered DOM elements, I'm happy to discuss this further if you feel strongly about it.

As to your query about the package, its not dead, and we're always happy to engage with people who want to help us maintain it.

In conversation with @JedWatson about opening this package up to more contributors, but in the meantime any help with triaging issues and PR submissions is always greatly appreciated; as is your patience.

IanVS commented 5 years ago

@gwyneplaine it definitely would be nice to have a way to use data- attributes rather than class names, as recommended in the cypress docs.

kylemh commented 5 years ago

I use something like this in my own app:

// General utilities for dealing with component prop types
import pickBy from 'lodash/pickBy';

export function getPropsStartingWith(string, props) {
  return pickBy(props, (value, key) => key.startsWith(string));
}

export function getDataAttributes(props) {
  return getPropsStartingWith('data-', props);
}

Which you can then call in the render of the react-select Control component and spread the results to allow the pass thru of any/all data- props

render() {
  const { /* other props */, ...props } = this;

  const customDataProps = getPropsStartingWith(props);

  return (<JSX {...otherProps} {...customDataProps} />);
}
consciousnessdev commented 5 years ago

Hope working soon :pray:

riceboyler commented 4 years ago

FWIW, I made a very simple version of this for our data-testid needs (it's using TS, so the types are there as well...)

import { ContainerProps } from 'react-select/src/components/containers';
const dataTestId = props['data-testid'];

  const CustomContainer: React.FC<ContainerProps<any>> = commonProps => (
    <components.SelectContainer
      {...commonProps}
      innerProps={Object.assign({}, commonProps.innerProps, {
        'data-testid': dataTestId,
      })}
    />
  );

return <ReactSelect components={{ SelectContainer: CustomContainer }} ... />;

Hope that helps someone until react-select actually renders these out by default.

ebonow commented 3 years ago

Greetings @RIP21 and others...

I am writing to inform you that https://github.com/JedWatson/react-select/pull/4289 may resolve at least one use-case for this (MenuList).

The recommended way would be to add data props into innerProps which could be spread. You can read more about the reasoning and logic here from Jed himself. https://github.com/JedWatson/react-select/pull/4289#issuecomment-742936297

As of now, innerMenu should be helpful for identifying the MenuList component, Options already supports innerProps, and a custom Input will already spread any additional props passed to it to the input element. There are others as well with the ability to spread props, but these would likely be the 3 most important.

If there are other components which anyone could list for us that might be a beneficial (especially for testing) or even put together a PR similar to what the one linked, it will be considered and likely added as a minor release.

In the meanwhile, I will mark this as awaiting=author-response simply as a note to follow up on later. If there's nothing further then I will come back in the near future after allowing users some time to review this and mark this closed.