Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Storybook to store components #1012

Merged
merged 20 commits into from
Jan 23, 2025
Merged

Add Storybook to store components #1012

merged 20 commits into from
Jan 23, 2025

Conversation

almsh
Copy link
Contributor

@almsh almsh commented Jan 20, 2025

Closes #969

This PR introduces the initial integration of Storybook and some AI-generated stories for components. You can run it locally using the command npm run ui:serve.

To simplify the setup, I copied the spinner icon directly from the site. This was necessary because Storybook could not handle imports from another workspace, and copying the asset was the simplest solution for now🙂

Let's discuss the next steps to determine what should be included in this PR:

  1. Should we deploy Storybook separately or integrate it within the main site build?
  2. Should all icons/logos be moved to @socialincome/ui, with the main site importing them from there?
  3. What improvements should be made to better document components?
  4. Should refinements be added to enhance the UI library?

Summary by CodeRabbit

Based on the comprehensive changes, here are the updated release notes:

  • New Features

    • Added Storybook configuration for multiple UI components, enhancing visual documentation and testing.
    • Introduced comprehensive stories for components like Button, Input, Dialog, Tooltip, and more.
    • Implemented a new GitHub Actions workflow for automating the deployment of Storybook to GitHub Pages.
    • Enhanced accessibility features for DonateIcon, SIIcon, and SpinnerIcon.
  • Chores

    • Reorganized UI component imports and exports.
    • Consolidated SpinnerIcon import across multiple files.
    • Removed dropdown-menu, menubar, and navigation-menu components from main exports.
    • Added new icons (DonateIcon, SIIcon, SpinnerIcon) to the main exports.
  • Documentation

    • Created extensive Storybook stories for UI components, providing interactive examples and usage guidelines.

Copy link

vercel bot commented Jan 20, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
public ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 23, 2025 1:26pm

Copy link

coderabbitai bot commented Jan 20, 2025

📝 Walkthrough

Walkthrough

This pull request introduces Storybook to the UI package, creating a comprehensive set of stories for various components. The changes include configuring Storybook in the UI workspace, adding story files for multiple components like Button, Input, Dialog, and others, and updating import statements to centralize the SpinnerIcon. The implementation provides a robust documentation and testing environment for the UI components.

Changes

File Change Summary
package.json Added Storybook-related scripts
ui/.storybook/main.js Created Storybook configuration with Vite support
ui/.storybook/preview.js Added global preview configuration
ui/package.json Added Storybook dev dependencies and scripts
ui/src/stories/* Created story files for multiple components
ui/src/index.ts Updated exports, removed some components
Various website files Updated SpinnerIcon imports

Assessment against linked issues

Objective Addressed Explanation
Install Storybook Fully implemented Storybook configuration
Add existing components Partially addressed with story files for multiple components

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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. (Beta)
  • @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

@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: 10

🧹 Nitpick comments (31)
ui/src/logos/spinner-icon.tsx (1)

14-14: Consider making animation duration configurable.

The animation speed is hardcoded via Tailwind's animate-spin. Consider making it configurable through props for different use cases.

-className={twMerge('h-5 w-5 animate-spin', className)}
+className={twMerge('h-5 w-5', animationSpeed === 'fast' ? 'animate-spin-fast' : 'animate-spin', className)}
ui/src/stories/alert.stories.tsx (1)

14-86: Consider enhancing stories with additional features.

The stories provide good coverage of component variants. Consider these enhancements:

  • Add args configuration for interactive controls
  • Include accessibility examples (ARIA labels, keyboard navigation)
  • Add responsive design examples
  • Demonstrate error handling scenarios

Example args configuration:

export const Primary: Story = {
  args: {
    variant: 'primary',
    title: 'Primary Alert',
    description: 'This is a primary alert with an icon.',
    showIcon: true,
  },
  render: (args) => (
    <Alert variant={args.variant}>
      {args.showIcon && <InformationCircleIcon className="h-4 w-4" />}
      <AlertTitle>{args.title}</AlertTitle>
      <AlertDescription>{args.description}</AlertDescription>
    </Alert>
  ),
};
ui/.storybook/preview.js (1)

4-13: Consider enhancing preview configuration with additional parameters.

Add viewport and theme configurations to improve story development experience.

 const preview = {
 	parameters: {
+		viewport: {
+			viewports: {
+				mobile: { name: 'Mobile', styles: { width: '360px', height: '640px' } },
+				tablet: { name: 'Tablet', styles: { width: '768px', height: '1024px' } },
+				desktop: { name: 'Desktop', styles: { width: '1280px', height: '800px' } },
+			},
+		},
+		themes: {
+			default: 'light',
+			list: [
+				{ name: 'light', class: 'light-theme', color: '#ffffff' },
+				{ name: 'dark', class: 'dark-theme', color: '#000000' },
+			],
+		},
 		controls: {
ui/.storybook/main.js (1)

14-18: Add useful Storybook addons for enhanced development.

Consider adding a11y and viewport addons for better component testing.

 	addons: [
 		getAbsolutePath('@storybook/addon-onboarding'),
 		getAbsolutePath('@storybook/addon-essentials'),
 		getAbsolutePath('@storybook/addon-interactions'),
+		getAbsolutePath('@storybook/addon-a11y'),
+		getAbsolutePath('@storybook/addon-viewport'),
 	],
ui/src/stories/avatar.stories.tsx (1)

4-8: Add component description and usage guidelines.

Enhance documentation with component description and usage examples.

 const meta = {
 	title: 'Components/Avatar',
 	component: Avatar,
 	tags: ['autodocs'],
+	parameters: {
+		docs: {
+			description: {
+				component: 'Avatar component for displaying user profile images with fallback support.',
+			},
+		},
+	},
 } satisfies Meta<typeof Avatar>;
ui/src/stories/accordion.stories.tsx (1)

20-20: Make accordion width responsive.

Replace hardcoded width with responsive classes.

-		className: 'w-[400px]',
+		className: 'w-full max-w-md',

-		<Accordion type="single" collapsible className="w-[400px]">
+		<Accordion type="single" collapsible className="w-full max-w-md">

-		className: 'w-[400px]',
+		className: 'w-full max-w-md',

-		<Accordion type="multiple" className="w-[400px]">
+		<Accordion type="multiple" className="w-full max-w-md">

Also applies to: 23-23, 47-47, 50-50

ui/src/stories/badge.stories.tsx (1)

64-74: Consider using CSS variables for colors.

Using direct Tailwind color classes like bg-blue-500 makes theme customization harder. Consider using CSS variables for better maintainability.

-<Badge className="bg-blue-500 hover:bg-blue-600">Custom Blue</Badge>
+<Badge className="bg-[var(--badge-color)] hover:bg-[var(--badge-hover-color)]">Custom Blue</Badge>
ui/src/stories/progress.stories.tsx (1)

46-67: Consider making animation speed configurable.

The animation interval is hardcoded to 1000ms. Consider making it configurable through story controls.

+export const Animated: Story = {
+  args: {
+    interval: 1000,
+  },
   render: ({ interval }) => {
     const [progress, setProgress] = React.useState(0);
     
     React.useEffect(() => {
-      const timer = setInterval(() => {
+      const timer = setInterval(() => {
         setProgress((prevProgress) => (prevProgress >= 100 ? 0 : prevProgress + 10));
-      }, 1000);
+      }, interval);
ui/src/stories/checkbox.stories.tsx (1)

91-102: Simplify the checkbox state handling.

The Boolean type casting and callback can be simplified.

-<Checkbox checked={checked} onCheckedChange={(checkedState) => setChecked(Boolean(checkedState))} />
+<Checkbox checked={checked} onCheckedChange={setChecked} />
ui/src/stories/switch.stories.tsx (2)

54-57: Add form submission handler implementation.

The form submission handler is currently empty. Consider implementing the handler or adding a comment explaining that it's intentionally left empty for demonstration purposes.

 onSubmit={(e) => {
   e.preventDefault();
-  // Handle form submission
+  // This is a demo form submission handler
+  console.log('Form submitted');
 }}

63-69: Add aria-label to notification settings section.

The notification settings section should be labeled for better accessibility.

-<div className="space-y-2">
+<div className="space-y-2" role="group" aria-label="Notification Settings">
ui/src/stories/popover.stories.tsx (2)

48-58: Add input validation and error handling to form fields.

The form fields lack validation and error handling. Consider adding required fields and validation messages.

 <input
   id="email"
   defaultValue="john@example.com"
+  required
+  pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$"
   className="border-input col-span-2 h-8 rounded-md border px-3"
+  aria-describedby="email-error"
 />
+<span id="email-error" className="text-destructive text-sm" />

69-70: Consider adding loading states for delayed popovers.

The custom delay implementation could benefit from a loading indicator during the delay period.

ui/src/stories/dialog.stories.tsx (1)

72-90: Add form validation and aria-required attributes.

The profile form fields should include proper validation attributes and aria labels.

 <input
   id="name"
+  required
+  aria-required="true"
   className="col-span-3 h-10 rounded-md border px-3"
   placeholder="Enter your name"
 />
ui/src/stories/carousel.stories.tsx (1)

108-116: Add pause on hover for autoplay carousel.

Consider adding a pause feature when users hover over the carousel for better user experience.

 options={{
   autoPlay: {
     enabled: true,
     delay: 3000,
+    pauseOnHover: true
   },
 }}
ui/src/stories/radio-group.stories.tsx (1)

119-132: Use design system tokens for custom styling.

Instead of using direct color classes like border-blue-500, consider using design system tokens for consistent theming.

-<RadioGroupItem value="option-1" id="custom-1" className="border-blue-500 text-blue-500" />
+<RadioGroupItem value="option-1" id="custom-1" className="border-primary text-primary" />
-<RadioGroupItem value="option-2" id="custom-2" className="border-green-500 text-green-500" />
+<RadioGroupItem value="option-2" id="custom-2" className="border-secondary text-secondary" />
ui/src/stories/toggle.stories.tsx (1)

17-31: Extract SVG icons into separate components.

The SVG icons are duplicated across multiple stories. Consider extracting them into reusable components.

Create an icons directory and move the SVGs there:

// src/components/icons/italic-icon.tsx
export const ItalicIcon = () => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    width="16"
    height="16"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <line x1="19" y1="4" x2="10" y2="4" />
    <line x1="14" y1="20" x2="5" y2="20" />
    <line x1="15" y1="4" x2="9" y2="20" />
  </svg>
);

Also applies to: 40-54, 110-123, 126-140, 143-156

ui/src/stories/typography.stories.tsx (1)

6-23: Import color tokens from design system.

Instead of maintaining a separate FONT_COLORS array, consider importing these values from your design system tokens.

import { colorTokens } from '../theme/tokens';

const FONT_COLORS: FontColor[] = Object.keys(colorTokens) as FontColor[];
ui/src/stories/tooltip.stories.tsx (2)

22-139: Add ARIA labels for better accessibility.

Consider adding aria-label attributes to buttons in the stories, especially for icon-only buttons.

-<button className="flex h-8 w-8 items-center justify-center rounded-full border">
+<button 
+  className="flex h-8 w-8 items-center justify-center rounded-full border"
+  aria-label="Information">

140-187: Document delay duration constraints.

Consider adding a comment about minimum/maximum recommended delay durations for optimal user experience.

ui/src/stories/collapsible.stories.tsx (2)

44-50: Optimize state management for multiple sections.

Consider using a Set instead of an array for better performance with includes/filter operations.

-const [openSections, setOpenSections] = React.useState<number[]>([]);
+const [openSections, setOpenSections] = React.useState<Set<number>>(new Set());

 const toggleSection = (index: number) => {
-  setOpenSections((current) =>
-    current.includes(index) ? current.filter((i) => i !== index) : [...current, index],
-  );
+  setOpenSections((current) => {
+    const newSet = new Set(current);
+    current.has(index) ? newSet.delete(index) : newSet.add(index);
+    return newSet;
+  });
 };

111-138: Make animation duration configurable.

Consider making the animation duration customizable through props for more flexibility.

ui/src/stories/menubar.stories.tsx (1)

1-171: Document keyboard navigation patterns.

Add comments or stories demonstrating keyboard navigation patterns (e.g., arrow keys, Enter, Escape) for better accessibility documentation.

ui/src/stories/hover-card.stories.tsx (1)

1-161: Add hover delay configuration.

Consider adding a delay prop to prevent accidental triggering, especially for interactive content.

-<HoverCard>
+<HoverCard openDelay={200} closeDelay={150}>
ui/src/stories/tabs.stories.tsx (2)

16-24: Add aria-label to Basic tabs example.

Enhance accessibility by adding descriptive aria-labels to the tabs component.

-<Tabs defaultValue="account">
+<Tabs defaultValue="account" aria-label="Account settings">

85-97: Extract SVG icons and enhance accessibility.

Consider extracting SVG icons into separate components and adding proper accessibility attributes.

-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
+<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">

Also applies to: 101-114

ui/src/stories/dropdown-menu.stories.tsx (1)

58-69: Add cross-platform keyboard shortcuts.

Consider showing different shortcuts for Windows/Linux users.

-New Tab <DropdownMenuShortcut>⌘T</DropdownMenuShortcut>
+New Tab <DropdownMenuShortcut>{isMac ? '⌘T' : 'Ctrl+T'}</DropdownMenuShortcut>
ui/src/stories/form.stories.tsx (1)

161-215: Add error boundary to form examples.

Wrap form examples with error boundaries to handle runtime errors gracefully.

+import { ErrorBoundary } from 'react-error-boundary';

 export const DifferentStates: Story = {
   render: () => (
+    <ErrorBoundary fallback={<div>Something went wrong</div>}>
       <div className="space-y-8">
         // ... existing code ...
       </div>
+    </ErrorBoundary>
   ),
 };
ui/src/stories/navigation-menu.stories.tsx (3)

23-44: Add accessibility improvements to ListItem component

Consider enhancing the component with aria-label and prop types validation.

 const ListItem = React.forwardRef<React.ElementRef<'a'>, React.ComponentPropsWithoutRef<'a'>>(
   ({ className, title, children, ...props }, ref) => {
     return (
       <li>
         <NavigationMenuLink asChild>
           <a
             ref={ref}
+            aria-label={title}
             className={cn(
               'hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors',
               className,
             )}
             {...props}
           >

46-70: Add aria-label to navigation menu

Enhance accessibility by adding an aria-label to the navigation menu.

-    <NavigationMenu>
+    <NavigationMenu aria-label="Main navigation">

160-180: Add documentation for custom styling approach

Consider adding comments to explain the custom styling methodology for better maintainability.

 // Custom Styled
+// This story demonstrates how to override default styles using Tailwind classes
+// primary and primary-foreground colors are defined in the theme configuration
 export const CustomStyled: Story = {
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2d28b07 and 3824032.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (35)
  • package.json (1 hunks)
  • ui/.gitignore (1 hunks)
  • ui/.storybook/main.js (1 hunks)
  • ui/.storybook/preview.js (1 hunks)
  • ui/package.json (2 hunks)
  • ui/src/components/button.tsx (1 hunks)
  • ui/src/logos/spinner-icon.tsx (1 hunks)
  • ui/src/stories/accordion.stories.tsx (1 hunks)
  • ui/src/stories/alert.stories.tsx (1 hunks)
  • ui/src/stories/avatar.stories.tsx (1 hunks)
  • ui/src/stories/badge.stories.tsx (1 hunks)
  • ui/src/stories/button.stories.tsx (1 hunks)
  • ui/src/stories/card.stories.tsx (1 hunks)
  • ui/src/stories/carousel.stories.tsx (1 hunks)
  • ui/src/stories/checkbox.stories.tsx (1 hunks)
  • ui/src/stories/collapsible.stories.tsx (1 hunks)
  • ui/src/stories/dialog.stories.tsx (1 hunks)
  • ui/src/stories/dropdown-menu.stories.tsx (1 hunks)
  • ui/src/stories/form.stories.tsx (1 hunks)
  • ui/src/stories/hover-card.stories.tsx (1 hunks)
  • ui/src/stories/input.stories.tsx (1 hunks)
  • ui/src/stories/label.stories.tsx (1 hunks)
  • ui/src/stories/menubar.stories.tsx (1 hunks)
  • ui/src/stories/navigation-menu.stories.tsx (1 hunks)
  • ui/src/stories/popover.stories.tsx (1 hunks)
  • ui/src/stories/progress.stories.tsx (1 hunks)
  • ui/src/stories/radio-group.stories.tsx (1 hunks)
  • ui/src/stories/select.stories.tsx (1 hunks)
  • ui/src/stories/separator.stories.tsx (1 hunks)
  • ui/src/stories/switch.stories.tsx (1 hunks)
  • ui/src/stories/table.stories.tsx (1 hunks)
  • ui/src/stories/tabs.stories.tsx (1 hunks)
  • ui/src/stories/toggle.stories.tsx (1 hunks)
  • ui/src/stories/tooltip.stories.tsx (1 hunks)
  • ui/src/stories/typography.stories.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • ui/.gitignore
  • ui/src/components/button.tsx
🔇 Additional comments (14)
ui/src/logos/spinner-icon.tsx (3)

1-2: LGTM! Imports are clean and necessary.


4-4: LGTM! Component signature is well-typed.


17-22: Verify licensing requirements for copied SVG.

Since this SVG was copied from another site, please verify and document any licensing or attribution requirements.

ui/src/stories/alert.stories.tsx (2)

1-13: LGTM! Well-structured Storybook configuration.

The meta configuration and imports are properly set up following Storybook best practices.


3-3: Verify Alert component exports.

Let's ensure the Alert component and its subcomponents are properly exported.

✅ Verification successful

Alert component imports are correct

The Alert components are properly exported from ui/src/components/alert.tsx and match the imports in the stories file.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if Alert components are properly exported
ast-grep --pattern 'export { Alert, AlertDescription, AlertTitle }' ui/src/components/alert/index.ts

Length of output: 182


Script:

#!/bin/bash
# Find alert-related files
fd alert.ts -t f
fd alert/index.ts -t f

Length of output: 71


Script:

#!/bin/bash
# Check exports in alert.tsx
ast-grep --pattern 'export function Alert' ui/src/components/alert.tsx
ast-grep --pattern 'export function AlertDescription' ui/src/components/alert.tsx
ast-grep --pattern 'export function AlertTitle' ui/src/components/alert.tsx

Length of output: 234


Script:

#!/bin/bash
# View the content of alert.tsx to understand export pattern
cat ui/src/components/alert.tsx

Length of output: 1709

ui/src/stories/badge.stories.tsx (1)

1-12: LGTM! Proper Storybook configuration.

The metadata setup and type definitions follow best practices.

ui/src/stories/label.stories.tsx (1)

1-116: Well-structured stories with good accessibility practices!

The Label stories effectively demonstrate various use cases while maintaining proper accessibility patterns.

ui/src/stories/radio-group.stories.tsx (1)

85-88: Implement form submission handler.

The form submission handler is currently empty.

Do you want me to generate an implementation for the form submission handler?

ui/src/stories/select.stories.tsx (1)

89-92: Implement form submission handler.

The form submission handler is currently empty.

Do you want me to generate an implementation for the form submission handler?

ui/src/stories/tooltip.stories.tsx (1)

1-21: LGTM! Well-structured imports and meta configuration.

ui/src/stories/navigation-menu.stories.tsx (2)

1-20: Well-structured Storybook configuration!

The meta configuration and imports are properly set up, with autodocs enabled for automatic documentation generation.


72-158: Well-implemented navigation menu variations!

The MultipleSections and WithActiveStates stories effectively demonstrate different use cases and states.

ui/package.json (1)

46-52: Verify Storybook version compatibility

The Storybook version 8.4.7 is quite recent. Please verify compatibility with the current React version (^18.2.0).

Also applies to: 64-64, 69-70

✅ Verification successful

Storybook 8.4.7 is compatible with React ^18.2.0

The peer dependencies explicitly support React versions ^18.0.0, which includes React ^18.2.0.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any compatibility issues between Storybook and React versions
npm info @storybook/react@8.4.7 peerDependencies

Length of output: 254

package.json (1)

46-47: Well-structured workspace scripts!

The ui:serve and ui:build scripts are properly configured using workspace references.

ui/src/logos/spinner-icon.tsx Outdated Show resolved Hide resolved
export const WithImage: Story = {
render: () => (
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace external image URL with local asset.

Using external URLs can make stories unreliable if the resource becomes unavailable.

-			<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
+			<AvatarImage src="/assets/avatar-placeholder.png" alt="Avatar" />

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +64 to +86
// In Card Layout
export const InCardLayout: Story = {
render: () => (
<div className="space-y-4 rounded-lg border p-4">
<div className="flex items-center justify-between">
<h3 className="font-semibold">Account Settings</h3>
<button className="text-sm text-blue-500">Edit</button>
</div>
<Separator />
<div className="space-y-4">
<div>
<h4 className="text-sm font-medium">Email</h4>
<p className="text-muted-foreground text-sm">john@example.com</p>
</div>
<Separator />
<div>
<h4 className="text-sm font-medium">Password</h4>
<p className="text-muted-foreground text-sm">Last changed 3 months ago</p>
</div>
</div>
</div>
),
};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add aria-label to the edit button.

The edit button needs an aria-label for better accessibility.

-<button className="text-sm text-blue-500">Edit</button>
+<button className="text-sm text-blue-500" aria-label="Edit account settings">Edit</button>
📝 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
// In Card Layout
export const InCardLayout: Story = {
render: () => (
<div className="space-y-4 rounded-lg border p-4">
<div className="flex items-center justify-between">
<h3 className="font-semibold">Account Settings</h3>
<button className="text-sm text-blue-500">Edit</button>
</div>
<Separator />
<div className="space-y-4">
<div>
<h4 className="text-sm font-medium">Email</h4>
<p className="text-muted-foreground text-sm">john@example.com</p>
</div>
<Separator />
<div>
<h4 className="text-sm font-medium">Password</h4>
<p className="text-muted-foreground text-sm">Last changed 3 months ago</p>
</div>
</div>
</div>
),
};
// In Card Layout
export const InCardLayout: Story = {
render: () => (
<div className="space-y-4 rounded-lg border p-4">
<div className="flex items-center justify-between">
<h3 className="font-semibold">Account Settings</h3>
<button className="text-sm text-blue-500" aria-label="Edit account settings">Edit</button>
</div>
<Separator />
<div className="space-y-4">
<div>
<h4 className="text-sm font-medium">Email</h4>
<p className="text-muted-foreground text-sm">john@example.com</p>
</div>
<Separator />
<div>
<h4 className="text-sm font-medium">Password</h4>
<p className="text-muted-foreground text-sm">Last changed 3 months ago</p>
</div>
</div>
</div>
),
};

Comment on lines +97 to +108
<Button size="icon" variant="default">
<PlusIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="secondary">
<TrashIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="outline">
<ArrowRightIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="ghost">
<ChevronRightIcon className="h-4 w-4" />
</Button>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add aria-labels to icon-only buttons for accessibility.

Icon-only buttons need aria-labels to be accessible to screen readers.

 <Button size="icon" variant="default">
+  <span className="sr-only">Add item</span>
   <PlusIcon className="h-4 w-4" />
 </Button>
 <Button size="icon" variant="secondary">
+  <span className="sr-only">Delete item</span>
   <TrashIcon className="h-4 w-4" />
 </Button>
 <Button size="icon" variant="outline">
+  <span className="sr-only">Next item</span>
   <ArrowRightIcon className="h-4 w-4" />
 </Button>
 <Button size="icon" variant="ghost">
+  <span className="sr-only">Show more</span>
   <ChevronRightIcon className="h-4 w-4" />
 </Button>
📝 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
<Button size="icon" variant="default">
<PlusIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="secondary">
<TrashIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="outline">
<ArrowRightIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="ghost">
<ChevronRightIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="default">
<span className="sr-only">Add item</span>
<PlusIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="secondary">
<span className="sr-only">Delete item</span>
<TrashIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="outline">
<span className="sr-only">Next item</span>
<ArrowRightIcon className="h-4 w-4" />
</Button>
<Button size="icon" variant="ghost">
<span className="sr-only">Show more</span>
<ChevronRightIcon className="h-4 w-4" />
</Button>

Comment on lines +89 to +94
<label htmlFor="email" className="text-sm font-medium">
Email
</label>
<Input id="email" type="email" placeholder="Enter email" className="border-destructive" />
<p className="text-destructive text-sm">Please enter a valid email address</p>
</div>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance error state accessibility.

Add ARIA attributes to properly communicate the error state to screen readers.

 <label htmlFor="email" className="text-sm font-medium">
   Email
 </label>
-<Input id="email" type="email" placeholder="Enter email" className="border-destructive" />
-<p className="text-destructive text-sm">Please enter a valid email address</p>
+<Input 
+  id="email" 
+  type="email" 
+  placeholder="Enter email" 
+  className="border-destructive"
+  aria-invalid="true"
+  aria-describedby="email-error"
+/>
+<p id="email-error" className="text-destructive text-sm">Please enter a valid email address</p>
📝 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
<label htmlFor="email" className="text-sm font-medium">
Email
</label>
<Input id="email" type="email" placeholder="Enter email" className="border-destructive" />
<p className="text-destructive text-sm">Please enter a valid email address</p>
</div>
<label htmlFor="email" className="text-sm font-medium">
Email
</label>
<Input
id="email"
type="email"
placeholder="Enter email"
className="border-destructive"
aria-invalid="true"
aria-describedby="email-error"
/>
<p id="email-error" className="text-destructive text-sm">Please enter a valid email address</p>
</div>

Comment on lines +49 to +61
export const Interactive: Story = {
render: () => (
<Card className="w-[350px] cursor-pointer transition-shadow hover:shadow-lg">
<CardHeader>
<CardTitle>Interactive Card</CardTitle>
<CardDescription>This card has hover and click effects</CardDescription>
</CardHeader>
<CardContent>
<p>Click or hover over this card to see the effects.</p>
</CardContent>
</Card>
),
};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add keyboard interaction support to Interactive card.

The card has hover effects but should also support keyboard interactions for accessibility.

-<Card className="w-[350px] cursor-pointer transition-shadow hover:shadow-lg">
+<Card 
+  className="w-[350px] cursor-pointer transition-shadow hover:shadow-lg focus-visible:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
+  tabIndex={0}
+  role="button"
+  onKeyDown={(e) => {
+    if (e.key === 'Enter' || e.key === ' ') {
+      // Handle interaction
+      e.preventDefault();
+    }
+  }}
+>
📝 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 Interactive: Story = {
render: () => (
<Card className="w-[350px] cursor-pointer transition-shadow hover:shadow-lg">
<CardHeader>
<CardTitle>Interactive Card</CardTitle>
<CardDescription>This card has hover and click effects</CardDescription>
</CardHeader>
<CardContent>
<p>Click or hover over this card to see the effects.</p>
</CardContent>
</Card>
),
};
export const Interactive: Story = {
render: () => (
<Card
className="w-[350px] cursor-pointer transition-shadow hover:shadow-lg focus-visible:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
tabIndex={0}
role="button"
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
// Handle interaction
e.preventDefault();
}
}}
>
<CardHeader>
<CardTitle>Interactive Card</CardTitle>
<CardDescription>This card has hover and click effects</CardDescription>
</CardHeader>
<CardContent>
<p>Click or hover over this card to see the effects.</p>
</CardContent>
</Card>
),
};

Comment on lines +139 to +142
<DialogFooter className="gap-2">
<Button variant="outline">Cancel</Button>
<Button variant="destructive">Yes, delete my account</Button>
</DialogFooter>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add confirmation step for destructive actions.

The delete account action should require a confirmation step, such as typing "delete" to confirm.

Comment on lines +16 to +22
const DemoSlide = ({ children }: { children: React.ReactNode }) => (
<Card className="m-1">
<CardContent className="flex aspect-square items-center justify-center p-6">
<span className="text-4xl font-semibold">{children}</span>
</CardContent>
</Card>
);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add keyboard navigation support to DemoSlide component.

The DemoSlide component should support keyboard navigation for better accessibility.

 const DemoSlide = ({ children }: { children: React.ReactNode }) => (
   <Card className="m-1">
     <CardContent className="flex aspect-square items-center justify-center p-6">
-      <span className="text-4xl font-semibold">{children}</span>
+      <span className="text-4xl font-semibold" tabIndex={0} role="region">
+        {children}
+      </span>
     </CardContent>
   </Card>
 );
📝 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
const DemoSlide = ({ children }: { children: React.ReactNode }) => (
<Card className="m-1">
<CardContent className="flex aspect-square items-center justify-center p-6">
<span className="text-4xl font-semibold">{children}</span>
</CardContent>
</Card>
);
const DemoSlide = ({ children }: { children: React.ReactNode }) => (
<Card className="m-1">
<CardContent className="flex aspect-square items-center justify-center p-6">
<span className="text-4xl font-semibold" tabIndex={0} role="region">
{children}
</span>
</CardContent>
</Card>
);

Comment on lines +159 to +161
<span className="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800">
Completed
</span>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance status indicators for accessibility.

Add aria-labels and icons to status indicators for better accessibility.

-<span className="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800">
+<span role="status" aria-label="Order completed" className="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800">
   Completed
 </span>

Also applies to: 169-171, 179-181

ui/src/stories/form.stories.tsx Show resolved Hide resolved
Copy link

@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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 837e8e7 and 25a3669.

📒 Files selected for processing (7)
  • ui/src/components/button.tsx (1 hunks)
  • ui/src/index.ts (1 hunks)
  • website/src/app/[lang]/[region]/(website)/me/contributions/contributions-table.tsx (1 hunks)
  • website/src/app/[lang]/[region]/(website)/me/donation-certificates/donation-certificates-table.tsx (1 hunks)
  • website/src/app/[lang]/[region]/(website)/me/subscriptions/subscriptions-client.tsx (1 hunks)
  • website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx (1 hunks)
  • website/src/app/[lang]/[region]/(website)/newsletter/subscription-info-form.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (5)
  • website/src/app/[lang]/[region]/(website)/newsletter/subscription-info-form.tsx
  • website/src/app/[lang]/[region]/(website)/me/donation-certificates/donation-certificates-table.tsx
  • website/src/app/[lang]/[region]/(website)/me/contributions/contributions-table.tsx
  • website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx
  • website/src/app/[lang]/[region]/(website)/me/subscriptions/subscriptions-client.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • ui/src/components/button.tsx
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Test website
  • GitHub Check: Prettify
  • GitHub Check: Security checks (typescript)
🔇 Additional comments (1)
ui/src/index.ts (1)

27-27: LGTM! Good organization.

The empty line helps separate component exports from icon exports.

ui/src/index.ts Show resolved Hide resolved
Copy link

@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 (2)
ui/src/icons/donate.tsx (1)

Line range hint 17-18: Consider removing commented color values.

The commented-out fill="#FAC800" values are redundant since the icon uses currentColor.

-				// fill="#FAC800"

Also applies to: 21-22

ui/package.json (1)

70-71: Consider adding documentation for Storybook scripts.

Add a README section explaining how to use these scripts, especially since PR objectives mention using npm run ui:serve instead of npm run storybook.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7f2cc90 and 2d37a19.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • ui/package.json (2 hunks)
  • ui/src/icons/donate.tsx (1 hunks)
  • ui/src/index.ts (1 hunks)
  • website/src/components/navbar/navbar-client.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • website/src/components/navbar/navbar-client.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • ui/src/index.ts
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Test website
  • GitHub Check: Prettify
  • GitHub Check: Security checks (typescript)
🔇 Additional comments (3)
ui/src/icons/donate.tsx (1)

13-13: LGTM! Props spreading enhances component flexibility.

The addition of props spreading allows the component to be more versatile by supporting event handlers and accessibility attributes.

ui/package.json (2)

43-43: Verify the tailwind-merge version upgrade.

The upgrade from v2.4.0 to v2.5.3 needs validation for breaking changes.

✅ Verification successful

The tailwind-merge upgrade is safe to proceed

The changes from v2.4.0 to v2.5.3 contain only performance improvements and bug fixes, with no breaking changes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for breaking changes in tailwind-merge changelog
curl -s https://raw.githubusercontent.com/dcastil/tailwind-merge/v2.5.3/CHANGELOG.md | grep -A 5 "## \[2.5"

Length of output: 109


Script:

#!/bin/bash
# Try GitHub API for release info
gh api repos/dcastil/tailwind-merge/releases | jq -r '.[] | select(.tag_name | startswith("v2.5")) | {tag_name, body}'

# Fetch NPM package info as backup
npm view tailwind-merge@2.5.3 repository.url changelog

Length of output: 3477


47-53: Verify Storybook version compatibility.

The Storybook v8.4.7 dependencies are in beta/preview. This version might be unstable.

Also applies to: 65-65

Copy link

@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)
.github/workflows/deploy-storybook.yml (3)

6-6: Remove unnecessary comment about default branch.

The comment # Or your default branch name is redundant since main is explicitly specified.

-      - main  # Or your default branch name
+      - main

57-57: Add newline at end of file.

Add a newline character at the end of the file to comply with POSIX standards.

   uses: actions/deploy-pages@v4
+
🧰 Tools
🪛 yamllint (1.35.1)

[error] 57-57: no new line character at the end of file

(new-line-at-end-of-file)


23-25: Document the expected URL pattern.

Consider adding a comment explaining the expected format of the Storybook URL (e.g., https://{org}.github.io/{repo}/).

   environment:
     name: github-pages
+    # URL format: https://{org}.github.io/{repo}/
     url: ${{ steps.deployment.outputs.page_url }}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2d37a19 and f17bc4b.

📒 Files selected for processing (1)
  • .github/workflows/deploy-storybook.yml (1 hunks)
🧰 Additional context used
🪛 yamllint (1.35.1)
.github/workflows/deploy-storybook.yml

[error] 57-57: no new line character at the end of file

(new-line-at-end-of-file)

🪛 actionlint (1.7.4)
.github/workflows/deploy-storybook.yml

33-33: shellcheck reported issue in this script: SC2086:info:1:31: Double quote to prevent globbing and word splitting

(shellcheck)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Test website
  • GitHub Check: Prettify
  • GitHub Check: Security checks (typescript)
🔇 Additional comments (1)
.github/workflows/deploy-storybook.yml (1)

11-19: Well-configured permissions and concurrency settings!

The configuration follows security best practices by using minimal permissions and preventing deployment conflicts.

.github/workflows/deploy-storybook.yml Outdated Show resolved Hide resolved
Copy link

@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

♻️ Duplicate comments (1)
.github/workflows/deploy-storybook.yml (1)

31-34: ⚠️ Potential issue

Fix shell script quoting in .nvmrc reading step.

The command needs proper quoting to prevent potential issues.

-        run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_OUTPUT
+        run: echo "NVMRC=$(cat '.nvmrc')" >> "$GITHUB_OUTPUT"
🧰 Tools
🪛 actionlint (1.7.4)

33-33: shellcheck reported issue in this script: SC2086:info:1:31: Double quote to prevent globbing and word splitting

(shellcheck)

🧹 Nitpick comments (1)
.github/workflows/deploy-storybook.yml (1)

44-46: Add error handling to the build step.

Consider adding error handling and workspace validation to make the build step more robust.

       - name: Build Storybook
-        run: npm run ui:build
+        run: |
+          if [ ! -d "ui" ]; then
+            echo "Error: ui directory not found"
+            exit 1
+          fi
+          npm run ui:build || {
+            echo "Error: Storybook build failed"
+            exit 1
+          }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f17bc4b and ae27d8c.

📒 Files selected for processing (1)
  • .github/workflows/deploy-storybook.yml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.4)
.github/workflows/deploy-storybook.yml

33-33: shellcheck reported issue in this script: SC2086:info:1:31: Double quote to prevent globbing and word splitting

(shellcheck)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Test website
  • GitHub Check: Prettify
  • GitHub Check: Security checks (typescript)
🔇 Additional comments (2)
.github/workflows/deploy-storybook.yml (2)

1-9: LGTM! Well-configured workflow triggers.

The workflow name is descriptive and the triggers are properly set up for both automated (main branch) and manual execution.


11-20: LGTM! Secure permissions and proper concurrency handling.

The configuration follows security best practices with minimal required permissions and prevents deployment conflicts.

Copy link

@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

♻️ Duplicate comments (1)
.github/workflows/deploy-storybook.yml (1)

29-41: ⚠️ Potential issue

Fix shell script quoting in .nvmrc reading step.

The command needs proper quoting to prevent globbing and word splitting issues.

-        run: echo "NVMRC=$(cat '.nvmrc')" >> $GITHUB_OUTPUT
+        run: echo "NVMRC=$(cat '.nvmrc')" >> "$GITHUB_OUTPUT"
🧰 Tools
🪛 actionlint (1.7.4)

31-31: shellcheck reported issue in this script: SC2086:info:1:33: Double quote to prevent globbing and word splitting

(shellcheck)

🧹 Nitpick comments (1)
.github/workflows/deploy-storybook.yml (1)

42-55: Add build output verification step.

Consider adding a step to verify the Storybook build output path exists before upload.

       - name: Build Storybook
         run: npm run ui:build
 
+      - name: Verify build output
+        run: |
+          if [ ! -d "ui/storybook-static" ]; then
+            echo "Error: Storybook build output directory not found"
+            exit 1
+          fi
+
       - name: Setup Pages
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ae27d8c and 5bc6625.

📒 Files selected for processing (1)
  • .github/workflows/deploy-storybook.yml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.4)
.github/workflows/deploy-storybook.yml

31-31: shellcheck reported issue in this script: SC2086:info:1:33: Double quote to prevent globbing and word splitting

(shellcheck)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Prettify
🔇 Additional comments (4)
.github/workflows/deploy-storybook.yml (4)

1-13: LGTM! Well-defined workflow with proper permissions.

The workflow name is descriptive and the permissions follow the principle of least privilege.


14-18: LGTM! Good concurrency configuration.

Prevents deployment conflicts and optimizes CI resources.


19-24: LGTM! Proper environment configuration.

Correctly sets up GitHub Pages environment with dynamic URL.


26-28: LGTM! Using latest checkout action.

Good practice to use the latest v4 version.

Copy link

@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)
ui/.storybook/main.js (5)

3-9: Add error handling to getAbsolutePath function.

The function should handle cases where the package.json cannot be resolved.

 function getAbsolutePath(value) {
+    try {
         return dirname(require.resolve(join(value, 'package.json')));
+    } catch (error) {
+        throw new Error(`Could not resolve package path for ${value}: ${error.message}`);
+    }
 }

15-19: Consider adding more Storybook addons for enhanced development experience.

Consider adding these useful addons:

  • @storybook/addon-a11y for accessibility testing
  • @storybook/addon-viewport for responsive design testing
 addons: [
     getAbsolutePath('@storybook/addon-onboarding'),
     getAbsolutePath('@storybook/addon-essentials'),
     getAbsolutePath('@storybook/addon-interactions'),
+    getAbsolutePath('@storybook/addon-a11y'),
+    getAbsolutePath('@storybook/addon-viewport'),
 ],

21-24: Document framework options for future reference.

Add a comment explaining available framework options for future customization needs.

 framework: {
     name: getAbsolutePath('@storybook/react-vite'),
-    options: {},
+    options: {
+        // Available options:
+        // builder: {} // Configure the Vite builder
+        // fastRefresh: true // Enable/disable fast refresh
+    },
 },

26-32: Consider additional Vite optimizations.

The current configuration only enables PostCSS. Consider adding other useful Vite configurations for better development experience.

 viteFinal: async (config) => {
     // Use PostCSS config from postcss.config.js
     config.css = {
         postcss: true,
     };
+    // Add optimizations for development
+    if (process.env.NODE_ENV === 'development') {
+        config.optimizeDeps = {
+            include: ['@storybook/react'],
+        };
+    }
     return config;
 },

34-38: Add documentation configuration options.

The docs configuration is empty. Consider adding explicit options for better documentation generation.

-docs: {},
+docs: {
+    autodocs: true,
+    defaultName: 'Documentation',
+    docsMode: true,
+},
ui/src/stories/icons.stories.tsx (3)

33-42: Add JSDoc comment to document available sizes.

Document the supported size variations for better developer experience.

+/**
+ * Demonstrates available icon sizes:
+ * - Small: h-4 w-4 (16px)
+ * - Medium: h-6 w-6 (24px)
+ * - Large: h-8 w-8 (32px)
+ * - Extra Large: h-12 w-12 (48px)
+ */
 export const Sizes: Story = {

44-53: Add JSDoc comment to document color usage.

Document when to use each color variant.

+/**
+ * Demonstrates themed color variants:
+ * - accent: Used for highlighting or emphasis
+ * - primary: Main brand color
+ * - secondary: Supporting elements
+ * - destructive: Warning or delete actions
+ */
 export const Colors: Story = {

55-64: Reuse size variations and document animation.

Consider extracting size variations into a shared constant and document the animation behavior.

+const ICON_SIZES = [
+  { className: "h-4 w-4", label: "Small" },
+  { className: "h-6 w-6", label: "Medium" },
+  { className: "h-8 w-8", label: "Large" },
+  { className: "h-12 w-12", label: "Extra Large" },
+] as const;
+
+/**
+ * Demonstrates the loading spinner with built-in animation.
+ * The spinner rotates continuously using CSS animation.
+ */
 export const AnimatedSpinner: Story = {
 	render: () => (
 		<div className="flex flex-wrap items-center gap-4">
-			<SpinnerIcon className="h-4 w-4" />
-			<SpinnerIcon className="h-6 w-6" />
-			<SpinnerIcon className="h-8 w-8" />
-			<SpinnerIcon className="h-12 w-12" />
+			{ICON_SIZES.map(({ className }) => (
+				<SpinnerIcon key={className} className={className} />
+			))}
 		</div>
 	),
 };
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5bc6625 and f5d6d0c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • ui/.storybook/main.js (1 hunks)
  • ui/.storybook/preview.js (1 hunks)
  • ui/package.json (1 hunks)
  • ui/src/stories/icons.stories.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • ui/.storybook/preview.js
  • ui/package.json
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Prettify
🔇 Additional comments (2)
ui/.storybook/main.js (1)

11-13: LGTM! Well-structured stories configuration.

The stories pattern covers all necessary file types and follows Storybook's recommended structure.

ui/src/stories/icons.stories.tsx (1)

1-13: LGTM! Clean imports and proper Storybook configuration.

The metadata setup with autodocs will help generate automatic documentation.

Comment on lines +14 to +31
export const AllIcons: Story = {
render: () => (
<div className="flex flex-wrap gap-8">
<div className="flex flex-col items-center gap-2">
<DonateIcon className="h-8 w-8" />
<span className="text-sm">DonateIcon</span>
</div>
<div className="flex flex-col items-center gap-2">
<SIIcon className="h-8 w-8" />
<span className="text-sm">SIIcon</span>
</div>
<div className="flex flex-col items-center gap-2">
<SpinnerIcon className="h-8 w-8" />
<span className="text-sm">SpinnerIcon</span>
</div>
</div>
),
};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add aria-labels for accessibility.

The icons should have aria-labels for screen readers.

-				<DonateIcon className="h-8 w-8" />
+				<DonateIcon className="h-8 w-8" aria-label="Donate icon" />
-				<SIIcon className="h-8 w-8" />
+				<SIIcon className="h-8 w-8" aria-label="SI icon" />
-				<SpinnerIcon className="h-8 w-8" />
+				<SpinnerIcon className="h-8 w-8" aria-label="Loading spinner" />
📝 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 AllIcons: Story = {
render: () => (
<div className="flex flex-wrap gap-8">
<div className="flex flex-col items-center gap-2">
<DonateIcon className="h-8 w-8" />
<span className="text-sm">DonateIcon</span>
</div>
<div className="flex flex-col items-center gap-2">
<SIIcon className="h-8 w-8" />
<span className="text-sm">SIIcon</span>
</div>
<div className="flex flex-col items-center gap-2">
<SpinnerIcon className="h-8 w-8" />
<span className="text-sm">SpinnerIcon</span>
</div>
</div>
),
};
export const AllIcons: Story = {
render: () => (
<div className="flex flex-wrap gap-8">
<div className="flex flex-col items-center gap-2">
<DonateIcon className="h-8 w-8" aria-label="Donate icon" />
<span className="text-sm">DonateIcon</span>
</div>
<div className="flex flex-col items-center gap-2">
<SIIcon className="h-8 w-8" aria-label="SI icon" />
<span className="text-sm">SIIcon</span>
</div>
<div className="flex flex-col items-center gap-2">
<SpinnerIcon className="h-8 w-8" aria-label="Loading spinner" />
<span className="text-sm">SpinnerIcon</span>
</div>
</div>
),
};

Copy link

@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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f5d6d0c and 4f772a9.

📒 Files selected for processing (4)
  • ui/.storybook/main.js (1 hunks)
  • ui/.storybook/preview.js (1 hunks)
  • ui/package.json (2 hunks)
  • ui/src/stories/icons.stories.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • ui/.storybook/preview.js
  • ui/src/stories/icons.stories.tsx
  • ui/.storybook/main.js
🔇 Additional comments (2)
ui/package.json (2)

70-71: LGTM: Storybook scripts are correctly configured.

The scripts for running and building Storybook are properly set up.


43-43: Verify the tailwind-merge version upgrade.

The update from ^2.4.0 to ^2.5.3 should be checked for breaking changes.

✅ Verification successful

The tailwind-merge upgrade is safe

The update to v2.5.3 contains only non-breaking changes: a bug fix for border colors, documentation updates, and internal test improvements.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for breaking changes in tailwind-merge changelog
curl -s https://raw.githubusercontent.com/dcastil/tailwind-merge/v2.5.3/CHANGELOG.md | grep -A 5 "## \[2.5"

Length of output: 109


Script:

#!/bin/bash
# Query npm registry for tailwind-merge package information
curl -s https://registry.npmjs.org/tailwind-merge | jq -r '.versions["2.5.3"].dist.tarball' | xargs curl -s | tar -xzO package/CHANGELOG.md | grep -A 10 "## \[2.5"

Length of output: 269


Script:

#!/bin/bash
# Query GitHub API for release information
curl -s "https://api.github.com/repos/dcastil/tailwind-merge/releases/tags/v2.5.3" | jq -r '.body'

Length of output: 702

ui/package.json Show resolved Hide resolved
Copy link

@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: 2

🧹 Nitpick comments (1)
ui/src/icons/spinner.tsx (1)

14-14: Consider users who prefer reduced motion.

The spinner uses animate-spin class but doesn't respect user's motion preferences.

Add a media query to pause animation for users who prefer reduced motion:

-			className={twMerge('h-5 w-5 animate-spin', className)}
+			className={twMerge('h-5 w-5 animate-spin motion-reduce:animate-none', className)}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4f772a9 and cc06be1.

📒 Files selected for processing (3)
  • ui/src/icons/donate.tsx (1 hunks)
  • ui/src/icons/si.tsx (1 hunks)
  • ui/src/icons/spinner.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • ui/src/icons/donate.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Prettify

@@ -9,12 +9,12 @@ export function SIIcon({ className, ...props }: HTMLAttributes<SVGElement>) {
xmlSpace="preserve"
fill="currentColor"
aria-hidden={true}
aria-labelledby="si-icon"
aria-labelledby="si-icon-title"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix conflicting ARIA attributes.

While the matching of aria-labelledby with id is good, having both aria-hidden="true" and aria-labelledby is contradictory. aria-hidden removes the element from the accessibility tree, preventing screen readers from announcing the title.

Choose one approach:

 <svg
   version="1.1"
   xmlns="http://www.w3.org/2000/svg"
   xmlSpace="preserve"
   fill="currentColor"
-  aria-hidden={true}
   aria-labelledby="si-icon-title"
   viewBox="0 0 816 815.8"
   className={twMerge('text-accent', className)}
   {...props}
 >
   <title id="si-icon-title">Social Income Icon</title>

Or if the icon should be decorative:

 <svg
   version="1.1"
   xmlns="http://www.w3.org/2000/svg"
   xmlSpace="preserve"
   fill="currentColor"
   aria-hidden={true}
-  aria-labelledby="si-icon-title"
   viewBox="0 0 816 815.8"
   className={twMerge('text-accent', className)}
   {...props}
 >
-  <title id="si-icon-title">Social Income Icon</title>

Also applies to: 17-17

Comment on lines 9 to +12
xmlSpace="preserve"
fill="none"
aria-hidden={true}
aria-labelledby="si-logo-title"
aria-labelledby="spinner-icon-title"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix contradicting accessibility attributes.

The SVG has both aria-hidden="true" and aria-labelledby which contradict each other. aria-hidden="true" hides the element from screen readers while aria-labelledby tries to label it for screen readers.

Apply this diff to resolve the contradiction:

-			aria-hidden={true}
-			aria-labelledby="spinner-icon-title"
+			aria-hidden={false}
+			aria-labelledby="spinner-icon-title"
+			role="status"
📝 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
xmlSpace="preserve"
fill="none"
aria-hidden={true}
aria-labelledby="si-logo-title"
aria-labelledby="spinner-icon-title"
xmlSpace="preserve"
fill="none"
aria-hidden={false}
aria-labelledby="spinner-icon-title"
role="status"

@almsh almsh merged commit 2b387bd into main Jan 23, 2025
16 checks passed
@almsh almsh deleted the almsh/add-storybook branch January 23, 2025 16:34
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.

[Web]: Add Storybook to store components
3 participants