Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

Commit

Permalink
fix: more Flow fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
FezVrasta committed Apr 16, 2020
1 parent 5a14fe0 commit 6483505
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[lints]

[options]
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectError
suppress_comment=\\(.\\|\n\\)*\\$\\(FlowExpectError\\|FlowFixMe\\)

[strict]

Expand Down
33 changes: 28 additions & 5 deletions src/__typings__/main-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import React from 'react';
import { Manager, Reference, Popper, usePopper } from '..';
import type { Modifier, StrictModifiers } from '@popperjs/core';

export const Test = () => (
<Manager>
Expand Down Expand Up @@ -68,21 +69,43 @@ export const HookTest = () => {
modifiers: [
{
name: 'arrow',
options: { element: arrowElement || undefined },
options: { element: arrowElement },
},
],
}
);

usePopper(
usePopper(referenceElement, popperElement, {
modifiers: [
// $FlowExpectError: offset tuple accepts only numbers
{
name: 'offset',
options: { offset: [0, ''] },
},
],
});

Number(2 + null);

type CustomModifier = $Shape<Modifier<'custom', { foo: boolean }>>;
usePopper<StrictModifiers | CustomModifier>(referenceElement, popperElement, {
modifiers: [
{
name: 'custom',
options: { foo: true },
},
],
});

usePopper<StrictModifiers | CustomModifier>(
referenceElement,
popperElement,
// $FlowExpectError
// $FlowExpectError: foo should be boolean
{
modifiers: [
{
name: 'offset',
options: { offset: [0, ''] },
name: 'custom',
options: { foo: 'str' },
},
],
}
Expand Down
21 changes: 11 additions & 10 deletions src/usePopper.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ type UpdateStateModifier = Modifier<'updateState', {||}>;

const EMPTY_MODIFIERS = [];

export const usePopper = <
TModifiers: StrictModifiers | $Shape<Modifier<string, {}>>
>(
type DefaultModifiers = StrictModifiers | $Shape<Modifier<any, any>>;

export const usePopper = <Modifiers: DefaultModifiers = DefaultModifiers>(
referenceElement: ?(Element | VirtualElement),
popperElement: ?HTMLElement,
options: Options<TModifiers> = {}
options: Options<Modifiers> = {}
) => {
type TExtendedModifier = TModifiers | $Shape<UpdateStateModifier>;
type InternalModifiers = Modifiers | $Shape<UpdateStateModifier>;

const prevOptions = React.useRef<?OptionsGeneric<TExtendedModifier>>(null);
const prevOptions = React.useRef<?OptionsGeneric<InternalModifiers>>(null);

const optionsWithDefaults = {
onFirstUpdate: options.onFirstUpdate,
Expand Down Expand Up @@ -79,7 +79,7 @@ export const usePopper = <
[setState]
);

const popperOptions = React.useMemo<OptionsGeneric<TExtendedModifier>>(() => {
const popperOptions = React.useMemo<OptionsGeneric<InternalModifiers>>(() => {
const newOptions = {
onFirstUpdate: optionsWithDefaults.onFirstUpdate,
placement: optionsWithDefaults.placement || 'bottom',
Expand All @@ -97,6 +97,7 @@ export const usePopper = <
) {
return prevOptions.current;
} else {
// $FlowFixMe: Cannot assign `newOptions` to `prevOptions.current` because string [1] is incompatible with string literal `updateState` [2] in property `name` of array element of property `modifiers`
prevOptions.current = newOptions;
return newOptions;
}
Expand All @@ -111,15 +112,15 @@ export const usePopper = <
const popperInstanceRef = React.useRef();

const createPopper = React.useMemo<typeof defaultCreatePopper>(
// For some reason the two identical types don't like to be cast to one of them
() => (options.createPopper: any) || defaultCreatePopper,
// $FlowFixMe: Cannot call `React.useMemo` with function bound to `create` because `TModifier` [1] is incompatible with `Modifier` [2] in array element of property `modifiers` of the third argument of the return value.
() => options.createPopper || defaultCreatePopper,
[options.createPopper]
);

useIsomorphicLayoutEffect(() => {
let popperInstance = null;
if (referenceElement != null && popperElement != null) {
popperInstance = createPopper<TExtendedModifier>(
popperInstance = createPopper<InternalModifiers>(
referenceElement,
popperElement,
popperOptions
Expand Down

0 comments on commit 6483505

Please sign in to comment.