@vanelsas/baredom 2.4.1 → 2.6.0

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.
Files changed (187) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +63 -270
  3. package/custom-elements.json +7373 -0
  4. package/dist/baredom.d.ts +97 -0
  5. package/dist/base.js +74 -74
  6. package/dist/integrity.json +93 -93
  7. package/dist/x-alert.d.ts +43 -0
  8. package/dist/x-alert.js +17 -17
  9. package/dist/x-avatar-group.d.ts +18 -0
  10. package/dist/x-avatar-group.js +10 -10
  11. package/dist/x-avatar.d.ts +21 -0
  12. package/dist/x-avatar.js +13 -13
  13. package/dist/x-badge.d.ts +19 -0
  14. package/dist/x-badge.js +11 -11
  15. package/dist/x-bento-grid.d.ts +12 -0
  16. package/dist/x-bento-grid.js +5 -5
  17. package/dist/x-bento-item.d.ts +12 -0
  18. package/dist/x-bento-item.js +4 -4
  19. package/dist/x-breadcrumbs.d.ts +20 -0
  20. package/dist/x-breadcrumbs.js +14 -14
  21. package/dist/x-button.d.ts +45 -0
  22. package/dist/x-button.js +15 -15
  23. package/dist/x-cancel-dialogue.d.ts +50 -0
  24. package/dist/x-cancel-dialogue.js +12 -12
  25. package/dist/x-card.d.ts +39 -0
  26. package/dist/x-card.js +7 -7
  27. package/dist/x-carousel.d.ts +48 -0
  28. package/dist/x-carousel.js +28 -28
  29. package/dist/x-chart.d.ts +23 -0
  30. package/dist/x-chart.js +46 -46
  31. package/dist/x-checkbox.d.ts +45 -0
  32. package/dist/x-checkbox.js +11 -11
  33. package/dist/x-chip.d.ts +41 -0
  34. package/dist/x-chip.js +8 -8
  35. package/dist/x-collapse.d.ts +42 -0
  36. package/dist/x-collapse.js +10 -10
  37. package/dist/x-color-picker.d.ts +47 -0
  38. package/dist/x-color-picker.js +41 -41
  39. package/dist/x-combobox.d.ts +47 -0
  40. package/dist/x-combobox.js +25 -25
  41. package/dist/x-command-palette.d.ts +46 -0
  42. package/dist/x-command-palette.js +24 -24
  43. package/dist/x-container.d.ts +14 -0
  44. package/dist/x-container.js +6 -6
  45. package/dist/x-context-menu.d.ts +17 -0
  46. package/dist/x-context-menu.js +18 -18
  47. package/dist/x-copy.d.ts +51 -0
  48. package/dist/x-copy.js +20 -20
  49. package/dist/x-currency-field.d.ts +52 -0
  50. package/dist/x-currency-field.js +23 -21
  51. package/dist/x-date-picker.d.ts +20 -0
  52. package/dist/x-date-picker.js +37 -37
  53. package/dist/x-divider.d.ts +20 -0
  54. package/dist/x-divider.js +8 -8
  55. package/dist/x-drawer.d.ts +44 -0
  56. package/dist/x-drawer.js +11 -11
  57. package/dist/x-dropdown.d.ts +42 -0
  58. package/dist/x-dropdown.js +9 -9
  59. package/dist/x-fieldset.d.ts +14 -0
  60. package/dist/x-fieldset.js +5 -5
  61. package/dist/x-file-download.d.ts +40 -0
  62. package/dist/x-file-download.js +7 -7
  63. package/dist/x-file-upload.d.ts +46 -0
  64. package/dist/x-file-upload.js +22 -22
  65. package/dist/x-form-field.d.ts +47 -0
  66. package/dist/x-form-field.js +15 -15
  67. package/dist/x-form.d.ts +41 -0
  68. package/dist/x-form.js +9 -9
  69. package/dist/x-gaussian-blur.d.ts +20 -0
  70. package/dist/x-gaussian-blur.js +16 -16
  71. package/dist/x-grid.d.ts +12 -0
  72. package/dist/x-grid.js +6 -6
  73. package/dist/x-icon.d.ts +15 -0
  74. package/dist/x-icon.js +7 -7
  75. package/dist/x-image.d.ts +48 -0
  76. package/dist/x-image.js +18 -18
  77. package/dist/x-kinetic-font.d.ts +48 -0
  78. package/dist/x-kinetic-font.js +28 -28
  79. package/dist/x-kinetic-typography.d.ts +27 -0
  80. package/dist/x-kinetic-typography.js +37 -37
  81. package/dist/x-liquid-dock.d.ts +47 -0
  82. package/dist/x-liquid-dock.js +35 -35
  83. package/dist/x-liquid-fill.d.ts +46 -0
  84. package/dist/x-liquid-fill.js +40 -40
  85. package/dist/x-liquid-glass.d.ts +25 -0
  86. package/dist/x-liquid-glass.js +35 -35
  87. package/dist/x-menu-item.d.ts +41 -0
  88. package/dist/x-menu-item.js +10 -10
  89. package/dist/x-menu.d.ts +42 -0
  90. package/dist/x-menu.js +10 -10
  91. package/dist/x-metaball-cursor.d.ts +21 -0
  92. package/dist/x-metaball-cursor.js +25 -25
  93. package/dist/x-modal.d.ts +44 -0
  94. package/dist/x-modal.js +11 -11
  95. package/dist/x-morph-stack.d.ts +46 -0
  96. package/dist/x-morph-stack.js +39 -39
  97. package/dist/x-navbar.d.ts +46 -0
  98. package/dist/x-navbar.js +12 -12
  99. package/dist/x-neural-glow.d.ts +22 -0
  100. package/dist/x-neural-glow.js +30 -30
  101. package/dist/x-notification-center.d.ts +42 -0
  102. package/dist/x-notification-center.js +10 -10
  103. package/dist/x-organic-divider.d.ts +19 -0
  104. package/dist/x-organic-divider.js +15 -15
  105. package/dist/x-organic-progress.d.ts +45 -0
  106. package/dist/x-organic-progress.js +35 -35
  107. package/dist/x-organic-shape.d.ts +18 -0
  108. package/dist/x-organic-shape.js +12 -12
  109. package/dist/x-pagination.d.ts +45 -0
  110. package/dist/x-pagination.js +17 -16
  111. package/dist/x-particle-button.d.ts +47 -0
  112. package/dist/x-particle-button.js +46 -46
  113. package/dist/x-popover.d.ts +45 -0
  114. package/dist/x-popover.js +23 -23
  115. package/dist/x-progress-circle.d.ts +41 -0
  116. package/dist/x-progress-circle.js +7 -7
  117. package/dist/x-progress.d.ts +44 -0
  118. package/dist/x-progress.js +7 -7
  119. package/dist/x-radio.d.ts +44 -0
  120. package/dist/x-radio.js +11 -11
  121. package/dist/x-ripple-effect.d.ts +42 -0
  122. package/dist/x-ripple-effect.js +11 -11
  123. package/dist/x-scroll-parallax.d.ts +45 -0
  124. package/dist/x-scroll-parallax.js +17 -17
  125. package/dist/x-scroll-stack.d.ts +46 -0
  126. package/dist/x-scroll-stack.js +18 -18
  127. package/dist/x-scroll-story.d.ts +56 -0
  128. package/dist/x-scroll-story.js +33 -33
  129. package/dist/x-scroll-timeline.d.ts +58 -0
  130. package/dist/x-scroll-timeline.js +44 -44
  131. package/dist/x-scroll.d.ts +51 -0
  132. package/dist/x-scroll.js +39 -39
  133. package/dist/x-search-field.d.ts +47 -0
  134. package/dist/x-search-field.js +15 -14
  135. package/dist/x-select.d.ts +41 -0
  136. package/dist/x-select.js +10 -10
  137. package/dist/x-sidebar.d.ts +40 -0
  138. package/dist/x-sidebar.js +16 -16
  139. package/dist/x-skeleton-group.d.ts +15 -0
  140. package/dist/x-skeleton-group.js +13 -13
  141. package/dist/x-skeleton.d.ts +16 -0
  142. package/dist/x-skeleton.js +1 -1
  143. package/dist/x-slider.d.ts +49 -0
  144. package/dist/x-slider.js +18 -16
  145. package/dist/x-soft-body.d.ts +44 -0
  146. package/dist/x-soft-body.js +20 -20
  147. package/dist/x-spacer.d.ts +15 -0
  148. package/dist/x-spacer.js +5 -5
  149. package/dist/x-spinner.d.ts +15 -0
  150. package/dist/x-spinner.js +5 -5
  151. package/dist/x-splash.d.ts +42 -0
  152. package/dist/x-splash.js +13 -13
  153. package/dist/x-stat.d.ts +21 -0
  154. package/dist/x-stat.js +9 -9
  155. package/dist/x-stepper.d.ts +42 -0
  156. package/dist/x-stepper.js +14 -14
  157. package/dist/x-switch.d.ts +44 -0
  158. package/dist/x-switch.js +10 -10
  159. package/dist/x-tab.d.ts +40 -0
  160. package/dist/x-tab.js +7 -7
  161. package/dist/x-table-cell.d.ts +50 -0
  162. package/dist/x-table-cell.js +19 -19
  163. package/dist/x-table-row.d.ts +43 -0
  164. package/dist/x-table-row.js +10 -10
  165. package/dist/x-table.d.ts +124 -0
  166. package/dist/x-table.js +13 -13
  167. package/dist/x-tabs.d.ts +71 -0
  168. package/dist/x-tabs.js +11 -11
  169. package/dist/x-text-area.d.ts +48 -0
  170. package/dist/x-text-area.js +20 -18
  171. package/dist/x-theme.d.ts +15 -0
  172. package/dist/x-theme.js +24 -24
  173. package/dist/x-timeline-item.d.ts +46 -0
  174. package/dist/x-timeline-item.js +19 -19
  175. package/dist/x-timeline.d.ts +78 -0
  176. package/dist/x-timeline.js +9 -9
  177. package/dist/x-toast.d.ts +45 -0
  178. package/dist/x-toast.js +21 -21
  179. package/dist/x-toaster.d.ts +41 -0
  180. package/dist/x-toaster.js +8 -8
  181. package/dist/x-tooltip.d.ts +43 -0
  182. package/dist/x-tooltip.js +12 -12
  183. package/dist/x-typography.d.ts +16 -0
  184. package/dist/x-typography.js +8 -8
  185. package/dist/x-welcome-tour.d.ts +92 -0
  186. package/dist/x-welcome-tour.js +58 -58
  187. package/package.json +506 -392
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  All notable changes to BareDOM will be documented in this file.
4
4
 
5
+ ## [2.6.0] - 2026-04-30
6
+
7
+ ### Added
8
+
9
+ - **Cancelable change-request events** — Seven input components now fire a cancelable `change-request` event before applying user-initiated value changes. Call `preventDefault()` to block the update (enables controlled component patterns in framework adapters). Components: x-slider, x-text-area, x-select, x-combobox, x-currency-field, x-tabs, x-pagination.
10
+
11
+ ### Fixed
12
+
13
+ - **x-context-menu** — Escape key and click-outside now correctly dismiss the menu. Handlers moved from the overlay layer (which has `pointer-events: none`) to document-level listeners.
14
+ - **x-button** — Fixed missing press events on mobile Safari. Added `touch-action: manipulation` and `-webkit-tap-highlight-color: transparent` to the internal button element (reset by `all: unset`).
15
+ - **x-carousel demo** — Control panel now uses correct BareDOM event names (`x-switch-change`, `x-form-field-input`, `select-change`, `press`) instead of native DOM events.
16
+ - **x-welcome-tour test** — Added missing `^js` type hint to fix Closure Advanced compilation warning.
17
+ - **x-combobox** — Fixed undefined category in demo gallery (changed from `"input"` to `"form"`).
18
+
19
+ ## [2.5.0] - 2026-04-29
20
+
21
+ ### Added
22
+
23
+ - **TypeScript support** — First-class `.d.ts` type declarations auto-generated from component model metadata. Per-component interfaces with typed properties, methods, and `addEventListener` overloads. Custom Elements Manifest (`custom-elements.json`) for IDE support.
24
+ - **Debug mode** — Dev-only visual debugging overlay for all BareDOM components. Activate via `?baredom-debug` URL param or `window.BAREDOM_DEBUG = true`. Shows dashed outlines, tag labels on hover, and a floating inspection panel with live attribute/property editing and structured console logging. Excluded from the production `:lib` build.
25
+
26
+ ### Fixed
27
+
28
+ - **TypeScript declarations** — Fixed invalid kebab-case identifiers in generated `.d.ts` files. Property names like `max-items` and event detail keys like `press-x` are now correctly output as camelCase (`maxItems`, `pressX`). Affected components: x-breadcrumbs, x-context-menu, x-pagination, x-particle-button.
29
+
5
30
  ## [2.4.1] - 2026-04-28
6
31
 
7
32
  ### Fixed
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  <picture>
5
5
  <source media="(prefers-color-scheme: dark)" srcset="public/assets/baredom_darkmode.svg">
6
6
  <source media="(prefers-color-scheme: light)" srcset="public/assets/baredom_lightmode.svg">
7
- <img alt="Project Logo" src="public/assets/baredom_lightmode.svg" width="200">
7
+ <img alt="Project Logo" src="public/assets/baredom_lightmode.svg" width="160">
8
8
  </picture>
9
9
  </p>
10
10
 
@@ -13,6 +13,7 @@
13
13
  [![npm version](https://img.shields.io/npm/v/%40vanelsas%2Fbaredom.svg)](https://www.npmjs.com/package/@vanelsas/baredom)
14
14
  [![license](https://img.shields.io/npm/l/%40vanelsas%2Fbaredom.svg)](./LICENSE)
15
15
  [![ESM](https://img.shields.io/badge/module-ESM-blue.svg)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
16
+ [![TypeScript](https://img.shields.io/badge/types-included-blue.svg)](https://www.typescriptlang.org/)
16
17
  [![Custom Elements v1](https://img.shields.io/badge/Custom%20Elements-v1-green.svg)](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements)
17
18
 
18
19
  ---
@@ -63,6 +64,55 @@ I first built the usual suspects for web components, a basis to create a UI. I t
63
64
 
64
65
  **Open Shadow DOM.** Shadow roots are `mode: "open"` — inspectable in DevTools, styleable via `::part()`, and testable with standard DOM APIs.
65
66
 
67
+ **First-class TypeScript support.** Every component ships with auto-generated `.d.ts` type declarations and a [Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest). TypeScript consumers get typed element interfaces, typed custom events with detail payloads, and `HTMLElementTagNameMap` augmentation for `querySelector` type narrowing — all without installing a separate `@types` package.
68
+
69
+ ---
70
+
71
+ ## TypeScript
72
+
73
+ BareDOM includes TypeScript declarations for every component. Types are auto-generated from component metadata and ship alongside the ESM files — no additional setup required.
74
+
75
+ ### What you get
76
+
77
+ - **Typed element interfaces** extending `HTMLElement` with all properties and methods
78
+ - **Typed custom events** with full `detail` payload types
79
+ - **`HTMLElementTagNameMap` augmentation** so `document.querySelector('x-button')` returns `XButton`
80
+ - **[Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest)** (`custom-elements.json`) for IDE tooling and HTML intellisense
81
+
82
+ ### Usage
83
+
84
+ ```typescript
85
+ import '@vanelsas/baredom/x-button';
86
+ import '@vanelsas/baredom/x-alert';
87
+
88
+ // querySelector returns typed XButton
89
+ const btn = document.querySelector('x-button')!;
90
+ btn.disabled = true; // type-checked
91
+ btn.loading = true; // autocomplete works
92
+
93
+ // Event listeners have typed detail payloads
94
+ btn.addEventListener('press', (e) => {
95
+ console.log(e.detail.source); // string — fully typed
96
+ });
97
+
98
+ // Custom events on other components
99
+ const alert = document.querySelector('x-alert')!;
100
+ alert.addEventListener('x-alert-dismiss', (e) => {
101
+ console.log(e.detail.reason); // string
102
+ console.log(e.detail.type); // string
103
+ });
104
+
105
+ // Components with methods
106
+ import '@vanelsas/baredom/x-modal';
107
+ const modal = document.querySelector('x-modal')!;
108
+ modal.show(); // typed method
109
+ modal.hide(); // typed method
110
+ ```
111
+
112
+ ### IDE support
113
+
114
+ The `custom-elements.json` manifest enables HTML intellisense in editors that support it. For VS Code, install the [Lit Plugin](https://marketplace.visualstudio.com/items?itemName=nicktomlin.vscode-lit-html) or the [Custom Elements Language Server](https://marketplace.visualstudio.com/items?itemName=nicktomlin.vscode-lit-html) to get attribute autocomplete and validation in HTML templates.
115
+
66
116
  ---
67
117
 
68
118
  ## Theming
@@ -107,228 +157,25 @@ See [docs/x-theme.md](./docs/x-theme.md) for the full token list, preset details
107
157
 
108
158
  ## Installation
109
159
 
110
- > **Using JavaScript?** See the [JavaScript Developer Guide](./docs/javascript-guide.md) for npm/ESM setup, event handling, theming, and framework integration examples (React, Vue, Svelte).
111
-
112
- 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**.
113
-
114
- ### Option A — ClojureScript via Clojars
115
-
116
- Add BareDOM to your `deps.edn`:
117
-
118
- ```clojure
119
- {:deps {com.github.avanelsas/baredom {:mvn/version "2.4.1"}}}
120
- ```
121
-
122
- Or in your `shadow-cljs.edn` dependencies:
123
-
124
- ```clojure
125
- :dependencies [[com.github.avanelsas/baredom "2.4.1"]]
126
- ```
127
-
128
- Then require component namespaces directly and call their `init!` function once at startup:
129
-
130
- ```clojure
131
- (ns my-app.core
132
- (:require
133
- [baredom.exports.x-button :as x-button]
134
- [baredom.exports.x-alert :as x-alert]
135
- [baredom.exports.x-toaster :as x-toaster]
136
- [baredom.exports.x-toast :as x-toast]))
137
-
138
- (defn- register-components! []
139
- (x-button/init)
140
- (x-alert/init)
141
- (x-toaster/init)
142
- (x-toast/init))
143
- ```
144
-
145
- Call `register-components!` once in your `init!` entry point. Registration is idempotent — calling `init` on an already-registered element is a no-op.
146
-
147
- ### Option B — Vanilla HTML/JS via ES modules
148
-
149
- 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">`:
150
-
151
- ```html
152
- <!DOCTYPE html>
153
- <html lang="en">
154
- <head>
155
- <meta charset="UTF-8">
156
- <title>BareDOM Example</title>
157
- </head>
158
- <body>
159
- <x-button variant="primary">Click me</x-button>
160
- <x-alert type="success" text="It works!"></x-alert>
161
-
162
- <script type="module">
163
- import { init as initButton } from './dist/x-button.js';
164
- import { init as initAlert } from './dist/x-alert.js';
165
-
166
- initButton();
167
- initAlert();
168
- </script>
169
- </body>
170
- </html>
171
- ```
172
-
173
- 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.
174
-
175
- ### Option C — npm
176
-
177
- Add the npm package to your `package.json`:
178
-
179
- ```json
180
- {
181
- "dependencies": {
182
- "@vanelsas/baredom": "^2.4.1"
183
- }
184
- }
160
+ ```bash
161
+ npm install @vanelsas/baredom
185
162
  ```
186
163
 
187
- Then `npm install`. shadow-cljs resolves npm packages automatically via `node_modules`. From ClojureScript:
188
-
189
- ```clojure
190
- (ns my-app.core
191
- (:require
192
- ["@vanelsas/baredom/x-button" :as x-button]
193
- ["@vanelsas/baredom/x-alert" :as x-alert]
194
- ["@vanelsas/baredom/x-toaster" :as x-toaster]
195
- ["@vanelsas/baredom/x-toast" :as x-toast]))
196
-
197
- (defn- register-components! []
198
- (.init x-button)
199
- (.init x-alert)
200
- (.init x-toaster)
201
- (.init x-toast))
164
+ ```js
165
+ import { init } from '@vanelsas/baredom/x-button';
166
+ init();
202
167
  ```
203
168
 
204
- Call `register-components!` once in your `init!` entry point. Registration is idempotent — calling `.init` on an already-registered element is a no-op.
169
+ Also available via [Clojars](./docs/installation.md#clojurescript-via-clojars) and [standalone ES modules](./docs/installation.md#vanilla-htmljs-via-es-modules). See the [full installation guide](./docs/installation.md).
205
170
 
206
171
  ---
207
172
 
208
173
  ## Usage
209
174
 
210
- ### 1. Register components
211
-
212
- 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.
213
-
214
- ### 2. Add a renderer
215
-
216
- 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.
217
-
218
- 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.
219
-
220
- What the renderer provides:
221
-
222
- - **Hiccup syntax** — describe UI as nested vectors: `[:tag {:attr val} children]`
223
- - **Prop handling** — `:on-*` keys become event listeners; `true`/`false` toggle boolean attributes; everything else calls `setAttribute`
224
- - **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.
225
- - **`mount!`** — renders the view and attaches `add-watch` to a state atom so every `swap!` triggers a reconciliation pass
226
-
227
- ### 3. Write views with hiccup syntax
175
+ BareDOM components are native HTML elements. Import, register, and use them in any framework or vanilla HTML.
228
176
 
229
- Views are plain ClojureScript functions that return nested vectors. The first element of each vector is a keyword matching the element tag name. An optional map of props follows, then children.
230
-
231
- ```clojure
232
- ;; String and number attributes
233
- [:x-button {:variant "primary"} "Save changes"]
234
- [:x-button {:variant "secondary" :size "sm"} "Cancel"]
235
-
236
- ;; Boolean attributes — true sets the attribute, false/nil removes it
237
- [:x-button {:variant "danger" :disabled true} "Delete"]
238
- [:x-button {:variant "primary" :loading true} "Saving…"]
239
- [:x-checkbox {:checked true}]
240
- [:x-checkbox {:indeterminate true}]
241
-
242
- ;; Nesting
243
- [:x-grid {:columns "2" :gap "md"}
244
- [:x-card "First card"]
245
- [:x-card "Second card"]]
246
-
247
- [:x-grid {:columns "4" :gap "md"}
248
- [:x-stat {:label "Revenue" :value "$48,295" :trend "up" :variant "positive"}]
249
- [:x-stat {:label "Users" :value "12,483" :trend "up"}]
250
- [:x-stat {:label "Orders" :value "1,429" :trend "neutral"}]
251
- [:x-stat {:label "Churn" :value "2.4%" :trend "down" :variant "danger"}]]
252
-
253
- ;; Slots — use the :slot attribute to target named slots
254
- [:x-navbar {:label "My App"}
255
- [:span {:slot "brand" :style "font-weight:700"} "My App"]
256
- [:div {:slot "actions"}
257
- [:x-button {:variant "ghost" :size "sm"} "Sign out"]]]
258
- ```
259
-
260
- ### 4. Handle events and manage state
261
-
262
- Event listeners are declared inline using `:on-<event-name>` keys. The key is stripped of `on-` and the remainder becomes the event name passed to `addEventListener`. Custom component events follow the same pattern — use the full event name after `on-`.
263
-
264
- ```clojure
265
- (defonce app-state (atom {:active-tab "overview"
266
- :sidebar-collapsed false}))
267
-
268
- ;; Standard DOM event
269
- [:x-button
270
- {:variant "ghost"
271
- :on-click (fn [_] (swap! app-state update :sidebar-collapsed not))}
272
- "Toggle sidebar"]
273
-
274
- ;; Custom component event — :on-value-change listens for "value-change"
275
- [:x-tabs
276
- {:value (:active-tab @app-state)
277
- :on-value-change (fn [e]
278
- (swap! app-state assoc
279
- :active-tab (.. e -detail -value)))}
280
- [:x-tab {:value "overview"} "Overview"]
281
- [:x-tab {:value "components"} "Components"]
282
- [:x-tab {:value "settings"} "Settings"]]
283
-
284
- ;; Custom event with detail payload
285
- [:x-alert
286
- {:type "success" :text "Changes saved." :dismissible true
287
- :on-x-alert-dismiss (fn [e]
288
- (js/console.log "dismissed by:" (.. e -detail -reason)))}]
289
-
290
- ;; Sidebar with open/collapse state
291
- [:x-sidebar
292
- {:open (:sidebar-open @app-state)
293
- :collapsed (:sidebar-collapsed @app-state)
294
- :placement "left"
295
- :on-toggle (fn [e]
296
- (swap! app-state assoc :sidebar-open (.. e -detail -open)))}
297
- ;; ... nav items ...
298
- ]
299
- ```
300
-
301
- Wire everything together in your `init!`:
302
-
303
- ```clojure
304
- (defn view []
305
- [:x-container {:size "xl" :padding "lg"}
306
- ;; ... your UI built from component vectors ...
307
- ])
308
-
309
- (defn init! []
310
- (register-components!)
311
- (renderer/mount! (.getElementById js/document "app") view app-state))
312
- ```
313
-
314
- `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.
315
-
316
- ### Theming
317
-
318
- Override CSS custom properties at any scope:
319
-
320
- ```css
321
- /* Global overrides */
322
- :root {
323
- --x-button-radius: 4px;
324
- --x-alert-radius: 8px;
325
- }
326
-
327
- /* Per-instance override */
328
- #sidebar-save-btn {
329
- --x-button-bg-primary: #0a5c99;
330
- }
331
- ```
177
+ - **JavaScript / TypeScript** — see the [JavaScript Developer Guide](./docs/javascript-guide.md)
178
+ - **ClojureScript** — see the [ClojureScript Guide](./docs/clojurescript-guide.md)
332
179
 
333
180
  ---
334
181
 
@@ -453,7 +300,7 @@ BareDOM compiles to lightweight ES modules. Sizes below are gzipped:
453
300
 
454
301
  Each component loads `base.js` once plus its own module. A typical page using 5-10 components weighs **40-65 KB** gzipped total.
455
302
 
456
- > **ESM only.** BareDOM ships ES modules exclusively — there is no CommonJS or UMD build. This works natively in all modern browsers and with any bundler that supports ESM (webpack 5+, Vite, esbuild, Rollup, Parcel). If you need server-side rendering, pre-render the HTML and hydrate with component registration on the client.
303
+ > **ESM only.** BareDOM ships ES modules exclusively — there is no CommonJS or UMD build. This works natively in all modern browsers and with any bundler that supports ESM (webpack 5+, Vite, esbuild, Rollup, Parcel). TypeScript declarations (`.d.ts`) are included for every component. If you need server-side rendering, pre-render the HTML and hydrate with component registration on the client.
457
304
 
458
305
  ---
459
306
 
@@ -471,63 +318,9 @@ No polyfills are included or required for these targets.
471
318
 
472
319
  ---
473
320
 
474
- ## Component Demo
475
-
476
- BareDOM ships with a built-in demo that lets you browse and interact with every component in isolation. It is intended for developer convenience when working on the library itself.
477
-
478
- ```bash
479
- npm install
480
- npx shadow-cljs watch app
481
- ```
482
-
483
- Then open `http://localhost:8000`. The dev server serves `public/index.html` and hot-reloads on every source change. Each component is demonstrated in its own section with controls for toggling attributes, properties, and variants.
484
-
485
- ---
486
-
487
- ## bare-demo — starter template for ClojureScript web apps
488
-
489
- 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.
490
-
491
- The architecture is built on three ideas:
492
-
493
- - **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.
494
- - **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.
495
- - **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.
496
-
497
- 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.
498
-
499
- **Run it:**
500
-
501
- ```bash
502
- cd bare-demo
503
- clj -M:dev
504
- ```
505
-
506
- Then open `http://localhost:8001`.
321
+ ## Development
507
322
 
508
- See [`bare-demo/README.md`](./bare-demo/README.md) for a full walkthrough of the renderer, component registration, view syntax, state management, and theming.
509
-
510
- > **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`).
511
-
512
- ---
513
-
514
- ## Building from Source
515
-
516
- BareDOM is authored in ClojureScript and compiled with [shadow-cljs](https://shadow-cljs.github.io/docs/UsersGuide.html).
517
-
518
- ```bash
519
- # Install dependencies
520
- npm install
521
-
522
- # Start development server with hot reload (http://localhost:8000)
523
- npx shadow-cljs watch app
524
-
525
- # Run browser-based tests (http://localhost:8021)
526
- npx shadow-cljs watch test
527
-
528
- # Build production ESM library to dist/
529
- npm run build
530
- ```
323
+ See the [development guide](./docs/development.md) for setting up the dev server, using [debug mode](./docs/development.md#debug-mode), and building from source.
531
324
 
532
325
  ---
533
326