Skip to content

Releases: MatthewKennedy/phlex_kit

v0.7.0 — DropdownMenu side: left/right + create-page shadcn parity

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 06 Jul 17:41
8497890

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 a flip-inline viewport fallback, mirroring shadcn's side prop. 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

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 06 Jul 14:36
857be4d

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

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 06 Jul 14:10
bb67f9b

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, Canvas background) showing through the unstyled outer wrapper. The wrappers now reset the UA chrome.
  • All popover panels: closed-state hiding now survives author display values (:not(:popover-open) { display: none } guard). Previously a host class like display: grid on 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

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 06 Jul 13:10
96129df

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-fallbacks flips 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: hidden ancestors (the Radix-portal equivalent); stacking z-index hacks are gone.
  • Less JavaScript: popover/dropdown/select/combobox get native or simplified dismiss handling; combobox's updatePopoverWidth() + resize listener are deleted outright (anchor-size(width) in CSS); context menus clamp to the viewport.
  • Tooltip keeps its pure-CSS :hover/:focus-within reveal, 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-dead on_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-activedescendant fixes, 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

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 05 Jul 22:51
d29e7a1

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 asChild merges 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-select now hugs its trigger (width: fit-content, shadcn's select-trigger:w-fit) instead of stretching to 100%.
  • Select: the panel is width: max-content with min-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: none was 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-switch was collapsing to a bare thumb circle; switch, checkbox and radio are now excluded.

Added

  • Icons: volume_off and user_x across 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-serif base token (ui-serif, Georgia, … default; the claude theme repoints it) and docs/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

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 05 Jul 21:53
cc96e2f

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

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 04 Jul 23:20
3e048ca

Sidebar offcanvas mode

  • PhlexKit::SidebarWrapper.new(collapsible: :offcanvas) — the wrapper becomes the phlex-kit--sidebar Stimulus scope and renders a click-to-close scrim. :none (default) is unchanged.
  • New PhlexKit::SidebarTrigger — hamburger toggle (:menu icon, 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, and turbo:before-cache (DOM-only state — Turbo page caches always restore closed).
  • New sidebar_controller.js registered via registerPhlexKitControllers; docs example at /docs/sidebar.

v0.3.0

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 03 Jul 21:51
f4c4218

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.js too, and auto-wires config/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

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 03 Jul 19:43
bdc061e

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

Choose a tag to compare

@MatthewKennedy MatthewKennedy released this 02 Jul 23:28
252fd90

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.md working-conventions guide for agentic sessions.
  • ROADMAP: corrected counts (70 families / 123 tests) and a forward-looking Next section.