Coder Social home page Coder Social logo

noriginmedia / norigin-spatial-navigation Goto Github PK

View Code? Open in Web Editor NEW
278.0 11.0 79.0 1.68 MB

React Hooks based Spatial Navigation (Key & Remote Control Navigation) / Web Browsers, Smart TVs and Connected TVs

License: MIT License

HTML 1.17% TypeScript 96.97% JavaScript 1.86%
react react-hooks spatial-navigation key-navigation tizen tizen-tv webos webos-tv smart-tv remote-control

norigin-spatial-navigation's People

Contributors

adrian-wozniak avatar asgvard avatar braggiouy avatar claudemassaad avatar eigil avatar evanwang0 avatar guilleccc avatar hans00 avatar joshreep avatar lynchyc avatar patricklizon avatar pickymtr avatar predikament avatar xavi160 avatar zemlanin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

norigin-spatial-navigation's Issues

Keydown event on focusable component

Is there a way to add keydown event listener on focusable component?
To capture any keydown event, not just enter press, enter release or arrow presses?

How to handle "Back" button functionality

We've recently started using Norigin Spatial Navigation on our React-based Smart TV application and we love it! However, one integral part of navigating smart TV apps with the remote is the option to press the "back" button. I didn't see it in the documentation, nor do I see many people talking about it. Now I'm questioning my sanity for thinking this should be a feature of the library.

Anyways, how would you suggest we go about implementing this on our end? Would the best solution be a global listener for the back keycode and then setting the focus manually based on that? Any help would be appreciated, thanks!

Question: keymap for tizen and webOS

Hi guys, I'm testing my web page in the native browser on a Samsung TV, and I cannot use the D-pad of the remote control.

A mouse icon (pointer) appears instead of moving the focus with the arrows.

How can I change this?

Thanks!

[Feature] webOS Magic Remote support

Currently it can run in webOS but only support remote navigational keypad. It will be great if it can support LG magic remote pointer as well.

Thanks

[Question] Virtualizing Recommendations

Hi Norigin Media Team,

I would like to take a moment to express my sincere gratitude for your team contribution to the open source community through the Norigin-Spatial-Navigation package. I truly appreciate the time and effort your team have put into developing and maintaining this package. The dedication to creating high-quality open source software is truly admirable and passing on a positive impact on the TV developer space.

Question: I would like to know the team's opinion on whether there are any recommends package for 'virtualizing' large number of rails, horizontal and vertically to improve memory management.
We have integrate with https://github.com/bvaughn/react-window, however it will does not work as elegantly / fuzz free as we it wanted to.

[Question] What is the defined behavior for when `useFocusable` is used without passing `ref`?

Hello and thank you for this very useful library!

Last week, I tried to have a component override a little bit of the of the behavior of the arrow keys, and for that I needed to use setFocus. However, I didn't need any of the other functionalities in that component, and so I was curious to know if I could've skipped passing the ref to an element and just use setFocus that I receive from useFocusable.

This seemed to work, but the documentation does not specify what the defined behavior is for when useFocusable is used without passing ref to an element, hence my question. So I wanted to know if things would be breaking in the future if I left this call to useFocusable without passing ref.

[Feature] Reset last saved child focus

When using the app there are certain scenarios that I would like to reset a components last saved child focus.

https://codesandbox.io/s/dank-wildflower-os0it1

Describe the solution you'd like

It may be buggy in parts, but the code linked above shows different content being shown for each of the Tabs. I have a keyup window listener set inside the ContentRows component.

If a user is navigating down the ContentRows for that selected tab and they press the Backspace key, I would like the Tabs list to be focused and the ContentRows component to be scrolled back up to the top (focusing on the first ContentRow).

The problem I am encountering is that once you have focused back on the Tab and the user presses the down key, they will go right back to the last ContentRow that was focused instead of the intended first row.

There is also the added caveat where I want the focus to be reset on the backspace key event listener, but is maintained if go left to the sidebar and come back.

Back button listener

Hey there! Great library!

Just one question, how would you implement the back button listener?

I was looking at what the lib provides but didn't find any mention of what could we do to handle the back navigation.

Get current focusKey on beforePopState

