Skip to contents

Following the tailwind example from reactflow here. This is how we can have fully customized HTML nodes.

The basics of HTML nodes can be found in the Examples vignette.

In short, we have to set the type of each node to "html" and then we apply custom CSS to style each element.

Global CSS styles

We will apply a mix of global CSS and direct styles (to stay in the spirit of Tailwind… :)).

Our global CSS will apply a general styling to each HTML node’s border, size, radius, etc. This is mostly copied from the default style for react-flow__node-default. Then, we also style our handle a little-bit to make it a bit more distinct.

.react-flow__node.react-flow__node-html {
  padding: 10px;
  border-radius: 15px;
  border: 4px solid #00808073;
  width: 150px;
  font-size: 12px;
  color: var(--xy-node-color, var(--xy-node-color-default));
  text-align: center;
  background-color: var(--xy-node-background-color, var(--xy-node-background-color-default));
}

.react-flow__handle{
  width: 3em;
  height: 5px;
  background-color: teal;
  border: none;
  border-radius: 0;
}

Node and Edges Definition

Each node will have an icon, a name and title for three fictional employees.

nodes <- list(
  list(id = "jd",
       data = list(icon = "bank2", name = "Jane Doe", title = "CEO"),
       position = list(x = 100, y = 0)),
  list(id = "tw",
       data = list(icon = "brush-fill", name = "Tyler Weary", title = "Designer"),
       position = list(x = 0, y = 100)),
  list(id = "kp", data = list(icon = "code-slash", name = "Kristi Price", title = "Developer"),
       position = list(x = 200, y = 100))
)

edges <- list(
  list(source = "jd", target = "tw", id = "js-tw"),
  list(source = "jd", target = "kp", id = "js-kp")
)

Note that we have not yet specified that the nodes are of type = "html", neither have we created HTML code somwhere.

To abstract this from the node definitions, we will do this next in a separate function.

# take a node element el and style it, using data$text, data$subtext, as well as data$icon
style_node <- function(el) {
  # 1. set the node type to html
  el$type <- "html"
  
  # 2. create the HTML code for each element but use as character
  el$data$html <- as.character(
    htmltools::div(
      style = paste(
        "display: flex; flex-direction: row; align-items: center;",
        "justify-content: space-around;"
      ),
      
      htmltools::div(
        style = paste(
          "background-color: #d1d1d187; border-radius: 10000px;",
          "height: 3em; width: 3em; display: flex; align-items: center;",
          "justify-content: center;"
        ),
        bsicons::bs_icon(el$data$icon, fill = "#00808080", 20)
      ),
      
      htmltools::div(
        htmltools::span(
          el$data$name,
          style = "font-weight: 800; color: teal;"
        ),
        htmltools::div(
          style = "font-size: 0.8em; font-weight: 600; color: #999999;",
          el$data$title
        )
      )
    )
  )
  el
}

Next, we will apply this styling to all nodes.

nodes <- lapply(nodes, style_node)

Draw the Graph

Last but not least, we have to draw the full flow:

library(reactflow)
reactflow(
  nodes = nodes,
  edges = edges,
  mini_map(),
  background(),
  controls()
)