RFC: Allow composition of the Select component.
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?
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?
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.
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
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.
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
bumping this. appreciate it if you could share @emrysal
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..
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
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