Skip to main content

SXML (e.g. for React)

SXML is a way to define XML or HTML inside Scheme code. In LIPS Scheme, it works like for JSX for libraries like React or Preact.

By default, with JSX you define code like this:

function MessageButton({ message }) {
    function clickHandler() {
       alert(message);
    }
    return (
        <button className="btn btn-primary" onClick={clickHandler}>
          Click me!
        </button>
    );
}

The code defines a simple component that use a button and onClick handler.

You can write the same code in LIPS as:

(define (MessageButton props)
  (let ((click-handler (lambda ()
                         (alert props.message))))
    (sxml (button (@ (className "btn btn-primary")
                     (onClick click-handler))
                  "Click me!"))))

To create an instance of this component, you use:

(MessageButton (@ (message "LIPS Scheme")))

The main element is sxml macro that do the same transoformation as JSX compiler like Babel do.

Inserting the Scheme code into SXML

By default, symbols in SXML are treated as tags. If you want to put code like with { } in JSX, you need to use ~ symbol in front of S-Expression:

(let ((x 10))
  (sxml (ul (li ~x)
            (li ~(+ x 1))
            (li ~(+ x 2)))))

You can also array from escaped expression:

(sxml (ul ~(list->array
            (map (lambda (x)
                   (sxml (li ~x)))
                 (range 10)))))

Remember to use list->array (or list->vector) if you process lists.

Using SXML with React and Preact

To use SXML with React you need to specify the main function that is used to create tags in JSX. In Preact is preact.h and in React it's React.createElement. Here is a required setup for them:

(define createElement React.createElement)
(pragma->sxml createElement)
(define <> React.Fragment)

With Preact it will just this:

(define h preact.h)

Because default pragma->sxml is h.

(pragma->sxml h)

Similarly, if you want to use SXML and sxml macro in LIPS with other libraries that accept JSX, all you have to do is run pragma->sxml. This is macro that define sxml macro with proper element creation function.

Here are few example applications: