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

feat: useFocusable #79

Closed
wants to merge 5 commits into from
Closed

Conversation

GeraldHost
Copy link

Note: this is not quite ready to merge but wanted to open this pull request as a start to figure out how this can be accomplished. We use this library at work and it would be cool to have a nice hooks implementation.

useFocusable

An initial implementation of useFocusable a hooks based version of the withFocusable HOC. This is current working using a ref callback to get the DOM node. It also requires the user to provide the parentFocusKey manually.

First Note

Because this is using a ref callback instead of findDomNode when used with react native components such as View the ref isn't going to point at a DOM node even if you are running it in the browser. I'm not familiar with how this library works with React native as it doesn't seem you can ever find the position of a native element when in nativeMode?

Second Note

It would be nice to come up with a solution to not have to pass in parentKey manually. This comes with some challenges when using hooks. I made a suggestion in this issue thread that would be worth putting a bit of brain power to to figure out if there is a solution.

@asgvard
Copy link
Collaborator

asgvard commented Jan 6, 2021

Hi! Thanks for your contribution, I will have some dedicated time to work on this very soon, so I will review it and also will try to figure out a good solution for the parent/child context issue. We are doing some updates internally and also have a need now to migrate to hooks, so this will speed up the process for sure :)

@GeraldHost
Copy link
Author

GeraldHost commented Jan 6, 2021

@asgvard Awesome no worries dude. I have update this implementation so it can now track the parent focus key without haven't to explicitly pass it to every child. It does so by taking a isParent prop. There may be an existing prop like trackChildren we could use to infer if something is a parent but I'm not familiar enough with this library to suggest what.

Here is a very quick example of it in use:

const MenuItem = ({ focusKey }) => {
  const { register, focused } = useFocusable({ focusKey });

  const styles = focused
    ? { ...styles.menuItem, ...styles.focusedBorder }
    : { ...styles.menuItem };

  return <button ref={register} style={styles} />;
};

const Menu = ({ focusKey }) => {
  const { register, setFocus } = useFocusable({
    focusKey,
    isParent: true,
  });

  useEffect(() => {
    setFocus();
  }, []);

  return (
    <div ref={register} style={styles.menu}>
      <MenuItem focusKey={"MENU-1"} />
      <MenuItem focusKey={"MENU-2"} />
      <MenuItem focusKey={"MENU-3"} />
      <MenuItem focusKey={"MENU-4"} />
      <MenuItem focusKey={"MENU-5"} />
      <MenuItem focusKey={"MENU-6"} />
    </div>
  );
};

@GeraldHost
Copy link
Author

This works but just realised that it only works if the parent item is the only sibling. So this needs more work/brain power. It could be that there really isn't any better way to do this with hooks other than passing a parentFocusKey.

@asgvard
Copy link
Collaborator

asgvard commented Mar 29, 2022

Here is the new version of this library that is migrated to hooks: https://github.com/NoriginMedia/Norigin-Spatial-Navigation

@asgvard asgvard closed this Mar 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants