New stateless components ported from org-mode-agenda-cli reference app:
- view-toggle: Grid/Agenda segmented control
- source-toggles: colored pill buttons for event source filtering
- event-detail-dialog: overlay with title, date, time, tags, source
- error-banner: dismissible error bar
- loading-indicator: pulsing dot for async state
Enhanced existing components:
- calendar-event-grid: added :loading?, :header-actions slots
- agenda-day-group/agenda-list: added :day-actions slot per day header
- Event data format extended with :tags and :source fields
CSS: view toggle, loading pulse animation, error banner, source toggles,
detail dialog overlay — all using theme tokens with dark mode support.
Tests: 126 tests, 794 assertions, 0 failures.
Dev demos updated in all 3 targets with full interactive calendar app.
Add src/ui/calendar.md with full documentation for both calendar
namespaces (picker props, event grid, ticker, agenda, event data
format, date utilities, CSS classes).
Add a minimal markdown-to-hiccup renderer (ui.markdown) that handles
headings, fenced code blocks, tables, lists, inline code, and bold.
Styled with ui/markdown.css using theme tokens.
Each dev target renders the docs inline on the Calendar page:
- Hiccup: slurps the .md file at render time
- Replicant: embeds via compile-time macro (ui.macros/inline-file)
- Squint: fetches from /calendar.md served by Vite
Also fixes calendar event grid day cells to be square (aspect-ratio: 1
with overflow: hidden instead of min-height).
Add date picker and event calendar components inspired by shadcn/radix
Calendar and org-mode-agenda-cli.
Components:
- ui.calendar: Month grid date picker with navigation, today/selected
highlighting, outside-month dimming. Pure date math utilities
(days-in-month, day-of-week, calendar-days, etc.)
- ui.calendar-events: Event-aware grid with colored pills, horizontal
day ticker strip with dot indicators, and agenda list view with
grouped events by day
CSS: Token-based styling with dark mode support for event color
variants (accent/danger/success/warning). Responsive breakpoints.
All three targets supported (squint/cljs/clj). Dev pages show calendar
on its own page with interactive demos (date selection, month nav,
event grid, ticker, agenda list).
Tests: 27 new assertions covering date math, class generation,
component structure, event filtering/sorting.
Button:
- :icon-left, :icon-right props for buttons with leading/trailing icons
- :icon prop for icon-only buttons (square padding via .btn-icon class)
- Icon size scales with button size (sm→sm, md/lg→sm/md)
Alert:
- Auto-assigns variant-specific icons (circle-check, alert-triangle,
alert-circle, info) per variant
- :icon-name prop to override default, false to suppress
- Layout restructured with .alert-icon + .alert-content wrapper
Badge:
- :icon-name prop adds a leading icon before text
- .badge-icon CSS scales icon to match badge font size
Form input:
- :icon-left and :icon-right props on form-input
- Wraps input in .form-input-wrap with absolutely-positioned icon spans
- Padding adjusts automatically via .form-input--icon-left/right
All three dev targets (hiccup, replicant, squint) updated with demos.
Untrack theme-adapter.js and ignore all three files copied by
`bb build-theme` (theme.css, theme-adapter.js, css-live-reload.js).
These are generated artifacts, not source files.
Two-part solution for automatic CSS updates during development:
1. `bb watch-theme` — polls src/ui/*.css and tokens.edn every 500ms,
rebuilds dist/theme.css and copies to dev targets on change.
2. `dev/css-live-reload.js` — browser-side script that polls /theme.css
and hot-swaps the stylesheet without a full page reload (no FOUC).
The watcher runs automatically in the hiccup tmux pane when using
`bb dev-all`. It can also be run standalone with `bb watch-theme`.
The live-reload script is included in all three dev targets (hiccup,
replicant, squint) and copied by `bb build-theme`.
Horizontal and vertical separator (divider) with CSS classes, ARIA
role="none", and data-orientation attribute. Includes dark mode support,
unit tests, and demos in all three dev targets.
Add interactive sliders for font base size, font ratio, and border
radius scale to the theme adapter panel. Font values follow the
geometric scale (base × ratio^power) matching the EDN token system.
Radius values scale the base px values by a 0–2× multiplier.
Includes apply/reset logic, localStorage persistence, EDN export,
and dirty-state detection for the new parameters.
Adds `card-list` and `card-list-item` to the card module for rendering
a list of items inside a single card background with border separators.
The `:divider` prop controls separator style:
- `:full` (default) — borders go edge-to-edge
- `:inset` — borders are inset from edges by `--size-4`h
Adds a "Spacing" section with a Base slider (0.10–0.50 rem) that
live-updates all --size-1 through --size-16 CSS variables. The value
persists in localStorage, resets with the Reset button, and is
included in the Copy EDN output.
Floating panel in bottom-right of all dev targets lets you:
- Switch presets (Purple, Blue, Neutral, Warm, Rose, Emerald)
- Adjust gray hue/saturation and accent hue/saturation with sliders
- Preview color swatches in real-time
- Copy EDN config to paste into tokens.edn
State persists in localStorage. Panel collapses to a small toggle button.
Hiccup handler changed to use #'handler var for hot-reload.
Replace the pattern of reading shadow-cljs.edn, mutating it with
pr-str (which destroyed formatting), and writing it back. Instead,
use shadow-cljs's built-in `#shadow/env` reader tag to read the port
from the SHADOW_HTTP_PORT environment variable at startup, with a
default of 3001.
Both `dev-replicant` and `dev-all` tasks now pass the port via env var
instead of file mutation. This eliminates the dirty-file problem where
the rewritten single-line config would show up as an unrelated change.
Each target reads the theme from ?theme=dark|light on load and applies
it to data-theme before first paint. A MutationObserver syncs theme
changes back to the URL via replaceState, and a click handler appends
?theme= to cross-port navigation links automatically.
The outer iframe shell (dev/index.html) uses postMessage to track theme
changes from iframes and passes the param when switching tabs.
For hiccup, the server also reads ?theme= and sets data-theme on the
<html> element server-side to prevent any flash of wrong theme.
Add a `[data-no-transitions]` CSS rule that suppresses all transitions.
The theme toggle in all three dev targets (hiccup, replicant, squint)
sets this attribute before switching, then removes it on the next
animation frame, preventing the jarring animated color shift.
Restructures all three dev targets (hiccup, replicant, squint) to use
the sidebar component as the actual app shell. The sidebar navigates
between three pages:
- Components — all UI component demos
- Icons — categorized gallery with all 50+ icons and size variants
- Sidebar — embedded sidebar example with dashboard layout
The sidebar includes a Targets section that links between all three dev
servers, with ports derived dynamically from the current port so they
stay correct when using a custom base port (bb dev-all 5000).
Port scheme: replicant=base+1, squint=base+2, hiccup=base+3.
Adds a general-purpose icon system (ui.icon) with inline SVG rendering:
- 50+ icons from the Lucide icon set (navigation, actions, objects, UI,
status, dev/technical categories)
- Size variants: sm (--size-4), md (--size-5), lg (--size-6), xl (--size-8)
- Pure data approach: icon paths stored as hiccup vectors, rendered into
SVG with stroke="currentColor" so icons inherit text color
- API: (icon/icon {:icon-name :home :size :lg :class "custom"})
Integrates icons into the sidebar component:
- sidebar-menu-item now accepts :icon-name prop
- Renders icon in a .sidebar-menu-item-icon wrapper at :sm size
All three dev targets updated with icon gallery demo and sidebar icons.
Shadow-cljs deprecated external paths (`../../src`). Add a root
`deps.edn` exposing `src/` and reference it via `:local/root` from
`dev/replicant/deps.edn` instead.
Children were appended to the outer <details> element instead of inside
the .accordion-content div, causing text to render outside the accordion
box. Also adds .accordion-group wrapper to eliminate parent gap between
stacked items, and styles content with smaller font and muted color.
When :href is provided, the button renders as <a> instead of <button>,
enabling navigation links with full button styling.
New :link variant renders as a minimal text link (underlined, accent
color, no background/padding) — works as both <button> and <a>.
CSS includes reset styles for a.btn (removes default link decoration)
and preserves underline for a.btn-link.
Components (.cljc + .css + tests):
- Alert (success/warning/danger/info variants)
- Badge (primary/secondary/outline/success/warning/danger)
- Card (card/card-header/card-body/card-footer)
- Accordion (collapsible with open/closed state)
- Table (headers/rows, striped/bordered variants)
- Dialog (modal with header/body/footer sections)
- Breadcrumb (nav with active item)
- Pagination (current/total with prev/next)
- Progress (value bar with color variants)
- Spinner (sm/md/lg sizes)
- Skeleton (line/box/circle/heading placeholders)
- Switch (toggle with checked/disabled states)
- Tooltip (hover text via data-tooltip attr)
CSS-only additions:
- Form elements (inputs, selects, checkboxes, radios, range, groups)
- Grid (12-column system with offsets, responsive)
- Utilities (flex, spacing, alignment, sr-only)
Also adds warning/fg-on-warning tokens to light and dark themes.
All 3 dev targets updated with full component showcase.
40 tests, 213 assertions, all passing.
Move font-family, background, color, margin, and transition from
duplicated inline <style> blocks in each dev target into the CSS
generator (base-css). Dev pages now only set page-specific padding.
Also fixes hiccup target rendering the wrong font due to hiccup2
HTML-escaping quotes inside <style> tags, and adds missing <!DOCTYPE>.