Skip to content

feat: shadcn UI component enhancements and RadioGroup rewrite#861

Draft
CGQAQ wants to merge 24 commits intomainfrom
feat/shadcn-changes-1
Draft

feat: shadcn UI component enhancements and RadioGroup rewrite#861
CGQAQ wants to merge 24 commits intomainfrom
feat/shadcn-changes-1

Conversation

@CGQAQ
Copy link
Contributor

@CGQAQ CGQAQ commented Feb 14, 2026

Summary

  • RadioGroup rewrite: Rename flutter-shadcn-radio to flutter-shadcn-radio-group to match shadcn/ui convention. Rewrite implementation with manual radio rendering (ShadRadio's InheritedWidget doesn't work in WebF), text extraction pattern for labels, proper hit testing, and CustomEvent dispatch with value detail.
  • Menubar & Cupertino Menu: Add Shadcn Menubar and Cupertino Menu components
  • InputOTP: Add InputOTP component for one-time password input
  • Popover fix: Enhance popover component and fix gesture conflicts
  • Progress enhancement: Add color, height, and radius props to progress component
  • Input improvements: Add ShadInput config fields and textAlign alignment mapping
  • Use-cases updates: Enable all shadcn component demos, fix layout, link local react-shadcn-ui package with prebuild step

Test plan

  • Verify radio group selection works (single selection per group)
  • Verify radio group labels display correctly
  • Verify radio group disabled state
  • Verify radio group change event carries value in detail
  • Verify menubar component renders and functions
  • Verify InputOTP component works
  • Verify popover opens/closes without gesture conflicts
  • Verify progress bar color/height/radius customization
  • Verify shadcn input demo renders correctly
  • Verify all shadcn component demos are accessible

🤖 Generated with Claude Code

@vercel
Copy link

vercel bot commented Feb 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
use-case Error Error Mar 3, 2026 6:50am
vue_usecase Ready Ready Preview, Comment Mar 3, 2026 6:50am

Request Review

@CGQAQ CGQAQ changed the title feat: shadcn input support and use-cases updates feat: shadcn UI component enhancements and RadioGroup rewrite Feb 14, 2026
@CGQAQ CGQAQ force-pushed the feat/shadcn-changes-1 branch from d8a1c1c to 7bb7c2d Compare March 2, 2026 06:57
@CGQAQ CGQAQ force-pushed the feat/shadcn-changes-1 branch from 7bb7c2d to 818cb1e Compare March 2, 2026 07:20
CGQAQ and others added 5 commits March 2, 2026 15:26
Use fixed card width and overflow-x auto for consistent sizing
and proper horizontal scrolling on all screen widths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uncomment previously hidden demos for Input, Select, Slider,
Radio Group, Form, Progress, Skeleton, Tabs, Table, and Popover.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use flex: 1 with minWidth instead of fixed width so cards fill
available space when there are only 2-3 items.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add hidden config to QuickStartItem and set it for Shadcn UI
since shadcn routes are only available in dev mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Input

Expose 10 additional ShadInput properties: textalign, autocapitalize,
autocorrect, enablesuggestions, enterkeyhint, maxlines, minlines,
cursorcolor, selectioncolor, and obscuringcharacter. Also add onSubmitted
support via a new 'submit' event.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CGQAQ and others added 13 commits March 2, 2026 15:26
Run `webf codegen` to regenerate all Dart bindings and produce the
React package at packages/react-shadcn-ui with the new input properties.
Update ShadcnInputPage with demos for text alignment, autocapitalize,
autocorrect, enterkeyhint, multi-line, cursor/selection colors, and
obscuring character.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Map textAlign to ShadInput's alignment and placeholderAlignment
parameters so both typed text and placeholder render correctly
for center and right alignment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unnecessary React.FC<any> cast now that local package
has proper types for all new input properties.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace npm registry dependency with link to local generated
package so new props (textalign, cursorcolor, etc.) are available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On CI, the linked package's dist/ doesn't exist since it's
gitignored. Add a prebuild script to build it before vite build.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CI doesn't have node_modules for the linked package, so
pnpm install is needed before tsdown can run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ShadInputOTP wrapper with group, slot, and separator child elements
following the existing parent-child pattern (radio). Includes TypeScript
definitions, Dart implementation, generated bindings, React wrappers,
and a use_cases demo page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Shadcn UI Menubar component wrapping ShadMenubar/ShadMenubarItem
Flutter widgets with full support for menu items, keyboard shortcuts,
submenus, checkbox items, radio groups, labels, and separators.
Also includes the Cupertino popup menu component from previous work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…icts

