rum

Simple, decomplected, isomorphic HTML UI library for Clojure and ClojureScript | 0.12.8 https://github.com/tonsky/rum/blob/gh-pages/CHANGELOG.md#0128
sergey.shvets 2020-07-13T19:28:12.170700Z

Not in rum, but you should grasp the idea:

(defn Header-Sider-Footer [{:keys [header footer sidebar]
                            :or   {sidebar nil}
                            :as props}
                           content]
  [:> Layout {:class-name (clj->js (concat ["pointr-layout"] (:body-class props [])))}
   [:> Header {:class-name "pointr-header"} header]
   [:> Layout {:class-name (if (some? sidebar) "pointr-body-w-sidebar" "pointr-body")}
    (when sidebar
      [:> Sider {:class-name "pointr-sidebar"
                 :theme "light"}
       sidebar])
    [:> Content {:class-name "pointr-content"} content]]
   [:> Footer {:class-name "pointr-footer"} footer]])

(defn DefaultLayout
  "Default layout for HAF"
  [props & children]
  [Header-Sider-Footer (merge {:header [TopBar] 
                               :footer [PointrFooter]}
                              props)
   (list children)])
You create a main level components (I use Ant.design in this particular project and uix as a react wrapper). Things that render in those panels are passed as props in a specific component. Here is how I use it:
[DefaultLayout {:body-class ["homepage"]}
     (if-not (nil? user)
       (list
        [:h1 "Hello, Homepage!"]
        [ProjectList {:projects (:pointr.users/projects user [])
                      :navigate navigate}]
        [:> Button {:on-click on-create-project
                    :type     "primary"}
         "Create Project"])
       [:div "Loading..."])]
This just takes children and uses Default Layout from the above. DefaultLayout takes a more generic layout and passes default header/footer/etc.