In the landscape of frontend development, managing focus within applications is a common yet nuanced challenge. In this article, we dive into PureScript's Halogen, a powerful framework in the functional programmer's arsenal, and explore how to manage focus effectively within our applications.
Refs in Halogen are labels attached to DOM elements that can be used to perform effects on those elements. While React utilizes refs primarily as mutable containers to store references to DOM nodes, Halogen treats refs more as keys to access DOM elements within the Halogen framework's controlled environment.
Consider a scenario where you have an input element in your Halogen component, and you wish to focus this input when a user clicks a button. This could be for example a search field which enlarges to an input field when the search icon is clicked. Here’s how you can achieve this:
In your component's render function, you attach a "ref" (a reference) to your desired input element using the HP.ref
function.
HP.InputText, HP.ref (H.RefLabel "input") ] HH.input [ HP.type_
Pay attention that we use not only a string but the H.RefLabel. The final name does not need to be unique across the whole DOM.
The focus management is performed in the eval
function of your component. When an action (triggered by a button
click, for example) is received, you can retrieve the element using getHTMLElementRef
and apply focus to it.
ToggleFocues -> do
<- getHTMLElementRef $ H.RefLabel "input"
mElement -> do
for_ mElement \element $ focus element H.liftEffect
The focus function is the foreign function from the Web.HTML.HTMLElement module. This way we stay very close to the default JavaScript implementation.
In conclusion, focusing elements in Halogen might require a different mindset, especially for those coming from an imperative or loosely-typed background. However, the robustness and clarity provided by PureScript and Halogen make these efforts worthwhile. As functional programming continues to make inroads into frontend development, understanding and mastering these concepts becomes increasingly valuable.
Thank you for reading this far! Let’s connect. You can @ me on X (@debilofant) with comments, or feel free to follow. Please like/share this article so that it reaches others as well.