Skip to content

feat(floating-actions): add FloatingActions component#745

Open
paanSinghCoder wants to merge 12 commits intomainfrom
feat/floating-actions
Open

feat(floating-actions): add FloatingActions component#745
paanSinghCoder wants to merge 12 commits intomainfrom
feat/floating-actions

Conversation

@paanSinghCoder
Copy link
Copy Markdown
Contributor

@paanSinghCoder paanSinghCoder commented Apr 20, 2026

Summary

  • New FloatingActions component — a contextual action bar (bulk-action toolbar, row-hover actions) built on Base UI's Toolbar primitive, so it inherits roving focus, arrow-key navigation, and the disabled cascade.
  • Two layout modes via variant: floating (default — position: fixed, anchored via side/align, defaults to bottom-center) and inline (in-flow). No positioning CSS at the call site.
  • Ships FloatingActions.Group and FloatingActions.Separator. Composes with existing Chip, Button, IconButton. Docs cover variants, grouped actions, icon-only, and a scrolling-context demo; Vitest suite + playground wired up.

Usage

<FloatingActions aria-label="Selection actions">
  <Chip isDismissible leadingIcon={<CheckCircledIcon />}>2 selected</Chip>
  <FloatingActions.Separator />
  <Button variant="outline" color="neutral" size="small">Move to</Button>
</FloatingActions>

Test plan

  • pnpm --filter @raystack/apsara test components/floating-actions
  • Docs site renders the variants, grouped actions, icon-only, and scrolling-context demos

🤖 Generated with Claude Code

A floating bar for surfacing contextual actions (bulk-action toolbar,
row hover actions, etc.). Position-agnostic visual primitive with a
matching vertical separator; composes freely with existing Chip, Button,
and IconButton.

- Component source, styles (--rs-shadow-lifted), and tests
- Docs page with preview, bulk-actions, and icon-only demos
- Playground example and examples/page.tsx section

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 20, 2026

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

Project Deployment Actions Updated (UTC)
apsara Ready Ready Preview, Comment Apr 27, 2026 8:10am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 20, 2026

Warning

Rate limit exceeded

@paanSinghCoder has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 32 minutes and 23 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d0737cea-5d9c-4e4a-b3f7-01ce84ca49e4

📥 Commits

Reviewing files that changed from the base of the PR and between a5d1afa and 8c57a4f.

📒 Files selected for processing (4)
  • apps/www/src/content/docs/components/floating-actions/demo.ts
  • apps/www/src/content/docs/components/floating-actions/index.mdx
  • apps/www/src/content/docs/components/floating-actions/props.ts
  • packages/raystack/components/floating-actions/floating-actions.tsx
📝 Walkthrough

Walkthrough

Adds a new FloatingActions UI component and exports it from the raystack package. Changes include: a Root component with variant, side, and align props; Group and Separator subcomponents; TypeScript prop interfaces; CSS module styles for floating/inline positioning; unit tests; documentation (MDX, props, and multiple demo code previews); playground examples and a playground re-export; demo scope update to include CheckCircledIcon; and public exports wired through package entrypoints and the www playground index.

Suggested reviewers

  • rsbh
  • rohanchkrabrty
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(floating-actions): add FloatingActions component' directly and clearly describes the main changeset—the introduction of a new FloatingActions component with all its supporting infrastructure.
Description check ✅ Passed The description is well-structured and comprehensively covers the changeset, detailing the component's purpose, variant modes, composition, documentation, tests, usage examples, and test plan.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/www/src/app/examples/page.tsx`:
- Around line 2818-2831: The IconButton components inside the FloatingActions
(the icon-only row actions using IconButton with GearIcon, FileTextIcon, and
DotsHorizontalIcon) lack accessible names; update each IconButton to provide an
accessible label (e.g., add an aria-label or aria-labelledby with a clear short
name like "Settings", "View file", "More actions") so screen readers can
identify them, or alternatively include visually hidden text inside the button
and keep the icons for visual users; ensure you update all three IconButton
instances (the ones wrapping GearIcon, FileTextIcon, and DotsHorizontalIcon).

In `@apps/www/src/content/docs/components/floating-actions/demo.ts`:
- Around line 42-47: The IconButton instances inside the FloatingActions demo
lack accessible names; update each icon-only IconButton (the IconButton
components wrapping Pencil2Icon, UploadIcon, and InfoCircledIcon) to provide
accessible labels—e.g., add an aria-label prop or include visually hidden text
describing the action like "Edit", "Upload", and "More info"—so screen readers
can announce their purpose; leave FloatingActions.Separator as-is.

In `@apps/www/src/content/docs/components/floating-actions/props.ts`:
- Around line 1-18: Update the docs types to match the implementation by
importing React types and extending the div passthrough API: add an import for
React (so React.ComponentProps and React.ReactNode are available) and change
FloatingActionsProps to extend React.ComponentProps<'div'> (keeping or removing
explicit props like children if desired) and change
FloatingActionsSeparatorProps to extend React.ComponentProps<'div'> so all
native div attributes (aria-*, data-*, event handlers, style, ref, etc.) are
supported; update references to FloatingActionsProps and
FloatingActionsSeparatorProps accordingly.