## Popover Property Enhancements

Wire up previously declared but unused properties on the popover component:

- **placement**: Add `_placementToAnchor()` conversion that maps placement
  strings (top/bottom/left/right and compound variants like top-start) to
  `ShadAnchorAuto` anchors with correct follower/target alignment
- **align**: Add new `align` property (start/center/end) for fine-grained
  positioning within the placement direction, with attribute binding and
  JS property binding support
- **closeOnOutsideClick**: Pass through to `ShadPopover.closeOnTapOutside`
  (was declared but never wired up)
- **Controller sync**: Add `ShadPopoverController` listener to sync native
  open/close state back to JS when popover is dismissed externally (e.g.
  outside tap)
- **Safety**: Add `mounted` checks in postFrameCallback for controller ops
- **Deprecation**: Fix `Colors.black.withOpacity()` → `.withValues(alpha:)`

## Gesture Arena Fix (popover, dropdown_menu, collapsible)

Replace `GestureDetector` with `Listener` for trigger tap handling in three
components: popover, dropdown_menu, and collapsible.

**Root cause**: When a `GestureDetector` wraps a WebF `WidgetElement`
containing interactive Flutter widgets (e.g. `ShadButton`), the inner
widget's `TapGestureRecognizer` wins the Flutter gesture arena, preventing
the outer `GestureDetector.onTap` from ever firing. This made popover
triggers completely non-functional when using button children.

**Fix**: `Listener` receives raw pointer events at the pointer level without
participating in the gesture arena, so both the outer Listener AND the inner
button receive events. A pointer-distance check (<20px) distinguishes taps
from scroll gestures to avoid false triggers inside scrollable containers.

## React Wrapper Updates

- Add `align` prop with documentation to `FlutterShadcnPopoverProps`
- Update `placement` docs with all supported compound values
- Add `align` to element interface and `attributeProps`

## Use Cases Updates

Add three new demo sections to ShadcnPopoverPage:
- Popover Placement (top/bottom/left/right)
- Popover Alignment (start/center/end)
- Controlled Popover (closeOnOutsideClick={false})

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… and radius props

Add backgroundColor, color, minHeight, and borderRadius properties to the
progress component. Fix the indeterminate variant which was defined but never
wired up in the build method. Update use_cases demo to cover all new properties.
Also fix input_otp maxlength type mismatch after codegen regeneration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… and manual rendering

Rename radio component from `flutter-shadcn-radio`/`flutter-shadcn-radio-item`
to `flutter-shadcn-radio-group`/`flutter-shadcn-radio-group-item` to match
the shadcn/ui naming convention.

Rewrite the implementation to render radio items manually rather than using
ShadRadioGroup/ShadRadio, because ShadRadio relies on ShadProvider
(InheritedWidget) which does not work correctly in WebF's widget tree.

Key changes:

- **Naming**: Renamed all Dart, TypeScript, and React files from `radio` to
  `radio_group`, updated element registrations, exports, and documentation.

- **Manual radio rendering**: Build radio circles manually using theme values
  from `ShadTheme.of(context).radioTheme` to match the visual style of
  ShadRadio (outer ring border + filled inner circle when selected).

- **Text extraction pattern**: Extract label text from child nodes recursively
  (matching the accordion component pattern) instead of using `toWidget()`
  which creates child render objects that interfere with gesture detection
  in WebF's widget tree.

- **Hit testing**: Use `GestureDetector` with `HitTestBehavior.opaque` to
  ensure taps register on the entire radio row, since DecoratedBox/SizedBox
  don't participate in hit testing by default.

- **CustomEvent dispatch**: Dispatch `CustomEvent('change', detail: {'value': itemValue})`
  instead of plain `Event('change')` so React handlers can read
  `e.detail.value` (consistent with select/calendar components).

- **Recursive item search**: `_getRadioItems()` recursively walks child nodes
  to find `FlutterShadcnRadioGroupItem` descendants, supporting arbitrary
  DOM nesting between parent and items.

- **Fallback value resolution**: Added `_resolveItemValue()` that tries
  `_itemValue`, then `getAttribute('value')`, with a final fallback to
  lowercase label text when no explicit value is set.

- **Use case updates**: Simplified ShadcnRadioPage.tsx to use the new
  component names with labels inside items. Updated BasicFormElementsPage
  with input event fallback for native radio controls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CGQAQ added 3 commits March 2, 2026 18:13
Root cause:
- shadcn_ui paints the secondary focused border outward with offset; in WebF this can overflow/clipped at left/right edges.
- our first mitigation removed the outward border, but focus border visibility/radius handling needed refinement.

Changes:
- input wrappers: apply bounded focus decoration in Flutter wrappers for ShadInput/ShadInputFormField.
  - disable secondary outward border (disableSecondaryBorder: true)
  - use focusedBorder with width: 1 so the focus outline remains visible
  - reuse theme input border radius so outline corners match field corners
  - files: input.dart, textarea.dart, form.dart
- theme config: add outline color override at theme level.
  - new attribute: outline-color on <flutter-shadcn-theme>
  - parse #RRGGBB/#AARRGGBB and override ShadColorScheme.ring via copyWith
  - files: theme.d.ts, theme.dart, theme_bindings_generated.dart
- use case: add Outline Color demo section in ShadcnInputPage showing red/blue outline via FlutterShadcnTheme outlineColor.

Result:
- focus outline stays inside bounds (no side overflow)
- focus outline remains visible
- outline corners match input radius
- outline color is now explicitly configurable from theme
…emented

Adds the missing generated typing/binding layer for the existing shadcn menubar
component and updates package docs/status to reflect support.

What changed:
- add `lib/src/components/menubar.d.ts`
  - declares menubar element/property/event interfaces for:
    - menubar root/menu/trigger/content
    - item/separator/label
    - sub/sub-trigger/sub-content
    - checkbox-item/radio-group/radio-item
- add `lib/src/components/menubar_bindings_generated.dart`
  - generated Dart bindings for `FlutterShadcnMenubarBindings`
- update `lib/src/components/menubar.dart`
  - import generated bindings
  - change `FlutterShadcnMenubar` to extend `FlutterShadcnMenubarBindings`
- update `README.md`
  - list `<flutter-shadcn-menubar>` under navigation components
- update `IMPLEMENTATION_STATUS.md`
  - mark Menubar as implemented
  - add menubar slot elements to implemented list
  - remove obsolete "Add Menubar component" optional enhancement item

Scope note:
- this commit intentionally includes only menubar-related source and docs.
Popover fixes:

- Keep trigger and content wrappers as inline-block so overlays anchor to visible controls instead of stretching to full row width.

- Add responsive max width and wrapping behavior for popover content to prevent text overflow on narrow screens.

Tooltip fixes:

- Implement placement mapping (top/bottom/left/right) to explicit ShadAnchorAuto anchors.

- Add controller-driven tap/hover handling in the native wrapper so tooltips work reliably for inline text and mobile tap interactions.

Use case updates:

- Replace tooltip demo prop usage from side to placement to match the wrapper API.

- Rework the popover placement demo to a centered single-trigger preview with selectable placement buttons.

- Improve Tooltip in Context with clearer copy and explicit mobile-friendly trigger examples.
CGQAQ added 3 commits March 3, 2026 12:35
Native tooltip wrapper:

- Replace ShadTooltip usage with ShadPopover-backed rendering to avoid bottom-placement close races.

- Keep explicit pointer/controller handling for reliable mobile tap interactions.

- Guard mouse-exit auto-close when tooltip is opened by tap.

Use case updates:

- Rework Tooltip Positions into a single centered preview with placement selector controls.

- Keep placement API consistent with wrapper behavior for easier verification on mobile.
Root cause:

- Bottom placement was uniquely unstable due to auto-position/hover timing interactions; the first hover could close or fail before the overlay stabilized.

- Wrapper-level custom pointer logic combined with tooltip internals made this race observable primarily on bottom-first interactions.

Component changes (native wrapper):

- Reworked tooltip rendering to use ShadPopover with an explicit controller for deterministic open/close behavior.

- Replaced auto anchors with explicit ShadAnchor mappings for top/bottom/left/right to avoid bottom-specific auto-position edge cases.

- Added explicit hover/tap trigger handling, hide scheduling, and a minimum visible guard to prevent immediate close during initial placement.

Use-case updates:

- Kept Tooltip Positions demo aligned with wrapper behavior using explicit placement selection and immediate show settings for verification.

- Preserves mobile/desktop validation path while making bottom-first reproduction and testing reliable.
Add explicit preflight instructions for shadcn_ui-related work in the webf-native-ui-dev skill.

Changes:

- Introduce a dedicated 'Preflight (Required for shadcn_ui work)' section in the workflow.

- Require reviewing the upstream shadcn_ui references before implementation work begins.

- Add the same links to the Resources section for quick access and long-term discoverability.

Why:

- Aligns wrapper implementation decisions with upstream shadcn_ui behavior and API expectations.

- Reduces regressions caused by local assumptions that differ from documented component semantics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant