downshift version: 6.0.5node version: 12npm (or yarn) version: yarn 1.22.4Relevant code or config
import downshift, { UseComboboxStateChangeTypes } from 'downshift';
// or
import type { UseComboboxStateChangeTypes } from 'downshift';
What you did:
I tried to compare onStateChange's type with UseComboboxStateChangeTypes.InputKeyDownEscape.
What happened:
Everything works fine in the editor, but the code fails to compile, because UseComboboxStateChangeTypes is in a definition file and apparently it does not play well with build tools:
Attempted import error: 'UseComboboxStateChangeTypes' is not exported from 'downshift'.
When trying to use import type { UseComboboxStateChangeTypes } from 'downshift';, the import would be stripped at build time, and the enum undefined.
Reproduction repository:
I think the explanation and steps to reproduce are quite easy, I can provide one if needed.
Problem description:
Suggested solution:
Can there be a way to access UseComboboxStateChangeTypes in the same way we can access downshift.stateChangeTypes? downshift.useComboboxStateChangeTypes or something?
Right now, we are forced to do things like
if (changes.type === 2) // __keydown_escape__
but if tomorrow this enum is going to change, our code is going to break without any warning.
Hi! Does this help? https://www.downshift-js.com/use-combobox#state-reducer https://github.com/downshift-js/downshift/tree/master/src/hooks/useCombobox#statechangetypes
They are part of the hook object.
~The thing is using the Downshift.stateChangeTypes won't work in Production as enums get simplified to numbers only.~
~And Downshift.stateChangeTypes and UseComboboxStateChangeTypes don't have the same index for each kind of events :( so if we use Downshift.stateChangeTypes directly, the wrong events indexes will be associated in the Production build.~
edit: wait, I need to try something
useCombobox.stateChangeTypes was exactly what we were looking for, thank you so much!
Curious if this might be able to re-opened as I still think there are scenarios where we might want access to the raw UseComboboxStateChangeTypes enum. My current scenario is that I'd like to augment the onStateChange types (with some custom types) but at current not possible to merge with the current enum as it isn't exposed.
Would be happy to create an PR doing this though I'll admit I'm not entirely sure how it's possible that UseComboboxStateChangeTypes is exposed (via export) in the typings file but cannot be imported by a transpiler (my case is webpack/babel).
/cc @silviuaavram
@wootencl it's answered above, use useCombobox.stateChangeTypes, like useCombobox.stateChangeTypes.InputKeyDownEscape. It's also in the documentation. https://github.com/downshift-js/downshift/tree/master/src/hooks/useCombobox#statechangetypes
Thanks!
@silviuaavram Yup, that works for catching events in a stateReducer or onStateChange. I'll break down my current use case as I think my brief explanation above more than likely was insufficient.
I have a component (lets say <Select />) and inside that component I utilize downshift to handle most of the logic. In that component I expose the onStateChange from downshift _but_ there are some events/state changes within my select that I've introduced that I want to augment/add to the type of onStateChange type (I still want to be able to catch the normal downshift state changes).
So for example if I had access to UseComboboxStateChangeTypes I could create an augmented onStateChange with the following:
enum CustomStateChangeTypes {
CustomStateChangeType = 'CustomStateChangeType'
}
type CustomOnStateChangeEvent = {
type: UseComboboxStateChangeTypes | CustomStateChangeTypes
customData?: CustomData
} & Omit<UseComboboxStateChange<Item>, 'type'>
type CustomOnStateChangeHandler = (changes: CustomOnStateChangeEvent) => void
At current without UseComboboxStateChangeTypes exposed I've had a hard time creating this augmented onStateChange.
Hopefully that makes sense but happy to answer questions/break down further if needed!
Well, even if you augment them in your type, you will still not get them in onStateChange or stateReducer. We only dispatch our downshift-related state changes, and those end up in your callbacks, to be used by you in order to have a better understanding on why the state changes/is about to get changed.
So if you added your own state changes in your select, you need to handle them separately. It should be easy to merge downshift + your logic via onChange / stateReducer / controlled props, but you cannot add your logic inside downshift directly. Or you can, just fork the repo and go wild :D
Ah, apologies 馃槵. Should have explained further: with the above in theory implemented I could do the following with my Select component:
type Props {
onStateChange: CustomOnStateChangeHandler
}
const Select: FunctionComponent<Props> = ({ onStateChange, ...rest }) => (
const handleCustomEvent = () => {
onStateChange({ type: CustomStateChangeTypes.CustomStateChangeType, customData: ... })
}
const downshiftReturnValue = useCombobox({
onStateChange
... //otherProps
})
... // implementaion details
)
With the above I can pass down a onStateChange prop to my Select component _and_ treat it as if it's downshift's own onStateChange _but_ also permit listening/reacting to my own custom events.
Unrelated, thanks for the super prompt replies/discussion!
Most helpful comment
useCombobox.stateChangeTypeswas exactly what we were looking for, thank you so much!