How to Programmatically trigger focus() on Material UI Select field? - reactjs

My app forms utilize the enter button to tab to specified fields for speed on a ten-key keyboard. When enter is hit, we do a DOM lookup and trigger focus() on the next element. This works great on text fields but I cannot understand how to accomplish this on a Select box in Material UI Beta#1.0.0-beta.21. I can get each of the DOM elements that make up the Select structure, but triggering focus() at any level does nothing.
Note: I am able to grab the ref of the item via inputRef on the select to prevent us from traversing the DOM but it still yields no results.
Question on GitHub: https://github.com/callemall/material-ui/issues/9182#issuecomment-345148074
Code Sandbox example: https://codesandbox.io/s/m43qqyo2zy

The node passed to Select.props.inputRef() references a hidden input. You would need to focus() on the div that is rendered as its sibling. Also, you need to handle the Select element case first in handleKeyPressInternal() because getElementsByName() will return the input.
This doesn't feel right, though, because you are relying on Select to render the focusable div as its immediate sibling. Could be grounds to extend inputRef() on Select to return the node that can visually receive focus.
https://codesandbox.io/s/zooz41oo3

Related

How to create custom tooltip on node hover in React Force Graph

I'm working with React Force Graph (2D - https://github.com/vasturiano/react-force-graph) and trying to display custom tooltip on node hover.
This custom Tooltip (dummy component) would display data that's not returned by node - I'd like to add some details to the tooltip, and those are not stored in node data that's returned for example by onNodeHover).
I've seen that I could use nodeLabel which displays simple text label... but it accepts only strings and some simple string interpolations. Unfortunately I can't pass a component as params.
Does anyone know what would be a good approach to this? How this could be handled? Extra points for working examples :D
So here's the answer:
nodeLabel doesn't accept React Node but can easily accept string. So workaround for that problem is just passing the whole stringified html code to nodeLabel and RFG will handle that! This is the best solution I believe (althou native RFG tooltip doesn't support left/right - top/bottom switching in case tooltip would be cut by the edge of screen, but thats minor problem).
other solution that I wouldn't recommend would be to create useCursorPosition and whenever onNodeHover returns something else than null we can set state of displayNode to true (and display it conditionally based on this state) in positions returned by useCursorPosition. This solution is flaky thou, because sometimes onNodeHover doesn't return null I user scrolls fast outside the canvas boundaries (hence the tooltip stays displayed forever). In this solution it's also recommended to use requestAnimationFrame to limit the listener on cursor position.

Ag-Grid keep custom filter open during interaction with dropdown

I have a custom filter component I'm giving Ag grid for each column. The component contains a dropdown. When user selects an option from dropdown, the filter closes immediately on selection rather than staying open like it should.
How can I keep the filter component to stay open on selection of option from dropdown?
Reading the docs more, I found the answer here:
https://www.ag-grid.com/javascript-data-grid/component-filter/#custom-filters-containing-a-popup-element
Custom Filters Containing a Popup Element
Sometimes you will need to create custom components for your filters that also contain popup elements. This is the case for Date Filter as it pops up a Date Picker. If the library you use anchors the popup element outside of the parent filter, then when you click on it the grid will think you clicked outside of the filter and hence close the column menu.
There are two ways you can get fix this problem:
Add a mouse click listener to your floating element and set it to
preventDefault(). This way, the click event will not bubble up to the
grid. This is the best solution, but you can only do this if you are
writing the component yourself.
Add the ag-custom-component-popup CSS
class to your floating element. An example of this usage can be found
here: Custom Date Component

Material-ui - Treeview Expand all

Using material-ui/lab 4.0.0-alpha.27 - TreeView Component
I have a treeview with a couple of hundred nodes. I have added a textfield before the treview that the user can use to search/filter the tree. As they type I add/remove classes from the TreeItems to hide and show TreeItems. It works fine BUT we want all of the nodes to be expanded once they enter something into the search/filter textfield.
I have tried feeding the "defaultExpanded" prop a new list that has all of the nodes in it but it doesn't seem to cause the nodes to expand as I had expected. The defaultExpanded prop only seems to be respected when the tree initially draws.
I am currently working around this by looking for collapsed nodes and firing click events for them to force them to open but that is causing issues (the textfield looses focus and the keyboard hides and the treeview jumps around). I need something a bit smoother.
You need to use the expanded prop, instead of defaultExpanded.

Handling focus with react-select

I'm trying to figure out how to work around what appears to be greedy-focus issues with react-select.
I'm using custom components in my MenuList component that need the focus to work (rc-slider). Basically, I'd like the select to support an additional value for each option and I'm using a Slider to do that.
The issue with the sliders is that I can click on them to change the value, but can't drag the handles, as the Select seems to take back the focus (and even close the drop-down if menuIsOpen is not controlled).
The select does need to re-render when the values change, but I can't figure out why the focus has to change.
https://codesandbox.io/s/epic-moon-cv33b

AngularJS ng-class Expression Not Updating Properly

So I'm trying to build a custom autocomplete dropdown for a text input. To do it, I am listening for the keydown event and if it's an up or down arrow press, I'm setting a $scope.arrowSelectedItem variable to the proper one in the list. (As a side note, all the functionality works as far as selecting an item from the list that pops up. All I'm trying to do is highlight the current one that they've marked with the up/down arrows).
On the markup side, the items in the autocomplete list are output with ng-repeat, with ng-repeat="item in itemList". The ng-class expression I'm using is ng-class="{highlighted: item === arrowSelectedItem}". I know that the $scope.arrowSelectedItem is being updated on each arrow press by using console.log, but for some reason the class isn't being updated to the list item properly.
What I've found is that after the first time of hitting an arrow key, if I make the text input box lose focus, then the class is added. Then if I click back in the box, move the arrow to select a different item, click out of the input box, then click back in, the class is added to the new one. I know that sounds weird, but that's what I've found.
What I'm not sure about is why the ng-class expression isn't being evaluated on every arrow key press. Does anyone have any ideas why?
The answer here is that "raw" DOM events which fire outside of one of angular's built in directives (such as click events via ng-click etc) will not trigger a $digest cycle update. Until this happens the $scope properties will not be updated.
If you are in a position where you are listening for DOM events by using another framework, or simply using addEventListener(), you will need to let angular know about any changes by using $scope.$apply(), or by wrapping the code in a $timeout().
If you do this in your event handler, angular will trigger a new $digest cycle update for every keypress and your new scope values will propagate to the view.

Resources