Sodium is a wrapper around soda-ash which, in turn, is a ClojureScript wrapper around semantic-ui-react. Sodium adds two sets of features into the mix, both aimed at making it easier to include Semantic UI in re-frame projects:
The element sodium is highly reactive. It also starts with an "S", like Soda-ash and Semantic-UI. The chemical symbol for sodium is "NA", nicely similar to the "SA" abbreviation used for the Soda-ash namespace. And, hey, I like bad puns.
Sodium is still a early work in progress. I am using it to help me with other projects and have only addded functionality that I need and can test. Sodium will only grow as it helps me (or other contributers) accomplish what they need. If you need features now, PRs are welcome.
Sodium 0.9.0 introduces incompatible changes.
I have divided Sodium into two libraries. The Soda-ash/Semantic-UI code remains in Sodium. But all the more general utilities have been moved to a new library, Iron. As of today, this is working well enough for me to use. But there may be teething pains, so please let me know if you hit any snags.
I used re-com in some of my earlier re-frame projects. Re-com is a wonderful, reliable, easy to use, and opinionated library of UI components. In many ways, it was perfect. But, as the authors warn, it is designed for desktop applications. When I tried using it for mobile and portable pages, I kept running into little annoyances.
I recently discovered Semantic UI and its Soda-ash wrapper. I switched to it, and my pages became much more usable on mobile devices. But, I miss the slick features and re-frame integration of re-com. Sodium is an attempt to bridge this gap.
Sodium is a wrapper around Soda-ash, Semantic UI React, and Semantic UI. Setup requires a couple of steps:
[com.degel/sodium "0.12.0"]
(Or, copy the clojars label above, if I forgot to update this line!)[soda-ash "0.79.1"]
, but see the Soda-ash README for
any recent changes).<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css">
[sodium.core :as na]
- Most of Sodium's functionality[iron.utils :as utils]
- Useful utilities[iron.re-utils :refer [sub2 <sub >evt]]
- Useful utilities[iron.chars :as chars]
- Minor Unicocde support[soda-ash.core :as sa]
- Soda-ash functionsIf you want to contribute to this project, you will want to test your changes. You can extend the (very minimal) tests inside Sodium, but you will probably need to really test by using Sodium in a ClojureScript project. The easiest way to do this, while you are changing Sodium, is by using Leiningen's checkouts directory feature by sym-linking directly to your copy of Sodium.
Sodium is a library, with a grab-bag of functions to enhance the usability of Semantic UI from your re-frame projects. You can use it in several ways:
Sodium offers the following in sodium.core (often :refer
'd to as na
)
na/value->event-fn
, and na/value->atom-fn
- Useful in :on-*
handlers to pass a
value to a re-frame event or react atom. They return a function that can be used as a
handler, which knows how to extract the relevant value from a semantic-ui component
and pass it to a re-frame event or into an atom. (Note carefully: these do not need
to be wrapped #(...)
. They return a function. This is done to hide the slightly
surprising ways in which semantic-ui delivers values from dom events.I am not happy yet with these two names. Suggestions welcome.
(defn login-panel []
(let [email (reagent/atom "")
password (reagent/atom "")]
(fn []
[na/form {}
[na/form-input {:label "Email"
:type "email"
:on-change (na/>value->atom-fn email)}]
[na/form-input {:label "Password"
:type "password"
:on-change (na/>value->atom-fn password)}]
[na/form-button {:content "Login"
:on-click (na/>value->event-fn [:login @email @password])}]])))
These functions work equally with with Sodium components and bare Soda-ash ones. I recommend using Sodium components where available. But, see below, you will still often need to use Soda-ash components.
na/list-option
and na/dropdown-list
are useful for converting data to a shape that
is useful to pass to Semantic-UI Dropdown or Select component options.
(na/dropdown-list
[[:one "one"] [:two "two"] [:three "three"]]
first
second)
returns:
[{:key :one, :value :one, :text "one"}
{:key :two, :value :two, :text "two"}
{:key :three, :value :three, :text "three"}]
As of v0.9.0, these have moved to Iron. Sodium no longer
includes ci-*
, validate
, the "Camelize" functions, <sub
, >evt
, sub2
, unicode
character definitions, etc. They are all in Iron.
Sodium adds a thin, but very useful wrapp around Soda-ash, that type-checks the parameters passed to components. This is the most experimental part of Sodium and, sadly, still very incomplete.
So far, it includes the following components, each a wrapper around the corresponding Soda-ash / Semantic UI one:
na/advertisement
: sa/Advertisement
na/checkbox
: sa/Checkbox
na/container
: sa/Container
na/divider
: sa/Divider
na/dropdown
: sa/Dropdown
na/form
: sa/Form
na/form-input
: sa/FormInput
na/form-group
: sa/FormGroup
na/grid
: sa/Grid
na/grid-column
: sa/GridColumn
na/grid-row
: sa/GridRow
na/header
: sa/Header
na/icon
: sa/Icon
na/icon-group
: sa/IconGroup
na/image
: sa/Image
na/input
: sa/Input
na/label
: sa/Label
na/list-na
: sa/ListSA
na/list-item
: sa/ListItem
na/menu
: sa/Menu
na/menu-header
: sa/MenuHeader
na/menu-item
: sa/MenuItem
na/menu-menu
: sa/MenuMenu
na/modal
: sa/Modal
na/modal-header
: sa/ModalHeader
na/modal-content
: sa/ModalContent
na/modal-description
: sa/ModalDescription
na/modal-actions
: sa/ModalActions
na/rail
: sa/Rail
na/search
: sa/Search
na/segment
: sa/Segment
na/segment-group
: sa/SegmentGroup
na/text-area
: sa/TextArea
These wrappers improve the components in two ways (both admittedly arguable):
These improvements have some drawbacks, which make Sodium still less usable that Soda-ash in many circumstances. For that reason, I deliberately designed the Sodium functions to work with both Sodium and Soda-ash components.
Some current limitations:
[na/form [na/...]]
. Instead, you have to explicitly specify even an empty map:
[na/form {} [na/...]]
HTML controls offer a lot of freedom, and sometimes too many choices. Our front-end code can be much more readable if we define controls with relatively constrained and consistent behavior. But, there is an art to doing this right; constrain a control too much, and it is perfect for one project, but too limited to be useful in other projects. Semantic UI helps a lot, but still offers too many choices for a consistent, simple, web page.
I am trying, slowly, to create a set of components that meet my needs yet are general purpose. Most of them are still in my other projects, mostly not public, that use Sodium. But, I intend to migrate them into Sodium as I gain comfort.
A few of these are already in Sodium. Most are in the sodium.extensions package (usually
:refer
'd as nax
'). But, form-button
and button
are in sodium.core. This is for
historical reasons and will probably change soon:
na\form-button
and na\button
- HTML forms are, by default, very tied to the
old-school HTML notions of page submission. This does not play well with the
re-frame philosophy that a form handler should simply trigger a re-frame event.
When I naively use the Soda-ash sa/FormButton component at first, I was hit with
unexpected extra connections to my server, trying to submit the form. The fix for
this, once I realized the problem, was simple: the component needs to explicitly
speicify a type of "button." The na/form-button
component handles this
automatically.nax/app-header
- Large header.nax/panel-header
- Medium header.nax/panel-subheader
- Small header.nax/section-header
- Medium de-emphasized header.nax/subsection-header
- Small de-emphasized header.nax/labelled-field
- Form field with label and arbitrary content.nax/native-text-area
- Workaround for some issues with Semantic UI's text-area componentnax/draw-tags
- Component that draws a row of tagsnax/tag-adder
- Component that lets the user add a tagnax tag-selector
- Component that lets the user select a tagnax/google-ad
- Google advertisement componentsodium.core/defcomponent
and sodium.core/def-simple-component
Define a component;
typically a thin wrapper around the Soda-ash component, to give parameter checking,
etc. (see below). Soon, Sodium will contain definitions wrapping all the Soda-ash
(Semantic-UI) components, but we are not there yet.
lein doo phantom test auto
will run the few unit tests I've written so far. More are
needed. PRs especially welcome here.
I can usually be found on the Clojurians Slack #reagent or #re-frame slack channels. My handle is @deg. Email is also fine.
Copyright © 2017, David Goldfarb deg@degel.com
Licensed under the Eclipse Public License.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close