In
`@packages/raystack/components/floating-actions/__tests__/floating-actions.test.tsx`:
- Around line 43-75: The Separator component currently allows callers to
override aria-hidden because props are spread after the hardcoded attribute;
update the FloatingActions.Separator implementation in floating-actions.tsx to
spread {...props} first and then set aria-hidden="true" (so the hardcoded value
wins), and add/keep a regression test in floating-actions.test.tsx that renders
<FloatingActions.Separator aria-hidden="false" data-testid="sep"> and asserts
the element has aria-hidden="true"; reference the FloatingActions.Separator
component and ensure ref forwarding and className tests still pass.

In `@packages/raystack/components/floating-actions/floating-actions.tsx`:
- Around line 24-28: The separator div in floating-actions.tsx currently spreads
{...props} after setting aria-hidden='true', allowing callers to override it;
fix by ensuring aria-hidden stays true when props are forwarded—either move
{...props} before aria-hidden or (preferable) keep {...props} but explicitly set
aria-hidden={true} after the spread on the same div (the element using
className={cx(styles.separator, className)}), so aria-hidden cannot be
overridden by incoming props.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e00c87d3-cd54-40ca-bfcf-9b26aff31d29

📥 Commits

Reviewing files that changed from the base of the PR and between 4ccb30c and cbbd2c8.

📒 Files selected for processing (11)
  • apps/www/src/app/examples/page.tsx
  • apps/www/src/components/playground/floating-actions-examples.tsx
  • apps/www/src/components/playground/index.ts
  • apps/www/src/content/docs/components/floating-actions/demo.ts
  • apps/www/src/content/docs/components/floating-actions/index.mdx
  • apps/www/src/content/docs/components/floating-actions/props.ts
  • packages/raystack/components/floating-actions/__tests__/floating-actions.test.tsx
  • packages/raystack/components/floating-actions/floating-actions.module.css
  • packages/raystack/components/floating-actions/floating-actions.tsx
  • packages/raystack/components/floating-actions/index.tsx
  • packages/raystack/index.tsx

Comment thread apps/www/src/app/examples/page.tsx Outdated
Comment thread apps/www/src/content/docs/components/floating-actions/demo.ts Outdated
Comment on lines +1 to +18
export interface FloatingActionsProps {
/**
* The ARIA role of the container.
* @defaultValue "toolbar"
*/
role?: string;

/** Additional CSS class names. */
className?: string;

/** The contents of the floating bar. */
children?: React.ReactNode;
}

