@vanelsas/baredom 1.0.0-rc.3 → 1.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +96 -87
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -47,27 +47,82 @@ BareDOM has been created using Claude Code. The CLAUDE.md file is added to the r
|
|
|
47
47
|
|
|
48
48
|
## Installation
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
BareDOM can be consumed three ways: as a **ClojureScript source dependency** (Clojars), as **standalone ES module files** (no build tool required), or as an **npm package**.
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
52
|
+
### Option A — ClojureScript via Clojars
|
|
53
|
+
|
|
54
|
+
Add BareDOM to your `deps.edn`:
|
|
55
|
+
|
|
56
|
+
```clojure
|
|
57
|
+
{:deps {com.github.avanelsas/baredom {:mvn/version "1.0.0-rc.4"}}}
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
Or in your `shadow-cljs.edn` dependencies:
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
```clojure
|
|
63
|
+
:dependencies [[com.github.avanelsas/baredom "1.0.0-rc.4"]]
|
|
64
|
+
```
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
Then require component namespaces directly and call their `init!` function once at startup:
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
```clojure
|
|
69
|
+
(ns my-app.core
|
|
70
|
+
(:require
|
|
71
|
+
[baredom.exports.x-button :as x-button]
|
|
72
|
+
[baredom.exports.x-alert :as x-alert]
|
|
73
|
+
[baredom.exports.x-toaster :as x-toaster]
|
|
74
|
+
[baredom.exports.x-toast :as x-toast]))
|
|
67
75
|
|
|
68
|
-
|
|
76
|
+
(defn- register-components! []
|
|
77
|
+
(x-button/init)
|
|
78
|
+
(x-alert/init)
|
|
79
|
+
(x-toaster/init)
|
|
80
|
+
(x-toast/init))
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Call `register-components!` once in your `init!` entry point. Registration is idempotent — calling `init` on an already-registered element is a no-op.
|
|
84
|
+
|
|
85
|
+
### Option B — Vanilla HTML/JS via ES modules
|
|
86
|
+
|
|
87
|
+
No build tool, no npm, no ClojureScript required. Copy the `dist/` folder (from a release or after running `npm run build`) to your web server and load components directly with `<script type="module">`:
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<!DOCTYPE html>
|
|
91
|
+
<html lang="en">
|
|
92
|
+
<head>
|
|
93
|
+
<meta charset="UTF-8">
|
|
94
|
+
<title>BareDOM Example</title>
|
|
95
|
+
</head>
|
|
96
|
+
<body>
|
|
97
|
+
<x-button variant="primary">Click me</x-button>
|
|
98
|
+
<x-alert type="success" text="It works!"></x-alert>
|
|
99
|
+
|
|
100
|
+
<script type="module">
|
|
101
|
+
import { init as initButton } from './dist/x-button.js';
|
|
102
|
+
import { init as initAlert } from './dist/x-alert.js';
|
|
69
103
|
|
|
70
|
-
|
|
104
|
+
initButton();
|
|
105
|
+
initAlert();
|
|
106
|
+
</script>
|
|
107
|
+
</body>
|
|
108
|
+
</html>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Each component is a separate ES module. Import only the components you use — the browser loads only those files plus the shared `base.js` runtime.
|
|
112
|
+
|
|
113
|
+
### Option C — npm
|
|
114
|
+
|
|
115
|
+
Add the npm package to your `package.json`:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"dependencies": {
|
|
120
|
+
"@vanelsas/baredom": "^1.0.0-rc.4"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Then `npm install`. shadow-cljs resolves npm packages automatically via `node_modules`. From ClojureScript:
|
|
71
126
|
|
|
72
127
|
```clojure
|
|
73
128
|
(ns my-app.core
|
|
@@ -86,77 +141,26 @@ Require each component module you need and call `.init` on it once, before any r
|
|
|
86
141
|
|
|
87
142
|
Call `register-components!` once in your `init!` entry point. Registration is idempotent — calling `.init` on an already-registered element is a no-op.
|
|
88
143
|
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Usage
|
|
147
|
+
|
|
148
|
+
### 1. Register components
|
|
149
|
+
|
|
150
|
+
Whichever installation method you chose above, the pattern is the same: require/import each component you need and call its `init` function once before any rendering. Only the components you register are active on the page.
|
|
151
|
+
|
|
89
152
|
### 2. Add a renderer
|
|
90
153
|
|
|
91
|
-
BareDOM components are plain DOM elements. You need no framework to use them — only a small
|
|
154
|
+
BareDOM components are plain DOM elements. You need no framework to use them — only a small renderer that turns ClojureScript hiccup vectors into DOM nodes and keeps them in sync with your state.
|
|
92
155
|
|
|
93
|
-
|
|
94
|
-
(ns my-app.renderer
|
|
95
|
-
(:require [clojure.string :as str]))
|
|
96
|
-
|
|
97
|
-
;;; ── Prop helpers ──────────────────────────────────────────────────────────
|
|
98
|
-
|
|
99
|
-
(defn- on-key? [k]
|
|
100
|
-
(str/starts-with? (name k) "on-"))
|
|
101
|
-
|
|
102
|
-
(defn- event-name [k]
|
|
103
|
-
;; :on-click → "click" :on-value-change → "value-change"
|
|
104
|
-
(subs (name k) 3))
|
|
105
|
-
|
|
106
|
-
(defn- set-prop! [el k v]
|
|
107
|
-
(let [attr (name k)]
|
|
108
|
-
(cond
|
|
109
|
-
(on-key? k) (.addEventListener el (event-name k) v)
|
|
110
|
-
(nil? v) (.removeAttribute el attr)
|
|
111
|
-
(true? v) (.setAttribute el attr "")
|
|
112
|
-
(false? v) (.removeAttribute el attr)
|
|
113
|
-
:else (.setAttribute el attr (str v)))))
|
|
114
|
-
|
|
115
|
-
;;; ── DOM creation ──────────────────────────────────────────────────────────
|
|
116
|
-
|
|
117
|
-
(declare create-nodes)
|
|
118
|
-
|
|
119
|
-
(defn- create-element [[tag & args]]
|
|
120
|
-
(let [has-props? (and (seq args) (map? (first args)))
|
|
121
|
-
props (when has-props? (first args))
|
|
122
|
-
children (if has-props? (rest args) args)
|
|
123
|
-
el (.createElement js/document (name tag))]
|
|
124
|
-
(doseq [[k v] props]
|
|
125
|
-
(set-prop! el k v))
|
|
126
|
-
(doseq [node (mapcat create-nodes children)]
|
|
127
|
-
(.appendChild el node))
|
|
128
|
-
el))
|
|
129
|
-
|
|
130
|
-
(defn create-nodes [x]
|
|
131
|
-
(cond
|
|
132
|
-
(nil? x) []
|
|
133
|
-
(false? x) []
|
|
134
|
-
(string? x) [(.createTextNode js/document x)]
|
|
135
|
-
(number? x) [(.createTextNode js/document (str x))]
|
|
136
|
-
(vector? x) [(create-element x)]
|
|
137
|
-
(seq? x) (mapcat create-nodes x)
|
|
138
|
-
:else []))
|
|
139
|
-
|
|
140
|
-
;;; ── Mount ─────────────────────────────────────────────────────────────────
|
|
141
|
-
|
|
142
|
-
(defn render! [container view-fn]
|
|
143
|
-
(set! (.-innerHTML container) "")
|
|
144
|
-
(doseq [node (create-nodes (view-fn))]
|
|
145
|
-
(.appendChild container node)))
|
|
146
|
-
|
|
147
|
-
(defn mount! [container view-fn state-atom]
|
|
148
|
-
(render! container view-fn)
|
|
149
|
-
(add-watch state-atom ::render
|
|
150
|
-
(fn [_ _ _ _]
|
|
151
|
-
(render! container view-fn))))
|
|
152
|
-
```
|
|
156
|
+
The `bare-demo/` project includes a complete renderer (~120 lines) with DOM reconciliation that you can copy into any ClojureScript project. See [`bare-demo/src/bare_demo/renderer.cljs`](./bare-demo/src/bare_demo/renderer.cljs). No Node.js required — just Java and the Clojure CLI.
|
|
153
157
|
|
|
154
|
-
What
|
|
158
|
+
What the renderer provides:
|
|
155
159
|
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
+
- **Hiccup syntax** — describe UI as nested vectors: `[:tag {:attr val} children]`
|
|
161
|
+
- **Prop handling** — `:on-*` keys become event listeners; `true`/`false` toggle boolean attributes; everything else calls `setAttribute`
|
|
162
|
+
- **DOM reconciliation** — on re-render, the existing DOM is patched in place. Elements are never destroyed and recreated, so Web Components keep their lifecycle, shadow DOM, focus state, and animations intact.
|
|
163
|
+
- **`mount!`** — renders the view and attaches `add-watch` to a state atom so every `swap!` triggers a reconciliation pass
|
|
160
164
|
|
|
161
165
|
### 3. Write views with hiccup syntax
|
|
162
166
|
|
|
@@ -245,7 +249,7 @@ Wire everything together in your `init!`:
|
|
|
245
249
|
(renderer/mount! (.getElementById js/document "app") view app-state))
|
|
246
250
|
```
|
|
247
251
|
|
|
248
|
-
`mount!` calls `view` immediately and re-calls it on every `swap!` or `reset!` to `app-state`.
|
|
252
|
+
`mount!` calls `view` immediately and re-calls it on every `swap!` or `reset!` to `app-state`. On each re-render the reconciler diffs the new hiccup tree against the live DOM and applies only the changes needed — attribute updates, text changes, children added or removed. Existing elements stay in place.
|
|
249
253
|
|
|
250
254
|
### Theming
|
|
251
255
|
|
|
@@ -397,26 +401,31 @@ Then open `http://localhost:8000`. The dev server serves `public/index.html` and
|
|
|
397
401
|
|
|
398
402
|
---
|
|
399
403
|
|
|
400
|
-
## bare-demo —
|
|
404
|
+
## bare-demo — starter template for ClojureScript web apps
|
|
401
405
|
|
|
402
|
-
The `bare-demo/` folder
|
|
406
|
+
The `bare-demo/` folder is a ready-to-use ClojureScript application that consumes BareDOM components with **zero framework dependency and no Node.js**. It is designed as a starting point for developers building new web apps on top of BareDOM.
|
|
403
407
|
|
|
404
|
-
The
|
|
408
|
+
The architecture is built on three ideas:
|
|
405
409
|
|
|
406
|
-
- **
|
|
407
|
-
- **A single state atom.** All UI state
|
|
408
|
-
- **
|
|
410
|
+
- **Declarative hiccup views.** UI is described as nested ClojureScript vectors — the same syntax used by Reagent and Hiccup. Views are plain functions, easy to compose and reason about.
|
|
411
|
+
- **A single state atom with reactive rendering.** All UI state lives in one `defonce` atom. `mount!` attaches `add-watch` so every `swap!` triggers a re-render automatically.
|
|
412
|
+
- **DOM reconciliation, not rebuild.** On state changes the renderer patches the existing DOM in place — updating attributes, text, and children without destroying elements. Web Components keep their lifecycle, shadow DOM, focus state, and animations intact.
|
|
413
|
+
|
|
414
|
+
This approach scales naturally: add more state, more views, more components — no manual wiring, no framework overhead, no impedance mismatch with the Web Component model.
|
|
409
415
|
|
|
410
416
|
**Run it:**
|
|
411
417
|
|
|
412
418
|
```bash
|
|
413
|
-
|
|
419
|
+
cd bare-demo
|
|
420
|
+
clj -M:dev
|
|
414
421
|
```
|
|
415
422
|
|
|
416
423
|
Then open `http://localhost:8001`.
|
|
417
424
|
|
|
418
425
|
See [`bare-demo/README.md`](./bare-demo/README.md) for a full walkthrough of the renderer, component registration, view syntax, state management, and theming.
|
|
419
426
|
|
|
427
|
+
> **Prefer NPM?** The `bare-node-demo/` folder contains the same demo consuming BareDOM via npm. Run it with `cd bare-node-demo && npm install && npm start` (opens on `http://localhost:8003`).
|
|
428
|
+
|
|
420
429
|
---
|
|
421
430
|
|
|
422
431
|
## Building from Source
|