I would like to store the current focusKey in session storage before navigating to a new page (during the beforePopState event), so that I can setFocus() to that focusKey when returning to the page. I know that the debug mode is spitting this info out to the console, but how can i get it programmatically?

Thanks for such an awesome library!

Navigating over the elements be skipping the elements

Hello all,

I have integrated this library with my react application. I have designed a grid view where I have added the Focus Container and also added each element from the grid as a Leaf Focusable component. I have added all the required configurations as well. But the behavior is skipping the focus over the third element when the focus moved from left to right and the same when the navigation started from right to left it skipping the second element. (Considering the grid has 4 columns)

Please find the code snippet as below,

const RibbonRowContent = function ({ ribbonContentList, onAssetPress, onAssetFocus }: RibbonRowContentProperties) { const { ref, focusKey } = useFocusable({}); return ( <FocusContext.Provider value={focusKey}> <ContentRowScrollingWrapper ref={ref}> {ribbonContentList.map((element: any) => ( <RibbonAsset key={element.videoId} assetDetails={element} onEnterPress={onAssetPress} onFocus={onAssetFocus} /> ))} </ContentRowScrollingWrapper> </FocusContext.Provider> ); };

Please let me know how I can resolve this issue, since similar kind of behaviour getting for the Navigation Drawer Menu integrated.

Cannot access items list without using the focusSelf on them

Hi team, I am trying to access the items of a list that has the ref and is wrapped on the FocusedContext.Provider component.
Using the visual debug I can see that they are referenced but I cannot access them without using the 'focusSelf' function which I think is not the ideal way to do these by looking at your READ.me

Example code:

List:
<S.Container> {list.length > 0 && ( <FocusContext.Provider key={focusKey} value={focusKey}> <S.CardContainer ref={ref}> {list.map((el) => ( <AnimeCard key={el.id} anime={el} justifySelf={true} /> ))} </S.CardContainer> </FocusContext.Provider> )} </S.Container>

Item:
<S.Container ref={ref} onClick={handleClick} justifySelf={justifySelf}> <S.Image image={anime.image} /> <S.Title>{anime.title}</S.Title> </S.Container>

Notes:

  1. It has a defined focusKey on the List component

What am I missing here?


Using CRA with React Router (Router rules are displayed on App.tsx)


Thanks


Update:

I did a sandbox to show an example, if I have a dynamic list it will not focus on it.
removing the conditional rendering and using the ´numbers´ array directly, it will work. How can I use the focus in a list that is being returned from an API?

Sandbox: https://codesandbox.io/s/react-typescript-forked-23kp1o?file=/src/App.tsx

How to prevent Event Listener firing event multiple times

How to prevent multiple presses on the button. Such as press the button left to navigate left on a rail, It will wait for the slide rail scroll to finish before firing the next event:

For example with normal event listener, I can do like this:

          useEffect(() => {
        const yourFunction = () => {console.log('hi')}
        document.addEventListener('keyup', yourFunction)

        return () => {
            document.removeEventListener('keyup', yourFunction)
        }
    }, [])

But I don't know how to do it with onEnterPress that libraries provides

React native example

Hello, could you give a sample react native tv app example because i have tried following the docs but i just cant fully understand how to use this library

Navigation between rails not happening as expected

Describe the bug
We are using the Norigin Media Spatial Navigation library to handle remote navigation on CTVs.
In this context, we wanted to check why we are seeing the below navigation behaviour

Goal

Achieve similar or close to Apple’s TV Navigation behavior

To Reproduce
Steps to reproduce the behaviour:

  1. Go to https://github.com/krackjack234/Norigin-Spatial-Navigation/tree/issues/53/Down-Navigation-Not-Working. The code is forked from main branch of norigin media repo where we have made few modifications
  2. Build and run the app
  3. Click on the DPAD right button of the keyboard to bring focus from the menu to the first rail (TV Channels)
  4. Press right to go to the 4th card (Asset 4) in the first rail
  5. Press down

Expected behaviour
The focus should come to the second card of the 2nd rail (Series) based on the distance of the last focused card (i.e 4th card of first rail i.e.TV Channels rail)

Actual behaviour
On pressing down, the focus goes to the 4th card of the 3rd rail (Recommended) completely skipping the 2nd rail.

Demo Code Changes

Remove FocusContext.Provider for each of the ContentRow so that all the rows are tested for nearest sibling in a single FocusContext.Provider

Proposal

Expose ADJACENT_SLICE_THRESHOLD , ADJACENT_SLICE_WEIGHT , DIAGONAL_SLICE_WEIGHT or similar so we can configure and achieve different navigation behaviors

Screenshots

Spatial-Navigation-Demo

Additional context
We wanted to check below

  1. Why we are seeing this behaviour and how can we override this to ensure the focus goes to the 2nd rail?
  2. Currently, we have put all the rails in a single FocusContextProvider so that we can match the Apple tv navigation behaviour. How can we achieve the Apple TV navigation behaviour where on pressing Dpad Up button, the focus always goes to the closest card in the left direction instead of in the right direction?

Thanks!

Support for webos magic remote

Hello we are looking into the library, to use it in our project.
But previously I remember you didn't have a support for the LG magic remote, there was such ticket open.
Is this changed now and you support it or is still in the future plans?
And do you accept pull request at one point, if we choose to you this library and write our own wrapper arround it.

Support for multiple key codes for directional navigation

Is your feature request related to a problem? Please describe.
I am working on an app that requires a gamepad (Xbox controller) and I'd like to use both the joystick and the d-pad (different key codes) for navigation.

Describe the solution you'd like
I'd like to update the setKeyCodes API to allow the use of specifying multiple key codes for a directional action.

Describe alternatives you've considered
I tried to intercept the KeyboardEvent and transform it to a single key code, but this doesn't work on some older browsers (Legacy Edge doesn't pass the keyCode property on Synthetic Events)

I've also tried to listen to the KeybardEvents and update the set of keyCodes depending on which set the user appears to be using, but this creates a debounced effect where the navigation doesn't work for the initial event in the new set.

Additional context
I'm also interested in updating to use the key property instead of the keyCode property since keyCode has been deprecated.

[Question] Accessibility and focus

Hello! Thank you for this library!

Is there a recommended way to handle a11y? Meaning, for each element that is focused, the TV text-to-speech when activated to read a given label.

At the moment I am working on a project, and the usual approach is to place the role and aria-label properties on each element. When the component is focused, then the TV reads the label to the user.

Do you have a standard way of handling this outside of what I described? Do you plan to? Maybe even a way to enforce it, as some TV platforms require this functionality.

Would this work?

import { useFocusable } from '@noriginmedia/norigin-spatial-navigation';

function MovieTile({ title, director }) {
  const { ref, focused } = useFocusable();

  return (
    <div ref={ref} role="" arial-label={`${title}, ${director}`} className={focused ? 'movie-focused' : 'movie'}>
      <img src="example" />
      <div>{ title }</div>
      <div>{ director }</div>
    </div>
  );
}

A way to identify when setFocus is called with a non-existing key

