Skip to content

Conversation

@kotAPI
Copy link
Collaborator

@kotAPI kotAPI commented Mar 21, 2025

Summary by CodeRabbit

  • New Features

    • Launched a full set of collapsible UI components that allow seamless toggling of content with flexible configuration, including both controlled and uncontrolled modes.
    • Added enhanced animation options and accessibility attributes to improve user experience.
    • Introduced new components for managing collapsible behavior: CollapsiblePrimitiveRoot, CollapsiblePrimitiveContent, and CollapsiblePrimitiveTrigger.
    • Provided interactive demos showcasing various usage scenarios such as default behavior, multiple instances, disabled animations, and custom effects.
  • Tests

    • Implemented extensive tests to ensure reliable functionality, correct state management, and enhanced accessibility compliance.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 21, 2025

Walkthrough

This pull request introduces a comprehensive set of collapsible component primitives. It adds a new context with its associated hook and types, along with React components for the collapsible root, content, and trigger. An aggregator module re-exports these primitives, and accompanying Storybook stories and tests demonstrate and verify usage scenarios, state management, and accessibility through ARIA attributes.

Changes

File(s) Change Summary
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx Adds a new context (CollapsiblePrimitiveContext), hook (useCollapsiblePrimitiveContext), and type (CollapsiblePrimitiveContextValue) for managing collapsible state.
src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx, src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveRoot.tsx, src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveTrigger.tsx Introduces new React components for collapsible content, root state management, and trigger functionality, each with their corresponding prop types.
src/core/primitives/Collapsible/index.tsx Aggregates and exports collapsible primitives as a unified component with subcomponents (Root, Content, Trigger) and prop type re-exports.
src/core/primitives/Collapsible/stories/Collapsible.stories.tsx Provides Storybook stories demonstrating various usage scenarios, including controlled/uncontrolled modes and custom animations.
src/core/primitives/Collapsible/tests/Collapsible.test.tsx Implements tests for rendering, state transitions, interactions, and accessibility attributes of the collapsible components.

Sequence Diagram(s)

sequenceDiagram
    participant TR as Trigger
    participant CTX as Context
    participant RT as Root
    participant CNT as Content

    TR->>CTX: useCollapsiblePrimitiveContext()
    CTX-->>TR: Return open state & onOpenChange
    TR->>CTX: onOpenChange (triggered by click)
    CTX->>RT: Update open/closed state
    RT->>CNT: Propagate updated state via context
Loading

Possibly related PRs

  • rad-ui/ui#407: Implements a basic collapsible component with similar context and state management patterns.
  • rad-ui/ui#677: Modifications involve state management and context for a collapsible component, specifically through the onOpenChange prop and context usage.

Suggested labels

automerge

Poem

In my burrow of code I happily bound,
New collapsible features hopping around.
With context and hooks to guide the way,
Triggers and content now dance and play!
A rabbit's delight in each line I’ve found 🐇
Hop on, embrace the change—code magic abounds!

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
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: 0

🧹 Nitpick comments (5)
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (1)

1-1: Remove unused React import

The React import isn't directly used in this file as there's no JSX being rendered. While it's commonly imported by habit, it's better to remove unused imports.

-import React, { createContext, useContext } from 'react';
+import { createContext, useContext } from 'react';
🧰 Tools
🪛 GitHub Check: lint

[warning] 1-1:
'React' is defined but never used

src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx (1)

56-94: Well-implemented animation logic with proper cleanup

The animation logic is thorough and handles both opening and closing states with proper timing. The component:

  1. Correctly manages height transitions
  2. Uses requestAnimationFrame for smooth animations
  3. Properly cleans up timeouts to prevent memory leaks
  4. Sets height to undefined after opening for responsive flexibility

One improvement could be made in the forced reflow implementation:

// Line 80: Use a more explicit variable name to indicate purpose
-                    const _ = ref.current?.offsetHeight;
+                    // Force a reflow by reading offsetHeight
+                    void ref.current?.offsetHeight;
🧰 Tools
🪛 GitHub Check: lint

[warning] 80-80:
'_' is assigned a value but never used

src/core/primitives/Collapsible/stories/Collapsible.stories.tsx (2)

36-36: Consider removing the potentially unnecessary data attribute.

The data-radui-collapsible-content attribute appears to be a leftover from a dependency or previous implementation. If it's not being used for styling or selection, it should be removed to keep the code clean.

-                        data-radui-collapsible-content

168-172: Mixing animation properties and manual display styling can create conflicts.

Using both transitionDuration={0} and manually controlling display with style={{display: isOpen ? 'block' : 'none'}} is redundant and could lead to unexpected behavior. The component likely handles visibility internally when animation is disabled.

                    <CollapsiblePrimitive.Content
                        transitionDuration={0}
-                        style={{
-                            display: isOpen ? 'block' : 'none',
-                            height: 'auto'
-                        }}
                    >
src/core/primitives/Collapsible/tests/Collapsible.test.tsx (1)

70-93: Consider enhancing the controlled component test.

While the test correctly verifies that the onOpenChange callback is called, it doesn't fully test the component behavior in controlled mode. Consider adding a test that simulates the parent updating the open prop in response to the callback.

test('onOpenChange callback is called when trigger is clicked', () => {
    const onOpenChangeMock = jest.fn();
+   const { rerender } = render(
-   render(
        <CollapsiblePrimitive.Root onOpenChange={onOpenChangeMock}>
            <CollapsiblePrimitive.Trigger data-testid="trigger">
                Toggle
            </CollapsiblePrimitive.Trigger>
            <CollapsiblePrimitive.Content data-testid="content">
                <div>Content</div>
            </CollapsiblePrimitive.Content>
        </CollapsiblePrimitive.Root>
    );

    // Initial state
    expect(screen.getByTestId('content')).toHaveAttribute('data-state', 'closed');

    // Toggle open
    fireEvent.click(screen.getByTestId('trigger'));
    expect(onOpenChangeMock).toHaveBeenCalledWith(true);

+   // Simulate parent updating the state
+   rerender(
+       <CollapsiblePrimitive.Root open={true} onOpenChange={onOpenChangeMock}>
+           <CollapsiblePrimitive.Trigger data-testid="trigger">
+               Toggle
+           </CollapsiblePrimitive.Trigger>
+           <CollapsiblePrimitive.Content data-testid="content">
+               <div>Content</div>
+           </CollapsiblePrimitive.Content>
+       </CollapsiblePrimitive.Root>
+   );
+   
+   // Verify content is now open
+   expect(screen.getByTestId('content')).toHaveAttribute('data-state', 'open');
+   
+   // Toggle closed
+   fireEvent.click(screen.getByTestId('trigger'));
+   expect(onOpenChangeMock).toHaveBeenCalledWith(false);
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ab30ef6 and 172b201.

📒 Files selected for processing (7)
  • src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (1 hunks)
  • src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx (1 hunks)
  • src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveRoot.tsx (1 hunks)
  • src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveTrigger.tsx (1 hunks)
  • src/core/primitives/Collapsible/index.tsx (1 hunks)
  • src/core/primitives/Collapsible/stories/Collapsible.stories.tsx (1 hunks)
  • src/core/primitives/Collapsible/tests/Collapsible.test.tsx (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveTrigger.tsx (2)
src/core/primitives/Collapsible/index.tsx (1) (1)
  • CollapsiblePrimitiveTriggerProps (9-9)
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (1) (1)
  • useCollapsiblePrimitiveContext (24-34)
src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveRoot.tsx (2)
src/core/primitives/Collapsible/index.tsx (1) (1)
  • CollapsiblePrimitiveRootProps (7-7)
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (1) (1)
  • CollapsiblePrimitiveContext (22-22)
🪛 GitHub Check: lint
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx

[warning] 1-1:
'React' is defined but never used

src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx

[warning] 80-80:
'_' is assigned a value but never used

🔇 Additional comments (12)
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (2)

3-20: Well-structured context type definition with thorough documentation

The CollapsiblePrimitiveContextValue type is well-defined with clear JSDoc comments explaining each property. The inclusion of the contentId for ARIA relationships shows good consideration for accessibility.


24-34: Good error handling in the context hook

The useCollapsiblePrimitiveContext hook properly checks if the context exists before returning it, providing a helpful error message that guides developers on correct usage within the component hierarchy.

src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveRoot.tsx (2)

6-37: Well-documented props with comprehensive type definition

The CollapsiblePrimitiveRootProps type is thoroughly documented with clear JSDoc comments for each property. The inclusion of both controlled and uncontrolled patterns through open and defaultOpen props follows React best practices.


39-79: Well-implemented component with proper state management

The component correctly:

  1. Uses useControllableState for managing controlled/uncontrolled state
  2. Handles the disabled state appropriately
  3. Provides complete context values to children
  4. Uses data attributes for styling hooks

The implementation of handleOpenChange correctly prevents state changes when the component is disabled.

src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveTrigger.tsx (2)

27-55: Excellent accessibility implementation with proper ARIA attributes

The component correctly implements accessibility features with:

  • aria-controls linked to the content ID
  • aria-expanded reflecting the open state
  • Data attributes for styling based on component state
  • Proper ref forwarding for parent component access
  • Clean event handling that allows event propagation

This implementation follows best practices for accessible UI components.


31-37: Clean event handler implementation

The handleClick function is well implemented, allowing event propagation while still toggling the open state. The disabled check prevents state changes when appropriate.

src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx (2)

37-55: Good implementation of prop override for context values

The component allows the open prop to override the context value, providing flexibility while maintaining the automatic context behavior when the prop is omitted. The default values for animation settings are sensible.


96-112: Properly implemented accessibility attributes with clean styling

The component correctly implements:

  • id linked to the trigger's aria-controls
  • aria-hidden attribute reflecting the open state
  • Clean inline style management for animations
  • Data attributes for styling hooks

The transition styling is applied efficiently with dynamic values based on props.

src/core/primitives/Collapsible/stories/Collapsible.stories.tsx (1)

1-222: Well-structured Storybook examples with comprehensive coverage.

The stories provide excellent examples of different usage patterns for the CollapsiblePrimitive component, including uncontrolled state, controlled state, multiple instances, and animation customization. This will serve as good documentation for consumers of the component.

src/core/primitives/Collapsible/index.tsx (2)

17-20: Good implementation of compound component pattern with helpful warning.

The warning message is helpful for guiding developers to use the correct sub-components instead of the main component directly. This follows best practices seen in other React component libraries.


1-28: Clean compound component implementation with proper type exports.

The file follows best practices for implementing compound components in React:

  1. Re-exporting prop types for type safety
  2. Using the direct assignment pattern for sub-components
  3. Providing clear guidance for usage

This approach makes the component easy to use and provides good developer experience.

src/core/primitives/Collapsible/tests/Collapsible.test.tsx (1)

1-125: Comprehensive test coverage with good accessibility testing.

The test suite covers all important aspects of the component:

  • Rendering behavior
  • State management
  • Controlled and uncontrolled modes
  • Event handling
  • Accessibility attributes

This thorough testing approach ensures the component will work reliably and be accessible to all users.

Copy link
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 (8)
src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveRoot.tsx (3)

1-4: Consider removing unused default React import.

The default import React isn’t referenced directly, as only named exports (useId) are used. This can trigger lint warnings in some setups.

-import React, { useId } from 'react';
+import { useId } from 'react';

6-45: Comprehensive prop documentation.

The CollapsiblePrimitiveRootProps interface is clearly documented, which helps maintainers understand each prop’s usage. Note that [key: string]: any; is flexible but can potentially mask type errors. You might consider a more specific approach for additional HTML attributes.


47-91: Implementation looks solid; consider adding ARIA attribute for disabled state.

Providing [data-disabled] is helpful for styling or logic, but screen readers may benefit from aria-disabled="true" when disabled is true. Verify if this aligns with your accessibility goals.

src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (1)

1-2: Remove unused default React import.

Only named exports (createContext, useContext) are used, so the default React import is unnecessary.

-import React, { createContext, useContext } from 'react';
+import { createContext, useContext } from 'react';
🧰 Tools
🪛 GitHub Check: lint

[warning] 1-1:
'React' is defined but never used

src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx (2)

5-22: Docstrings enhance clarity for component props.

Using JSDoc on each prop is helpful for future maintainers and tooling. Similar to the root props, consider refining [key: string]: any; if more specific typing is preferred.


43-81: Good use of forced reflow; consider renaming the underscore.

Setting a temporary variable (currently _) triggers layout calculation to ensure the animation transitions smoothly. Renaming _ to _forceReflow or similar might clarify its intent.

🧰 Tools
🪛 GitHub Check: lint

[warning] 67-67:
'_' is assigned a value but never used

src/core/primitives/Collapsible/stories/Collapsible.stories.tsx (2)

16-46: Consider removing the data attribute that seems out of place.

The story demonstrates a basic collapsible implementation well, but there's an unnecessary data-radui-collapsible-content attribute on line 36 that doesn't appear in other stories and seems like a remnant from Radix UI.

    <CollapsiblePrimitive.Content
-        data-radui-collapsible-content
    >

48-83: Controlled example is well-implemented with a minor formatting issue.

The controlled component pattern is properly demonstrated with state management. The comment on line 50 has inconsistent indentation with the surrounding code.

-    // Use React state for controlled component
+    // Use React state for controlled component
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 172b201 and f9ddbe1.

📒 Files selected for processing (4)
  • src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (1 hunks)
  • src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx (1 hunks)
  • src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveRoot.tsx (1 hunks)
  • src/core/primitives/Collapsible/stories/Collapsible.stories.tsx (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveRoot.tsx (2)
src/core/primitives/Collapsible/index.tsx (1) (1)
  • CollapsiblePrimitiveRootProps (7-7)
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (1) (1)
  • CollapsiblePrimitiveContext (38-38)
src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx (2)
src/core/primitives/Collapsible/index.tsx (1) (1)
  • CollapsiblePrimitiveContentProps (8-8)
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (1) (1)
  • useCollapsiblePrimitiveContext (40-50)
🪛 GitHub Check: lint
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx

[warning] 1-1:
'React' is defined but never used

src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx

[warning] 67-67:
'_' is assigned a value but never used

🔇 Additional comments (10)
src/core/primitives/Collapsible/contexts/CollapsiblePrimitiveContext.tsx (2)

3-36: Well-structured context type.

The properties and JSDoc clearly convey the context value’s purpose, enhancing maintainability and discoverability.


38-50: Custom hook usage is appropriate.

Requiring usage within CollapsiblePrimitiveRoot ensures consistent state management, which is a best practice for compound components.

src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx (5)

1-3: Imports are valid for forwardRef and hooks usage.

The default React import is needed for React.forwardRef. No concerns here.


24-36: ForwardRef pattern is well structured.

Wrapping the component in React.forwardRef ensures consistent ref handling across parent components.


38-42: Ref combination is done properly.

Assigning the forwarded ref to combinedRef extends the usage while allowing fallback to a local ref. This is a clean approach.


83-99: Transition logic and ARIA usage look correct.

Dynamically setting height and aria-hidden aligns with best practices for collapsible content. This should support screen readers appropriately.


103-105: DisplayName and default export assigned properly.

Providing displayName improves debugging in React DevTools. The default export keeps the component import succinct.

src/core/primitives/Collapsible/stories/Collapsible.stories.tsx (3)

1-15: Well-structured Storybook setup!

The imports and metadata are correctly set up following Storybook's best practices. The component is properly categorized under "Primitives" with appropriate parameters.


85-141: Excellent implementation of multiple collapsibles.

This example effectively demonstrates managing multiple independent collapsible elements using a record for state management. The approach of mapping over Object.entries with unique keys is clean and efficient.


184-220: Custom animation implementation showcases the headless nature well.

This example effectively demonstrates how to customize animations through props rather than inline styles, correctly following the headless UI pattern. The cubic-bezier timing function creates a nice spring effect, and the explanation in the content helps users understand the approach.

Comment on lines +143 to +182
export const AnimationDisabled: Story = {
render: () => {
const [isOpen, setIsOpen] = useState(false);

return (
<div style={{ width: '300px', border: '1px solid #ccc', borderRadius: '4px', padding: '8px' }}>
<CollapsiblePrimitive.Root
open={isOpen}
onOpenChange={(open) => setIsOpen(open)}
transitionDuration={0}
>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px' }}>
<span>No Animation</span>
<CollapsiblePrimitive.Trigger
style={{
background: 'none',
border: '1px solid #ddd',
borderRadius: '4px',
padding: '4px 8px',
cursor: 'pointer'
}}
>
{isOpen ? 'Close' : 'Open'}
</CollapsiblePrimitive.Trigger>
</div>
<CollapsiblePrimitive.Content
style={{
display: isOpen ? 'block' : 'none',
height: 'auto'
}}
>
<div style={{ padding: '8px', backgroundColor: '#f5f5f5', borderRadius: '4px', marginTop: '8px' }}>
<p>This content toggles instantly without animation.</p>
</div>
</CollapsiblePrimitive.Content>
</CollapsiblePrimitive.Root>
</div>
);
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Potentially conflicting animation control approaches.

While setting transitionDuration={0} is the right way to disable animations, adding inline styles to directly control the Content's display and height properties (lines 169-172) might conflict with the component's internal behavior.

    <CollapsiblePrimitive.Content
-        style={{
-            display: isOpen ? 'block' : 'none',
-            height: 'auto'
-        }}
    >

This change would let the component handle its own visibility, relying solely on the transitionDuration={0} prop to disable animations.

📝 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
export const AnimationDisabled: Story = {
render: () => {
const [isOpen, setIsOpen] = useState(false);
return (
<div style={{ width: '300px', border: '1px solid #ccc', borderRadius: '4px', padding: '8px' }}>
<CollapsiblePrimitive.Root
open={isOpen}
onOpenChange={(open) => setIsOpen(open)}
transitionDuration={0}
>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px' }}>
<span>No Animation</span>
<CollapsiblePrimitive.Trigger
style={{
background: 'none',
border: '1px solid #ddd',
borderRadius: '4px',
padding: '4px 8px',
cursor: 'pointer'
}}
>
{isOpen ? 'Close' : 'Open'}
</CollapsiblePrimitive.Trigger>
</div>
<CollapsiblePrimitive.Content
style={{
display: isOpen ? 'block' : 'none',
height: 'auto'
}}
>
<div style={{ padding: '8px', backgroundColor: '#f5f5f5', borderRadius: '4px', marginTop: '8px' }}>
<p>This content toggles instantly without animation.</p>
</div>
</CollapsiblePrimitive.Content>
</CollapsiblePrimitive.Root>
</div>
);
}
};
export const AnimationDisabled: Story = {
render: () => {
const [isOpen, setIsOpen] = useState(false);
return (
<div style={{ width: '300px', border: '1px solid #ccc', borderRadius: '4px', padding: '8px' }}>
<CollapsiblePrimitive.Root
open={isOpen}
onOpenChange={(open) => setIsOpen(open)}
transitionDuration={0}
>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px' }}>
<span>No Animation</span>
<CollapsiblePrimitive.Trigger
style={{
background: 'none',
border: '1px solid #ddd',
borderRadius: '4px',
padding: '4px 8px',
cursor: 'pointer'
}}
>
{isOpen ? 'Close' : 'Open'}
</CollapsiblePrimitive.Trigger>
</div>
<CollapsiblePrimitive.Content>
<div style={{ padding: '8px', backgroundColor: '#f5f5f5', borderRadius: '4px', marginTop: '8px' }}>
<p>This content toggles instantly without animation.</p>
</div>
</CollapsiblePrimitive.Content>
</CollapsiblePrimitive.Root>
</div>
);
}
};

@kotAPI kotAPI merged commit a4eac5b into main Mar 22, 2025
6 checks passed
@kotAPI kotAPI deleted the kotapi/collapsible-primitive branch March 22, 2025 01:19
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