wabi 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abcbfe9f2785a854e687d5f992d6ceb32c4e4fb67ba0d081416ff4bd9b383988
4
- data.tar.gz: 6706563e1af726d59eafc0dbee7020a1fe565ed51cde9846020dcd74239b97e3
3
+ metadata.gz: 5c5512565440dd12e42434dceb8522dbd9b0757e41b63981617e8a645f69bb37
4
+ data.tar.gz: 2f0c77f0a635bcd6bb2673fb403db9d9247bc916a4adf77ef9398a6816e3fbff
5
5
  SHA512:
6
- metadata.gz: a367a2820c7e1276ce580cae7f577fca70d0f2f2c2f211a222f97dffc8920b1d4bbdfd3745c3ac76a921e654b74cf958b465d7fcd3501bbedfbe8aa474b8a387
7
- data.tar.gz: c1de47b6186629b44e908fb3a364a564605a5b34c3551307057909fec013ae4e71b2c0a12f42e69d714f88a94a1f1ef38be755e4c1206a577edf668e469317e4
6
+ metadata.gz: 2a4eaf8d667a84e467238e9ba0b4f9cd14d9a5b685698ea82ed3c7ed443bac56b5ddc3c35bf68299947ec38ba7ed49b7d2a6fc0799a5311fc98e3aa9a443b5fe
7
+ data.tar.gz: 1f03f62dbcf1907505f19dd570d2ca7e06b15cbb9ad3cacb579885deba29b947057da789296981cf6ccafbca2c502989d400bb8e2011e84e0550d20dd49b3419
data/CHANGELOG.md CHANGED
@@ -2,6 +2,69 @@
2
2
 
3
3
  All notable changes to Wabi land here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
4
 
5
+ ## [0.4.0] — 2026-05-27
6
+
7
+ Sprint 8 — docs completeness + theme polish. The docs site gains the
8
+ three-column shell (grouped sidebar, content, right-side TOC) on every
9
+ `/docs/*` route, a Pagefind-powered search, and detail pages for the
10
+ remaining 16 components — every component in the registry now has its
11
+ own page. Theming gains a tinted secondary/accent per color palette,
12
+ a quick sun/moon mode toggle in the header, and a swap of `slate` +
13
+ `zinc` for `yellow` + `orange`.
14
+
15
+ ### Added
16
+
17
+ - **`Components::Site::Sidebar` + `Sidebar::Group` + `Sidebar::Link`** — Grouped left navigation for `/docs/*`. 7 groups (Getting Started / Forms / Layout & Display / Overlays / Menus / Navigation / Feedback) listing all 20 components + the prose pages. Active link highlighted via `current_path:` kwarg.
18
+ - **`Components::Site::TableOfContents` + `site--toc` Stimulus controller** — Right-side TOC on `chrome: :full` pages. Empty `<aside>` filled client-side by scanning `main h2[id], main h3[id]`. Tracks the active section via `IntersectionObserver`.
19
+ - **`Components::Site::SidebarToggle` + `site--sidebar` controller** — Hamburger button visible below `lg` breakpoint; opens the sidebar as a fixed overlay with scroll lock + Escape-to-close.
20
+ - **`Components::Site::SearchBox` + `site--search` controller** — Header search input that lazy-loads PagefindUI as a classic script, mounts it on the input, and renders results as an absolute-positioned dropdown styled with Wabi popover tokens.
21
+ - **`Components::Site::ModeToggle`** — Sun/moon icon button next to the ThemePicker. One-click dark/light flip via the existing `wabi--theme#toggleMode` action.
22
+ - **`Wabi::Docs::Indexer` + `wabi:docs:index` rake task** — Crawls 26 docs routes via `Rack::Test` (with `HTTP_HOST=localhost` + Chrome UA to satisfy `ActionDispatch::HostAuthorization` and `allow_browser :modern`), writes the response HTML to files mirroring the URL structure, then shells out to `npx pagefind` to build the static index. Index lives at `docs/public/pagefind/` and ships in the repo — deploys stay Node-free.
23
+ - **`docs/spec/requests/docs_smoke_spec.rb`** — Request specs covering every documented route (3 chrome modes: bare / sidebar_only / full) and the SearchBox markup on non-bare routes.
24
+ - **16 new detail pages** under `/docs/components/`: checkbox, input, label, select, switch, textarea, alert, avatar, badge, card, separator, drawer, popover, tooltip, accordion, toast. Each follows a single canonical anatomy: Installation / Example (ComponentPreview) / Source / Accessibility.
25
+ - **Two new theme palettes**: `yellow` (vibrant amber primary) and `orange`. Both follow the standard light + dark structure.
26
+ - **`Site::Layout(chrome:)` kwarg** — `:bare` (default, no sidebar/TOC), `:sidebar_only`, `:full`. Drives where the sidebar, TOC, and SearchBox render. 11 views updated to pass the appropriate value.
27
+ - **`ROADMAP` updates** + **README "Working on docs" section** documenting the Pagefind workflow.
28
+
29
+ ### Changed
30
+
31
+ - **Theme palettes**: `slate` and `zinc` replaced with `yellow` and `orange`. Neutral baselines stay covered by `default` and `stone`.
32
+ - **Theme tinting**: the 6 color palettes (rose, blue, green, violet, yellow, orange) now redefine `--secondary` and `--accent` as pale tints of their primary hue (lightness ~92-96% light / ~18% dark) with foreground colors at the same hue darkened/lightened for AA contrast. Default and Stone stay neutral on purpose. `--muted` stays neutral across all themes.
33
+ - **Theme dark-mode propagation**: each theme's dark block now also matches `[data-mode="dark"] [data-theme="X"]:not([data-mode="light"])`, so dark mode cascades into nested `data-theme` cards (e.g. the `/docs/themes` palette grid).
34
+ - **Button `:outline` appearance**: `border-input` (neutral) replaced with `border-primary` + `text-primary`. Outline buttons now adopt the active theme color on their stroke and label.
35
+ - **`Site::ComponentPreview`**: replaced the ad-hoc `site--preview-tabs` Stimulus controller with the real `Wabi::UI::Tabs` (dogfooding). Switcher uses an underline pattern — active trigger gets a 3px primary-colored bottom border + bold primary-color text.
36
+ - **`Site::CodeBlock` copy button**: word "Copy" replaced with a 14px clipboard SVG inside a 28×28 button. On copy: swap to checkmark SVG for 1.2s. `pre` reserves the button's column with `pr-12` so long code lines never tuck under the button while scrolling.
37
+ - **Components index**: every component links to its detail page. The `DETAILED` constant gate was dropped from `ComponentsController#show`; the only guard is membership in `ALL`.
38
+ - **Site::Layout header**: sticky with `z-30`, gains the SearchBox + ModeToggle on `chrome != :bare` routes.
39
+
40
+ ### Fixed
41
+
42
+ - **Tailwind 4 migration — explicit `border` width on every `border-input` element.** TW3 implicitly set `border-width: 1px` on any element with a `border-{color}` class; TW4 removed that default. Components that only declared `border-input` rendered with width 0 — no visible outline. Affected: `select_trigger`, `select_content`, `dropdown_menu_content`, `dropdown_menu_sub_content`, `drawer_content` (4 side variants), `dialog_content`, `popover_content`, `toast`.
43
+ - **Tailwind 4 migration — cursor: pointer on interactive elements.** TW4 Preflight removed the legacy default on `<button>`. Added a CSS rule under `_shared.css` (`@layer base`) restoring `cursor: pointer` for `button`, `[role="button"/"switch"/"checkbox"/"tab"/"option"/"menuitem"/"menuitemradio"/"menuitemcheckbox"]`, plus `cursor: not-allowed` for `[disabled]` and `[aria-disabled="true"]`.
44
+ - **`Wabi::UI::TabsTrigger` active state**: switched all `data-[state=active]:*` variants to `aria-selected:*`. Zag.js's tabs API emits `aria-selected="true"` + `data-selected=""`, NOT `data-state="active"` — so the active styling never fired. Affected `TabsTrigger` base tokens (both light and dark mode active styles).
45
+ - **`Avatar` image/fallback overlap**: `AvatarImage` is now `absolute inset-0 object-cover` so it stacks over `AvatarFallback`. Previously both rendered as flow-positioned siblings inside the flex Avatar container.
46
+ - **`Toast` sticky mode**: `wabi--toast` controller treats `durationMsValue <= 0` as "no timer" — toasts render persistently until manually dismissed. The Toast detail-page preview now uses this so the 3 appearances stay visible.
47
+ - **`SidebarToggle` Stimulus wiring**: button declared `data-action` but no element declared `data-controller="site--sidebar"`, so the controller never instantiated and the hamburger didn't open the sidebar. Added `data-controller` to the button itself.
48
+ - **TOC anchor jumps**: sticky 56px header was tapping over scrolled-to headings. Added `scroll-margin-top: 5rem` to `main :is(h1, h2, h3, h4, h5, h6)[id]`.
49
+ - **SearchBox PagefindUI loader**: PagefindUI ships as classic IIFE scripts (sets `window.PagefindUI`), not ES modules. The original `await import("/pagefind/pagefind-ui.js")` returned an empty module. Rewrote the loader to inject a `<script>` tag and await its `load` event.
50
+ - **Search result URLs**: Indexer wrote `docs_components_button.html` (flattened with `_`), and Pagefind built result URLs from those filenames. Now writes files mirroring the URL structure (`docs/components/button.html` with `mkdir_p`) and PagefindUI's `processResult` callback strips `.html` from the displayed URL — clicks navigate to `/docs/components/button` directly.
51
+ - **Select example wiring**: `items:` array was missing on the `/docs/components/select` example, so Zag's collection was empty and clicks on SelectItem elements were no-ops. Added a `FRUITS` array passed via `items:` and iterated for the SelectItem children.
52
+
53
+ ### Spec totals
54
+
55
+ - Registry: **125/125**.
56
+ - Gem: **66/66**.
57
+ - Docs (request + component specs): **40/40** — every smoke route (`:bare` / `:sidebar_only` / `:full`) returns 200 with the expected sidebar/TOC/search markup; Indexer crawl writes one file per route, mirroring URL structure with `index.html` at root.
58
+
59
+ ### Known v0.4 deferrals → v0.5
60
+
61
+ - `@zag-js/toast` group machine — Wabi v0.4 Toast still uses a vanilla setTimeout-based controller. v0.5 will adopt the real Zag toast group machine for cross-toast coordination (max visible, stacking, etc.).
62
+ - `wabi:update` generator — Pulling registry updates back into a host app is still manual (re-run `wabi:add <name>`). v0.5 will add a generator that diffs registry vs. host and applies changes.
63
+ - Real portal pattern — Overlay components (Dialog, Drawer, Popover, Tooltip) currently render in-tree. A `<dialog>`-element-based or `Components::UI::Portal`-based pattern is queued for v0.5.
64
+ - Backfill `bin/importmap pin` footnote on the 5 pre-existing Zag pages (checkbox, select, switch, dialog, tabs). v0.4 added the warning to the new overlay/accordion pages; sweep across all pages happens in v0.5 docs polish.
65
+
66
+ ---
67
+
5
68
  ## [0.3.0] — 2026-05-26
6
69
 
7
70
  Sprint 7 (docs site polish). The docs site stops being a one-page kitchen
data/README.md CHANGED
@@ -4,15 +4,15 @@
4
4
 
5
5
  Wabi is an open-source UI component library for **Ruby on Rails 8**, built on **Phlex + Tailwind 4 + Stimulus + Hotwire**. Inspired by shadcn/ui, components are *copied* into your app — you own the code, customize freely, no upstream API to drift away from.
6
6
 
7
- 🎉 **Status:** v0.3.0 alpha. 20 components, 8 theme palettes, WCAG-AA targeted. Not yet on RubyGems.
7
+ 🎉 **Status:** v0.4.0 alpha — [available on RubyGems](https://rubygems.org/gems/wabi). 20 components, 8 theme palettes, WCAG-AA targeted, full docs site at the GitHub repo's `docs/` Rails app.
8
8
 
9
9
  ---
10
10
 
11
11
  ## Quick start
12
12
 
13
13
  ```bash
14
- # 1. Add the gem (path-based for now; RubyGems push pending)
15
- bundle add wabi --git https://github.com/wabikit/wabi --glob 'gem/*'
14
+ # 1. Add the gem
15
+ bundle add wabi
16
16
 
17
17
  # 2. Run the installer (copies tokens.css + theme controller + lockfile)
18
18
  bin/rails g wabi:install
@@ -153,15 +153,35 @@ Then visit:
153
153
 
154
154
  ---
155
155
 
156
+ ## Working on docs
157
+
158
+ The docs site is a Rails app under `docs/`. Local dev: `bin/dev` from
159
+ repo root. The static search index lives at `docs/public/pagefind/`
160
+ and is regenerated by a Rake task that crawls every docs route via
161
+ `Rack::Test`, dumps HTML to disk, then runs `npx pagefind` on it.
162
+
163
+ ```bash
164
+ cd docs && bin/rails wabi:docs:index
165
+ ```
166
+
167
+ Run this after touching any content under `docs/app/views/pages/` or
168
+ adding new component detail pages, then commit `docs/public/pagefind/`.
169
+ Requires Node 20+ in PATH (Pagefind is fetched via `npx` on demand).
170
+
171
+ ---
172
+
156
173
  ## Roadmap
157
174
 
158
175
  | Version | Target | Status |
159
176
  |---|---|---|
160
177
  | v0.1 | 20 components | ✅ shipped 2026-05-26 |
161
178
  | v0.2 | 8 themes + theme picker | ✅ shipped 2026-05-26 |
162
- | v0.3 | Real docs site (marketing + components index + 4 detailed pages + prose) | ✅ shipped 2026-05-26 |
163
- | v0.4 | Detailed pages for remaining 16 components; Pagefind search; sidebar nav | planned |
179
+ | v0.3 | Real docs site + RubyGems publish | ✅ shipped 2026-05-26 |
180
+ | v0.4 | Detailed pages for all 20 components; Pagefind search; sidebar nav; theme polish | shipped 2026-05-27 |
164
181
  | v0.5 | `@zag-js/toast` group machine; real portal pattern; `wabi:update` generator | planned |
182
+ | v0.6 | Forms expansion: RadioGroup, Toggle, ToggleGroup, Slider, Combobox, Command, Form | planned |
183
+ | v0.7 | Navigation & layout: Sheet, ContextMenu, Pagination, NavigationMenu | planned |
184
+ | v0.8 | Data + dates + ecosystem: Calendar, DatePicker, DataTable, Blocks, community registry | planned |
165
185
  | v1.0 | API stability; external a11y audit | 2027-04 target |
166
186
 
167
187
  See [ROADMAP.md](./ROADMAP.md) for the long-term view and [CHANGELOG.md](./CHANGELOG.md) for the per-release detail.
data/lib/wabi/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wabi
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
data/templates/tokens.css CHANGED
@@ -9,6 +9,30 @@
9
9
 
10
10
  @custom-variant dark (&:where([data-mode="dark"], [data-mode="dark"] *));
11
11
 
12
+ /* Tailwind 4 Preflight removed the legacy `cursor: pointer` on <button>.
13
+ * Wabi's stance: any element that's interactive (button, role=button,
14
+ * Zag-machine triggers like role=switch / role=tab / role=option /
15
+ * role=menuitem*) should signal that on hover. Disabled / aria-disabled
16
+ * elements opt out — their pointer-events are suppressed elsewhere but
17
+ * we also want the cursor to reflect "not clickable" for clarity. */
18
+ @layer base {
19
+ button:not(:disabled):not([aria-disabled="true"]),
20
+ [role="button"]:not([aria-disabled="true"]),
21
+ [role="switch"]:not([aria-disabled="true"]),
22
+ [role="checkbox"]:not([aria-disabled="true"]),
23
+ [role="tab"]:not([aria-disabled="true"]),
24
+ [role="option"]:not([aria-disabled="true"]),
25
+ [role="menuitem"]:not([aria-disabled="true"]),
26
+ [role="menuitemradio"]:not([aria-disabled="true"]),
27
+ [role="menuitemcheckbox"]:not([aria-disabled="true"]) {
28
+ cursor: pointer;
29
+ }
30
+ button[disabled],
31
+ [aria-disabled="true"] {
32
+ cursor: not-allowed;
33
+ }
34
+ }
35
+
12
36
  @theme inline {
13
37
  --color-background: hsl(var(--background));
14
38
  --color-foreground: hsl(var(--foreground));
@@ -64,7 +88,8 @@
64
88
  --popover-foreground: 240 10% 3.9%;
65
89
  }
66
90
 
67
- [data-theme="default"][data-mode="dark"] {
91
+ [data-theme="default"][data-mode="dark"],
92
+ [data-mode="dark"] [data-theme="default"]:not([data-mode="light"]) {
68
93
  --background: 240 10% 3.9%;
69
94
  --foreground: 0 0% 98%;
70
95
  --primary: 0 0% 98%;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wabi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Ortega