Is your feature request related to a problem? Please describe.
Error calling setFocus(MyFocusKey) with a non-existing focus key. In this case the focus will lose but there is no easy way to identify when it happens (when the focus key doesn't exist or when the setFocus with that key fails).

Describe the solution you'd like
It'd be helpful to get in somehow when the focus is set to a non-existing key or any way to identify when a key doesn't exist previous to call setFocus(..) so if we know it doesn't exist we don't try to focus it.

Describe alternatives you've considered

  • a second param to setFocus to send a callback in case the focus key is not found
  • Someway to get if there is an element with an specific focus key

Additional context
Currently, my team is using Noring Spatial Navigation and we found the next scenario:

  1. There is a list of components (cards) that come from an API so we set keys depending on the name
  2. If a user clicks over a card, the list is unmounted and we redirect the user to another page (we save in the state the last focused card)
  3. When the user goes back to the list of items we set the focus to the last focused card saved in the state

With this scenario in mind, sometimes when we call setFocus(MyFocusKey) the key doesn't exist in the list of cards fetched from the API therefore the focus is lost.

I have tried to identify when the focus is lost but even calling getCurrentFocusKey it returns the non-existing focus.

Export `navigateByDirection`

Is your feature request related to a problem? Please describe.
I want to do navigation with a gamepad

Describe the solution you'd like
Export navigateByDirection, like the other methods are exported.

Describe alternatives you've considered
Current work-around:

import { SpatialNavigation } from '@noriginmedia/norigin-spatial-navigation'

declare module '@noriginmedia/norigin-spatial-navigation' {
  const SpatialNavigation: any
}

Additional context
Related to #67

Get prev focusKey on onFocus handler

Hi all.

Could you please help how I can know prev focus key?

Fox example I have input filed and button to set focus to this field and if I press this button I should automatically set focus to input (not focus from library) but if use general arrow navigation I don't set focus to input.

Input component:

const Input = () => {
  const inputRef = useRef<HTMLInputElement>(null!);
  const { ref } = useFocusable({
    focusKey: 'SEARCH_INPUT',   <<---
    onFocus() {
      // todo: check if focus was set from button
      // inputRef.current.focus();
    },
  });

  return (
    <div ref={ref} ...>
      <input ref={inputRef} ... />
    </div>
  );
};

Button component:

const Button = () => {
  const { setFocus } = useFocusable({ focusable: false });

  return (
    <div
      onClick={() => setFocus('SEARCH_INPUT')}
    >set focus to search input</div>
  )
};

Maybe we can pass additional params to setFocus method and get it in onFocus or something like that?

Right now it's not valid:
image

Thank you.

Help Required: Looking for a support on Large List Virtualisation

I tried different Plugins which currently available on market and i see.. none of them supporting properly one or the other having issues. (like focus not works, scroll not proper, too much code complications )

Can you help me choose the proper one which supports Norigin-Spatial-Navigation

Really sorry to bring this here

Thank you

Performance optimization for measureLayout

Hello, this is not necessarily a feature request, but some thoughts/questions regarding performance optimization.

When user pressed the arrow key, measureLayout is essentially triggered for the current focused element as well as all of its "focusable siblings".

There seem to be 3 problems here:

  1. x and y field returned by measureLayout is not used by SpatialNavigation service, if I'm not wrong on this. In order to calculate x and y, you had to call getRect on parent node additionally. If we remove x and y, it seems we can save some perf cost?

  2. In getRect, you used a while loop to keep tracing the offsetParent up to the root in order to calculate left and top accurately. It seems to me that we can alternatively use getBoundingClientRect which is browser standard and easier to understand. But I'm not sure which method is better from performance perspective.

  3. Missing memoization on getRect. For example, let's say we have a simple carousel of 100 focusable items. When we navigate from one item to another, SpatialNavigation calls measureLayout and getRect on all 100 elements. We have to take measurements of offsetLeft, scrollLeft, offsetTop, scrollTop of the same offsetParent 100 times. How about memoizing it?

// Source code in src/measureLayout.ts
const getRect = (node: HTMLElement) => {
  let offsetParent = node.offsetParent as HTMLElement;
  const height = node.offsetHeight;
  const width = node.offsetWidth;
  let left = node.offsetLeft;
  let top = node.offsetTop;

  while (offsetParent && offsetParent.nodeType === ELEMENT_NODE) {
    left += offsetParent.offsetLeft - offsetParent.scrollLeft;
    top += offsetParent.offsetTop - offsetParent.scrollTop;
    offsetParent = offsetParent.offsetParent as HTMLElement;
  }

  return {
    height,
    left,
    top,
    width
  };
};

const measureLayout = (node: HTMLElement) => {
  const relativeNode = node && node.parentElement;

  if (node && relativeNode) {
    const relativeRect = getRect(relativeNode);
    const { height, left, top, width } = getRect(node);
    const x = left - relativeRect.left;
    const y = top - relativeRect.top;

    return {
      x,
      y,
      width,
      height,
      left,
      top
    };
  }

  return { x: 0, y: 0, width: 0, height: 0, left: 0, top: 0 };
};

How To Compile For LG WebOS Smart Tv

Hello, I would like to know is there a way to compile the project for WebOS LG. I tried adding the appinfo.json, and other required files to for webos lg but all I get is a white screen when I install the app on a Lg TV. Is there any instructions for compiling for webos lg tv? thanks

Why stop using "getBoundingClientRect" for layout measurements?

In the latest release: https://github.com/NoriginMedia/Norigin-Spatial-Navigation/releases/tag/v1.0.2, you reverted the way it measures the layout/position of the nodes.

So now, if a node moved (ie: css transforms) after its initial rendering, it might not being taken into the potential next focus.
The current logic, as i understand, is that it only checks the siblings of the current node by measuring their layouts again before using the algo to get the next focus node.
However with this logic, if a node in another tree moved and now should "visually" be the next focus (ie: on press arrow right) it might not because maybe it wasnt the next focus using the previous layout measurement.

The current implementation makes sense and has its pros and cons, but i was wondering why the switch?
Did you see real performance issues with getBoundingClientRect?

Detect gamepad inputs or add a way of triggering arrows / enter

Is your feature request related to a problem? Please describe.
I want this library to work on Xbox. The Xbox supports the Gamepad API. However, this library only supports keyboard events.

Describe the solution you'd like

Automatic

Detects when 'A' (or another button for other controllers) and plus pad buttons are pressed, and does the navigation according to the gamepad

Custom

Export functions or hooks:

import { move } from '@noriginmedia/norigin-spatial-navigation'

move('up')
move('enter')

Describe alternatives you've considered
Here is my current work-around (which works), which will probably be useful to others even if this issue doesn't get solved:

// Dispatches keyup and keydown events for arrow keys and enter when the first gamepad uses plus pad and A button
let animationFrame: number | undefined
addEventListener('gamepadconnected', () => {
  // Only run loop if it's not already running
  if (animationFrame === undefined) {
    console.log('check')
    // Left, right, up, down, A
    const pressedButtons = [false, false, false, false, false]
    const keyCodes = [37, 39, 38, 40, 13]
    const buttons = [14, 15, 12, 13, 0]
    const check = (): void => {
      for (let i = 0; i < pressedButtons.length; i++) {
        const pressed = navigator.getGamepads()[0]?.buttons[buttons[i]].pressed ?? false
        if (pressed && !pressedButtons[i]) {
          dispatchEvent(new KeyboardEvent('keydown', { keyCode: keyCodes[i] }))
        } else if (!pressed && pressedButtons[i]) {
          dispatchEvent(new KeyboardEvent('keyup', { keyCode: keyCodes[i] }))
        }
        pressedButtons[i] = pressed
      }
      animationFrame = requestAnimationFrame(check)
    }
    check()
  }
})
addEventListener('gamepaddisconnected', () => {
  cancelAnimationFrame(animationFrame as number)
  animationFrame = undefined
})

I prefer to not use dispatchEvent with the keyboard keyCodes though.

Additional context
Add any other context or screenshots about the feature request here.

Change throttle after initialization

Hi all, I'm currently using this library in a smart tv app with a full feature video player.

In order to avoid too much repainting during the navigation, I set the throttle attribute to 250 on the init method; by the way, in the player view I would like to change the throttle to a lesser value in order to move the seekbar faster.
In the same way, after the user has changed the seek point, I would like to set the throttle again to the initial value (250).

Any ideas to do that?

Thanks

How to replace `LastFocusedChild` for specific container?

Hi all.

Could you please suggest hot to replace LastFocusedChild for specific container when I back to this specific container.

For example: I've the container with children and leave this container on second child, but when I'm going to return to this component I want that the focus will be on fourth child. How I can implement this?

I don't have direct access to the SpatialNavigationService for example.

Previous Element Focused when returning to Component

Describe the bug
Focus does not go back to expected element when returning to a component.
It returns to focus the element before the Element expected.
This would be an Implementation issue. Some help on why the element focused before this one is being chosen when returning to the component rather than the one used to leave the component would be great.

The Component has trackChildren: true

Expected behavior
The component that has focus when moving to another container should be the One that is focused when retuning.

Spatial navigation with dropdown select

Dear all,

I have trouble trying to make Norigin-Spatial-Navigation work with the dropdown select element.

I want the following typical behavior:
-The dropdown button could get focused with directional navigation.
-When focused, pressing Enter will expand the dropdown menu.
-When the menu is expanded, pressing the up and down keys will highlight the different dropdown options.
-When Enter is pressed, the highlighted option is selected, the dropdown is retracted, and the onSelect callback function is called.

I have tried making the dropdown component focusable as follows:

import {useFocusable} from "@noriginmedia/norigin-spatial-navigation";

function DropdownSelection() {

    const { ref, focused } = useFocusable()

    return (
        <select ref={ref} name="cars" id="cars">
            <option value="volvo">Volvo</option>
            <option value="saab">Saab</option>
            <option value="mercedes">Mercedes</option>
            <option value="audi">Audi</option>
        </select>
    );
}

export default DropdownSelection;

But this did not work. The menu does not expand on Enter press when the element is focused.

I even tried with dropdown components from libraries like Semantic-ui and react-bootsrap, but also failed.

Any suggestions?

extraProps values not updating in callback functions

Hello,

I am currently trying to pass some props through to the onFocus callback. This value is not defined during the mounting of the component (gets set after a fetch request on a mounting useEffect).

I have found that even after the value has changed and the component has rendered, the onFocus prop arguments remain the same.

I have used the example code provided in the project to simulate this issue. In the ContentRow component, I have added a useEffect that will set a local state value after 5 seconds.

This value is passed into the extraProps property. If you try to navigate through the different ContentRow's, you will see the console log message always reports the value to be null and not the expected value is updated

onFocus callback always returns y:0

Hey all! I've been migrating an app over to your new hooks library, and I've ran into a slight issue - the onFocus callback seems to return y:0 regardless of the elements position. The Dom and component structure are identical to pre-migration, the only difference being the provider. The structure itself is a bunch of focusable rows on top of each other that all share the same parent component. CSS top is calculating correctly, just not y.

Anyway, my question is - are we now calculating x and y differently from the previous HOC library? Has anyone else ran into this problem?

Cheers

Integration of Norigin Spatial Navigation with Material UI Tree View

I wanted to include the NOrigin Spatial Navigation with Material UI's TreeView component. I want the navigation to be handled with the tree view. User navigates from tree node to the main content section.

Please find the below code snippate for the integration of Material UI Tree view.

  1. Tree view is used as a navigation menu.
  2. The main content section will contain a list.

codesandbox

One more help needed,

Since we have the concept of Leaf Focusable elements and the Focusable continers.

From the application prespective let's say we have enclosed it inside the Focus Container and added the Leaf Focusable nodes.The keyboard interaction callback for a "onArrowPress" will be handled inside the leaf node. What should be done if we needed to do tha callback should handled in both the callback added inside the leaf focusable node and as well in the Application.

Eg. Referce from the library documentation see, point "Wrapping Leaf components with a Focusable Container"

Where we have the layers defined as,

Page -> ContentWrapper -> ContentList -> ListItem.

We want a common "onArrowPress" will be invoked from the "Page", though we have triggered the event from "ListItem".

I request @asgvard @predikament @LynchyC Please provide inputs on the same.

[question] Unit tests

Hello!

(I didn't know where to write this question so I just went with "Bug Report")

First of all, thank out very much for contributing back to the community! Especially in this very specific context of TV navigation.

I've looked at the code and wonder if there is a specific reason why it doesn't contain any test. If there are no reason, that's totally fine; contributing with unit tests can be an excellent opportunity for any new contributor who would like to participate here.

Cheers!

Published package contains arrow functions

Describe the bug
Application that uses Norigin-Spacial-Navigation is crashing on non ES6 compliant browsers.

tsconfig.json has target property set to es5, but still produced index.js contains arrow functions that cause crash.

To Reproduce
Steps to reproduce the behavior:

  1. Launch example on browser that has no support for ES6.

Expected behavior
Application that bundles Norigin-Spacial-Navigation should not crash on non ES6 browsers.

Additional context
Some Connected TVs have really low spec :)

Bundled code including all of Lodash

When bundling a client app with the navigation library, I have found that it brings in all of Lodash as a dependency.

To shave a bit off the vendor bundles, is it possible to look through the possible options:

  1. Cherry pick the functions needed e.g. import forOwn from "lodash/forOwn";
  2. Install the individual lodash packages for the methods needed e.g. lodash.forOwn
  3. Migrate the lodash functions to a native approach

Nodes not focusable anymore after hot reload

Describe the bug
In a Vite.js live reload environment, focusable elements are not focusable anymore after hot reloading the component.

To Reproduce
Steps to reproduce the behavior:

  1. Init a simple Vite.js project
  2. Add the Norigin Spatial Navigation library
  3. Add a simple component that uses useFocusable
  4. Run the project
  5. Make a change to the component

Expected behavior
After a hot reload, the component should still be focusable.

Additional context
Not sure if it is Vite.js specific. Perhaps it can be reproduced in Webpack as well.

I've cloned and linked the repo to do some debugging and found that the useEffectOnce is the culprit. After a hot reload, the useEffect is triggered which removes the node from the registry. But the effectCalled ref isn't cleared, so the node never gets added again.

Event handlers do not update during hook lifetime

Describe the bug
Event handlers are not updated. Only initial handlers are passed do Focusable

To Reproduce

  1. Modify in example a function onAssetPress
const onAssetPress = (asset) => {
  console.log(selectedAsset);
  setSelectedAsset(asset);
};
  1. Press Enter in any of assets
  2. In console see that no matter what current value of selectedAsset is, in console it outputs null all the time

Expected behavior
In console we should see proper current value from selectedAsset

Additional context
onEnter passed to SpatialNavigation.addFocusable
https://github.com/NoriginMedia/Norigin-Spatial-Navigation/blob/main/src/useFocusable.ts#L132
but when it should update there are no handlers passed to SpatialNavigation.updateFocusable
https://github.com/NoriginMedia/Norigin-Spatial-Navigation/blob/main/src/useFocusable.ts#L157

How to track the current item in focus after focus loss

Is your feature request related to a problem? Please describe.

We are using Norigin Media for smart tv app development.
One issue we keep of facing is loss of focus because of incorrect code and from the logs we are unable to track how to find out the current item in focus.

e.g.

setFocusnewFocusKey sn:focusable-item-1
index.js:1 smartNavigatedirection down
index.js:1 smartNavigatefromParentFocusKey null
index.js:1 smartNavigatethis.focusKey sn:focusable-item-1
index.js:1 smartNavigatecurrentComponent sn:focusable-item-1 null
index.js:1 smartNavigatecurrentCutoffCoordinate 0
index.js:1 smartNavigatesiblings 3 elements: sn:focusable-item-1, MAIN

So even though now that we have lost focus and current focussed item is sn:focusable-item-1, we are unable to locate which item in DOM corresponds to this element

Describe the solution you'd like

Is there a way we can track the currently focussed item in DOM, so that we can track why it is focussed now. E.g. if we can log the entire focussable tree in console or see the focused item (sn:focusable-item-1) in DOM so that developer can debug the issue better?

Please also suggest is there any other way to solve this problem which we may have missed out

Remove enter button

Is your feature request related to a problem? Please describe.
I don't think the enter button is related to navigation. Like #56 (comment), a keydown listener that checks if the element is focused can be used instead of an enter press.

Describe the solution you'd like
Remove enter key from key map, and remove other inputs related to enter button.

Describe alternatives you've considered
N/A

Additional context
Related to #56 (comment)

Whale OS (Philips Smart TV) key events

Is your feature request related to a problem? Please describe.
We are working in supporting Philips Smart TVs. They seem to require using VK_ keyCodes instead of standard HTML 5.
https://partner.zeasn.com/partnerportal/RemoteControl/index.jhtml
The app mostly work as is but the validation seems to require using their VK constants when handling key events.

Describe the solution you'd like
Has anyone else looked at this ? Could we have a flag or a nice API to reconfigure the navigation handler to use those.

Describe alternatives you've considered

Additional context

Compiling for WebOS LG Question

I recently left a question and I think there was a misunderstanding. Is there any commands to compile the example source demo into a webos project. Like some other ReactTV Projects have commands (react-tv-cli -webos). Im very familiar with building apps for tv, but I'm not sure how to get this to compile for WebOS. Any advice? Thanks so much..

TypeScript Errors

Describe the bug

  • Property 'includes' does not exist on type 'string[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2016' or later.ts(2550)
  • Cannot find name 'require'. Do you need to install type definitions for node? Try npm i --save-dev @types/node`

To Reproduce
Steps to reproduce the behavior:

  1. Clone repo
  2. Run pnpm i
  3. Run pnpm start
  4. See error

Expected behavior
No TypeScript or Webpack errors

Screenshots
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.