Skip to content

Instantly share code, notes, and snippets.

@painedpineapple
Last active March 10, 2020 16:55
Show Gist options
  • Save painedpineapple/a87bc03852d6642867c3316c1eb4ca7a to your computer and use it in GitHub Desktop.
Save painedpineapple/a87bc03852d6642867c3316c1eb4ca7a to your computer and use it in GitHub Desktop.
[@bs.module "react"]
external useMemo8:
([@bs.uncurry] (unit => 'any), ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h)) => 'any =
"useMemo";
[@bs.module "react"]
external useCallback4:
([@bs.uncurry] ('input => 'output), ('a, 'b, 'c, 'd)) =>
React.callback('input, 'output) =
"useCallback";
[@bs.module "react"]
external useCallback5:
([@bs.uncurry] ('input => 'output), ('a, 'b, 'c, 'd, 'e)) =>
React.callback('input, 'output) =
"useCallback";
[@bs.module "react"]
external useCallback6:
([@bs.uncurry] ('input => 'output), ('a, 'b, 'c, 'd, 'e, 'f)) =>
React.callback('input, 'output) =
"useCallback";
[@bs.module "react"]
external useCallback7:
([@bs.uncurry] ('input => 'output), ('a, 'b, 'c, 'd, 'e, 'f, 'g)) =>
React.callback('input, 'output) =
"useCallback";
[@bs.module "react"]
external useEffect6:
([@bs.uncurry] (unit => option(unit => unit)), ('a, 'b, 'c, 'd, 'e, 'f)) =>
unit =
"useEffect";
[@bs.module "react"]
external useEffect7:
(
[@bs.uncurry] (unit => option(unit => unit)),
('a, 'b, 'c, 'd, 'e, 'f, 'g)
) =>
unit =
"useEffect";
[@bs.module "react"]
external useEffect8:
(
[@bs.uncurry] (unit => option(unit => unit)),
('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h)
) =>
unit =
"useEffect";
[@bs.module "react"]
external useEffect15:
(
[@bs.uncurry] (unit => option(unit => unit)),
('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n)
) =>
unit =
"useEffect";
let useAsyncStateEffect4 = (callback, dependencies) => {
React.useEffect4(
() => {
let didCancel = ref(false);
switch (callback(), didCancel^ == false) {
| (Some(returnedValue), true) => returnedValue()
| (Some(_), false)
| (None, true)
| (None, false) => ()
};
Some(() => {didCancel := true});
},
dependencies,
);
};
let useHookWithDecoderToJs = (hookBase, decoder, ()) => {
let item = hookBase();
React.useMemo2(() => item->decoder, (item, decoder));
};
let useHookOptionalValueWithDecoderToJs = (hookBase, decoder, ()) => {
let item = hookBase();
React.useMemo2(
() =>
switch (item) {
| None => None
| Some(item) => Some(item->decoder)
},
(item, decoder),
);
};
[@genType]
[@genType.as "usePrevious"]
let usePrevious = (value: 'a) => {
let reference = React.useRef(value);
React.useEffect1(
() => {
React.Ref.setCurrent(reference, value);
Some(() => ());
},
[|value|],
);
React.Ref.current(reference);
};
[@genType]
[@genType.as "useInterval"]
let useInterval = (callback: unit => unit, delay) => {
let savedCallback = React.useRef(() => ());
React.useEffect1(
() => {
React.Ref.setCurrent(savedCallback, callback);
Some(() => ());
},
[|callback|],
);
React.useEffect1(
() => {
let tick = () => {
let current = React.Ref.current(savedCallback);
current();
};
switch (delay) {
| None => Some(() => ())
| Some(delay) =>
let id = Js.Global.setInterval(tick, delay);
Some(() => id->Js.Global.clearInterval);
};
},
[|delay|],
);
};
type animateDisplayValue = {
show: unit => unit,
hide: unit => unit,
toggle: unit => unit,
animateDisplayClassName: string,
isVisible: bool,
isDisplayed: bool,
};
let useAnimateDiplay =
(
~animationDuration=500,
~display as displayProp=`block,
~defaultIsVisible=false,
~defaultIsDisplayed=false,
(),
) => {
let (isVisible, setIsVisible) = React.useState(() => defaultIsVisible);
let (isDisplayed, setIsDisplayed) =
React.useState(() => defaultIsDisplayed);
let show = () => {
setIsDisplayed(_ => true);
};
React.useEffect2(
() => {
if (isDisplayed) {
setIsVisible(_ => true);
};
None;
},
(isDisplayed, setIsVisible),
);
let hide = () => {
setIsVisible(_ => false);
};
React.useEffect3(
() => {
if (!isVisible) {
Js.Global.setTimeout(
() => setIsDisplayed(_ => false),
animationDuration,
)
->ignore;
};
None;
},
(isVisible, animationDuration, setIsDisplayed),
);
let toggle = () =>
if (isVisible && isDisplayed) {
hide();
} else {
show();
};
let isVisibleClassName = isVisible ? " is-visible " : " is-not-visible";
let isDisplayedClassName =
isDisplayed ? " is-displayed " : " is-not-displayed";
let className = isVisibleClassName ++ isDisplayedClassName;
let animateDisplayClassName =
className
++ " "
++ Css.(
style([
selector("&.is-displayed", [display(displayProp)]),
selector("&.is-not-displayed", [display(`none)]),
])
)
++ " ";
{show, hide, toggle, animateDisplayClassName, isVisible, isDisplayed};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment