Releases: MatthewKennedy/phlex_kit
Release list
v0.7.0 — DropdownMenu side: left/right + create-page shadcn parity
Kit
DropdownMenuContent side: :left / :right(#34) — the panel can now open beside its trigger, joining:bottom/:top. Anchor-positioned (position-area: inline-end/-start span-block-end) with aflip-inlineviewport fallback, mirroring shadcn'ssideprop. Invalid sides fail loud.
Dummy app (docs site)
- /create rebuilt to match ui.shadcn.com/create (#34, #35): a fixed app shell where only the canvas scrolls (both axes); two demo screens (01 finance, 02 smart home + artist) switched by the floating pill; and a like-for-like Customizer sidebar — seven side-right picker rows with working Theme / Icon Library / Heading / Font / Chart Color knobs, shareable
--preset <code>bundles, Open Preset dialog, Shuffle, and Get Code.
Suite green (263 runs, +5 assertions). Verified interactively in Chrome and WebKit 26.5.
v0.6.2 — NavigationMenu hover: sibling-link close + grace delay
NavigationMenu hover behavior, matching Radix/shadcn (#33):
- Sibling links close the panel: hovering a plain top-level link (one without a panel) now closes an open sibling's panel — previously the panel stayed open until the pointer left the entire nav. Links inside a panel are unaffected (they resolve to the open menu, so the panel stays).
- 150ms grace delay on hover closes: the natural diagonal pointer path from a trigger to its panel — which can clip a sibling link or briefly exit the nav — no longer slams the panel shut. Closes arm a short timer; reaching the panel or any trigger cancels it. Resting on a sibling, leaving the nav, Escape, and trigger-to-trigger switching all still behave as expected (the latter two instantly).
Menubar is unaffected (its top-level items are all triggers). Suite green (263 runs); verified with timing-controlled pointer paths in WebKit 26.5 and interactively in Chrome on the theme-builder page that surfaced the report.
v0.6.1 — popover UA-chrome fixes + flip-aware tooltip arrow
Patch on top of v0.6.0 (which was tagged but never published to rubygems — this is the version to install; all v0.6.0 notes apply).
Fixes (#31)
- DropdownMenu / Select: open panels rendered with a thick ring — the
[popover]UA defaults (border: solid,padding,Canvasbackground) showing through the unstyled outer wrapper. The wrappers now reset the UA chrome. - All popover panels: closed-state hiding now survives author
displayvalues (:not(:popover-open) { display: none }guard). Previously a host class likedisplay: gridon a panel defeated the UA's[popover] { display: none }and left it permanently open.
Improvement (#32)
- Tooltip: the notch now follows flip fallbacks — pure CSS. The arrow's center chases the trigger via
anchor()and is clamped inside the bubble's box, so it always sits on the trigger-facing edge, whichever side the bubble actually renders on. One rule replaces the four per-side arrow rules; the v0.6.0 "known limitation" is gone.
Suite green (263 runs); verified in Chrome and WebKit 26.5 (trusted input) across the affected gallery pages, including the theme-builder page that surfaced the stuck-open panel.
v0.6.0 — native popover + CSS anchor positioning, a11y round 2
Floating panels: native [popover] + CSS anchor positioning (#22–#30)
Every floating panel — popover, tooltip, hover card, dropdown menu (+ submenus), select, combobox, context menu, menubar, navigation menu — now uses the native Popover API and CSS anchor positioning (Baseline 2026: Chrome 125+, Safari 26, Firefox 147) instead of static absolute positioning:
- Panels respect the viewport:
position-try-fallbacksflips them to the opposite side at screen edges, live while scrolling — matching shadcn/Radix behavior, with zero JS and zero dependencies. - Top-layer rendering escapes
overflow: hiddenancestors (the Radix-portal equivalent); stackingz-indexhacks are gone. - Less JavaScript: popover/dropdown/select/combobox get native or simplified dismiss handling; combobox's
updatePopoverWidth()+resizelistener are deleted outright (anchor-size(width)in CSS); context menus clamp to the viewport. - Tooltip keeps its pure-CSS
:hover/:focus-withinreveal, gaining anchor positioning + edge flipping without the popover attribute.
Breaking-ish (DOM contract): panels now carry a popover attribute instead of the pk-hidden class, and are position: fixed in the top layer. Host CSS that targeted panel positioning (or pk-hidden on panels) needs the same treatment. Public Ruby APIs (side:, align:, delays) are unchanged. Combobox's undocumented min_popover_width Stimulus value was removed (now width: max(anchor-size(width), 15rem) in CSS).
Accessibility & correctness round 2 (#20, #21)
- APG keyboard models: menubar + context menu navigation, tabs/accordion, roving focus; combobox/command ARIA 1.2 wiring with
aria-activedescendant+ live result counts; command dialog + sheet/drawer real modality (focus trap, scroll lock, focus return, double-open guards); dialog accessible-name wiring; input OTP labelled group + numeric paste filter;aria-sort+ selection/pagination announcements on data table; toast focus-pause + previously-deadon_dismiss:/on_auto_close:callbacks; new tooltip controller (aria-describedby, WCAG 1.4.13 Escape dismiss). - Correctness: Switch ARIA/markup rebuild, attr-clobbering fixes (ThemeToggle, AlertDialogCancel), gemspec cwd-relative glob (foreign-cwd builds were silently empty), select
aria-activedescendantfixes, calendar UTC/frozen-date + spurious-change fixes, CSS.escape'd data-table column keys, ResizablePanel numeric coercion, standalone-require crash fix. - CI rubocop gate is real now (all offenses cleared).
40 Stimulus controllers, 263 tests green. Verified end-to-end in Chrome and WebKit 26.5 (Playwright, trusted input) across all affected gallery pages.
v0.5.1 — button-group composite triggers + UI fixes
Fixes surfaced by a docs-site sweep of the button-group and field pages, plus two new icons.
Fixed
- Button group: corner squaring and shared-edge borders now reach trigger buttons nested inside composite children (DropdownMenu, Popover, HoverCard, Tooltip, Select, Combobox). shadcn's
asChildmerges the trigger onto the button; PhlexKit's wrapper divs were absorbing the group rules, leaving the inner button fully rounded with a doubled border. Nested triggers also lift on focus like direct children, and a direct-child.pk-selectnow hugs its trigger (width: fit-content, shadcn'sselect-trigger:w-fit) instead of stretching to 100%. - Select: the panel is
width: max-contentwithmin-width: 100%— options never wrap, a narrow trigger (e.g. a currency select in a button group) still gets a readable panel, and full-width form selects keep panel = trigger width. - Dropdown menu:
href:items no longer show the UA underline at rest (text-decoration: nonewas only applied on hover/focus; menubar and navigation-menu already had it). - Field: vertical/responsive orientation width coercion (
> * { width: 100%/auto }) no longer crushes fixed-size controls —.pk-switchwas collapsing to a bare thumb circle; switch, checkbox and radio are now excluded.
Added
- Icons:
volume_offanduser_xacross all four libraries (lucide, tabler, phosphor, remix) — used by the rebuilt button-group dropdown example, which now mirrors shadcn's demo with per-row icons. --pk-font-serifbase token (ui-serif, Georgia, …default; the claude theme repoints it) anddocs/07-TOKENS.md, the complete--pk-*token reference. Shortcut keys now read--pk-font-mono.
🤖 Generated with Claude Code
v0.5.0 — full shadcn/ui page parity
Every component page on ui.shadcn.com now has a verified PhlexKit counterpart — the page-parity sweep in PARITY.md is 65/65, audited against the shadcn monorepo's current `nova` style with one commit per page.
Highlights
New part families
- Field — the full presentational vocabulary: FieldSet/FieldLegend/FieldGroup/Field (vertical/horizontal/responsive via container query)/FieldContent/FieldLabel/FieldTitle/FieldDescription/FieldSeparator/FieldError. Pure-CSS choice cards via `:has(input:checked)`. Field is layout; FormField remains the live-validation wrapper — they nest.
- Calendar rebuilt — `mode: :single/:range/:multiple`, booked/disabled dates, min/max, ISO week numbers, `caption_layout: :dropdown` (native month/year selects — no JS lib), `--pk-cell-size`/`--pk-cell-radius` sizing. DatePicker composes every mode with zero changes.
- Sidebar icon rail — `collapsible: :icon` (3rem strip, pure-CSS hover tooltips), SidebarRail grab strip, ⌘B, `pk_sidebar_state` cookie with server-side no-flash restore.
- Menu family completed across context-menu and menubar (Checkbox/Radio items, submenus, shortcuts, destructive); popover Header/Title/Description; button-group orientation + Text/Separator; item sizes/media/Header/Footer; avatar Badge + GroupCount; alert Action; command Shortcut/Separator + pill search; input-group block addons + InputGroupButton; pagination Link/Previous/Next; resizable grip handle; drawer/hover-card/tooltip sides.
Respecs to shadcn's current look
- Form-control grammar unified (input, textarea, select, native-select, OTP, input-group, combobox): translucent dark fills, `--pk-ring` focus, aria-invalid rings with light/dark splits.
- Checkbox, radio and switch fully custom-drawn (appearance:none, masked glyphs, extended touch targets) — replacing the native accent-color controls, still zero JS.
- Badge → solid pill; Button gains xs + icon tiers and the tinted destructive; tooltip inverted with arrow + sides; tabs line variant + vertical; toggle/toggle-group, empty, sheet, dialog (incl. a real footer-band bug fix), table, progress, slider, skeleton, kbd, marker, message, breadcrumb, bubble metrics.
- Overlays unified at nova's `black/10 + blur-xs` with a no-backdrop-filter fallback.
Conventions established (see `.claude/skills/shadcn-parity/SKILL.md`): their `asChild` → `href:`, `data-icon="inline-start/end"` adopted verbatim, dark-first theme forks, `light-dark()` example colors.
Docs: ~200 examples recreated with shadcn's own demo content for side-by-side comparison; interactive message-scroller streaming demos; the chart page now walks their build-a-chart tutorial on Chart.js options.
Suite: 215 runs green on Ruby 3.2–4.0. No new dependencies — still just @hotwired/stimulus.
v0.4.0 — Sidebar offcanvas mode
Sidebar offcanvas mode
PhlexKit::SidebarWrapper.new(collapsible: :offcanvas)— the wrapper becomes thephlex-kit--sidebarStimulus scope and renders a click-to-close scrim.:none(default) is unchanged.- New
PhlexKit::SidebarTrigger— hamburger toggle (:menuicon, block overrides). - Desktop: the rail slides out of the layout (
data-collapsed, transitioned, reduced-motion aware). - Mobile (<768px): fixed overlay drawer behind the scrim (
data-open); closes on scrim click, Escape, andturbo:before-cache(DOM-only state — Turbo page caches always restore closed). - New
sidebar_controller.jsregistered viaregisterPhlexKitControllers; docs example at /docs/sidebar.
v0.3.0
Highlights
-
Colocated component JavaScript (#13) — each component's Stimulus controller now lives in its component folder (
app/components/phlex_kit/<name>/<name>_controller.js), so a component is fully self-contained:.rb+.css+_controller.js. The public JS API is unchanged (import { registerPhlexKitControllers } from "phlex_kit/controllers"and the flat controller module IDs are preserved), so this is a non-breaking restructure. -
One-step, fully-editable component eject (#15) —
rails g phlex_kit:component <name>now ejects the colocated_controller.jstoo, and auto-wiresconfig/application.rb(idempotently) so the ejected Ruby, CSS, and JS all shadow the gem:Rails.autoloaders.main.collapse(Rails.root.join("app/components/phlex_kit/*")) config.assets.paths.unshift(Rails.root.join("app/components"))
Previously only the Ruby shadowed; the CSS/JS silently kept serving the gem's originals.
-
Propshaft + importmap install guide (#14) — a step-by-step, validated walkthrough at
docs/05-PROPSHAFT-INSTALL.md.
Validated end-to-end in a fresh importmap Rails app, in both development and production (precompiled) mode. Suite green (159 runs).
Full changelog: v0.2.2...v0.3.0
v0.2.2
Reframes the gem summary/description: PhlexKit is a shadcn/ui-style component system for Phlex + Rails, no longer described as a ruby_ui port. Also documents booting the docs site with PK_THEME / PK_ICONS in the README. No code changes.
v0.2.1 — docs release
Documentation release — no component changes.
- Rewritten README: install + Stimulus registration, usage examples (form live validation, toast API), the full
--pk-*token surface, the charts host-supplies contract, gallery instructions, and the complete component catalog. Publishing this version puts the new README on rubygems.org. CLAUDE.mdworking-conventions guide for agentic sessions.- ROADMAP: corrected counts (70 families / 123 tests) and a forward-looking Next section.