|
128 | 128 | [:li [:strong [:code ":part"]] |
129 | 129 | " is a keyword, with the namespace of the component and the name of the part. " |
130 | 130 | " For instance, " [:code ":re-com.dropdown/anchor"] "."] |
131 | | - [:li [:strong [:code ":re-com"]] " is a map describing the re-com component overall, " |
| 131 | + [:li [:strong [:code ":re-com"]] " is a map describing the component overall, " |
132 | 132 | "such as its " [:code ":state"] ", and " [:code "theme"] " information (see the " |
133 | 133 | [:code "theme"] " section below)."]]] |
134 | 134 | [rc/p {:style {:background-color "#eee" :padding 7}} |
|
169 | 169 | (rdu/with-src |
170 | 170 | [rc/dropdown |
171 | 171 | {:parts {:body "Sesame" |
172 | | - :anchor {:style {:background-color "pink"} |
| 172 | + :anchor {:style {:color "pink"} |
173 | 173 | :class "italic"}}}])]]]]}]) |
174 | 174 |
|
175 | 175 | (defn theme [] |
|
207 | 207 | :children |
208 | 208 | [[rc/p "Themes synergize well with both map and function parts. " |
209 | 209 | "Hiccup and string parts aren't affected by themes, since re-com " |
210 | | - "doesn't control their props. In light of this, let's define some functional " |
211 | | - [:i "part"] "-specs for this example."] |
212 | | - [rc/v-box |
213 | | - :gap "12px" |
| 210 | + "doesn't control their props. In light of this, let's define a functional " |
| 211 | + [:i "part"] "-spec for this example."] |
| 212 | + [rc/h-box |
214 | 213 | :children |
215 | | - [[rc/h-box |
216 | | - :children |
217 | | - (rdu/with-src |
218 | | - (defn my-anchor [{:keys [style class attr]}] |
219 | | - [rc/box (merge {:style style :class class :child "Open"} attr)]))] |
220 | | - [rc/h-box |
221 | | - :children |
222 | | - (rdu/with-src |
223 | | - (defn my-body [{:keys [style class attr]}] |
224 | | - [rc/box (merge {:style style :class class :child "Sesame"} attr)]))]]]]] |
| 214 | + (rdu/with-src |
| 215 | + (defn my-body [{:keys [style class attr]}] |
| 216 | + [rc/box (merge {:style style :class class :child "Sesame"} attr)]))]]] |
225 | 217 | [rc/gap :size "19px"] |
226 | 218 | [rc/h-box |
227 | 219 | :gap "31px" |
|
245 | 237 | :children |
246 | 238 | [[rc/p "Finally we apply the theme, " |
247 | 239 | "simply by passing our " [:i "theme"] "-function to the component. " |
248 | | - "Note that both the anchor and body are orange, since the " [:code ":theme"] " " |
249 | | - "function applies to every part (including parts you don't specify)."]]] |
| 240 | + "Note that the " [:code ":theme"] " function applies to every part - " |
| 241 | + "including parts you don't specify. " |
| 242 | + "In this case, the anchor turns orange, even though we haven't added any " |
| 243 | + [:code ":anchor"] "in the parts map. Although the anchor is in its default " |
| 244 | + " configuration, re-com still applies your " [:i "theme"] "-function to the props " |
| 245 | + "it passes to the anchor's component function."]]] |
250 | 246 | [rc/h-box |
251 | 247 | :style {:height :fit-content :gap "12px"} |
252 | 248 | :align :start |
253 | 249 | :children |
254 | | - (rdu/with-src |
255 | | - [rc/dropdown |
256 | | - {:parts {:anchor my-anchor :body my-body} |
257 | | - :theme orange-theme}])]]] |
| 250 | + (rdu/with-src [rc/dropdown {:parts {:body my-body} :theme orange-theme}])]]] |
| 251 | + [rc/gap :size "19px"] |
| 252 | + [rc/h-box |
| 253 | + :gap "31px" |
| 254 | + :children |
| 255 | + [[rc/v-box |
| 256 | + :children |
| 257 | + [[rc/p "A theme function will also compose with a map " [:i "part"] "-spec. " |
| 258 | + "Here, for the anchor part, re-com modifies its props twice - first with the theme, " |
| 259 | + "and then with your " [:code ":anchor"] " spec."]]] |
| 260 | + [rc/h-box |
| 261 | + :style {:height :fit-content :gap "12px"} |
| 262 | + :align :start |
| 263 | + :children |
| 264 | + (rdu/with-src [rc/dropdown {:parts {:body my-body |
| 265 | + :anchor {:style {:color "white"}}} |
| 266 | + :theme orange-theme}])]]] |
258 | 267 | [rc/gap :size "19px"] |
259 | 268 | [rc/h-box |
260 | 269 | :gap "31px" |
|
265 | 274 | "Re-com passes a " [:code ":part"] " argument to each part, identifying it " |
266 | 275 | "with a fully-qualified keyword. " |
267 | 276 | "Here is a " [:i "theme"] "-function that adds background-color only to the " |
268 | | - [:code ":body"] ", and font-style only to the " [:code ":anchor"] "."]]] |
| 277 | + [:code ":body"] ", and font-style only to the " [:code ":anchor"] ". "] |
| 278 | + [rc/p |
| 279 | + "Hint: you could express a " [:i "theme"] "-function using a multimethod: " |
| 280 | + [:code "(defmulti my-theme :part)"]]]] |
269 | 281 | [rc/v-box |
270 | 282 | :gap "19px" |
271 | 283 | :children |
|
287 | 299 | :children |
288 | 300 | (rdu/with-src |
289 | 301 | [rc/dropdown |
290 | | - {:parts {:anchor my-anchor :body my-body} |
| 302 | + {:parts {:body my-body} |
291 | 303 | :theme precise-theme}])]]]]] |
292 | 304 | [rc/gap :size "19px"] |
293 | 305 | [rc/title :level :level3 :label "Themes can be global"] |
|
319 | 331 | :children |
320 | 332 | [[rdu/zprint-code |
321 | 333 | '[rc/dropdown |
322 | | - {:parts {:anchor my-anchor :body my-body}}]] |
| 334 | + {:parts {:body my-body}}]] |
323 | 335 | [rc/dropdown |
324 | | - {:parts {:anchor my-anchor :body my-body} |
325 | | - :theme precise-theme}]] |
326 | | - ]]]]] |
| 336 | + {:parts {:body my-body} :theme precise-theme}]]]]]]] |
327 | 337 | [rc/gap :size "19px"] |
328 | 338 | [rc/title :level :level3 :label "Themes are layered"] |
329 | 339 | [rc/h-box |
|
333 | 343 | :children |
334 | 344 | [[rc/p "To fully determine the props for a " [:i "part"] ", " |
335 | 345 | "re-com composes a handful of " [:i "theme"] "-functions, " |
336 | | - "including those you pass in or register." |
| 346 | + "including those you pass in or register. " |
337 | 347 | "In order of application, these include:"] |
338 | 348 | [rc/p |
339 | 349 | [:ul |
|
366 | 376 | [rc/v-box |
367 | 377 | :gap "19px" |
368 | 378 | :children |
369 | | - []]]] |
| 379 | + [[rc/h-box |
| 380 | + :style {:height :fit-content :gap "12px"} |
| 381 | + :align :start |
| 382 | + :children |
| 383 | + (rdu/with-src |
| 384 | + (defn dark-mode [props] |
| 385 | + (update-in props [:re-com :variables] merge |
| 386 | + {:background "black" |
| 387 | + :foreground "white"})))] |
| 388 | + [rc/h-box |
| 389 | + :style {:height :fit-content :gap "12px"} |
| 390 | + :align :start |
| 391 | + :children |
| 392 | + (rdu/with-src |
| 393 | + [rc/dropdown {:parts {:body my-body} |
| 394 | + :pre-theme dark-mode}])] |
| 395 | + [rc/h-box |
| 396 | + :style {:height :fit-content :gap "12px"} |
| 397 | + :align :start |
| 398 | + :children |
| 399 | + (rdu/with-src |
| 400 | + [rc/dropdown {:parts {:body my-body} |
| 401 | + :theme (fn [props] |
| 402 | + (update-in props [:re-com :variables] merge |
| 403 | + {:background "black" |
| 404 | + :foreground "white"}))}])]]]]] |
370 | 405 | [rc/gap :size "19px"] |
371 | 406 | [rc/title :level :level3 :label "Themes are (not) reactive"] |
372 | 407 | [rc/h-box |
373 | 408 | :gap "31px" |
374 | 409 | :children |
375 | 410 | [[rc/v-box |
376 | 411 | :children |
377 | | - [[rc/p "A re-com component composes the theme " |
| 412 | + [[rc/p "A re-com component composes the " [:i "theme"] "-function " |
378 | 413 | [:strong "once"] ", when it mounts. That means it will not react to changes in the passed-in " |
379 | 414 | [:code ":theme"] " or " [:code ":pre-theme"] " arguments. This makes themes more performant. " |
380 | 415 | "If you do need to do reactive programming, consider doing it within the theme function."]]] |
381 | 416 | [rc/v-box |
382 | 417 | :children |
383 | | - [ |
384 | | - "For instance, instead of this:" |
385 | | - [:br] |
386 | | - [rdu/zprint-code |
387 | | - '[rc/dropdown |
388 | | - {:theme (if (deref night-mode?) dark-theme light-theme)}]] |
389 | | - [:br] |
390 | | - "try this:" |
391 | | - [:br] |
392 | | - [rdu/zprint-code |
393 | | - '[rc/dropdown |
394 | | - {:theme (fn [props] (if (deref night-mode?) |
395 | | - (dark-theme props) |
396 | | - (light-theme props)))}]]]]]] |
397 | | - #_[rc/title :level :level3 :label "Targeting the top-level hiccup"] |
398 | | - #_[rc/h-box |
399 | | - :gap "31px" |
400 | | - :children |
401 | | - [[rc/v-box |
402 | | - :children |
403 | | - [[rc/p "Hello."]]] |
404 | | - [rc/v-box |
405 | | - :gap "19px" |
406 | | - :children |
407 | | - [[rc/h-box |
408 | | - :style {:height :fit-content :gap "12px"} |
409 | | - :align :start |
410 | | - :children |
411 | | - [[rdu/zprint-code '(re-com.core/reg-theme my-theme)]]] |
412 | | - [rc/h-box |
413 | | - :style {:height :fit-content :gap "12px"} |
414 | | - :align :start |
415 | | - :children |
416 | | - [[rdu/zprint-code |
417 | | - '[rc/dropdown |
418 | | - {:parts {:anchor my-anchor :body my-body}}]] |
419 | | - [rc/dropdown |
420 | | - {:parts {:anchor my-anchor :body my-body} |
421 | | - :theme my-theme}]] |
422 | | - ]]]]]]}]) |
| 418 | + ["For instance, instead of this:" |
| 419 | + [:br] |
| 420 | + [rdu/zprint-code |
| 421 | + '[rc/dropdown |
| 422 | + {:theme (if (deref night-mode?) dark-theme light-theme)}]] |
| 423 | + [:br] |
| 424 | + "try this:" |
| 425 | + [:br] |
| 426 | + [rdu/zprint-code |
| 427 | + '[rc/dropdown |
| 428 | + {:theme (fn [props] (if (deref night-mode?) |
| 429 | + (dark-theme props) |
| 430 | + (light-theme props)))}]]]]]]]}]) |
423 | 431 |
|
424 | 432 | (defn panel* [] |
425 | 433 | [rc/v-box |
|
0 commit comments