Skip to content

Instantly share code, notes, and snippets.

@ghostandthemachine
Last active July 20, 2022 02:15
Show Gist options
  • Save ghostandthemachine/347d1a1c679615a93930e4fdb48d907e to your computer and use it in GitHub Desktop.
Save ghostandthemachine/347d1a1c679615a93930e4fdb48d907e to your computer and use it in GitHub Desktop.
(defn- attach
"Takes a function to clone and a map of CSF related values
including:
- :args
- :arg-types
- :parameters
These are then properly named and assigned to the template prototype
properties."
[f m]
(reduce
(fn [f [k opts]]
(when (= k :parameters)
(set! f.parameters (->js opts)))
(when (= k :args)
(set! f.args (->js opts)))
(when (= k :arg-types)
(set! f.argTypes (->js opts))))
f
m))
(defn template
"Helper for CSF (https://storybook.js.org/docs/react/api/csf) defined
storybook stories defintions.
Takes a template to clone and optionally a map of CSF related values
including:
- :args
- :arg-types
- :parameters
These are then properly named and assigned to the template prototype."
([f]
(template f {}))
([f {:keys [return] :as opts}]
(let [opts (dissoc opts return)
template-opts (if return
{:return return}
{})
-template (.bind f (->js template-opts))
handler (fn [props]
(-template (->clj props)))]
(when-not (empty? opts)
(attach handler opts))
handler)))
(defn coerce-args
"Applies the coercion functions from b to the same keys which are present in a.
(coerce-args {:foo \"bar\"} {:foo keyword}
=> {:foo :bar}"
([a]
(coerce-args a {}))
([a b]
(reduce
(fn [a [k f]]
(update a k f))
(->clj a)
b)))
;;;; Using helpers
(ns client.components.stories.header
(:require
[cljs-bean.core :refer [->js]]
[client.components.header :refer [header]]
[client.storybook :as sb]))
(def ^:export default
(->js
{:title "UI/components/header"
:component header}))
;; These define the control types
(def ARG-TYPES
{:arg-types {:label {:description "Mauris sollicitudin urna et urna egestas elementum. Donec eget libero mauris. Donec gravida leo a lobortis ultrices."}
:variant
{:description "Donec ultricies, felis vitae facilisis eleifend, orci eros faucibus tortor, ac commodo mi enim ac nulla."
:control {:type "radio"}
:options ["warn" "info" "success" "error"]}}})
;; After we ->js the args for the template, we need to do the inverse when
;; storybook returns the args. Since these go through the addon qnd storybook
;; system they need to be js<->clj compatible.
;;
;; sb/coerce-args is crude for now now and just takes a map of coercion fns
;; to apply back to the args. Since keywords are ->js supported, they are an
;; example here to show how to convert back in the template
(defn header-template
[args]
(header
(sb/coerce-args
args
{:variant keyword})))
;; Export a sub story using the sb/template helper
(def ^:export Success
(sb/template
header-template
(merge
{:args {:label "Success"
:variant :success}}
ARG-TYPES)))
(def ^:export Info
(sb/template
header-template
(merge
{:args {:label "Info"
:variant :info}}
ARG-TYPES)))
(def ^:export Warn
(sb/template
header-template
(merge
{:args {:label "Warn"
:variant :warn}}
ARG-TYPES)))
(def ^:export Error
(sb/template
header-template
(merge
{:args {:label "Error"
:variant :error}}
ARG-TYPES)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment