jamesplease / lrud Goto Github PK
View Code? Open in Web Editor NEWA React library for managing focus in TV apps.
License: MIT License
A React library for managing focus in TV apps.
License: MIT License
Returns the active node
When a trap receives focus, what is the best way to specify that a given node to receive that focus?
such as defaultFocusRow
. atm the node isn't updated when these update. tbqh they should prob all be dynamic
The biggest issue with this lib is handling animations. Specifically, an animation where there something on the previous page is in focus and something on the new page is entering in a focused state. isExiting
was added to solve this use case, but there are clearly some bugs with that approach.
A few thoughts:
isExiting
can be fixed. It needs to support animating in as well as out (right now it can error on some in transitions)So, imagine:
Architecturally it is simple. What would the API look like?
This idea of screens seems like a natural evolution of the already-implemented trap, btw. And it would actually tie in super nicely with #62
This will need a new Event type; ActiveEvent
interface ActiveEvent {
prevActiveId: Id | null;
nextActiveId: Id;
prevActiveNode: Id | null;
nextActiveNode: Node;
}
pointer-events: none
for traps; complexity involved)usePreviousFocusedChildIndex
Useful for when you care to know the last child index that was focused, even if the node becomes unfocused. For example, when navigating off of the nav. The focus indicator still displays on the last-focused nav item, even though no nav items are focused nor active at that time.
<FocusNode
onArrow={e => {
e.preventDefault();
setFocus('nav');
}}/>
Does this work?
I think the current names can be confusing. Maybe wrapGridHorizontal
and wrapGridVertical
instead.
Hello, we are faced with the problem that navigation does not work on tizen 3. Could you, please, give some advice on how to fix this?
Rename this to further indicate that it is a dangerous API.
Source could be:
Really it's a lot of work to document all of the sources. But this is useful for responding to events based on the direction of the arrow that led to the focus.
Integration-style tests rather than the traditional per-file unit tests.
preferredChildren
?onMountAssignFocusTo
onMountAssignFocusTo
When a trap is focused, so is its immediate parent. In many situations this is unlikely to be the desired behavior.
One way around this would be to render traps in their own separate subtrees...outside of the root, even.
In the store, it could be managed like this:
trees: {
root: { /* default tree */ },
focusTrapOne: { ... },
focusTrapTwo: { ... }
}
It's easy enough to work around this right now, but it would still be pretty cool if traps behaved like this.
The following is a peculiar arrangement of nodes:
<FocusNode focusId="A">
<FocusNode disabled focusId="B" />
</FocusNode>
Consider a tree that is just the root. After some time, the above tree mounts. What would you expect to happen? Right now, the focus moves to A.
However, consider if this a sibling of another node. Trying to arrow into this won't work, as the parent has no eligible children to be focused.
These two situations treat this tree differently. In Situation 1, disabled nodes are effectively nonexistent, so the parent is considered a "leaf." In Situation 2, disabled nodes are treated as children, and can therefore make their parents ineligible for focus.
I currently think Situation 2 is the appropriate behavior, so I should probably update Situation 1 to match it. This will ensure that non-leaf nodes are never focused, no matter the situation.
Note: this must also apply to traps and isExiting
nodes!
Looking through the code I think I can guess the answer to this, but will ask anyway.
Is this library HTML (react-dom) only, or can you see this being usable on other renderers, such as React Native?
Rename this hook
I should prob. just make it so traps aren't accessible by arrows, and get rid of the canReceiveFocusFromArrows
prop altogether.
It's buggy atm.
If your cursor is hovering a node, then you can't key off of it.
Here's the possible situation. Needs to be investigated further:
useState
onGridMove
defaultRowIndex
and defaultColumnIndex
This is a bug because the updated default indices gets wiped. The reason is as follows:
onGridMove
is calledonGridMove
sets the external grid state, which then re-renders the <FocusNode/>
, causing the node's update function to be executedonGridMove
doesn't know about State2 as it hasn't been committed yetI need to verify this...although this explanation seems plausible for what I was seeing, I'm surprised because step 4/5 occur in a useEffect
and should therefore be async from the arrow key handler.
What values can be null?
This is a problem in computeFocusHierarchy
Maybe?
I'm going to close and tag this as revisit for now, but leave a comment if you would find this useful.
This will allow me to see where the file size is coming from. And for the record the lib seems to be a hefty 32kb atm. I feel pretty confident I can shrink that down a bit!
A parent becoming disabled should disable the children.
Question: should exiting a parent also exit the children? Perhaps?
Yes
To implement this:
this.disabled || this.ancestorDisabled
I added this to focus
but intentionally left it out of this library. I wonder why?
Hi
We are planning to create a TV application. For navigation purpose can we use this library for production purpose ?
Is there any performance bench mark for this library ?
Users should be able to set a default column/row for grid nodes
Navigating in a trap is not currently functioning
onFocus
onBlur
onSelect
This should apply even when the grid receives focus
The node callbacks are not currently dynamic. This is OK if you always use refs, but if you rely on the recreate-every-render behavior, then you might encounter stale values (todo: verify this claim).
One way to handle this is to treat callbacks the same as #38 , but this could cause infinite renders.
Node callback changes in React component =>
node is updated in the store =>
store updates subscribers =>
subscribers re-render the React components =>
repeat
A better solution is to ref the callbacks internally within the FocusNode component. Then a static wrapper fn would be called on the node itself, which then calls the ref. The downside is that this is an unfortunate amount of boilerplate code.
For consistent naming throughout the documentation and within app code.
I need to verify that the pointer events don't bypass the disabled node functionality
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.