export interface FloatingActionsSeparatorProps {
/** Additional CSS class names. */
className?: string;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Compare FloatingActions docs props against implementation/docs prop typing patterns.
# Expected: implementation uses div passthrough props; docs should either mirror that or intentionally document native props elsewhere.

rg -n -C3 "FloatingActionsProps|FloatingActionsSeparatorProps|ComponentProps<'div'>|React\\.ReactNode" \
  packages/raystack/components/floating-actions \
  apps/www/src/content/docs/components/floating-actions

Repository: raystack/apsara

Length of output: 4739


🏁 Script executed:

# Check for docs generator behavior with inherited props
find apps/www -type f -name "*.ts" -o -name "*.tsx" -o -name "*.js" | xargs grep -l "auto-type-table\|type-table" | head -5

Repository: raystack/apsara

Length of output: 105


🏁 Script executed:

# Find other components using ComponentProps<'div'> in docs to see if there's a pattern
fd -e "props.ts" "apps/www/src/content/docs/components" | head -10

Repository: raystack/apsara

Length of output: 508


🏁 Script executed:

# Check if React is imported in the docs props file
head -20 apps/www/src/content/docs/components/floating-actions/props.ts

Repository: raystack/apsara

Length of output: 440


🏁 Script executed:

# Look for an implementation pattern in other components that use ComponentProps<'div'>
find packages/raystack/components -type f -name "*.tsx" -exec grep -l "extends ComponentProps<'div'>" {} \; | head -3

Repository: raystack/apsara

Length of output: 453


🏁 Script executed:

# Check other component docs props files for import patterns
ls apps/www/src/content/docs/components/*/props.ts | head -5 | xargs head -3

Repository: raystack/apsara

Length of output: 832


🏁 Script executed:

# Check if any docs props files import React or ComponentProps
grep -r "^import\|^export interface" apps/www/src/content/docs/components/*/props.ts | head -20

Repository: raystack/apsara

Length of output: 1991


🏁 Script executed:

# Check the auto-type-table implementation in mdx-components
grep -A 20 "auto-type-table" apps/www/src/components/mdx/mdx-components.tsx | head -40

Repository: raystack/apsara

Length of output: 41


🏁 Script executed:

# Check tsconfig for global React types
find . -name "tsconfig.json" -o -name "tsconfig.*.json" | xargs grep -l "React\|types" | head -3

Repository: raystack/apsara

Length of output: 156


🏁 Script executed:

# Check tsconfig for global React types
cat apps/www/tsconfig.json | grep -A 5 -B 5 "React\|types\|skipLibCheck"

Repository: raystack/apsara

Length of output: 530


🏁 Script executed:

# Check the actual implementation interfaces more carefully
cat -n packages/raystack/components/floating-actions/floating-actions.tsx | head -30

Repository: raystack/apsara

Length of output: 1083


🏁 Script executed:

# Check if floating-actions docs props.ts actually compiles (check for any import)
cat -n apps/www/src/content/docs/components/floating-actions/props.ts

Repository: raystack/apsara

Length of output: 566


🏁 Script executed:

# Look at breadcrumb props.ts (which has imports) for comparison
cat -n apps/www/src/content/docs/components/breadcrumb/props.ts | head -30

Repository: raystack/apsara

Length of output: 1050


Align the docs props with the implementation's div passthrough API.

The implementation extends ComponentProps<'div'> and spreads all props, but the docs interface is a manual subset listing only role, className, and children. This hides the supported native div attributes (aria-, data-, event handlers, style, ref, etc.). Also, the docs file uses React.ReactNode without importing React, which is inconsistent with other component docs files like breadcrumb.

Import React types explicitly and extend ComponentProps<'div'> in both interfaces to match the implementation:

📝 Proposed docs type update
+import type { ComponentProps } from 'react';
+
-export interface FloatingActionsProps {
+export interface FloatingActionsProps extends ComponentProps<'div'> {
   /**
    * The ARIA role of the container.
    * `@defaultValue` "toolbar"
    */
-  role?: string;

   /** Additional CSS class names. */
-  className?: string;

   /** The contents of the floating bar. */
-  children?: React.ReactNode;
 }

-export interface FloatingActionsSeparatorProps {
+export interface FloatingActionsSeparatorProps extends ComponentProps<'div'> {
   /** Additional CSS class names. */
-  className?: string;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/src/content/docs/components/floating-actions/props.ts` around lines
1 - 18, Update the docs types to match the implementation by importing React
types and extending the div passthrough API: add an import for React (so
React.ComponentProps and React.ReactNode are available) and change
FloatingActionsProps to extend React.ComponentProps<'div'> (keeping or removing
explicit props like children if desired) and change
FloatingActionsSeparatorProps to extend React.ComponentProps<'div'> so all
native div attributes (aria-*, data-*, event handlers, style, ref, etc.) are
supported; update references to FloatingActionsProps and
FloatingActionsSeparatorProps accordingly.

Comment on lines +43 to +75
it('renders a separator with the separator class', () => {
render(
<FloatingActions>
<FloatingActions.Separator data-testid='sep' />
</FloatingActions>
);
const sep = screen.getByTestId('sep');
expect(sep).toBeInTheDocument();
expect(sep.className).toContain(styles.separator);
expect(sep).toHaveAttribute('aria-hidden', 'true');
});

it('applies custom className', () => {
render(
<FloatingActions>
<FloatingActions.Separator data-testid='sep' className='custom-sep' />
</FloatingActions>
);
const sep = screen.getByTestId('sep');
expect(sep.className).toContain(styles.separator);
expect(sep.className).toContain('custom-sep');
});

it('forwards ref', () => {
const ref = createRef<HTMLDivElement>();
render(
<FloatingActions>
<FloatingActions.Separator ref={ref} data-testid='sep' />
</FloatingActions>
);
expect(ref.current).toBeInstanceOf(HTMLDivElement);
expect(ref.current).toBe(screen.getByTestId('sep'));
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Lock the separator’s decorative accessibility contract.

The current implementation can let callers override aria-hidden because props are spread after the hardcoded value. Add a regression test here and move aria-hidden='true' after {...props} in floating-actions.tsx.

♿ Proposed regression test and implementation adjustment
     it('renders a separator with the separator class', () => {
       render(
         <FloatingActions>
           <FloatingActions.Separator data-testid='sep' />
         </FloatingActions>
@@
       expect(sep.className).toContain(styles.separator);
       expect(sep).toHaveAttribute('aria-hidden', 'true');
     });
+
+    it('keeps the separator hidden from assistive technology', () => {
+      render(
+        <FloatingActions>
+          <FloatingActions.Separator data-testid='sep' aria-hidden={false} />
+        </FloatingActions>
+      );
+
+      expect(screen.getByTestId('sep')).toHaveAttribute('aria-hidden', 'true');
+    });

Apply this in packages/raystack/components/floating-actions/floating-actions.tsx:

   <div
-    aria-hidden='true'
     className={cx(styles.separator, className)}
     {...props}
+    aria-hidden='true'
   />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it('renders a separator with the separator class', () => {
render(
<FloatingActions>
<FloatingActions.Separator data-testid='sep' />
</FloatingActions>
);
const sep = screen.getByTestId('sep');
expect(sep).toBeInTheDocument();
expect(sep.className).toContain(styles.separator);
expect(sep).toHaveAttribute('aria-hidden', 'true');
});
it('applies custom className', () => {
render(
<FloatingActions>
<FloatingActions.Separator data-testid='sep' className='custom-sep' />
</FloatingActions>
);
const sep = screen.getByTestId('sep');
expect(sep.className).toContain(styles.separator);
expect(sep.className).toContain('custom-sep');
});
it('forwards ref', () => {
const ref = createRef<HTMLDivElement>();
render(
<FloatingActions>
<FloatingActions.Separator ref={ref} data-testid='sep' />
</FloatingActions>
);
expect(ref.current).toBeInstanceOf(HTMLDivElement);
expect(ref.current).toBe(screen.getByTestId('sep'));
});
it('renders a separator with the separator class', () => {
render(
<FloatingActions>
<FloatingActions.Separator data-testid='sep' />
</FloatingActions>
);
const sep = screen.getByTestId('sep');
expect(sep).toBeInTheDocument();
expect(sep.className).toContain(styles.separator);
expect(sep).toHaveAttribute('aria-hidden', 'true');
});
it('keeps the separator hidden from assistive technology', () => {
render(
<FloatingActions>
<FloatingActions.Separator data-testid='sep' aria-hidden={false} />
</FloatingActions>
);
expect(screen.getByTestId('sep')).toHaveAttribute('aria-hidden', 'true');
});
it('applies custom className', () => {
render(
<FloatingActions>
<FloatingActions.Separator data-testid='sep' className='custom-sep' />
</FloatingActions>
);
const sep = screen.getByTestId('sep');
expect(sep.className).toContain(styles.separator);
expect(sep.className).toContain('custom-sep');
});
it('forwards ref', () => {
const ref = createRef<HTMLDivElement>();
render(
<FloatingActions>
<FloatingActions.Separator ref={ref} data-testid='sep' />
</FloatingActions>
);
expect(ref.current).toBeInstanceOf(HTMLDivElement);
expect(ref.current).toBe(screen.getByTestId('sep'));
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/raystack/components/floating-actions/__tests__/floating-actions.test.tsx`
around lines 43 - 75, The Separator component currently allows callers to
override aria-hidden because props are spread after the hardcoded attribute;
update the FloatingActions.Separator implementation in floating-actions.tsx to
spread {...props} first and then set aria-hidden="true" (so the hardcoded value
wins), and add/keep a regression test in floating-actions.test.tsx that renders
<FloatingActions.Separator aria-hidden="false" data-testid="sep"> and asserts
the element has aria-hidden="true"; reference the FloatingActions.Separator
component and ensure ref forwarding and className tests still pass.

Comment on lines +24 to +28
<div
aria-hidden='true'
className={cx(styles.separator, className)}
{...props}
/>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Keep the separator hidden even when props are forwarded.

Because {...props} is applied after aria-hidden, a caller can override it with aria-hidden={false}, which breaks the documented separator semantics.

🛡️ Proposed fix
   <div
-    aria-hidden='true'
-    className={cx(styles.separator, className)}
     {...props}
+    aria-hidden='true'
+    className={cx(styles.separator, className)}
   />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div
aria-hidden='true'
className={cx(styles.separator, className)}
{...props}
/>
<div
{...props}
aria-hidden='true'
className={cx(styles.separator, className)}
/>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/raystack/components/floating-actions/floating-actions.tsx` around
lines 24 - 28, The separator div in floating-actions.tsx currently spreads
{...props} after setting aria-hidden='true', allowing callers to override it;
fix by ensuring aria-hidden stays true when props are forwarded—either move
{...props} before aria-hidden or (preferable) keep {...props} but explicitly set
aria-hidden={true} after the spread on the same div (the element using
className={cx(styles.separator, className)}), so aria-hidden cannot be
overridden by incoming props.

@paanSinghCoder paanSinghCoder requested a review from rsbh April 20, 2026 10:44
Keep the component, docs, and playground — the examples/page.tsx
scratch page is out of scope for this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
FloatingActions.Separator now wraps `Separator` from the design system
with `orientation="vertical"` and `size="full"` defaults, instead of
re-implementing a local 1px×16px div. Drops the local `.separator`
CSS class and picks up proper `role="separator"` semantics, size/color
variants, and Base UI behavior for free.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The floating bar is horizontal-only, so the separator is always
vertical. `Omit<..., 'orientation'>` from the prop type and drop the
unused horizontal CSS rule. Scoped `.separator` class overrides the
Separator primitive's size variant to --rs-space-5 per the Figma spec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@rohanchkrabrty rohanchkrabrty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. IMO the FloatingActions component should have position agnostic props, like side and align.

There can be two variants - inline and floating(default), inline will be the current one. But in floating the FloatingAction will be actually floating using the side and align position props.

Right now consumer has to write a a block of css just to use this component. The name also is FloatingActions but nowhere it supports that functionality, so it's misleading.

  1. I think it should also support orientation for cases where the component is used on the left or right. But this is can be picked up later too

Comment on lines +36 to +38
export const FloatingActions = Object.assign(FloatingActionsRoot, {
Separator: FloatingActionsSeparator
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split the object assign into a separate file or do it in index.ts

This pattern with client directive creates some weird client/server issues

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to index.tsx keeping same export pattern as other components.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File name should be index.ts for barrel export

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

role = 'toolbar',
...props
}: FloatingActionsProps) => (
<div role={role} className={cx(styles.root, className)} {...props} />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let' use Toolbar Primitive from Base UI.

Also let's expose a Group subcomponent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Using the Base UI primitive. Also exposed the Group.


## Anatomy

Compose the bar from existing Apsara primitives. `FloatingActions` provides the container and a matching vertical separator; everything inside is freely composable.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a simpler line like - Import and assemble the component along with other primtives

Follows other docs pattern

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

children?: React.ReactNode;
}

export interface FloatingActionsSeparatorProps {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Separator props should be documented especially color


### Separator

A vertical divider sized to the bar's content.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mention that it's built on top of Separator component

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to the docs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no demo where the component is seen in a scrolling context.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Introduce variant, side, and align props so the component owns its
positioning instead of pushing it onto consumers. Floating is the
default and pins the bar to the viewport via position: fixed,
mirroring Toast's data-position pattern. Inline preserves the prior
in-flow behaviour for embedded contexts (cards, tables, docs demos).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Replace hand-rolled <div role="toolbar"> with Base UI Toolbar primitive
  to inherit roving focus, arrow-key navigation, and disabled cascade.
- Expose FloatingActions.Group wrapping Toolbar.Group.
- Move Object.assign out of the 'use client' file into a non-client
  index.ts (matches Field/Sidebar precedent), avoiding client/server
  boundary issues. Rename index.tsx -> index.ts (no JSX).
- Trim Anatomy intro to the standard "Import and assemble the
  component:" line used by peer docs.
- Document Separator's size and render props, and the Toolbar
  primitive props (disabled, orientation, loopFocus) on Root.
- Add a scrolling-context demo using transform: translateZ(0) so the
  floating bar is scoped to the demo container instead of the page.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
packages/raystack/components/floating-actions/__tests__/floating-actions.test.tsx (2)

27-31: Test name doesn't match its assertions.

The test is titled "renders the inline variant without floating positioning attributes" but only asserts data-variant='inline'. To match the title (and provide actual coverage for the inline behavior), assert the absence of floating-only positioning side-effects or rename the test to something like applies data-variant="inline" when variant="inline".

♻️ Suggested tightening
 it('renders the inline variant without floating positioning attributes', () => {
   render(<FloatingActions variant='inline'>content</FloatingActions>);
   const root = screen.getByRole('toolbar');
   expect(root).toHaveAttribute('data-variant', 'inline');
+  // Inline variant should not be position: fixed; data-side/data-align are
+  // documented as floating-only and should not influence layout here.
+  expect(getComputedStyle(root).position).not.toBe('fixed');
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/raystack/components/floating-actions/__tests__/floating-actions.test.tsx`
around lines 27 - 31, The test title and assertions are inconsistent: update the
test in floating-actions.test.tsx for the FloatingActions component so it either
(A) renames the spec to "applies data-variant=\"inline\" when
variant=\"inline\"" to match the existing assertion for data-variant, or (B)
keep the current title and add assertions that verify inline does not apply
floating positioning (for example, assert the toolbar returned by
getByRole('toolbar') does not have floating-only attributes/classes such as a
data-floating attribute, a CSS class like 'floating', or a computed style
position of 'fixed' or 'absolute'). Choose one approach and apply it to the test
containing the render(<FloatingActions variant='inline'>...) and the
expect(root)... assertion.

87-99: Color prop not actually asserted.

The test name promises pass-through of both color and className, but only custom-sep is verified. Consider asserting the color variant class (or at least that the rendered element carries the corresponding Separator color class) so a regression in color forwarding is caught.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/raystack/components/floating-actions/__tests__/floating-actions.test.tsx`
around lines 87 - 99, The test for FloatingActions.Separator only asserts
className forwarding but not color forwarding; update the spec in
floating-actions.test.tsx to also assert that the rendered separator reflects
the color='secondary' prop by checking for the Separator's color variant (e.g.,
expect(sep.className).toContain the Separator's secondary color class or expect
a data-attribute/style that indicates 'secondary'), targeting
FloatingActions.Separator in the existing test so both color and className
pass-through are verified.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/www/src/content/docs/components/floating-actions/index.mdx`:
- Line 92: Update the documentation sentence that currently states the separator
renders with role="separator" and aria-orientation="vertical" so it accurately
reflects the Base UI primitive output: change the description to say it emits
role="separator" and data-orientation="vertical" (i.e., replace
aria-orientation="vertical" with data-orientation="vertical" in the separator
description).
- Around line 8-10: The page currently reuses the same demo export `preview` for
both the hero and inline sections, so create a distinct `inlineDemo` export in
demo.ts (clone or adapt from the existing `preview` but set variant="inline" and
any inline-specific props) and export it alongside `floatingDemo`/`preview`;
then update the MDX to render the hero with `preview` or `floatingDemo` and the
inline section with `<Demo data={inlineDemo} />` so the floating and inline
variants are different.

In `@packages/raystack/components/floating-actions/floating-actions.tsx`:
- Around line 1-6: The code uses React.ComponentProps<typeof Separator> but
never imports React; add an explicit import of ComponentProps from 'react'
(e.g., import { ComponentProps } from 'react') and update the type usage to use
ComponentProps<typeof Separator> where referenced (the type on/around the
FloatingActions props definition that currently uses React.ComponentProps<typeof
Separator>) so the file no longer depends on the global React namespace and
matches the package's peer components.

---

Nitpick comments:
In
`@packages/raystack/components/floating-actions/__tests__/floating-actions.test.tsx`:
- Around line 27-31: The test title and assertions are inconsistent: update the
test in floating-actions.test.tsx for the FloatingActions component so it either
(A) renames the spec to "applies data-variant=\"inline\" when
variant=\"inline\"" to match the existing assertion for data-variant, or (B)
keep the current title and add assertions that verify inline does not apply
floating positioning (for example, assert the toolbar returned by
getByRole('toolbar') does not have floating-only attributes/classes such as a
data-floating attribute, a CSS class like 'floating', or a computed style
position of 'fixed' or 'absolute'). Choose one approach and apply it to the test
containing the render(<FloatingActions variant='inline'>...) and the
expect(root)... assertion.
- Around line 87-99: The test for FloatingActions.Separator only asserts
className forwarding but not color forwarding; update the spec in
floating-actions.test.tsx to also assert that the rendered separator reflects
the color='secondary' prop by checking for the Separator's color variant (e.g.,
expect(sep.className).toContain the Separator's secondary color class or expect
a data-attribute/style that indicates 'secondary'), targeting
FloatingActions.Separator in the existing test so both color and className
pass-through are verified.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1329785d-07f0-4724-a138-ae458c095ac5

📥 Commits

Reviewing files that changed from the base of the PR and between cbbd2c8 and cd9bba9.

📒 Files selected for processing (9)
  • apps/www/src/components/demo/demo.tsx
  • apps/www/src/components/playground/floating-actions-examples.tsx
  • apps/www/src/content/docs/components/floating-actions/demo.ts
  • apps/www/src/content/docs/components/floating-actions/index.mdx
  • apps/www/src/content/docs/components/floating-actions/props.ts
  • packages/raystack/components/floating-actions/__tests__/floating-actions.test.tsx
  • packages/raystack/components/floating-actions/floating-actions.module.css
  • packages/raystack/components/floating-actions/floating-actions.tsx
  • packages/raystack/components/floating-actions/index.ts
✅ Files skipped from review due to trivial changes (3)
  • apps/www/src/components/demo/demo.tsx
  • packages/raystack/components/floating-actions/index.ts
  • packages/raystack/components/floating-actions/floating-actions.module.css
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/www/src/components/playground/floating-actions-examples.tsx
  • apps/www/src/content/docs/components/floating-actions/demo.ts

Comment thread apps/www/src/content/docs/components/floating-actions/index.mdx Outdated
## Accessibility

- The root uses `role="toolbar"` (enforced by the Base UI Toolbar primitive) and is announced as a group of interactive controls. Keyboard focus moves between toolbar items with the arrow keys.
- The separator renders with `role="separator"` and `aria-orientation="vertical"` via the Base UI primitive, communicating structural grouping between action clusters.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Does Base UI @base-ui/react Separator primitive emit aria-orientation attribute when orientation="vertical"?

💡 Result:

No, the Base UI @base-ui/react Separator primitive does not emit the aria-orientation attribute when orientation="vertical". It emits data-orientation="vertical" instead, along with role="separator" on a div element. This follows ARIA practices where aria-orientation is only required for vertical separators if not using the hr element (which Base UI does not), but official docs and sources confirm data-orientation for styling/selectors, not aria-orientation. Secondary docs and CSS examples referencing [aria-orientation="vertical"] appear to be incorrect or illustrative.

Citations:


Update the documentation to reflect that the separator emits data-orientation="vertical", not aria-orientation="vertical".

The Base UI Separator primitive does not emit aria-orientation. It emits data-orientation="vertical" along with role="separator". Update line 92 to accurately describe the actual rendered attributes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/src/content/docs/components/floating-actions/index.mdx` at line 92,
Update the documentation sentence that currently states the separator renders
with role="separator" and aria-orientation="vertical" so it accurately reflects
the Base UI primitive output: change the description to say it emits
role="separator" and data-orientation="vertical" (i.e., replace
aria-orientation="vertical" with data-orientation="vertical" in the separator
description).

Comment on lines +1 to +6
'use client';

import { Toolbar as ToolbarPrimitive } from '@base-ui/react/toolbar';
import { cx } from 'class-variance-authority';
import { Separator } from '../separator';
import styles from './floating-actions.module.css';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm whether React is imported anywhere in the file and how peers in the package handle the namespace.
fd -e tsx -e ts . packages/raystack/components -x sh -c 'grep -lE "React\.(ComponentProps|ReactNode|ReactElement|HTMLAttributes)" "$1"' _ {} | head -20
echo "---"
rg -nP "^import .*['\"]react['\"]" packages/raystack/components/floating-actions/floating-actions.tsx

Repository: raystack/apsara

Length of output: 794


🏁 Script executed:

cat -n packages/raystack/components/floating-actions/floating-actions.tsx

Repository: raystack/apsara

Length of output: 2657


🏁 Script executed:

# Check a couple of the files from the initial output to see if they import React
head -20 packages/raystack/components/avatar/avatar.tsx | grep -E "^import|React"
echo "---"
head -20 packages/raystack/components/data-table/components/virtualized-content.tsx | grep -E "^import|React"

Repository: raystack/apsara

Length of output: 994


🏁 Script executed:

# Check tsconfig for React ambient settings
fd tsconfig.json packages/raystack | head -1 | xargs cat | head -50

Repository: raystack/apsara

Length of output: 568


🏁 Script executed:

# Check if there's a global React declaration in global.d.ts or similar
cat packages/raystack/global.d.ts 2>/dev/null || echo "File not found or no React globals"
echo "---"
# Also check how avatar.tsx uses React.ComponentProps vs ComponentProps
rg "React\.ComponentProps|ComponentProps" packages/raystack/components/avatar/avatar.tsx

Repository: raystack/apsara

Length of output: 443


Add an explicit ComponentProps import.

Line 60 references React.ComponentProps<typeof Separator> but the file never imports React. This relies on the global React namespace, which TypeScript can resolve through ambient types but is fragile and inconsistent with how peer components in the package handle it (e.g., avatar.tsx explicitly imports ComponentProps from 'react'). Replace with a direct import:

♻️ Proposed change
 'use client';

+import type { ComponentProps } from 'react';
 import { Toolbar as ToolbarPrimitive } from '@base-ui/react/toolbar';
 import { cx } from 'class-variance-authority';
 import { Separator } from '../separator';
 import styles from './floating-actions.module.css';
@@
-export type FloatingActionsSeparatorProps = Omit<
-  React.ComponentProps<typeof Separator>,
-  'orientation'
->;
+export type FloatingActionsSeparatorProps = Omit<
+  ComponentProps<typeof Separator>,
+  'orientation'
+>;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/raystack/components/floating-actions/floating-actions.tsx` around
lines 1 - 6, The code uses React.ComponentProps<typeof Separator> but never
imports React; add an explicit import of ComponentProps from 'react' (e.g.,
import { ComponentProps } from 'react') and update the type usage to use
ComponentProps<typeof Separator> where referenced (the type on/around the
FloatingActions props definition that currently uses React.ComponentProps<typeof
Separator>) so the file no longer depends on the global React namespace and
matches the package's peer components.

# Conflicts:
#	apps/www/src/components/demo/demo.tsx
…preview edges

Wrap each inline demo's bar in a div with paddingBlock so the rendered
preview shows visible breathing room above and below. Inline style keeps
the change scoped to floating-actions demos without leaking into other
component preview areas.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… API

FloatingActions accepts arbitrary children (Apsara Button, IconButton,
Chip, custom components) rather than wrapping them via a registered
Toolbar.Button-style subcomponent, so the Toolbar primitive's disabled
cascade only affected items that happened to register with the
primitive — not the typical children. Documenting it as "cascades to
every focusable item" was misleading.

Omit disabled from both FloatingActionsProps and
FloatingActionsGroupProps. Consumers can disable individual items
explicitly when needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/raystack/components/floating-actions/floating-actions.tsx (2)

40-47: data-* attributes can be silently overridden by callers.

data-variant, data-side, and data-align drive the floating CSS positioning, but {...props} is spread after them, so a consumer who passes any of these as props (e.g. via type-loose forwarding) will silently break layout. Consider spreading props first and pinning the styling-critical attributes last.

♻️ Proposed change
   <ToolbarPrimitive.Root
-    data-variant={variant}
-    data-side={side}
-    data-align={align}
-    className={cx(styles.root, className)}
     {...props}
+    data-variant={variant}
+    data-side={side}
+    data-align={align}
+    className={cx(styles.root, className)}
   />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/raystack/components/floating-actions/floating-actions.tsx` around
lines 40 - 47, The data-* attributes controlling floating positioning
(data-variant, data-side, data-align) are currently set before spreading
{...props} into ToolbarPrimitive.Root, which allows callers to override them;
move the {...props} spread before those attributes and ensure data-variant,
data-side, data-align (and className={cx(styles.root, className)}) are specified
last on ToolbarPrimitive.Root so the component's positioning props cannot be
silently overridden by consumers.

12-13: Reconsider omitting disabled from the public props.

Both FloatingActionsProps and FloatingActionsGroupProps omit the disabled prop from the underlying ToolbarPrimitive.Root.Props and ToolbarPrimitive.Group.Props. This prevents consumers from using the toolbar's built-in disabled cascade feature—which disables all child controls—that the PR description explicitly identifies as an inherited behavior. Unless there's an intentional design reason (e.g., styling constraints for disabled state), consider removing the Omit restrictions to allow disabled to pass through.

♻️ Proposed change
-export interface FloatingActionsProps
-  extends Omit<ToolbarPrimitive.Root.Props, 'disabled'> {
+export interface FloatingActionsProps extends ToolbarPrimitive.Root.Props {
@@
-export type FloatingActionsGroupProps = Omit<
-  ToolbarPrimitive.Group.Props,
-  'disabled'
->;
+export type FloatingActionsGroupProps = ToolbarPrimitive.Group.Props;

Also applies to: 50-53

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/raystack/components/floating-actions/floating-actions.tsx` around
lines 12 - 13, The props types currently strip the built-in disabled cascade by
using Omit<'disabled'>; update FloatingActionsProps and
FloatingActionsGroupProps to stop omitting disabled so consumers can pass the
toolbar-level disabled flag (i.e., change the extends from
Omit<ToolbarPrimitive.Root.Props, 'disabled'> and
Omit<ToolbarPrimitive.Group.Props, 'disabled'> to extend the original
ToolbarPrimitive.Root.Props and ToolbarPrimitive.Group.Props or include
'disabled' explicitly), and adjust any local usages or tests that assumed
disabled was absent to accept and forward the disabled prop to the underlying
ToolbarPrimitive components (refer to FloatingActionsProps,
FloatingActionsGroupProps, ToolbarPrimitive.Root and ToolbarPrimitive.Group to
locate the changes).
apps/www/src/components/playground/floating-actions-examples.tsx (1)

83-101: Floating example will overlap the inline examples on this page.

Since variant="floating" (default) renders position: fixed at bottom-center, this last instance will sit on top of whatever else is on screen — including the three inline examples above — making the playground page visually noisy and potentially obscuring controls. Consider isolating the floating demo in its own scrolling/section container, or rendering it conditionally (e.g. behind a toggle), as the docs’ scrolling-context demo does.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/src/components/playground/floating-actions-examples.tsx` around
lines 83 - 101, The floating example (FloatingActions with default floating
variant) overlaps the inline examples because it uses position:fixed; update the
demo so the floating instance is not always fixed over the page—either render it
conditionally behind a toggle or move it into an isolated scrolling/demo
container with its own stacking context (e.g., a bounded div with overflow and
relative positioning) so it doesn't cover the three inline examples; locate the
FloatingActions usage in floating-actions-examples.tsx and apply one of these
approaches (or alternatively change this demo instance to variant="inline") to
prevent visual overlap.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/www/src/components/playground/floating-actions-examples.tsx`:
- Line 32: Two FloatingActions components share the same aria-label "Bulk
actions", causing duplicate region names for assistive tech; update one of the
FloatingActions instances (the second one used in this component) to a distinct
label such as "Bulk actions (grouped)" or another descriptive string so each
toolbar has a unique aria-label, ensuring the change is applied to the
FloatingActions JSX element(s) in this file (search for the FloatingActions
component usages and update the aria-label prop).

---

Nitpick comments:
In `@apps/www/src/components/playground/floating-actions-examples.tsx`:
- Around line 83-101: The floating example (FloatingActions with default
floating variant) overlaps the inline examples because it uses position:fixed;
update the demo so the floating instance is not always fixed over the
page—either render it conditionally behind a toggle or move it into an isolated
scrolling/demo container with its own stacking context (e.g., a bounded div with
overflow and relative positioning) so it doesn't cover the three inline
examples; locate the FloatingActions usage in floating-actions-examples.tsx and
apply one of these approaches (or alternatively change this demo instance to
variant="inline") to prevent visual overlap.

In `@packages/raystack/components/floating-actions/floating-actions.tsx`:
- Around line 40-47: The data-* attributes controlling floating positioning
(data-variant, data-side, data-align) are currently set before spreading
{...props} into ToolbarPrimitive.Root, which allows callers to override them;
move the {...props} spread before those attributes and ensure data-variant,
data-side, data-align (and className={cx(styles.root, className)}) are specified
last on ToolbarPrimitive.Root so the component's positioning props cannot be
silently overridden by consumers.
- Around line 12-13: The props types currently strip the built-in disabled
cascade by using Omit<'disabled'>; update FloatingActionsProps and
FloatingActionsGroupProps to stop omitting disabled so consumers can pass the
toolbar-level disabled flag (i.e., change the extends from
Omit<ToolbarPrimitive.Root.Props, 'disabled'> and
Omit<ToolbarPrimitive.Group.Props, 'disabled'> to extend the original
ToolbarPrimitive.Root.Props and ToolbarPrimitive.Group.Props or include
'disabled' explicitly), and adjust any local usages or tests that assumed
disabled was absent to accept and forward the disabled prop to the underlying
ToolbarPrimitive components (refer to FloatingActionsProps,
FloatingActionsGroupProps, ToolbarPrimitive.Root and ToolbarPrimitive.Group to
locate the changes).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5083cfa8-9915-4b5a-9c98-7d28f73d6e9b

📥 Commits

Reviewing files that changed from the base of the PR and between 8c8ee5e and a5d1afa.

📒 Files selected for processing (5)
  • apps/www/src/components/playground/floating-actions-examples.tsx
  • apps/www/src/content/docs/components/floating-actions/demo.ts
  • apps/www/src/content/docs/components/floating-actions/index.mdx
  • apps/www/src/content/docs/components/floating-actions/props.ts
  • packages/raystack/components/floating-actions/floating-actions.tsx
✅ Files skipped from review due to trivial changes (2)
  • apps/www/src/content/docs/components/floating-actions/index.mdx
  • apps/www/src/content/docs/components/floating-actions/props.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/www/src/content/docs/components/floating-actions/demo.ts

</FloatingActions>

<Text>Inline — multiple action groups:</Text>
<FloatingActions variant='inline' aria-label='Bulk actions'>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Duplicate aria-label="Bulk actions" on two distinct toolbars.

Lines 32 and 56 both label their FloatingActions toolbar "Bulk actions". Assistive tech users navigating by landmarks/regions on this playground page will hear the same name twice. Consider differentiating, e.g. "Bulk actions" and "Bulk actions (grouped)".

Also applies to: 56-56

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/src/components/playground/floating-actions-examples.tsx` at line 32,
Two FloatingActions components share the same aria-label "Bulk actions", causing
duplicate region names for assistive tech; update one of the FloatingActions
instances (the second one used in this component) to a distinct label such as
"Bulk actions (grouped)" or another descriptive string so each toolbar has a
unique aria-label, ensuring the change is applied to the FloatingActions JSX
element(s) in this file (search for the FloatingActions component usages and
update the aria-label prop).

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.

2 participants