react-timezone-select icon indicating copy to clipboard operation
react-timezone-select copied to clipboard

RFC: Allow composition of the Select component.

Open emrysal opened this issue 3 years ago • 5 comments

Hi @ndom91, hope you're doing well.

react-select does a lot of it's styling inline, with keys like theme={} and styles={], as you well know. Therefore I think a common pattern people use is to extend the component like so (example from my code):

function Select<
  Option,
  IsMulti extends boolean = false,
  Group extends GroupBase<Option> = GroupBase<Option>
>({ className, ...props }: SelectProps<Option, IsMulti, Group>) {
  return (
    <ReactSelect
      theme={(theme) => ({
        ...theme,
        borderRadius: 2,
        colors: {
          ...theme.colors,
          primary: "var(--brand-color)",

          primary50: "rgba(209 , 213, 219, var(--tw-bg-opacity))",
          primary25: "rgba(244, 245, 246, var(--tw-bg-opacity))",
        },
      })}
      styles={{
        option: (provided, state) => ({
          ...provided,
          color: state.isSelected ? "var(--brand-text-color)" : "black",
          ":active": {
            backgroundColor: state.isSelected ? "" : "var(--brand-color)",
            color: "var(--brand-text-color)",
          },
        }),
      }}
      components={{
        ...components,
        IndicatorSeparator: () => null,
        Input: InputComponent,
      }}
      className={classNames("text-sm shadow-sm", className)}
      {...props}
    />
  );
}

Due to the definition of react-timezone-select, such configuration is quite easily done; just take that entire code, copy it; and create a secondary wrapper TimezoneSelect and done. Except the drawback of this "easy fix" approach is that you now need to make Select changes in two locations. (An alternative fix is to somehow configure it outside of the component and re-use the config, but this in IMO also a little ugly). So this got me thinking.

I wonder what your opinion is to do something like: (pseudocode)

// file: react-timezone-select.js
import Select from "react-select";
const TimezoneSelect = ({
  innerSelect = Select,
  ...
}: Props) => .... (<innerSelect />)

// This would allow in the implementation
import TimezoneSelect from "react-timezone-select";
import Select from "@components/Select";

<TimezoneSelect innerSelect={Select} /* ... */ />

There's a couple of stylistic ways to achieve the same thing, but what do you think?

emrysal avatar Apr 09 '22 16:04 emrysal

Sorry for the late reply! So in principle i'm not against it. Seems like it wouldn't be a huge change either. I see yall have more or less achieved the same in the mentioned calcom/cal.com#2453 PR, no?

ndom91 avatar May 01 '22 22:05 ndom91

wouldn't therefore a better way be to somehow export the functionality of the select to a hook? const { selectedZone, options, selectZone } = useTimezoneSelect(initialSelectedTimezone) in order to be able to use the functionality, but not have to use the opinionated piece of UI. Arguably the best part about this is the logic, not the UI itself. Then it could integrated without friction into something like MUI or semantic or whatever.

ortonomy avatar Jun 27 '22 07:06 ortonomy

wouldn't therefore a better way be to somehow export the functionality of the select to a hook? const { selectedZone, options, selectZone } = useTimezoneSelect(initialSelectedTimezone) in order to be able to use the functionality, but not have to use the opinionated piece of UI. Arguably the best part about this is the logic, not the UI itself. Then it could integrated without friction into something like MUI or semantic or whatever.

Yeah in theory I really like that too. Not a huge fan of forcing react-select / select2 on everyone..

When I have some time Ill look into this as the next major release possibly

ndom91 avatar Jun 27 '22 13:06 ndom91

Yes @ndom91 - sorry for my late reply my month has been very, very hectic. We've managed to implement a wrapper ourselves to achieve similar results. This RFC is only "Hmm, this is also a good idea for core".

But I fully agree not forcing react-select on everyone, react-select is probably not a permanent first class citizen in our codebase, it has too much complexity.

emrysal avatar Jul 11 '22 11:07 emrysal

Yes @ndom91 - sorry for my late reply my month has been very, very hectic. We've managed to implement a wrapper ourselves to achieve similar results. This RFC is only "Hmm, this is also a good idea for core".

But I fully agree not forcing react-select on everyone, react-select is probably not a permanent first class citizen in our codebase, it has too much complexity.

Yeah no worries! So you do have a prototype wrapper though? Is it based a bit on this or completely written from scratch?

Would be awesome if you'd be willing to share 😁

You can paste it in a gist or something

ndom91 avatar Jul 11 '22 12:07 ndom91

bumping this. appreciate it if you could share @emrysal

abetoots avatar Nov 18 '22 09:11 abetoots

I'm thinking about making react-select a peer-dependency, since we have a timezone select hook PR open and getting ready to merge (https://github.com/ndom91/react-timezone-select/pull/81 - Thanks @DreierF).

What do folks think? People would have to explicitly also install react-select then, right - but npm 7+ seems to install peer-deps by default now anyway. So I think it'd be relatively safe..

ndom91 avatar Mar 29 '23 15:03 ndom91

I've gone ahead and made react-select a peer dependency in 2.0.0 :+1:

Hopefully we can merge the useTimezoneSelect hook PR soon then

ndom91 avatar Mar 29 '23 15:03 ndom91

This has been released in v2.1.0

  • PR: https://github.com/ndom91/react-timezone-select/pull/81
  • Docs: https://github.com/ndom91/react-timezone-select#-custom-select-component

Thanks @DreierF

ndom91 avatar Mar 30 '23 12:03 ndom91