Skip to content

chore: tailwind-configuration #63

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

Merged
merged 93 commits into from
Apr 15, 2025
Merged

chore: tailwind-configuration #63

merged 93 commits into from
Apr 15, 2025

Conversation

tractorss
Copy link
Contributor

@tractorss tractorss commented Mar 7, 2025

PR-Codex overview

This PR focuses on a significant refactor of the codebase, including the removal of unused files, updates to styling and component structures, and enhancements to Storybook stories for better component documentation and testing.

Detailed summary

  • Deleted multiple unused configuration and source files.
  • Updated src/index.html to include a stylesheet.
  • Refactored various components to use utility functions for class names.
  • Enhanced Storybook stories for various components, including forms, buttons, and progress indicators.
  • Introduced new components and improved existing ones with better props and structure.
  • Adjusted TypeScript configurations for stricter type checking.
  • Updated global styles to incorporate Tailwind CSS utilities.

The following files were skipped due to too many changes: src/stories/text-area.stories.tsx, src/stories/number-field.stories.tsx, src/lib/dropdown/select/simple-button.tsx, src/lib/tag/index.tsx, src/lib/progress/timeline/index.tsx, src/lib/display/icon.tsx, src/lib/dropdown/select/dropdown-button.tsx, src/lib/form/datepicker/arrow-button.tsx, src/stories/dropdown-cascader.stories.tsx, src/stories/radioGroup.stories.tsx, src/lib/form/datepicker/time-control.tsx, src/lib/dropdown/cascader/item.tsx, src/lib/progress/steps/bullet.tsx, src/stories/dropdown-select.stories.tsx, eslint.config.mjs, src/lib/copiable/index.tsx, src/lib/form/switch.tsx, src/lib/form/slider.tsx, src/lib/progress/steps/bullet-circle.tsx, src/lib/progress/timeline/spine.tsx, src/lib/form/searchbar.tsx, src/lib/accordion/accordion-item.tsx, src/lib/form/datepicker/calendar.tsx, src/lib/breadcrumb.tsx, src/stories/custom-timeline.stories.tsx, src/lib/form/datepicker/display-button.tsx, src/lib/form/radio-group.tsx, src/stories/bignumber-field.stories.tsx, src/lib/button/index.tsx, src/lib/form/text-area.tsx, src/lib/form/checkbox.tsx, src/lib/form/text-field.tsx, src/lib/progress/steps/horizontal-bullet.tsx, src/lib/dropdown/select/index.tsx, src/lib/progress/circular/index.tsx, src/lib/dropdown/cascader/dropdown-container.tsx, src/lib/messages/push.tsx, src/lib/pagination/compact.tsx, src/lib/messages/alert.tsx, src/lib/progress/linear/index.tsx, package.json, src/lib/form/number-field.tsx, src/lib/dropdown/cascader/index.tsx, src/lib/pagination/standard.tsx, src/lib/form/bignumber-field/index.tsx, src/lib/form/datepicker/index.tsx, src/lib/progress/timeline/bullet.tsx, src/lib/pagination/tabs.tsx, src/styles/theme.css, README.md, src/lib/tooltip/index.tsx, src/lib/form/file-uploader.tsx, src/stories/KlerosUIComponentsLibrary.mdx, src/lib/form/bignumber-field/useBigNumberField.tsx, yarn.lock

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Introduced BigNumberField for large numeric inputs with formatting and step controls.
    • Added accessible DatePicker with time selection, RadioGroup, TextArea, NumberField, Slider, and Searchbar using React Aria.
    • Added accessible dropdown, cascader, and select components with multi-level and keyboard navigation support.
    • Enhanced FileUploader with drag-and-drop support via React Aria primitives.
    • Added Storybook stories and documentation with theme support and usage examples.
    • Implemented global theming via CSS variables and Tailwind CSS integration.
  • Refactor

    • Migrated all components from styled-components to utility-first CSS (Tailwind) and React Aria for accessibility and consistency.
    • Replaced custom stateful UI implementations with declarative, accessible React Aria primitives.
    • Consolidated component APIs for improved developer experience and accessibility.
    • Removed legacy styled-components, CSS-in-JS, and manual event handling in favor of declarative patterns.
    • Updated pagination, progress, timeline, accordion, dropdown, button, and form components to use utility classes and React Aria.
    • Removed legacy example files and deprecated theme exports.
    • Updated global styles and scrollbar components to use utility CSS classes.
  • Chores

    • Switched build system from Parcel to Vite; updated scripts, dependencies, and Volta configuration.
    • Upgraded ESLint, Prettier, TypeScript, Tailwind CSS, and Storybook configurations.
    • Removed Parcel configuration and .babelrc.
    • Added comprehensive README and Storybook MDX landing page for documentation.
    • Updated .gitignore and lint-staged configurations for improved workflow.
    • Added new ESLint configuration using FlatCompat and updated TypeScript excludes.
    • Added Vite configuration files for library and theme builds.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
Copy link
Contributor

coderabbitai bot commented Mar 7, 2025

Walkthrough

This update introduces a comprehensive refactor and modernization of the UI components library. The build system is migrated from Parcel to Vite, and the codebase transitions from styled-components to utility-first CSS using Tailwind and react-aria-components for accessibility and composability. Many components are reimplemented to remove custom state and styling in favor of accessible primitives and utility classes. Theming is now handled via CSS variables and theme files, with dark and light modes defined in CSS. Numerous example files and legacy components are deleted, replaced by new, composable, and accessible counterparts. The package configuration, linting, and formatting tools are updated, and extensive Storybook stories are added for component documentation and testing.

Changes

File(s) / Path(s) Change Summary
package.json, tsconfig.json, .gitignore, .lintstagedrc.json, .prettierrc, .babelrc, .eslintrc.json, eslint.config.mjs, .parcelrc, vite.config.ts, vite.config.theme.ts, .storybook/main.ts, .storybook/preview.tsx Migrated build system from Parcel to Vite; updated to ES module conventions; added Tailwind CSS, react-aria-components, and related plugins; updated scripts, dependencies, and peer dependencies; revised linting and formatting configs; introduced Storybook and Vite configs; removed Parcel and styled-components related settings.
src/styles/global.css, src/styles/theme.css Introduced new global and theme CSS files defining Tailwind base, utility classes, scrollbar styles, and CSS variables for light/dark themes; removed styled-components global styles.
src/lib/**/*, src/utils/index.ts Major refactor of all core components: removed styled-components usage, replaced with utility-first CSS and react-aria-components; reimplemented most components for accessibility and composability; introduced new components (e.g., BigNumberField, NumberField, TextField, TextArea, Slider, RadioGroup); added utility functions for class name merging and type guards; removed legacy/duplicate components and files.
src/examples/*, src/styles/common-style.ts, src/styles/global-style.ts, src/styles/themes.ts, src/lib/form/field.tsx, src/lib/form/textarea.tsx, src/lib/form/radio.tsx, src/lib/form/slider/index.tsx, src/lib/form/slider/handle.tsx, src/lib/form/datepicker/*, src/lib/dropdown/base-item.tsx, src/lib/dropdown/base-item-container.tsx, src/lib/dropdown/button.tsx, src/lib/dropdown/simple-button.tsx, src/lib/dropdown/select/button.tsx, src/lib/dropdown/select/item-container.tsx, src/lib/dropdown/select/index.tsx, src/lib/dropdown/select/item.tsx, src/lib/dropdown/select/dropdown-container.tsx, src/lib/dropdown/cascader/item-container.tsx, src/lib/dropdown/cascader/selector.tsx, src/lib/dropdown/cascader/index.tsx, src/lib/dropdown/cascader/button.tsx, src/lib/dropdown/cascader/dropdown-container.tsx, src/lib/dropdown/cascader/item.tsx, src/lib/dropdown/cascader/select-button.tsx Deleted legacy example files, styled-components theme files, and obsolete component implementations; replaced dropdown and cascader logic with new react-aria-components-based implementations; restructured dropdown/cascader item and container logic; removed old field, textarea, radio, and slider implementations.
src/global.d.ts, global.d.ts Updated global TypeScript declarations for SVG imports; removed styled-components theme typings.
README.md Expanded and restructured documentation: added introduction, features, component list, usage, theming, development, publishing, contributing, and license sections.
index.html Updated resource paths for stylesheet and script to use absolute paths.
src/stories/* Added comprehensive Storybook stories for all major components, including usage examples and variants; introduced MDX documentation page.

Sequence Diagram(s)

Loading
sequenceDiagram
    participant User
    participant UIComponent
    participant ReactAria
    participant UtilityCSS
    participant ThemeCSS

    User->>UIComponent: Interacts with component (e.g., click, input)
    UIComponent->>ReactAria: Delegates accessibility and state logic
    UIComponent->>UtilityCSS: Applies utility CSS classes for styling
    UIComponent->>ThemeCSS: Reads CSS variables for theming (light/dark)
    ReactAria-->>UIComponent: Provides state, accessibility props
    UtilityCSS-->>UIComponent: Applies styles
    ThemeCSS-->>UIComponent: Supplies theme colors/variables
    UIComponent-->>User: Renders accessible, themed UI

Possibly related PRs

  • kleros/ui-components-library#60: Refactored Checkbox and Tooltip components from styled-components to react-aria-components and utility CSS, similar to the broad refactoring in this PR.
  • kleros/ui-components-library#54: Modified Checkbox dark mode styling using styled-components, which is now superseded by the react-aria and utility CSS refactor in this PR.
  • kleros/ui-components-library#69: Refactored button components to use react-aria's AriaButton and utility CSS, which aligns with the button refactoring in this PR.

Suggested reviewers

  • alcercu

Poem

A bunny hopped through fields of code,
Swapping styles for a lighter load.
Tailwind breezes, Aria's song,
Parcel's gone, Vite moves along.
Components now accessible, bright—
With every hop, the UI feels light!
🐇✨


🪧 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 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 or @coderabbitai title 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: 1

🧹 Nitpick comments (1)
src/styles/global.css (1)

113-128: Form Elements Styling

Inputs, optgroups, selects, and textareas have standardized styling applied via Tailwind. Consider extending this to handle focus or active states for improved user experience.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4d5a869 and 0d021bd.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • .postcssrc (1 hunks)
  • .prettierrc.json (1 hunks)
  • package.json (3 hunks)
  • src/index.html (1 hunks)
  • src/styles/global.css (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/styles/global.css

[error] 29-29: Invalid color

(parse)

🔇 Additional comments (20)
.postcssrc (1)

1-5: Tailwind PostCSS Configuration Setup

The configuration correctly registers the @tailwindcss/postcss plugin, which will enable Tailwind CSS to process your styles through PostCSS.

package.json (7)

31-31: Dependency Added: @tailwindcss/postcss

The Tailwind PostCSS plugin is added with version ^4.0.11, aligning with your Tailwind integration.


48-48: Parcel Version Update

The Parcel dependency has been updated to ^2.13.3, ensuring you benefit from recent fixes and features. Please verify that all Parcel-specific configurations or customizations remain compatible.


50-50: Prettier Plugin for TailwindCSS Added

The inclusion of prettier-plugin-tailwindcss (version ^0.6.11) enhances class ordering for Tailwind. This aligns well with the new .prettierrc.json setup.


53-53: TailwindCSS Dependency Addition

The tailwindcss dependency (version ^4.0.11) is correctly added, ensuring that Tailwind’s functionality is available within your build process.


57-62: Peer Dependencies Update for Tailwind Integration

Adding @tailwindcss/postcss and tailwindcss to peerDependencies (along with their expected versions) ensures that any consumer of this library uses compatible versions. Consider verifying that these constraints align with your broader dependency management strategy.


67-67: Dependency Added: clsx

The clsx library (version ^2.1.1) is added to help with conditional className concatenation, which is useful in React component development.


82-83: Volta Node Version Update

The Node version in the Volta configuration has been updated from 16.20.1 to 20.18.3. This upgrade should provide performance improvements and new language features. Please verify that your build tools and library code are fully compatible with Node 20.

.prettierrc.json (1)

1-3: Prettier Configuration for TailwindCSS

The configuration enables the use of prettier-plugin-tailwindcss, which will improve the readability and consistency of Tailwind class names in your project.

src/index.html (1)

6-6: Global Stylesheet Inclusion

The added <link href="./styles/global.css" type="text/css" rel="stylesheet" /> in the <head> section integrates the new global styles that are based on Tailwind CSS and your custom theming.

src/styles/global.css (10)

1-1: Tailwind CSS Import

Importing Tailwind at the top of your CSS file ensures that Tailwind’s utilities and base styles are available before applying your customizations.


3-35: Custom CSS Variables for Default Theme

Within the @layer base block and the :root selector, a comprehensive set of CSS custom properties is defined for colors, typography, and spacing.

Note: A static analysis tool flagged an issue on line 29 regarding an invalid color value.

🧰 Tools
🪛 Biome (1.9.4)

[error] 29-29: Invalid color

(parse)


37-69: Dark Mode Theme Variables

The dark mode configuration under :root[class="dark"] is well structured with alternative color values to suit dark themes. Ensure that the contrast and accessibility standards meet the design guidelines.


71-90: Typography Styles Implementation

The typography rules for headings (h1, h2), paragraphs (p), and small tags effectively use Tailwind’s @apply directive to standardize styling.


92-112: Element Styles Consistency

The styles for elements like hr, svg, img, and button ensure consistent behavior across browsers. The hover effects on buttons are also appropriately defined.


129-132: Box-Sizing Normalization

The .border-box class along with its universal selector usage ensures consistent box-sizing across your components.


134-141: Transition Effects

The classes .hover-short-transition and .hover-long-transition provide useful hover transition durations that enhance interactivity.


143-150: Hover Background Effects

The classes .hover-medium-blue and .hover-white-background apply background color changes on hover using predefined custom properties.


152-167: Fade-In Animation Definition

The keyframe animation fadeIn and the associated .fade-in class offer a smooth visual effect. This animation is well defined for transitional UI elements.


170-216: @theme Block Mapping

The final block maps your custom properties to theme-specific variables, enhancing reusability and consistency across your project. Verify that your build tools or CSS processors recognize the @theme at-rule.

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 (3)
src/styles/global.css (3)

1-2: Tailwind CSS Import Directive: Validate Import Method

The use of @import "tailwindcss"; correctly brings in Tailwind’s styles; however, in newer Tailwind CSS versions it’s common to use the directive-based syntax (i.e. @tailwind base;, @tailwind components;, and @tailwind utilities;). Please verify that your build pipeline and PostCSS configuration support your chosen import method.


37-69: Dark Mode Custom Properties: Verify Contrast and Consistency

The dark mode overrides provided in the :root[class="dark"] block are well structured. Please double-check that the chosen color values offer sufficient contrast for readability and accessibility in dark mode. Additionally, ensure consistency in naming and that these values are in line with the design system.


170-216: Theme Mapping Block (@theme): Ensure Build Tool Compatibility

The custom @theme block that maps your CSS custom properties to theme-specific aliases is innovative. Please verify that your build and PostCSS toolchain support custom at-rules like @theme, and consider simplifying the multi-line variable declarations (if feasible) to improve readability and reduce potential parsing issues in some environments.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 0d021bd and 2210d55.

📒 Files selected for processing (1)
  • src/styles/global.css (1 hunks)
🔇 Additional comments (2)
src/styles/global.css (2)

3-35: Default Theme Custom Properties: Verify Color Values and Consistency

The :root block defines a comprehensive set of custom properties for the default theme. Notably, the color values (including --klerosUIComponentsErrorLight set to #FEF0F3) are now valid and correctly formatted. Ensure that these values align with your design guidelines and that any past concerns (e.g. invalid hex lengths) have been fully resolved.


71-168: Typography & Element Styling with Tailwind’s @apply: Conformance Check

The usage of Tailwind’s @apply directive in styling typography (headings, paragraphs, small text) and common elements (buttons, inputs, images, etc.) is concise and maintainable. Confirm that these styles match your UI components library’s design standards and that no unintended overrides occur.

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 (3)
.eslintrc.json (3)

23-24: Switch to Legacy Security Configuration:
The update replaces "plugin:security/recommended" with "plugin:security/recommended-legacy", which appears to be an intentional change for compatibility or project-specific reasons. Please verify that this legacy configuration meets your current security requirements and that you have a plan for eventual migration if needed.


30-30: Reformatting Plugins Array for Readability:
The plugins array has been reformatted into a single line, which improves clarity and consistency with the rest of the configuration. This change is stylistic and does not affect functionality.


39-39: Clean Up of Import Resolver Extensions:
The extensions array in the import/resolver settings is now on a single line. This reformatting makes it easier to read and maintain while preserving its functionality.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 2210d55 and 38a5f0a.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (18)
  • .eslintrc.json (3 hunks)
  • .prettierrc (1 hunks)
  • package.json (2 hunks)
  • src/examples/input.tsx (1 hunks)
  • src/hooks/pagination/use-pagination.tsx (2 hunks)
  • src/hooks/useElementSize.ts (1 hunks)
  • src/hooks/useResizeObserver.ts (1 hunks)
  • src/lib/breadcrumb.tsx (1 hunks)
  • src/lib/dropdown/cascader/index.tsx (4 hunks)
  • src/lib/dropdown/cascader/selector.tsx (1 hunks)
  • src/lib/dropdown/select/index.tsx (1 hunks)
  • src/lib/form/datepicker/day.tsx (2 hunks)
  • src/lib/form/datepicker/dropdown.tsx (3 hunks)
  • src/lib/form/datepicker/month.tsx (1 hunks)
  • src/lib/form/datepicker/time-selector.tsx (1 hunks)
  • src/lib/messages/alert.tsx (1 hunks)
  • src/lib/progress/steps/horizontal-bullet.tsx (2 hunks)
  • src/styles/common-style.ts (1 hunks)
✅ Files skipped from review due to trivial changes (16)
  • src/hooks/pagination/use-pagination.tsx
  • src/hooks/useResizeObserver.ts
  • src/lib/form/datepicker/dropdown.tsx
  • src/lib/form/datepicker/time-selector.tsx
  • src/lib/breadcrumb.tsx
  • src/lib/form/datepicker/month.tsx
  • src/examples/input.tsx
  • .prettierrc
  • src/lib/dropdown/select/index.tsx
  • src/lib/messages/alert.tsx
  • src/lib/progress/steps/horizontal-bullet.tsx
  • src/lib/dropdown/cascader/selector.tsx
  • src/styles/common-style.ts
  • src/hooks/useElementSize.ts
  • src/lib/dropdown/cascader/index.tsx
  • src/lib/form/datepicker/day.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🔇 Additional comments (2)
.eslintrc.json (2)

44-44: Consistent max-len Rule Formatting:
The max-len rule has been updated to { "code": 80 } for improved readability and consistency. This minor reformatting aids in maintaining a clean configuration file.


57-58: Streamlined no-console Rule Configuration:
The no-console rule now permits ["warn", "error", "info", "debug"] in a single-line format. This adjustment is purely for readability and does not change the rule's functionality.

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/hooks/use-focus-outside.tsx (2)

5-5: Consider using a more specific function type signature.

While the ESLint rule has been updated, the underlying issue of using the generic Function type could be improved by using a more specific function signature to gain better type safety.

-function useFocusOutside(ref: any, callback: Function) {
+function useFocusOutside(ref: React.RefObject<HTMLElement>, callback: () => void) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 5-5: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


7-7: Consider using a more specific event type.

The event: any parameter could be typed more specifically for better type safety.

-function handleEvent(event: any) {
+function handleEvent(event: MouseEvent | FocusEvent) {
src/lib/dropdown/simple-button.tsx (1)

69-70: Consider using a typed function signature.

While the ESLint directive has been updated to the more specific rule, the use of the generic Function type could be improved for better type safety.

-  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
-  setIsOpen: Function;
+  setIsOpen: (isOpen: boolean) => void;
🧰 Tools
🪛 Biome (1.9.4)

[error] 70-70: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

src/lib/messages/push.tsx (1)

75-76: Consider using a more specific function type instead of the generic Function

While the ESLint rule has been updated from ban-types to no-unsafe-function-type, using the generic Function type still isn't type-safe. Consider defining a more specific callback signature:

- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
- callback: Function;
+ callback: () => void;

This approach provides better type safety and eliminates the need for the ESLint disable comment altogether.

🧰 Tools
🪛 Biome (1.9.4)

[error] 76-76: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

src/lib/dropdown/button.tsx (1)

46-47: Replace generic Function type with a specific function signature

While the ESLint rule has been updated from ban-types to no-unsafe-function-type, using the generic Function type still lacks type safety. Consider defining a more specific function signature:

- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
- setIsOpen: Function;
+ setIsOpen: (isOpen: boolean) => void;

This provides better type safety and IDE support while eliminating the need for the ESLint disable comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 47-47: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

src/lib/form/file-uploader.tsx (3)

80-81: Define a specific callback signature instead of using generic Function

Similar to other components, consider replacing the generic Function type with a specific function signature for better type safety:

- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
- callback: Function;
+ callback: (file: File) => void;

This provides better type checking and documentation while removing the need for the ESLint disable comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 81-81: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


132-134: Handle potential null values safely

The non-null assertion (!) on event.target.files could lead to runtime errors if files is null. Consider a safer approach:

- setFileSelected(event.target.files![0]);
- callback(event.target.files![0]);
+ const files = event.target.files;
+ if (files && files.length > 0) {
+   setFileSelected(files[0]);
+   callback(files[0]);
+ }

This guards against potential null/undefined values and empty file selections.


94-94: Replace any type with a more specific type

The ref is typed as any with a TODO comment. Consider using a more specific type:

- const fileInputRef = useRef<any>(); //! type
+ const fileInputRef = useRef<HTMLInputElement>(null);

This provides better type safety and IDE support.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 38a5f0a and 90d6cef.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (14)
  • .eslintrc.json (0 hunks)
  • eslint.config.mjs (1 hunks)
  • package.json (2 hunks)
  • src/hooks/use-focus-outside.tsx (1 hunks)
  • src/hooks/useElementSize.ts (1 hunks)
  • src/lib/breadcrumb.tsx (2 hunks)
  • src/lib/dropdown/button.tsx (1 hunks)
  • src/lib/dropdown/simple-button.tsx (1 hunks)
  • src/lib/form/file-uploader.tsx (2 hunks)
  • src/lib/form/slider/handle.tsx (1 hunks)
  • src/lib/form/slider/index.tsx (1 hunks)
  • src/lib/messages/push.tsx (1 hunks)
  • src/lib/pagination/tabs.tsx (1 hunks)
  • tsconfig.json (1 hunks)
💤 Files with no reviewable changes (1)
  • .eslintrc.json
✅ Files skipped from review due to trivial changes (3)
  • src/lib/form/slider/handle.tsx
  • src/lib/pagination/tabs.tsx
  • src/lib/form/slider/index.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/lib/breadcrumb.tsx
  • src/hooks/useElementSize.ts
  • package.json
🔇 Additional comments (6)
src/hooks/use-focus-outside.tsx (1)

4-4: Updated ESLint directive to use more specific rule.

The ESLint directive has been updated from the generic @typescript-eslint/ban-types to the more specific @typescript-eslint/no-unsafe-function-type rule. This change is consistent with similar updates in other files and better represents the specific issue being suppressed.

eslint.config.mjs (3)

1-121: Well-structured modern ESLint configuration.

The new ESLint configuration using the flat config format is well-organized and comprehensive. It properly integrates various plugins and sets up appropriate rules for a TypeScript React project.


90-96: Good handling of unused variables.

The configuration for unused variables is well thought out, providing specific patterns for ignoring variables that are intentionally unused.


47-64:

✅ Verification successful

Verify TypeScript parser configuration.

The TypeScript parser is configured with ECMAScript 2020. Make sure this aligns with your project's targets and browser compatibility requirements.


🏁 Script executed:

#!/bin/bash
# Check package.json for browserslist or TypeScript target configuration
grep -r "browserslist\|target" package.json
# Check if there are any TypeScript files using features beyond ES2020
rg "\\?\\?=" --type ts

Length of output: 123


ESLint TypeScript Parser Config Verification

The current ESLint configuration in eslint.config.mjs correctly sets the ECMAScript version to 2020, which aligns with the project's compatibility target as defined in your package.json browserslist ("> 0.5%, last 2 versions, not dead"). Additionally, the absence of TypeScript files using features beyond ES2020 confirms that the parser configuration is appropriate. If you plan to adopt newer ECMAScript features later, remember to update both the parser configuration and your compatibility targets accordingly.

tsconfig.json (2)

34-35: Added exclusion for new ESLint config file.

The addition of eslint.config.mjs to the excluded files is appropriate as it shouldn't be processed by TypeScript.


1-37: Stricter type checking with implicit index errors enabled.

The removal of suppressImplicitAnyIndexErrors from the compiler options (based on the AI summary) is a positive change that enforces stricter type checking, helping to catch potential type errors related to object indexing.

tractorss and others added 6 commits March 10, 2025 20:51
chore: accordion-migration
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: 2

🔭 Outside diff range comments (3)
src/lib/accordion/index.tsx (1)

31-39: ⚠️ Potential issue

Fix syntax errors in component structure.

There are multiple syntax errors in the component structure, including:

  1. Duplicated state declaration (lines 31 and 36)
  2. Component signature is broken (missing function declaration)
  3. Inconsistent className usage

This code will not compile. Fix the structure to properly define the Accordion component:

-  const [expanded, setExpanded] = useState(defaultExpanded ?? -1);
-  return (
-    <div
-      className={clsx("box-border flex w-[1000px] flex-col", className)}
-}) => {
-  const [expanded, setExpanded] = useState(defaultExpanded ?? -1);
-  return (
-    <div className="border-box flex w-[1000px] flex-col" {...props}>
+const Accordion: React.FC<AccordionProps> = ({ items, defaultExpanded, ...props }) => {
+  const [expanded, setExpanded] = useState(defaultExpanded ?? -1);
+  return (
+    <div className="border-box flex w-[1000px] flex-col" {...props}>
package.json (1)

81-91: ⚠️ Potential issue

Fix duplicate volta configuration.

There's a duplicate volta configuration in the package.json file.

  "volta": {
    "node": "20.18.3",
    "yarn": "1.22.19"
  },
  "packageManager": "[email protected]+sha256.732620bac8b1690d507274f025f3c6cfdc3627a84d9642e38a07452cc00e0f2e"
- "volta": {
-   "node": "20.18.3",
-   "yarn": "1.22.19"
- },
- "packageManager": "[email protected]+sha256.732620bac8b1690d507274f025f3c6cfdc3627a84d9642e38a07452cc00e0f2e"
}
src/lib/accordion/accordion-item.tsx (1)

10-10: ⚠️ Potential issue

Duplicate prop declaration

The setExpanded prop is declared twice in the AccordionItemProps interface (lines 9 and 10).

 interface AccordionItemProps {
   setExpanded: React.Dispatch<React.SetStateAction<number>>;
-  setExpanded: React.Dispatch<React.SetStateAction<number>>;
   index: number;
   title: ReactNode;
   body: ReactNode;
   expanded?: boolean;
 }
♻️ Duplicate comments (1)
src/styles/global.css (1)

29-29: ⚠️ Potential issue

Invalid Color Value Detected

The value assigned to --klerosUIComponentsErrorLight appears as #FEFF0F3, which is invalid since hex color codes should be 3, 4, 6, or 8 characters long (after the #). This appears to be a typo.

-  --klerosUIComponentsErrorLight: #FEFF0F3;
+  --klerosUIComponentsErrorLight: #FFF0F3;
🧹 Nitpick comments (3)
src/lib/accordion/custom.tsx (1)

22-25: Consider making the width more responsive.

While the clsx usage is good, the fixed width of 1000px might limit responsiveness on different screen sizes.

-      className={clsx("box-border flex w-[1000px] flex-col", className)}
+      className={clsx("box-border flex w-full max-w-[1000px] flex-col", className)}
src/App.tsx (1)

69-80: Theme toggle implementation needs refinement.

The implementation works but has a few areas for improvement:

  1. The "temporary" comment suggests this is an interim solution
  2. There's no synchronization of initial state between styled-components and Tailwind themes
  3. Consider extracting this logic to a custom hook for better reusability
-  // temporary
-  const changeTheme = () => {
-    if (tailwindTheme === "dark") {
-      document.documentElement.classList.remove("dark");
-      setTailwindTheme("light");
-    } else {
-      document.documentElement.classList.add("dark");
-      setTailwindTheme("dark");
-    }
-    if (theme === lightTheme) setTheme(darkTheme);
-    else setTheme(lightTheme);
-  };
+  // Handle theme toggling for both styled-components and Tailwind
+  const changeTheme = () => {
+    const newTailwindTheme = tailwindTheme === "dark" ? "light" : "dark";
+    const newTheme = theme === lightTheme ? darkTheme : lightTheme;
+    
+    // Update Tailwind theme
+    if (newTailwindTheme === "dark") {
+      document.documentElement.classList.add("dark");
+    } else {
+      document.documentElement.classList.remove("dark");
+    }
+    
+    // Update state
+    setTailwindTheme(newTailwindTheme);
+    setTheme(newTheme);
+  };
src/styles/global.css (1)

170-216: Consider simplifying theme variable mapping

The theme mapping creates duplicate CSS variables with a --color- prefix. This approach might add unnecessary complexity and increase CSS size. If possible, consider using the original variables directly in your components.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 896fd94 and c4cbd5f.

⛔ Files ignored due to path filters (6)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (30)
  • package.json (3 hunks)
  • src/styles/global.css (1 hunks)
  • src/styles/global.css (1 hunks)
  • package.json (1 hunks)
  • eslint.config.mjs (1 hunks)
  • package.json (2 hunks)
  • package.json (1 hunks)
  • eslint.config.mjs (1 hunks)
  • src/App.tsx (2 hunks)
  • src/lib/accordion/accordion-item.tsx (2 hunks)
  • src/lib/accordion/custom.tsx (2 hunks)
  • src/lib/accordion/index.tsx (4 hunks)
  • src/styles/global.css (3 hunks)
  • src/lib/accordion/accordion-item.tsx (2 hunks)
  • src/lib/accordion/custom.tsx (1 hunks)
  • src/lib/accordion/index.tsx (2 hunks)
  • src/styles/global.css (1 hunks)
  • src/lib/accordion/index.tsx (1 hunks)
  • package.json (1 hunks)
  • src/lib/accordion/accordion-item.tsx (3 hunks)
  • src/lib/accordion/accordion-item.tsx (1 hunks)
  • src/lib/accordion/custom.tsx (2 hunks)
  • src/lib/accordion/index.tsx (1 hunks)
  • eslint.config.mjs (1 hunks)
  • package.json (1 hunks)
  • src/App.tsx (2 hunks)
  • src/lib/accordion/accordion-item.tsx (2 hunks)
  • src/lib/accordion/custom.tsx (3 hunks)
  • src/lib/accordion/index.tsx (3 hunks)
  • src/styles/global.css (3 hunks)
✅ Files skipped from review due to trivial changes (4)
  • src/lib/accordion/index.tsx
  • src/lib/accordion/index.tsx
  • src/lib/accordion/accordion-item.tsx
  • src/lib/accordion/custom.tsx
🚧 Files skipped from review as they are similar to previous changes (11)
  • package.json
  • eslint.config.mjs
  • package.json
  • eslint.config.mjs
  • package.json
  • eslint.config.mjs
  • package.json
  • src/styles/global.css
  • src/styles/global.css
  • src/styles/global.css
  • package.json
🔇 Additional comments (15)
src/lib/accordion/custom.tsx (3)

3-3: Good addition of clsx for class name composition.

Adding clsx library is appropriate for composing class names, especially when transitioning to a utility-first CSS approach with Tailwind.


12-12: LGTM: Good enhancement of component props.

Adding an optional className prop allows for better component customization and follows best practices for composable React components.


15-19: Component signature properly updated.

The function signature has been appropriately updated to destructure the newly added className prop along with existing props.

src/App.tsx (2)

66-66: Good addition of tailwindTheme state.

Adding a separate state for Tailwind's theme is a good approach for managing the dual theming system during transition.


124-124: Good simplification of onClick handler.

The onClick handler has been properly updated to use the extracted changeTheme function instead of an inline function.

src/lib/accordion/index.tsx (3)

3-3: Good addition of clsx for class name composition.

Adding clsx library is appropriate for composing class names in the Tailwind CSS implementation.


20-27: Good transition to utility classes.

The DefaultTitle component has been properly updated to use utility classes instead of styled-components, which aligns with the Tailwind approach.


48-49: ⚠️ Potential issue

Missing closing braces from component.

The component's closing structure is incomplete.

Fix the component's closing structure:

      ))}
-    </div>
+    </div>

Likely an incorrect or invalid review comment.

package.json (3)

82-82:

❓ Verification inconclusive

Node version update might require dependency review.

The significant node version update from 16.x to 20.x might require a review of dependencies for compatibility.


🏁 Script executed:

#!/bin/bash
# Check if any package.json dependencies have Node engine restrictions
grep -r "\"engines\":" --include="package.json" .

Length of output: 41946


Action Required: Verify Dependency Compatibility with Node 20

The Node version bump from 16.x to 20.x is significant. The grep results show that many packages in our node_modules declare their own "engines" fields (mostly indicating minimum versions like ">=10"). However, none of these explicitly restrict upgrading to Node 20. Since our top-level package.json doesn’t impose an "engines" field that might block Node 20, the risk seems low—but this change still warrants a careful look.

  • Confirm that any direct dependencies (or those critical at runtime) have been tested and are fully compatible with Node 20.
  • Consider checking release notes for key packages, especially those influencing build or linting (e.g., lint-staged), to ensure there are no subtle compatibility issues.

79-79: ⚠️ Potential issue

Remove misplaced lint-staged configuration.

This line appears to be a fragment from lint-staged configuration that shouldn't be in the dependencies section.

    "simplebar": "^5.3.6",
    "simplebar-react": "^2.3.6",
-   "*.{js,css,md}": "prettier --write"

Likely an incorrect or invalid review comment.


31-31:

✅ Verification successful

Verify Tailwind CSS version compatibility.

The specified version of Tailwind CSS (4.0.11) and @tailwindcss/postcss (4.0.11) seem unusually high. The current stable version of Tailwind CSS is typically around 3.x.

Also applies to: 57-57, 61-62


🌐 Web query:

What is the latest version of tailwindcss and @tailwindcss/postcss?

💡 Result:

The latest version of Tailwind CSS is v4.0.12 (released March 7, 2025), and the latest version of @tailwindcss/postcss is also v4.0.12 (updated March 11, 2025)[1][4][10][9].

Key Details:

Tailwind CSS v4.0

  • Major release on January 22, 2025, with significant performance improvements (full builds up to 5x faster, incremental builds 100x faster)[1][4].
  • Introduced CSS-first configuration, automatic content detection, and native CSS variables for theme customization[1][4][6].
  • Now ships with a dedicated Vite plugin and simplified installation requiring just @import "tailwindcss"; in CSS[4][5].

@tailwindcss/postcss

  • Part of Tailwind CSS v4's modular architecture, handling PostCSS integration[5][8].
  • Latest patch (v4.0.12) includes fixes for URL rebasing in CSS imports and template file processing[10].

For new projects, installation now involves:

npm install tailwindcss @tailwindcss/postcss
@import "tailwindcss";

For existing projects, use the official upgrade tool:

npx @tailwindcss/upgrade

Both packages are maintained in lockstep, with frequent updates for compatibility and performance[9][10].

Citations:


Tailwind CSS Versions Are Consistent with Latest Stable Releases

After verifying current release data, Tailwind CSS and its accompanying package are now in the 4.0.x series—with the latest patch at v4.0.12. The versions specified in your package.json (v4.0.11 on lines 57 and 61–62) are nearly up-to-date. If you’d like to benefit from the latest patch fixes, consider updating to v4.0.12; otherwise, these versions are fully compatible.

src/lib/accordion/accordion-item.tsx (1)

25-58: Good implementation of Tailwind CSS conversion

The styled-components have been successfully replaced with div elements and Tailwind utility classes. The use of clsx for conditionally applying classes is a good practice.

src/styles/global.css (3)

1-4: Good Tailwind CSS integration

The file correctly imports Tailwind CSS and sets up the layer structure. Using @layer base ensures these styles are applied with the appropriate specificity within Tailwind's cascade.


71-90: Well-structured typography styles

The typography styles are well-organized and properly use Tailwind's @apply directive combined with CSS custom properties for colors. This approach provides good flexibility while maintaining a consistent design system.


152-167: Good implementation of animation

The fadeIn animation is well-defined with appropriate keyframes and timing. The .fade-in class makes it easy to apply this animation to elements throughout the application.

alcercu and others added 7 commits March 11, 2025 12:38
feat: migrate to vite and add storybook
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: 4

🔭 Outside diff range comments (1)
vite.config.ts (1)

9-19: ⚠️ Potential issue

Fix configuration structure issues

There are several structural issues in the Vite configuration that need to be fixed.

export default defineConfig({
  build: {
-  build: {
    lib: {
      entry: resolve(__dirname, "src/lib/index.ts"),
      name: "Kleros-UI-Components",
    },
  },
-    svgr({
-      include: "**/*.svg",
-    }),
-    tailwindcss(),
-  ],
+  plugins: [
+    svgr({
+      include: "**/*.svg",
+    }),
+    tailwindcss(),
+  ],
});
-  ],
-});

This fixes:

  1. Duplicate build: entry
  2. Moves plugins to the correct location in the configuration structure
  3. Removes extra closing brackets
♻️ Duplicate comments (3)
eslint.config.mjs (1)

67-69: ⚠️ Potential issue

Action Required: Update React Version in ESLint Config

The React version in the ESLint configuration is set to "^16.12.0", which doesn't match the project's actual React version ("^18.0.0"). This mismatch could lead to incorrect linting rules being applied.

Apply this diff to update the React version:

      react: {
-        version: "^16.12.0",
+        version: "^18.0.0",
      },
src/lib/accordion/accordion-item.tsx (1)

51-51: ⚠️ Potential issue

Fix CSS transition duration syntax

The CSS class for the transition duration contains a syntax error. It uses parentheses around the CSS variable when it should use square brackets.

-  "transition-[height] duration-(--klerosUIComponentsTransitionSpeed) ease-initial",
+  "transition-[height] duration-[var(--klerosUIComponentsTransitionSpeed)] ease-initial",
src/styles/global.css (1)

29-29: ⚠️ Potential issue

Invalid Color Value Detected

The value assigned to --klerosUIComponentsErrorLight appears as #FEFF0F3, which is unusual since valid hex color codes are typically 3, 4, 6, or 8 characters long (after the #). Please verify if this value is a typo or requires correction.

🧹 Nitpick comments (7)
src/stories/Page.stories.ts (1)

4-4: Add file extension to import statement.

The import statement is missing a file extension, which violates the ESLint import/extensions rule defined in your project.

Apply this diff to fix the issue:

-import { Page } from "./Page";
+import { Page } from "./Page.tsx";

If the file has a different extension, adjust accordingly (.ts, .jsx, etc.).

🧰 Tools
🪛 ESLint

[error] 4-4: Missing file extension for "./Page"

(import/extensions)

src/stories/Header.tsx (1)

23-70: Consider using Tailwind CSS utility classes

Since this PR is adding Tailwind CSS configuration, consider refactoring the component to use Tailwind utility classes instead of relying on a separate CSS file.

For example, you could replace the className="storybook-header" with Tailwind classes like:

-<div className="storybook-header">
+<div className="flex items-center justify-between p-4 border-b">

This would align with the PR's objective of enhancing styling with Tailwind CSS.

src/App.tsx (2)

69-70: Remove or explain "temporary" comment

The "temporary" comment doesn't provide context on why this solution is temporary or what the permanent solution might be.

-  // temporary
+  // Toggle between light and dark themes for both Tailwind and styled-components

70-80: Improve theme toggle implementation

The current implementation has a few areas for improvement:

  1. Initialize Tailwind theme based on system preferences:
+  // Initialize theme based on user preferences
+  React.useEffect(() => {
+    const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
+    if (prefersDark) {
+      document.documentElement.classList.add("dark");
+      setTailwindTheme("dark");
+      setTheme(darkTheme);
+    }
+  }, []);
  1. Refactor the theme toggle function to be more concise:
  const changeTheme = () => {
-    if (tailwindTheme === "dark") {
-      document.documentElement.classList.remove("dark");
-      setTailwindTheme("light");
-    } else {
-      document.documentElement.classList.add("dark");
-      setTailwindTheme("dark");
-    }
-    if (theme === lightTheme) setTheme(darkTheme);
-    else setTheme(lightTheme);
+    const newTheme = tailwindTheme === "dark" ? "light" : "dark";
+    document.documentElement.classList.toggle("dark");
+    setTailwindTheme(newTheme);
+    setTheme(theme === lightTheme ? darkTheme : lightTheme);
  };
src/stories/Button.tsx (1)

19-41: Enhance Button component with Tailwind and accessibility improvements

Since this PR focuses on Tailwind CSS integration, consider updating the Button component to use Tailwind classes and improve accessibility.

export const Button = ({
  primary = false,
  size = "medium",
  backgroundColor,
  label,
+  className = "",
  ...props
}: ButtonProps) => {
-  const mode = primary
-    ? "storybook-button--primary"
-    : "storybook-button--secondary";
+  const baseClasses = "font-sans font-medium rounded";
+  const sizeClasses = {
+    small: "py-1.5 px-4 text-xs",
+    medium: "py-2 px-5 text-sm",
+    large: "py-2.5 px-6 text-base"
+  };
+  const colorClasses = primary
+    ? "bg-blue-600 text-white hover:bg-blue-700"
+    : "bg-gray-200 text-gray-800 hover:bg-gray-300";

  return (
    <button
      type="button"
-      className={["storybook-button", `storybook-button--${size}`, mode].join(
-        " ",
-      )}
+      className={`${baseClasses} ${sizeClasses[size]} ${colorClasses} ${className}`}
      style={{ backgroundColor }}
+      aria-label={label}
      {...props}
    >
      {label}
    </button>
  );
};

This implementation:

  1. Uses Tailwind utility classes instead of custom CSS
  2. Adds aria-label for better accessibility
  3. Allows className prop for additional customization
src/lib/accordion/index.tsx (1)

33-36: Consider making the width more flexible

The hardcoded width (w-[1000px]) might limit the component's reusability across different UI contexts. Consider making it more responsive or configurable.

-      className={clsx("box-border flex w-[1000px] flex-col", className)}
+      className={clsx("box-border flex w-full max-w-[1000px] flex-col", className)}
src/stories/Page.tsx (1)

22-88: Consider extracting content sections into separate components

The Page component contains a significant amount of static content. Consider extracting some of this content into separate components to improve readability and maintainability.

For example, you could create components like:

  • PageIntroduction for the introductory text
  • PageGuidelines for the best practices list
  • PageTip for the tip section

This would make the main Page component more concise and easier to understand.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between c4cbd5f and 227a8b0.

⛔ Files ignored due to path filters (41)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • src/stories/assets/accessibility.png is excluded by !**/*.png
  • src/stories/assets/accessibility.svg is excluded by !**/*.svg
  • src/stories/assets/addon-library.png is excluded by !**/*.png
  • src/stories/assets/assets.png is excluded by !**/*.png
  • src/stories/assets/context.png is excluded by !**/*.png
  • src/stories/assets/discord.svg is excluded by !**/*.svg
  • src/stories/assets/docs.png is excluded by !**/*.png
  • src/stories/assets/figma-plugin.png is excluded by !**/*.png
  • src/stories/assets/github.svg is excluded by !**/*.svg
  • src/stories/assets/share.png is excluded by !**/*.png
  • src/stories/assets/styling.png is excluded by !**/*.png
  • src/stories/assets/testing.png is excluded by !**/*.png
  • src/stories/assets/theming.png is excluded by !**/*.png
  • src/stories/assets/tutorials.svg is excluded by !**/*.svg
  • src/stories/assets/youtube.svg is excluded by !**/*.svg
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • src/stories/assets/accessibility.png is excluded by !**/*.png
  • src/stories/assets/accessibility.svg is excluded by !**/*.svg
  • src/stories/assets/addon-library.png is excluded by !**/*.png
  • src/stories/assets/assets.png is excluded by !**/*.png
  • src/stories/assets/context.png is excluded by !**/*.png
  • src/stories/assets/discord.svg is excluded by !**/*.svg
  • src/stories/assets/docs.png is excluded by !**/*.png
  • src/stories/assets/figma-plugin.png is excluded by !**/*.png
  • src/stories/assets/github.svg is excluded by !**/*.svg
  • src/stories/assets/share.png is excluded by !**/*.png
  • src/stories/assets/styling.png is excluded by !**/*.png
  • src/stories/assets/testing.png is excluded by !**/*.png
  • src/stories/assets/theming.png is excluded by !**/*.png
  • src/stories/assets/tutorials.svg is excluded by !**/*.svg
  • src/stories/assets/youtube.svg is excluded by !**/*.svg
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (85)
  • package.json (3 hunks)
  • src/styles/global.css (1 hunks)
  • src/styles/global.css (1 hunks)
  • package.json (1 hunks)
  • eslint.config.mjs (1 hunks)
  • package.json (2 hunks)
  • tsconfig.json (1 hunks)
  • package.json (1 hunks)
  • eslint.config.mjs (1 hunks)
  • src/App.tsx (2 hunks)
  • src/lib/accordion/accordion-item.tsx (2 hunks)
  • src/lib/accordion/custom.tsx (2 hunks)
  • src/lib/accordion/index.tsx (4 hunks)
  • src/styles/global.css (3 hunks)
  • src/lib/accordion/accordion-item.tsx (2 hunks)
  • src/lib/accordion/custom.tsx (1 hunks)
  • src/lib/accordion/index.tsx (2 hunks)
  • src/styles/global.css (1 hunks)
  • src/lib/accordion/index.tsx (1 hunks)
  • package.json (1 hunks)
  • src/lib/accordion/accordion-item.tsx (3 hunks)
  • src/lib/accordion/accordion-item.tsx (1 hunks)
  • src/lib/accordion/custom.tsx (2 hunks)
  • src/lib/accordion/index.tsx (1 hunks)
  • eslint.config.mjs (1 hunks)
  • package.json (1 hunks)
  • src/App.tsx (2 hunks)
  • src/lib/accordion/accordion-item.tsx (2 hunks)
  • src/lib/accordion/custom.tsx (3 hunks)
  • src/lib/accordion/index.tsx (3 hunks)
  • src/styles/global.css (3 hunks)
  • .gitignore (1 hunks)
  • .lintstagedrc.json (1 hunks)
  • .storybook/main.ts (1 hunks)
  • .storybook/preview.ts (1 hunks)
  • package.json (3 hunks)
  • src/stories/Button.stories.ts (1 hunks)
  • src/stories/Button.tsx (1 hunks)
  • src/stories/Configure.mdx (1 hunks)
  • src/stories/Header.stories.ts (1 hunks)
  • src/stories/Header.tsx (1 hunks)
  • src/stories/Page.stories.ts (1 hunks)
  • src/stories/Page.tsx (1 hunks)
  • src/stories/button.css (1 hunks)
  • src/stories/header.css (1 hunks)
  • src/stories/page.css (1 hunks)
  • tsconfig.json (1 hunks)
  • vite.config.ts (1 hunks)
  • eslint.config.mjs (1 hunks)
  • package.json (1 hunks)
  • src/App.tsx (2 hunks)
  • src/lib/accordion/accordion-item.tsx (2 hunks)
  • src/lib/accordion/custom.tsx (3 hunks)
  • src/lib/accordion/index.tsx (3 hunks)
  • src/styles/global.css (3 hunks)
  • .parcelrc (0 hunks)
  • index.html (1 hunks)
  • vite.config.ts (1 hunks)
  • eslint.config.mjs (0 hunks)
  • index.html (1 hunks)
  • package.json (1 hunks)
  • vite.config.ts (2 hunks)
  • package.json (1 hunks)
  • package.json (1 hunks)
  • vite.config.ts (2 hunks)
  • .gitignore (1 hunks)
  • .lintstagedrc.json (1 hunks)
  • .parcelrc (0 hunks)
  • .storybook/main.ts (1 hunks)
  • .storybook/preview.ts (1 hunks)
  • eslint.config.mjs (0 hunks)
  • index.html (1 hunks)
  • package.json (4 hunks)
  • src/stories/Button.stories.ts (1 hunks)
  • src/stories/Button.tsx (1 hunks)
  • src/stories/Configure.mdx (1 hunks)
  • src/stories/Header.stories.ts (1 hunks)
  • src/stories/Header.tsx (1 hunks)
  • src/stories/Page.stories.ts (1 hunks)
  • src/stories/Page.tsx (1 hunks)
  • src/stories/button.css (1 hunks)
  • src/stories/header.css (1 hunks)
  • src/stories/page.css (1 hunks)
  • tsconfig.json (1 hunks)
  • vite.config.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • .parcelrc
  • .parcelrc
✅ Files skipped from review due to trivial changes (15)
  • .gitignore
  • .gitignore
  • vite.config.ts
  • .storybook/main.ts
  • index.html
  • .storybook/main.ts
  • index.html
  • index.html
  • src/stories/header.css
  • src/stories/header.css
  • src/stories/page.css
  • src/stories/page.css
  • src/stories/button.css
  • src/stories/button.css
  • vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (28)
  • eslint.config.mjs
  • eslint.config.mjs
  • src/styles/global.css
  • package.json
  • package.json
  • src/lib/accordion/accordion-item.tsx
  • src/lib/accordion/accordion-item.tsx
  • eslint.config.mjs
  • tsconfig.json
  • package.json
  • tsconfig.json
  • package.json
  • src/lib/accordion/custom.tsx
  • src/lib/accordion/index.tsx
  • tsconfig.json
  • src/lib/accordion/index.tsx
  • src/lib/accordion/accordion-item.tsx
  • src/styles/global.css
  • src/lib/accordion/index.tsx
  • src/lib/accordion/custom.tsx
  • src/lib/accordion/custom.tsx
  • src/lib/accordion/custom.tsx
  • src/lib/accordion/custom.tsx
  • src/lib/accordion/index.tsx
  • package.json
  • src/styles/global.css
  • src/lib/accordion/index.tsx
  • package.json
🧰 Additional context used
🪛 ESLint
src/stories/Page.tsx

[error] 3-3: Missing file extension for "./Header"

(import/extensions)


[error] 3-3: Missing file extension for "./Header"

(import/extensions)

src/stories/Page.stories.ts

[error] 4-4: Missing file extension for "./Page"

(import/extensions)


[error] 4-4: Missing file extension for "./Page"

(import/extensions)

src/stories/Header.stories.ts

[error] 4-4: Missing file extension for "./Header"

(import/extensions)


[error] 4-4: Missing file extension for "./Header"

(import/extensions)

src/stories/Header.tsx

[error] 3-3: Missing file extension for "./Button"

(import/extensions)


[error] 3-3: Missing file extension for "./Button"

(import/extensions)

src/stories/Button.stories.ts

[error] 4-4: Missing file extension for "./Button"

(import/extensions)


[error] 4-4: Missing file extension for "./Button"

(import/extensions)

🔇 Additional comments (34)
eslint.config.mjs (2)

79-119: Well-structured ESLint rules configuration.

The rules configuration is comprehensive and tailored to the project needs, with good defaults for:

  • Line length limits
  • TypeScript unused variables with appropriate ignore patterns
  • Controlled console usage
  • Import extensions handling

These settings will help maintain code quality while reducing unnecessary noise during development.


22-38: Good use of ESLint flat config with comprehensive plugin extensions.

The configuration properly uses the modern ESLint flat config format with appropriate extensions for React, TypeScript, and security. The use of fixupConfigRules and fixupPluginRules ensures compatibility between the new flat config system and traditional plugin formats.

.lintstagedrc.json (1)

2-2: Improved developer workflow with auto-fixing capability.

Adding the --fix flag to ESLint in the lint-staged configuration allows automatic fixing of issues during the pre-commit phase, which improves developer experience and ensures consistent code style.

.storybook/preview.ts (1)

1-14: Clean Storybook preview configuration.

This is a standard and clean Storybook preview configuration that properly sets up control matchers for color and date properties. This configuration will help in automatically generating appropriate controls in the Storybook UI for props that match these patterns.

src/stories/Page.stories.ts (1)

20-32: Well-structured interactive Storybook story with testing.

The LoggedIn story includes an excellent play function that demonstrates how to test component interactions. The use of within, userEvent, and expect shows good practices for component testing within Storybook.

src/stories/Header.tsx (1)

4-4:

❓ Verification inconclusive

Verify the correct CSS filename casing

Ensure that the imported CSS file matches the actual filename on disk to avoid case-sensitivity issues across different operating systems.


🏁 Script executed:

#!/bin/bash
# Check if the header.css file exists and if its casing matches
fd --type file --exact-path "src/stories/header.css" || fd --type file --exact-path "src/stories/Header.css"

Length of output: 565


Action Required: Confirm CSS File Casing Consistency

The original comment is valid, but the verification script needs adjustment due to an incorrect flag. Please re-run the updated shell script below to check if either header.css or Header.css exists in the src/stories directory. This manual check is critical to ensure that the CSS import in src/stories/Header.tsx (line 4) references the file with the correct casing to avoid issues on case-sensitive file systems.

  • File Under Review: src/stories/Header.tsx
  • Concern: The CSS import (import "./header.css";) may not match the actual file’s casing on disk.

Please execute the following script to verify:

#!/bin/bash
echo "Checking for header.css in src/stories:"
fd --type file --exact-depth 1 --regex '^header\.css$' src/stories || echo "Not found: header.css"
echo "Checking for Header.css in src/stories:"
fd --type file --exact-depth 1 --regex '^Header\.css$' src/stories || echo "Not found: Header.css"

Once the correct filename is confirmed, update the import statement in Header.tsx accordingly if needed.

src/App.tsx (1)

124-124: Good implementation of event handler refactoring

The event handler has been refactored to use the dedicated changeTheme function, which improves readability and maintainability in line with the PR objectives.

src/stories/Button.tsx (1)

5-16: Well-documented props interface

The ButtonProps interface is well-documented with JSDoc comments that clearly explain the purpose of each prop.

vite.config.ts (2)

4-5: Good addition of Tailwind CSS integration

The addition of the Tailwind CSS plugin is appropriate for the PR objectives.


18-18:

❓ Verification inconclusive

Verify Tailwind CSS plugin configuration

Ensure that the Tailwind CSS plugin is properly configured for your needs.


🏁 Script executed:

#!/bin/bash
# Check tailwind configuration files
echo "Checking for tailwind.config.js"
fd --type file --exact-pattern "tailwind.config.js" --max-depth 2 --exec cat {}

echo -e "\nChecking for postcss configuration"
fd --type file --name ".postcssrc" --max-depth 2 --exec cat {}

Length of output: 788


Action Required: Verify and Correct Tailwind CSS Configuration Check

The current verification commands in vite.config.ts use incorrect fd flags (i.e., --exact-pattern and --name), causing errors instead of checking for your Tailwind CSS configuration files. Please update your verification commands as follows and manually reconfirm that your Tailwind CSS setup is correct:

  • Replace:

    fd --type file --exact-pattern "tailwind.config.js" --max-depth 2 --exec cat {}

    with:

    fd --type file "tailwind.config.js" --max-depth 2 --exec cat {}
  • Replace:

    fd --type file --name ".postcssrc" --max-depth 2 --exec cat {}

    with:

    fd --type file ".postcssrc" --max-depth 2 --exec cat {}

Next Steps:

  • Re-run the updated commands to verify that your tailwind.config.js and your postcss configuration file are present and correctly configured.
  • Review the contents of these files to ensure the Tailwind CSS plugin is set up as needed for your project.
src/stories/Button.stories.ts (1)

1-54: LGTM! Well-structured Storybook configuration

The Button stories follow Storybook's recommended patterns with proper typing and configuration for different variants. The setup with Meta and StoryObj types ensures type safety, and the component variations (Primary, Secondary, Large, Small) provide good test coverage.

🧰 Tools
🪛 ESLint

[error] 4-4: Missing file extension for "./Button"

(import/extensions)

src/lib/accordion/index.tsx (3)

3-3: LGTM! Good addition of clsx for conditional class names

Using clsx is a best practice for managing conditional class names when using utility-first CSS frameworks like Tailwind.


15-15: LGTM! Proper interface extension

Adding the optional className prop to the interface allows for better component composition and customization.


21-21: LGTM! Refactored styled component to use Tailwind classes

The transition from styled-components to Tailwind CSS classes maintains the same styling while aligning with the new approach.

src/stories/Header.stories.ts (1)

1-34: LGTM! Well-structured Header stories

The Header stories are well-organized with proper typing and configuration for logged-in and logged-out states. The use of fn() for action callbacks is a good practice for Storybook.

🧰 Tools
🪛 ESLint

[error] 4-4: Missing file extension for "./Header"

(import/extensions)

src/stories/Page.tsx (1)

1-92: LGTM! Well-structured Page component

The Page component is well-structured with proper state management for the user and good organization of the UI elements. The component effectively showcases the Header usage and provides informative content about Storybook practices.

🧰 Tools
🪛 ESLint

[error] 3-3: Missing file extension for "./Header"

(import/extensions)

src/lib/accordion/accordion-item.tsx (4)

6-7: Good integration of modern libraries for component development.

Adding clsx for class name management and react-aria-components for accessible UI elements is a great approach that aligns well with the Tailwind CSS integration.


26-46: Good migration to Tailwind-based styling.

The refactoring from styled-components to Tailwind CSS utility classes is well-structured. The use of clsx for conditional class application makes the code more maintainable, and the class organization follows a logical pattern (background/border, hover states, sizing, and flex layout).


34-34: Note event handler change from onClick to onPress.

You've changed the event handler from onClick to onPress which is the correct approach when using react-aria-components. This improves accessibility by handling various input methods beyond mouse clicks.


47-57: Good approach for collapsible animation.

The implementation of the collapsible section is well done. Using the calculated height from useElementSize hook with a conditional overflow setting creates a smooth transition effect. Just make sure to fix the transition duration syntax as noted in the other comment.

src/stories/Configure.mdx (4)

1-17: Good organization of Storybook documentation resources.

The imports are well-structured and provide all necessary assets for the documentation page. This follows the Storybook best practices for organizing documentation resources.


18-32: Well-implemented arrow component for documentation navigation.

The RightArrow component is appropriately defined and uses inline styles for consistency. This is a good approach for small UI elements that are specific to documentation.


36-81: Well-structured documentation content with proper semantic HTML.

The main documentation content is well-organized with appropriate headings, paragraphs, and links. The use of Storybook's container classes ensures consistent styling across the documentation.


208-364: Good responsive design implementation in documentation styles.

The CSS styles are well-organized with appropriate media queries for different screen sizes. The use of flexbox and grid layouts ensures the documentation looks good on all devices.

src/styles/global.css (5)

1-36: Good organization of design tokens using CSS custom properties.

The CSS custom properties are well-organized by category (colors, backgrounds, shadows, etc.) which makes them easy to understand and maintain. This is a good approach for a design system.


37-69: Well-implemented dark mode theme.

The dark mode theme implementation is complete and thorough, defining alternate values for all the custom properties. This ensures consistent theming across the application.


71-127: Good standardization of typography and element styles.

The use of @apply directives with Tailwind CSS utilities provides consistent styling for typography and HTML elements across the application. This approach makes maintenance easier and ensures visual consistency.


129-167: Well-organized transition and animation definitions.

The transition classes and animation keyframes are clearly defined and properly organized. The fade-in animation is particularly useful for improving perceived performance in UI elements.


170-216: Good theme variable mapping for consistency.

The @theme block effectively maps CSS custom properties to theme variables, which ensures consistent theming across the application. This approach makes it easier to maintain and update the design system.

package.json (5)

9-9: Migration to ES modules format.

Adding "type": "module" indicates that the project is using ES modules format by default. This is a modern approach that aligns well with Vite's default behavior.


15-23: Good migration from Parcel to Vite build system.

The updated scripts reflect a migration from Parcel to Vite, which offers better performance and modern features. The Storybook scripts are also properly configured.


29-71: Comprehensive update of development dependencies.

The addition of Storybook packages and Vite-related tools is well-organized. This update ensures that the project has all the necessary tools for modern development.


84-84: Added Tailwind CSS Vite plugin.

The addition of @tailwindcss/vite is essential for integrating Tailwind CSS with the Vite build system. This aligns well with the project's move to Tailwind-based styling.


102-109: Updated Yarn version and added ESLint configuration.

Updating to Yarn 4.7.0 and adding Storybook-specific ESLint configuration ensures the project follows modern best practices. This will help maintain code quality as the project evolves.

alcercu and others added 4 commits March 11, 2025 18:25
Feat: add accordion stories
alcercu and others added 4 commits April 14, 2025 11:31
fix: add toString config to useBigNumberField
Chore/tag migration
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: 18

♻️ Duplicate comments (4)
src/lib/messages/push.tsx (1)

15-16: Use a properly shaped function type instead of Function.

TypeScript discourages using Function because it silently accepts any function-like value and can lead to unclear or buggy code. A more explicit type shape is recommended, for example:

- callback: Function;
+ callback: () => void;

or a shape that matches your intended usage.

🧰 Tools
🪛 Biome (1.9.4)

[error] 16-16: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

src/lib/pagination/tabs.tsx (2)

42-42: Use a properly shaped function type instead of Function.

As previously noted, relying on Function erodes type safety. For instance, define a signature reflecting the expected parameters:

- callback?: Function;
+ callback?: (key: Key, value: unknown) => void;
🧰 Tools
🪛 Biome (1.9.4)

[error] 42-42: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


70-70: Use item.id instead of item.text when matching the selected key.

The selected key (from AriaTabs) is stored in id, but your code uses text for the lookup. This can cause discrepancies if text differs from id. Consider:

- const selectedItem = items.find((item) => item.text === key);
+ const selectedItem = items.find((item) => item.id === key);
package.json (1)

90-90: Duplicate dependency on clsx resolved.

The previous issue of a duplicate clsx entry in dependencies has been fixed. No further action needed.

🧹 Nitpick comments (79)
src/utils/index.ts (1)

8-11: Consider renaming isUndefined for clarity.

While functionally correct, the function name isUndefined is slightly misleading since it checks for both undefined and null. A more accurate name might be isNullOrUndefined to better reflect its behavior.

-export const isUndefined = (
+export const isNullOrUndefined = (
  maybeObject: any,
): maybeObject is undefined | null =>
  typeof maybeObject === "undefined" || maybeObject === null;
src/lib/container/box.tsx (1)

7-11: Consider making dimensions configurable via props.

The component has fixed dimensions (h-[200px] w-[328px]) which might limit its flexibility. Consider accepting size props with defaults or using responsive classes for more versatile usage across different contexts.

-function Box({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
+interface BoxProps extends React.HTMLAttributes<HTMLDivElement> {
+  width?: string;
+  height?: string;
+}
+
+function Box({ 
+  className, 
+  width = "328px", 
+  height = "200px", 
+  ...props 
+}: BoxProps) {
  return (
    <div
      className={cn(
-       "bg-klerosUIComponentsMediumBlue h-[200px] w-[328px]",
+       "bg-klerosUIComponentsMediumBlue",
        "box-border rounded-[18px]",
        className,
      )}
+     style={{ width, height }}
    >
      {props.children}
    </div>
  );
}
src/lib/accordion/accordion-item.tsx (1)

34-35: Consider memoizing the onPress handler.

The onPress handler creates a new function on each render. For better performance, consider using useCallback to memoize it.

+import React, { ReactNode, useCallback } from "react";
 // ...
 
 const AccordionItem: React.FC<AccordionItemProps> = ({
   title,
   body,
   index,
   expanded,
   setExpanded,
 }) => {
   const [ref, { height }] = useElementSize();
+  const handlePress = useCallback(
+    () => setExpanded(expanded ? -1 : index),
+    [expanded, index, setExpanded]
+  );
   return (
     <div className="my-2">
       <Button
         className={cn(
           "bg-klerosUIComponentsWhiteBackground border-klerosUIComponentsStroke border",
           "hover-medium-blue hover-short-transition hover:cursor-pointer",
           "rounded-[3px] px-8 py-[11.5px]",
           "flex w-full items-center justify-between",
         )}
-        onPress={() => setExpanded(expanded ? -1 : index)}
+        onPress={handlePress}
src/lib/messages/alert.tsx (2)

6-7: Standardize utility imports.

You're importing both cn and clsx, but cn already uses clsx internally. For consistency, consider using just the cn utility throughout the component.

 import React from "react";
 import SuccessIcon from "../../assets/svgs/status-icons/success.svg";
 import WarningIcon from "../../assets/svgs/status-icons/warning.svg";
 import ErrorIcon from "../../assets/svgs/status-icons/error.svg";
 import InfoIcon from "../../assets/svgs/status-icons/info.svg";
 import { cn } from "../../utils";
-import clsx from "clsx";

48-53: Use cn utility consistently.

For consistency, use the cn utility function here instead of clsx directly, as cn is used everywhere else in the component.

        <h2
-         className={clsx("text-base font-semibold", {
+         className={cn("text-base font-semibold", {
            "text-klerosUIComponentsSuccess": variant === "success",
            "text-klerosUIComponentsError": variant === "error",
            "text-klerosUIComponentsPrimaryBlue": variant === "info",
            "text-klerosUIComponentsWarning": variant === "warning",
          })}
        >
src/lib/display/icon.tsx (1)

22-45: Consider responsive design improvements

While the current implementation is solid, consider whether fixed dimensions like "size-12" and "w-72" provide enough flexibility for responsive layouts. You might want to make these more customizable or responsive based on viewport size.

- <Card className={cn("flex h-20 w-72 p-4", className)} {...props}>
-   <Card className={clsx("size-12", "flex items-center justify-center")}>
+ <Card className={cn("flex p-4", "h-20 w-72 md:w-auto", className)} {...props}>
+   <Card className={clsx("size-12 md:size-14", "flex items-center justify-center")}>
src/lib/form/switch.tsx (1)

27-36: Consider standardizing transition durations

The "duration-400" class might be a custom utility. Consider ensuring that this duration is consistent with other transitions in your design system for a unified user experience.

-           "bg-klerosUIComponentsStroke cursor-pointer rounded-[34px] duration-400",
+           "bg-klerosUIComponentsStroke cursor-pointer rounded-[34px] transition-colors duration-300",
-           "before:absolute before:bottom-0.5 before:left-0.5 before:rounded-full before:bg-white before:duration-400",
+           "before:absolute before:bottom-0.5 before:left-0.5 before:rounded-full before:bg-white before:transition-transform before:duration-300",
src/lib/tag/index.tsx (1)

14-36: Consider using a <span> instead of <p> for inline text.

While embedding a <p> element inside a button is valid, a <span> is more common for inline text, potentially improving semantics and layout behavior. If multiline content is not expected, this could be a minor, nice-to-have refinement.

- <p
+ <span
    className={clsx(
      "hover-short-transition text-klerosUIComponentsPrimaryBlue text-base",
      !active && ["hover:text-klerosUIComponentsSecondaryBlue"],
    )}
  >
    {text}
- </p>
+ </span>
src/lib/form/searchbar.tsx (1)

14-62: Validate custom width class usage.

The w-69.5 utility class at line 31 relies on a custom Tailwind configuration. Make sure it is defined to avoid potential style mismatches in production.

src/lib/form/slider.tsx (2)

12-20: Consider renaming callback for clarity.
callback works, but naming it something like onValueChange or onSliderChange may improve clarity and consistency with typical React naming conventions.


69-71: Revisit hiding the label when disabled.
While hiding the value label in a disabled state may be by design, consider displaying it even when disabled, to keep the user informed of the read-only value.

src/lib/tooltip/index.tsx (1)

64-97: Reduce repetition in arrow positioning classes.
Consider extracting repeated arrow-positioning styles into a helper or an object lookup to reduce duplication for each placement.

src/lib/messages/push.tsx (1)

63-63: Pass the callback directly if no arguments are needed.

Currently, you're wrapping callback with an arrow function:

onPress={() => callback()}

If callback doesn’t require arguments, passing it directly can simplify the code:

- onPress={() => callback()}
+ onPress={callback}
src/stories/form.stories.tsx (1)

1-45: Consider adding more form scenario coverage.

Your story covers a single basic case. For improved test coverage and demonstration, you could add variants showcasing error handling, validation feedback, or multiple fields with different types. This helps users see more real-world usage.

vite.config.ts (1)

5-6: Consider resolving the eslint-disable comment for a cleaner codebase.

The eslint-disable comment suggests there might be an issue with resolving the @tailwindcss/vite import. Consider updating the ESLint configuration or resolving the module properly to avoid needing this comment.

src/stories/timeline.stories.tsx (1)

44-66: Consider enhancing TimelineAlignment story with more diverse examples.

The current TimelineAlignment story only shows a simple case of different alignments. Consider enhancing it with more complex examples like the ones in custom-timeline.stories.tsx that show rich content in the party field.

-        party: "No",
+        party: (
+          <div className="flex items-center gap-2">
+            <label className="text-klerosUIComponentsPrimaryText leading-4">
+              alice.eth -
+            </label>
+            <a
+              className="text-klerosUIComponentsPrimaryBlue text-sm"
+              href="https://docs.kleros.io/"
+              target="_blank"
+              rel="noreferrer"
+            >
+              Justification
+            </a>
+          </div>
+        ),
src/lib/dropdown/select/dropdown-button.tsx (1)

29-29: Improve icon rendering logic for better clarity.

The current condition icon ?? (Icon && <Icon className="max-h-4 min-h-3 max-w-4 min-w-3" />) might not behave as expected if icon is undefined but Icon is provided.

-      {icon ?? (Icon && <Icon className="max-h-4 min-h-3 max-w-4 min-w-3" />)}
+      {icon ? icon : Icon ? <Icon className="max-h-4 min-h-3 max-w-4 min-w-3" /> : null}
src/stories/copiable.stories.tsx (1)

1-43: Well-structured Storybook story with minor improvement opportunities

The Copiable component stories are well-organized with appropriate controls and variants. Consider these improvements:

  1. There's an inconsistency in the info text between stories - one ends with a period (line 30) while the other doesn't (line 41).
  2. Adding some documentation parameters would help explain the component's purpose and usage.
  info: "Copy this text.",

to

  info: "Copy this text",

or vice versa for consistency.

src/lib/form/datepicker/arrow-button.tsx (1)

49-76: Consider extracting color tokens for better theming flexibility

The component uses hardcoded color classes like fill-klerosUIComponentsPrimaryBlue. This might make theming difficult if you need to change colors across the application.

Consider using CSS variables or a more abstract token system that can be changed globally:

  <Arrow
    className={cn(
-     "fill-klerosUIComponentsPrimaryBlue ease-ease size-4 transition",
+     "fill-primary ease-ease size-4 transition",
      {
        "rotate-90":
          arrowType === "hour-increment" ||
          arrowType === "minute-increment",
        "-rotate-90":
          arrowType === "hour-decrement" ||
          arrowType === "minute-decrement",
      },
-     isHovered && "fill-klerosUIComponentsSecondaryBlue",
+     isHovered && "fill-secondary",
    )}
  />

This would require defining these color variables in your CSS or using a theme provider.

src/lib/container/modal.tsx (1)

8-23: Add semantic structure for better accessibility and UX

The modal lacks semantic regions like header, body, and footer, which are common in modal components and improve accessibility and user experience.

Consider adding a structure for organizing modal content:

function Modal({
  className,
+  title,
+  footer,
  ...props
}: ModalOverlayProps & React.RefAttributes<HTMLDivElement> & {
+  title?: React.ReactNode;
+  footer?: React.ReactNode;
}) {
  return (
    <AriaModal
      className={cn(
        "bg-klerosUIComponentsWhiteBackground h-[200px] w-[328px]",
        "rounded-base box-border flex flex-col",
        className,
      )}
    >
+      {title && (
+        <div className="border-b border-klerosUIComponentsStroke p-4 font-semibold">
+          {title}
+        </div>
+      )}
+      <div className="flex-1 overflow-auto p-4">{props.children}</div>
+      {footer && (
+        <div className="border-t border-klerosUIComponentsStroke flex justify-end gap-2 p-4">
+          {footer}
+        </div>
+      )}
-      {props.children}
    </AriaModal>
  );
}
src/lib/dropdown/cascader/button.tsx (3)

33-38: Use cn utility consistently

The component uses clsx directly here but imports and uses cn elsewhere. For consistency, use the same utility throughout.

- className={clsx(
+ className={cn(
    "text-base",
    isPlaceholder || !selectedItem
      ? "text-klerosUIComponentsSecondaryText"
      : "text-klerosUIComponentsPrimaryText",
  )}

48-51: Use cn utility consistently here too

Similar to the previous comment, use the cn utility for consistency with the rest of the codebase.

- className={clsx(
+ className={cn(
    "hover-short-transition fill-klerosUIComponentsStroke ease-ease ml-2 size-4 transition",
    state?.isOpen && "rotate-180",
  )}

17-17: Add defensive handling for missing SelectStateContext

The component accesses state from context but only checks for state?.isOpen when rotating the arrow. Consider adding more defensive handling.

Add a fallback or warning if the dropdown button is used outside a Select context:

const DropdownButton: React.FC<ButtonProps & { placeholder?: string }> = ({
  placeholder,
  ...props
}) => {
  const state = useContext(SelectStateContext);
+ 
+ // Optional: add a warning in development if context is missing
+ if (process.env.NODE_ENV !== 'production' && !state) {
+   console.warn('DropdownButton should be used within a Select component');
+ }
src/lib/dropdown/select/dropdown-container.tsx (1)

22-31: Consider making the width more configurable

The dropdown width is hardcoded in multiple places (w-59.5). This may limit reusability in different contexts where varying widths are needed.

- <Scrollbar className="max-h-87.5 w-59.5">
+ <Scrollbar className="max-h-87.5 w-full">
  <ListBox
    className={clsx(
-     "bg-klerosUIComponentsWhiteBackground box-border w-59.5",
+     "bg-klerosUIComponentsWhiteBackground box-border w-full",
      "cols-[repeat(auto-fill,_minmax(0,_45px))] grid grow py-4",
    )}
  >
src/lib/progress/steps/horizontal.tsx (1)

13-16: Consider making the width responsive or configurable

The component has a fixed width (w-62.5) which might limit its flexibility in different contexts.

  <div
    className={cn(
-     "box-border flex w-62.5 items-start justify-center",
+     "box-border flex w-full max-w-62.5 items-start justify-center",
      className,
    )}
src/lib/progress/steps/vertical.tsx (1)

31-38: Consider consistency in bullet styling approach

The last bullet has special styling with an explicit className, while others are wrapped in a container. Consider a more consistent approach for all bullets.

- <div className="flex h-auto grow flex-col">
+ <div className="flex h-auto grow flex-col" data-bullet-container>
  {items.slice(0, -1).map(({ title, subitems }, i) => (
    <Bullet
      {...{ title, subitems }}
      completed={i < currentItemIndex}
      active={i === currentItemIndex}
      line={!(i + 1 === items.length)}
      index={i + 1}
      key={i}
    />
  ))}
</div>
<Bullet
  title={lastItem.title}
  subitems={lastItem.subitems}
  completed={items.length - 1 < currentItemIndex}
  active={items.length - 1 === currentItemIndex}
  index={items.length}
- className="grow-0 basis-auto"
+ className="grow-0 basis-auto" 
+ data-last-bullet
/>
src/lib/progress/steps/horizontal-bullet.tsx (2)

75-85: Use optional chaining for conditional rendering

As suggested by the static analysis, it's better to use optional chaining for conditional rendering.

- {subitems &&
-   subitems.map((item, i) => (
-     <small
-       className="text-klerosUIComponentsSecondaryText text-xs font-normal break-words"
-       key={i}
-       aria-label={item}
-       aria-description={`subitem ${i + 1}`}
-     >
-       {item}
-     </small>
-   ))}
+ {subitems?.map((item, i) => (
+   <small
+     className="text-klerosUIComponentsSecondaryText text-xs font-normal break-words"
+     key={i}
+     aria-label={item}
+     aria-description={`subitem ${i + 1}`}
+   >
+     {item}
+   </small>
+ ))}
🧰 Tools
🪛 Biome (1.9.4)

[error] 75-85: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


34-46: Simplify complex class conditional

The nested array syntax in clsx makes the code harder to read. Consider simplifying the conditional classes.

<div
  className={clsx(
    "relative flex h-fit items-start justify-center",
    "lg:!pb-0",
-   last
-     ? "grow-0"
-     : [
-         "grow",
-         "after:mx-4 after:my-3 after:h-0 after:w-auto after:grow after:border-t",
-         completed
-           ? "after:border-t-klerosUIComponentsPrimaryBlue"
-           : "after:border-t-klerosUIComponentsStroke",
-       ],
+   last ? "grow-0" : "grow",
+   !last && "after:mx-4 after:my-3 after:h-0 after:w-auto after:grow after:border-t",
+   !last && completed 
+     ? "after:border-t-klerosUIComponentsPrimaryBlue" 
+     : !last && "after:border-t-klerosUIComponentsStroke"
  )}
src/lib/form/datepicker/time-control.tsx (3)

7-9: Consider expanding the interface props

The interface only accepts minValue, but the component might benefit from additional customization options like a className prop for external styling, or a disabled state that could be passed to child components.

 interface ITimeControl {
   minValue: ArrowButtonProps["minValue"];
+  className?: string;
+  disabled?: boolean;
 }

21-30: Consider adding keyboard navigation for better accessibility

The role="group" is good, but time selection is a keyboard-intensive task. Consider adding keyboard navigation handlers to improve accessibility.

-      <div role="group" className="flex grow flex-col">
+      <div 
+        role="group" 
+        className="flex grow flex-col"
+        aria-labelledby="time-selection-label"
+      >

57-67: Consider using more descriptive aria-labels for arrow buttons

The arrow buttons might benefit from more descriptive aria-labels to better communicate their function to screen reader users.

        <div
          className={clsx(
            "h-16 w-full grow",
            "flex items-center justify-between px-6",
          )}
+         aria-label="time adjustment controls"
        >
          <ArrowButton arrowType="hour-decrement" {...{ minValue }} />
          <ArrowButton arrowType="minute-decrement" {...{ minValue }} />
        </div>
src/lib/progress/steps/bullet-circle.tsx (1)

43-52: Consider adding a11y improvements to line element

The line element could benefit from being hidden from screen readers since it's purely decorative.

    {line && (
      <div
        className={clsx(
          "my-2 h-auto w-0 grow border-l",
          completed
            ? "border-l-klerosUIComponentsPrimaryBlue"
            : "border-l-klerosUIComponentsStroke",
        )}
+       aria-hidden="true"
      />
    )}
src/lib/scrollbar.tsx (1)

13-17: Consider improving the readability of complex Tailwind selectors

The complex selector syntax with brackets and dots is powerful but can be hard to read. Consider extracting these to a separate CSS file or using Tailwind's @apply directive in a global style for better maintainability.

      className={cn(
-        "[&_.simplebar-scrollbar]:before:!bg-klerosUIComponentsPrimaryBlue",
-        "[&_.simplebar-visible]:before:!opacity-100",
-        "[&_.simplebar-mask]:!bg-klerosUIComponentsWhiteBackground",
+        "scrollbar-custom", // Define this in your global CSS with @apply
        className,
      )}
src/lib/dropdown/cascader/select-button.tsx (2)

14-46: Enhance null-checking consistency in the component.

The component implementation is solid, but I suggest making the null/undefined checking more consistent. Currently, isUndefined() is used in some places while direct value checking is used in others.

Consider these improvements:

  const selectedItem = !isUndefined(selectedKey)
    ? state?.collection.getItem(selectedKey)
    : undefined;

  return (
    <div
      className={clsx(
        "box-border px-4 py-2",
        "border-t-klerosUIComponentsStroke border-t",
        "flex items-center justify-center lg:justify-end",
      )}
    >
      <Button
        onPress={() => {
-          if (!isUndefined(selectedKey)) state?.setSelectedKey(selectedKey);
+          if (!isUndefined(selectedKey) && state) state.setSelectedKey(selectedKey);
          if (selectedItem) {
            callback(selectedItem.value as IItem);
          }
-          state?.close();
+          if (state) state.close();
        }}
        text={
-          isUndefined(selectedItem)
+          !selectedItem
            ? "No Selection"
            : `Select\n${selectedItem.textValue}`
        }
        isDisabled={isUndefined(selectedKey)}
      />
    </div>
  );

17-19: Add defensive check for state existence before accessing collection.

The code accesses state?.collection directly without verifying that state exists, which could lead to potential issues.

A more robust approach would be:

  const selectedItem = !isUndefined(selectedKey)
-    ? state?.collection.getItem(selectedKey)
+    ? state ? state.collection.getItem(selectedKey) : undefined
    : undefined;
src/lib/form/datepicker/calendar.tsx (2)

68-77: Add internationalization support for weekday names.

The weekday abbreviations are currently hardcoded by taking the first two characters, which won't work correctly for all languages.

Consider using proper internationalization:

    <CalendarGridHeader>
      {(day) => (
        <CalendarHeaderCell
          className={clsx(
            "size-6 cursor-pointer pb-1",
            "text-klerosUIComponentsPrimaryText text-center text-sm font-semibold",
          )}
        >
-          {day.substring(0, 2)}
+          {(() => {
+            // Get proper localized abbreviated weekday 
+            const date = new Date();
+            const formatter = new Intl.DateTimeFormat(locale, { weekday: 'short' });
+            date.setDate(date.getDate() + ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'].indexOf(day.toLowerCase()) - date.getDay());
+            return formatter.format(date).substring(0, 2);
+          })()}
        </CalendarHeaderCell>
      )}
    </CalendarGridHeader>

This approach would correctly handle weekday abbreviations across different languages and locales.


82-98: Extract state-based styling into reusable utility functions.

The calendar cell has complex conditional styling that could be more maintainable if extracted into utility functions.

Consider simplifying the component by extracting styling logic:

+ // Add this function outside the component
+ const getCalendarCellClassName = ({ isFocused, isUnavailable, isDisabled, isSelected }) => {
+   return cn(
+     "flex size-6 cursor-pointer items-center justify-center rounded-full",
+     "text-klerosUIComponentsSecondaryText text-center text-sm font-semibold",
+     "hover:bg-klerosUIComponentsSecondaryBlue hover:text-klerosUIComponentsWhiteBackground",
+     "outside-month:hidden",
+     isSelected && [
+       "bg-klerosUIComponentsPrimaryBlue text-klerosUIComponentsWhiteBackground",
+       "hover:bg-klerosUIComponentsPrimaryBlue",
+     ],
+     (isDisabled || isUnavailable) &&
+       "text-klerosUIComponentsStroke cursor-not-allowed",
+     isFocused && [
+       "outline-klerosUIComponentsPrimaryBlue outline-2",
+     ]
+   );
+ };

// Then in the component:
<CalendarCell
  date={date}
-  className={({ isFocused, isUnavailable, isDisabled, isSelected }) =>
-    cn(
-      "flex size-6 cursor-pointer items-center justify-center rounded-full",
-      "text-klerosUIComponentsSecondaryText text-center text-sm font-semibold",
-      "hover:bg-klerosUIComponentsSecondaryBlue hover:text-klerosUIComponentsWhiteBackground",
-      "outside-month:hidden",
-      isSelected && [
-        "bg-klerosUIComponentsPrimaryBlue text-klerosUIComponentsWhiteBackground",
-        "hover:bg-klerosUIComponentsPrimaryBlue",
-      ],
-      (isDisabled || isUnavailable) &&
-        "text-klerosUIComponentsStroke cursor-not-allowed",
-      isFocused && [
-        "outline-klerosUIComponentsPrimaryBlue outline-2",
-      ],
-    )
-  }
+  className={getCalendarCellClassName}
>

This approach improves readability and maintainability of the component.

src/lib/form/bignumber-field/index.tsx (4)

97-137: Extract duplicate button styling into a reusable component.

Both increment and decrement buttons have nearly identical styling logic, leading to code duplication. Consider extracting this into a reusable component or shared utility.

+ // Add this component outside the main component
+ interface StepperButtonProps {
+   direction: 'up' | 'down';
+   buttonProps: React.ComponentProps<typeof Button>;
+ }
+ 
+ const StepperButton: React.FC<StepperButtonProps> = ({ direction, buttonProps }) => {
+   const Icon = direction === 'up' ? UpArrowIcon : DownArrowIcon;
+   
+   return (
+     <Button
+       {...buttonProps}
+       excludeFromTabOrder
+       className={clsx(
+         "rounded-base hover:bg-klerosUIComponentsStroke size-3.5 cursor-pointer border-none bg-transparent",
+         "flex items-center justify-center",
+         "disabled:cursor-default",
+       )}
+     >
+       {({ isDisabled }) => (
+         <Icon
+           className={clsx(
+             "size-2",
+             isDisabled
+               ? "[&_path]:fill-klerosUIComponentsStroke"
+               : "[&_path]:fill-klerosUIComponentsSecondaryText",
+           )}
+         />
+       )}
+     </Button>
+   );
+ };

// Then in the main component:
- <Button
-   {...incrementButtonProps}
-   excludeFromTabOrder
-   className={clsx(
-     "rounded-base hover:bg-klerosUIComponentsStroke size-3.5 cursor-pointer border-none bg-transparent",
-     "flex items-center justify-center",
-     "disabled:cursor-default",
-   )}
- >
-   {({ isDisabled }) => (
-     <UpArrowIcon
-       className={clsx(
-         "size-2",
-         isDisabled
-           ? "[&_path]:fill-klerosUIComponentsStroke"
-           : "[&_path]:fill-klerosUIComponentsSecondaryText",
-       )}
-     />
-   )}
- </Button>
- <Button
-   {...decrementButtonProps}
-   excludeFromTabOrder
-   className={clsx(
-     "rounded-base hover:bg-klerosUIComponentsStroke size-3.5 cursor-pointer border-none bg-transparent",
-     "flex items-center justify-center",
-     "disabled:cursor-default",
-   )}
- >
-   {({ isDisabled }) => (
-     <DownArrowIcon
-       className={clsx(
-         "size-2",
-         isDisabled
-           ? "[&_path]:fill-klerosUIComponentsStroke"
-           : "[&_path]:fill-klerosUIComponentsSecondaryText",
-       )}
-     />
-   )}
- </Button>
+ <StepperButton direction="up" buttonProps={incrementButtonProps} />
+ <StepperButton direction="down" buttonProps={decrementButtonProps} />

50-58: Make component width more configurable for better flexibility.

The component has a hardcoded width which limits its flexibility in different layouts.

  return (
-    <div className={cn("flex w-[278px] flex-col", className)}>
+    <div className={cn("flex flex-col", className)}>
      {label && (
        <label
          {...labelProps}
          className="text-klerosUIComponentsSecondaryText mb-1 text-sm"
        >

This change allows the component to inherit width from its parent container or be specified through className prop, making it more adaptable to different layouts.


85-95: Simplify conditional stepper button visibility logic.

The conditions for showing stepper buttons are complex and could be simplified.

  <div
    className={cn(
-      "animate-fade-in absolute top-0 right-3 hidden h-full w-3.5",
-      isHovered &&
-        !isDisabled &&
-        "flex flex-col items-center justify-center gap-1",
+      "animate-fade-in absolute top-0 right-3 h-full w-3.5",
+      isHovered && !isDisabled
+        ? "flex flex-col items-center justify-center gap-1"
+        : "hidden",
      {
        "right-9": variant && variant !== "info",
        "right-12": Icon,
      },
    )}
  >

This change makes the conditional logic clearer while maintaining the same functionality.


138-157: Extract status icon rendering into a separate helper function.

The variant-based icon rendering creates multiple similar conditional blocks that could be simplified.

+ // Add this helper function
+ const renderStatusIcon = (variant) => {
+   if (!variant) return null;
+   
+   const icons = {
+     success: <SuccessIcon className="fill-klerosUIComponentsSuccess absolute top-3.5 right-4 size-4" />,
+     warning: <WarningIcon className="fill-klerosUIComponentsWarning absolute top-3.5 right-4 size-4" />,
+     error: <ErrorIcon className="fill-klerosUIComponentsError absolute top-3.5 right-4 size-4" />,
+   };
+   
+   return icons[variant] || null;
+ };

// Then in the render:
- {variant === "success" && (
-   <SuccessIcon className="fill-klerosUIComponentsSuccess absolute top-3.5 right-4 size-4" />
- )}
- {variant === "warning" && (
-   <WarningIcon className="fill-klerosUIComponentsWarning absolute top-3.5 right-4 size-4" />
- )}
- {variant === "error" && (
-   <ErrorIcon className="fill-klerosUIComponentsError absolute top-3.5 right-4 size-4" />
- )}
+ {renderStatusIcon(variant)}

{Icon && (
  <div
    className={cn(
      "bg-klerosUIComponentsLightBlue absolute top-0.25 right-0.25 h-10.75 w-11",
      "border-l-klerosUIComponentsStroke rounded-r-base border-l",
      "flex items-center justify-center",
    )}
  >
    <Icon className="size-6" />
  </div>
)}

This approach centralizes the icon rendering logic, making it easier to maintain and extend.

src/stories/number-field.stories.tsx (3)

42-102: Enhance story documentation and add more comprehensive examples.

The current stories provide good basic coverage, but would benefit from additional examples and better documentation of what each story demonstrates.

Improve the stories with these additions:

export const Default: Story = {
  args: {
    themeUI: "dark",
    backgroundUI: "light",
    className: "w-[500px]",
    placeholder: "Enter Number",
  },
+  parameters: {
+    docs: {
+      description: {
+        story: "Basic NumberField component with default configuration."
+      }
+    }
+  }
};

// Add new stories to showcase more features:

+ export const WithMinMax: Story = {
+   args: {
+     ...Default.args,
+     label: "Score (0-100)",
+     minValue: 0,
+     maxValue: 100,
+   },
+   parameters: {
+     docs: {
+       description: {
+         story: "NumberField with minimum and maximum value constraints."
+       }
+     }
+   }
+ };
+
+ export const WithValidationError: Story = {
+   args: {
+     ...Default.args,
+     label: "Required field",
+     isRequired: true,
+     variant: "error",
+     message: "This field is required",
+   },
+   parameters: {
+     docs: {
+       description: {
+         story: "NumberField showing validation error state."
+       }
+     }
+   }
+ };
+
+ export const WithFormatting: Story = {
+   args: {
+     ...Default.args,
+     label: "Price",
+     placeholder: "0.00",
+     formatOptions: {
+       style: 'currency',
+       currency: 'USD'
+     }
+   },
+   parameters: {
+     docs: {
+       description: {
+         story: "NumberField with number formatting applied."
+       }
+     }
+   }
+ };
+
+ export const Disabled: Story = {
+   args: {
+     ...Default.args,
+     label: "Disabled field",
+     value: 42,
+     isDisabled: true,
+   },
+   parameters: {
+     docs: {
+       description: {
+         story: "Disabled NumberField component."
+       }
+     }
+   }
+ };

These additional stories would provide better documentation and more comprehensive examples of the component's capabilities.


80-102: Enhance the form validation example to show error feedback.

The current Required story demonstrates form integration but doesn't show validation error feedback.

Improve the Required story to demonstrate validation error states:

export const Required: Story = {
  args: {
    ...Default.args,
    isRequired: true,
+   label: "Required Field",
  },
  render: (args) => {
+   const [showError, setShowError] = React.useState(false);
+   
    return (
      <Form
        onSubmit={(e) => {
          e.preventDefault();
+         // Access form data and validate
+         const formData = new FormData(e.currentTarget);
+         const value = formData.get('number-field');
+         setShowError(!value);
        }}
+       validationBehavior="native"
      >
        <NumberFieldComponent 
+         {...args} 
+         variant={showError ? "error" : undefined}
+         message={showError ? "This field is required" : undefined}
+         name="number-field"
+       />
        <Button
          variant="primary"
          type="submit"
          aria-pressed="true"
          text="Click me!"
          small
          className="mt-4"
        />
+       {showError && (
+         <div className="text-klerosUIComponentsError text-sm mt-2">
+           Please fill in all required fields
+         </div>
+       )}
      </Form>
    );
  },
+ parameters: {
+   docs: {
+     description: {
+       story: "NumberField with required validation in a form context. Try submitting the form without entering a value to see validation errors."
+     }
+   }
+ }
};

This enhanced example demonstrates real form validation with error feedback to the user.


11-36: Add more configuration options to improve story controls.

The current meta configuration has limited controls for some important props.

Enhance the component controls:

const meta = {
  component: NumberFieldComponent,
  title: "Form/NumberField",
  tags: ["autodocs"],
  argTypes: {
    variant: {
      options: ["success", "warning", "error", "info"],
      control: "radio",
    },
    isRequired: {
      control: "boolean",
    },
    isDisabled: {
      control: "boolean",
    },
+   isReadOnly: {
+     control: "boolean",
+   },
    message: {
      control: "text",
    },
    label: {
      control: "text",
    },
    placeholder: {
      control: "text",
    },
+   minValue: {
+     control: { type: "number" },
+   },
+   maxValue: {
+     control: { type: "number" },
+   },
+   step: {
+     control: { type: "number" },
+     description: "Step value for increment/decrement",
+   },
+   defaultValue: {
+     control: { type: "number" },
+   },
+   formatOptions: {
+     control: "object",
+     description: "Number formatting options (e.g., currency)",
+   },
  },
} satisfies Meta<typeof NumberFieldComponent>;

These additional controls would allow users to explore more of the component's capabilities directly in Storybook.

src/stories/bignumber-field.stories.tsx (2)

140-170: Consider renaming the Error story variant to avoid shadowing global Error.

The "Error" story name shadows the global Error constructor.

-export const Error: Story = {
+export const ErrorState: Story = {
🧰 Tools
🪛 Biome (1.9.4)

[error] 156-156: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


179-185: Inconsistent type usage for defaultValue.

The ReadOnly story uses a string for defaultValue while other stories use BigNumber instances.

-    defaultValue: "42",
+    defaultValue: new BigNumber("42"),
src/lib/progress/timeline/index.tsx (2)

27-40: Consider simplifying translation class logic.

The translation class logic could be simplified for better readability.

  className={clsx(
    "relative",
-    item.rightSided
-      ? "translate-x-[calc(50%_-_8px)]"
-      : "translate-x-[calc(-50%_+_8px)]",
+    item.rightSided ? "translate-x-[calc(50%_-_8px)]" : "translate-x-[calc(-50%_+_8px)]",
  )}

41-52: Consider extracting repeated translation logic.

The translation logic is duplicated between regular items and the last item. Consider extracting to a function or variable.

+  const getTranslateClass = (rightSided: boolean | undefined) => 
+    rightSided ? "translate-x-[calc(50%_-_8px)]" : "translate-x-[calc(-50%_+_8px)]";

  return (
    <div
      className={cn("box-border flex flex-col", className)}
      {...props}
      aria-label="Timeline"
      role="list"
    >
      {items.slice(0, -1).map((item, i) => (
        <Bullet
          key={i}
          line
          {...item}
          isLast={false}
-          className={clsx(
-            "relative",
-            item.rightSided
-              ? "translate-x-[calc(50%_-_8px)]"
-              : "translate-x-[calc(-50%_+_8px)]",
-          )}
+          className={clsx("relative", getTranslateClass(item.rightSided))}
        />
      ))}
      <Bullet
        {...lastItem}
        isLast={true}
-        className={clsx(
-          "relative",
-          lastItem.rightSided
-            ? "translate-x-[calc(50%_-_8px)]"
-            : "translate-x-[calc(-50%_+_8px)]",
-          "h-[unset] grow-0 basis-auto",
-        )}
+        className={clsx("relative", getTranslateClass(lastItem.rightSided), "h-[unset] grow-0 basis-auto")}
      />
    </div>
  );
src/lib/form/radio-group.tsx (1)

102-110: FieldError integration is consistent with accessibility best practices.
Rendering the FieldError component here conveys validation feedback near the radio group. Ensure you add corresponding tests to verify error messages display correctly under different conditions.

src/lib/form/number-field.tsx (2)

48-48: Consider making the width more responsive.
Currently, the input has a fixed width of 278px. Consider allowing flexible widths for improved usability in different layouts, e.g., by removing a fixed width or using max-w classes.

- className={cn("flex w-[278px] flex-col", className)}
+ className={cn("flex w-full max-w-xs flex-col", className)}

80-130: Hover-driven increment/decrement buttons.
Relying on hover to display the stepper buttons is a sleek UI choice. However, consider how this behaves on touch devices without a hover state. You might conditionally show stepper buttons at all times on small viewports.

src/lib/form/datepicker/display-button.tsx (1)

13-17: Fallback behavior when DatePickerStateContext is unavailable.
The callback checks if (state) state.open();. Consider providing a more explicit fallback or warning if state is missing to help debug misconfigured contexts.

src/stories/radioGroup.stories.tsx (1)

4-4: Consider adding an import type annotation.

The import from './utils' could benefit from being explicitly imported as a type to avoid including it in the bundle.

-import { IPreviewArgs } from "./utils";
+import type { IPreviewArgs } from "./utils";
src/lib/form/text-field.tsx (1)

42-47: Consider adding the htmlFor attribute to the Label.

While React Aria Components typically handle label associations automatically, explicitly adding the htmlFor attribute can improve accessibility in some screen readers.

src/lib/dropdown/select/simple-button.tsx (1)

69-69: Remove unnecessary whitespace.

There's a trailing space inside a JSX expression that isn't needed and could potentially cause layout issues.

-          />{" "}
+          />
src/lib/form/text-area.tsx (1)

89-101: Consider extracting status icons to a reusable component.

The status icon rendering logic is repeated in both TextArea and TextField components. Consider extracting this to a shared component to avoid duplication.

src/lib/progress/steps/bullet.tsx (1)

38-49: Consider using cn consistently instead of mixing with clsx

While the code correctly implements conditional styling, you're using both cn (at the root level) and clsx (for the title element). For consistency, consider using just cn throughout since it's a wrapper that includes Tailwind-specific class merging via twMerge.

-      <h2
-        className={clsx(
-          "text-sm font-semibold",
-          active
-            ? "text-klerosUIComponentsPrimaryText"
-            : "text-klerosUIComponentsSecondaryText",
-        )}
-        id={`step-${index}-title`}
-      >
+      <h2
+        className={cn(
+          "text-sm font-semibold",
+          active
+            ? "text-klerosUIComponentsPrimaryText"
+            : "text-klerosUIComponentsSecondaryText",
+        )}
+        id={`step-${index}-title`}
+      >
src/styles/global.css (1)

36-42: Avoid using !important in hover effect utilities

Using !important in the hover effect utilities may cause specificity issues and make it harder to override these styles in specific contexts. Consider implementing these hover effects without !important if possible.

 /* Hover effects */
 .hover-medium-blue:hover {
-  background-color: var(--klerosUIComponentsMediumBlue) !important;
+  background-color: var(--klerosUIComponentsMediumBlue);
 }

 .hover-white-background:hover {
-  background-color: var(--klerosUIComponentsWhiteBackground) !important;
+  background-color: var(--klerosUIComponentsWhiteBackground);
 }
src/lib/progress/timeline/spine.tsx (2)

5-5: Use regex literal instead of RegExp constructor

The RegExp constructor is less efficient and requires additional escaping compared to using a regex literal. This was flagged by static analysis.

-export const colorRegex = new RegExp("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
+export const colorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
🧰 Tools
🪛 Biome (1.9.4)

[error] 5-5: Use a regular expression literal instead of the RegExp constructor.

Regular expression literals avoid some escaping required in a string literal, and are easier to analyze statically.
Safe fix: Use a literal notation instead.

(lint/complexity/useRegexLiterals)


38-46: Consider layout stability for topHeight conditional rendering

The conditional rendering based on topHeight could potentially cause layout shifts. Consider using a more stable approach, such as setting a min-height or using CSS to handle the visibility.

-      {topHeight ? (
-        <div
-          className={clsx(
-            "border-l-klerosUIComponentsStroke w-0 grow-0 border-l",
-          )}
-          style={{ height: `${topHeight}px` }}
-        />
-      ) : null}
+      <div
+        className={clsx(
+          "border-l-klerosUIComponentsStroke w-0 grow-0 border-l",
+          { "hidden": !topHeight }
+        )}
+        style={{ height: topHeight ? `${topHeight}px` : '0' }}
+      />
src/lib/progress/timeline/bullet.tsx (1)

31-40: Overall container styling logic looks appropriate.
Using cn to merge base utility classes and additional conditional classes for rightSided and state yields a flexible layout.

To simplify readability, consider grouping the style logic for each state (disabled, loading, active) in a small helper function, so the className block remains concise and maintainable.

src/lib/display/small.tsx (2)

20-25: Ensure label is a valid unique ID for accessibility.
Using the label prop directly as the element’s id and referencing it via aria-labelledby may cause collisions if multiple components share the same label text or if the label text contains spaces or special characters.

Consider generating a unique ID or sanitizing the label, for example:

- <Label id={label} className="text-klerosUIComponentsPrimaryText text-sm break-words">
+ <Label id={`display-small-${label?.replace(/\s+/g, '-')}`} className="text-klerosUIComponentsPrimaryText text-sm break-words">

26-34: Reassess the fixed width and icon accessibility.

  1. The fixed width (w-[217px]) may restrict responsiveness; consider using more fluid styles.
  2. You may want to provide an aria-label or alternative text for the <Icon> if it conveys meaning.

Here’s one approach to make the container more responsive:

- <div className={cn("box-border flex w-[217px] flex-col", className)}>
+ <div className={cn("box-border flex w-auto max-w-sm flex-col", className)}>
src/lib/progress/linear/index.tsx (2)

17-17: Minor grammatical fix in documentation comment.
“progress bas” should be “progress bar.”

- /** Whether the progress bas should animate to it's value. */
+ /** Whether the progress bar should animate to its value. */

70-80: Zero-value progress is hidden by the condition.
Using {value && …} hides the fill path when value === 0. If you want a 0% fill to be visible, consider checking for value != null or value > 0 more explicitly.

- {value && (
+ {typeof value === "number" && (
src/lib/dropdown/select/index.tsx (1)

19-19: Naming consistency suggestion.
callback might be more recognizable if named onSelectionChange or onSelectItem, aligning with typical React event naming conventions.

src/lib/breadcrumb.tsx (2)

12-12: Double-check the need for the "secondary" variant.
Currently, only "primary" is styled differently, but "secondary" has no additional styling. If "secondary" isn't used or doesn't differ, consider removing it or adding the appropriate styles for clarity.


31-77: Consider optional chaining for the callback invocation.
Inside the click handler (onPress), you could simplify:

onPress={() => callback?.(value)}

instead of:

onPress={() => (callback ? callback(value) : null)}

This is purely stylistic but can improve readability.

src/lib/dropdown/cascader/dropdown-container.tsx (2)

46-61: Extract magic number into a named constant.
The value 239 appears here and in the CSS style for column positioning. Defining this at the top of the file (e.g., const COLUMN_WIDTH = 239;) makes the code clearer and more maintainable.


79-157: Unify repeated column width references.
You use 239 again in the TreeItem styling (before:left-[calc(var(--tree-item-level))_*_239px]). Consider referencing a single source of truth for this column width (e.g., a constant) to avoid drifting changes in the future.

README.md (4)

82-82: Fix minor grammar issue.
A small grammatical correction makes the sentence more natural:

-If you wish the use the library's tailwind theme variables in your tailwind app.
+If you wish to use the library's Tailwind CSS theme variables in your application,
🧰 Tools
🪛 LanguageTool

[uncategorized] ~82-~82: “the” seems less likely than “to”.
Context: ... ); } ``` ### Theme usage If you wish the use the library's tailwind theme variab...

(AI_HYDRA_LEO_CP_THE_TO)


89-89: Add missing pronoun for clarity.
Including "you" helps maintain consistency and clarity:

-If want to override or edit the defined theme variables,
+If you want to override or edit the defined theme variables,
🧰 Tools
🪛 LanguageTool

[grammar] ~89-~89: It seems that a pronoun is missing.
Context: ...variables here. If want to override or edit the defined th...

(IF_VB)


185-185: Consider a more direct phrase.
A less frequent alternative to “feel free to” can sound more concise:

-Contributions are welcome! Please feel free to submit a Pull Request.
+Contributions are welcome! Please consider submitting a Pull Request.
🧰 Tools
🪛 LanguageTool

[style] ~185-~185: The phrase ‘feel free to’ is used quite frequently. Consider using a less frequent alternative to set your writing apart from others and make it sound more professional.
Context: ...ontributing Contributions are welcome! Please feel free to submit a Pull Request. 1. Fork the rep...

(FEEL_FREE_TO_STYLE_ME)


189-189: Use a more descriptive word than “amazing” for professional tone.

-'feat: add some amazing feature'
+'feat: add a remarkable new feature'
🧰 Tools
🪛 LanguageTool

[style] ~189-~189: Consider using a more formal and expressive alternative to ‘amazing’.
Context: ...our changes using conventional commits (git commit -m 'feat: add some amazing feature') 4. Push to the branch (`git ...

(AWESOME)

src/lib/form/bignumber-field/useBigNumberField.tsx (2)

143-156: Handle console error logging in production.

Logging parsing errors with console.error() is helpful in development. However, consider whether these messages might be too noisy in production and if a more user-friendly form of error display is needed.


301-392: Consider refactoring repetitive unformatting logic.

The input change handling is split between formatted/unformatted states but duplicates certain checks (particularly the "" / "-" checks). Extracting this logic into a helper function might improve maintainability.

src/lib/progress/circular/index.tsx (1)

43-46: Enhance ARIA labeling for accessibility.

Currently, aria-label is set to progress.toString(); consider a more descriptive label, such as "Progress: X%", to improve screen reader context.

package.json (2)

79-85: Peer dependencies are appropriate for a component library.

Peer dependencies for Tailwind, react, and react-aria-components are correctly specified. Ensure these are documented for consumers in the README.


34-36: Consider including theme assets in the published files.

Currently, only the dist directory is included in the files array. If theme.css or other theme assets are meant to be published, ensure they're included in dist or add them to the files array.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 953def3 and 35f733c.

⛔ Files ignored due to path filters (5)
  • src/stories/assets/cover.png is excluded by !**/*.png
  • src/stories/assets/figma.png is excluded by !**/*.png
  • src/stories/assets/file.png is excluded by !**/*.png
  • src/stories/assets/github.png is excluded by !**/*.png
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (145)
  • .babelrc (0 hunks)
  • .gitignore (1 hunks)
  • README.md (1 hunks)
  • eslint.config.mjs (1 hunks)
  • global.d.ts (0 hunks)
  • package.json (1 hunks)
  • src/App.tsx (0 hunks)
  • src/examples/accordion.tsx (0 hunks)
  • src/examples/buttons.tsx (0 hunks)
  • src/examples/containers.tsx (0 hunks)
  • src/examples/copiable.tsx (0 hunks)
  • src/examples/displays.tsx (0 hunks)
  • src/examples/dropdowns.tsx (0 hunks)
  • src/examples/form.tsx (0 hunks)
  • src/examples/input.tsx (0 hunks)
  • src/examples/messages.tsx (0 hunks)
  • src/examples/pagination.tsx (0 hunks)
  • src/examples/progress.tsx (0 hunks)
  • src/examples/timeline.tsx (0 hunks)
  • src/examples/tooltip.tsx (0 hunks)
  • src/global.d.ts (1 hunks)
  • src/lib/accordion/accordion-item.tsx (2 hunks)
  • src/lib/accordion/index.tsx (3 hunks)
  • src/lib/breadcrumb.tsx (1 hunks)
  • src/lib/button/ButtonIcon.tsx (1 hunks)
  • src/lib/button/ButtonText.tsx (1 hunks)
  • src/lib/button/index.tsx (1 hunks)
  • src/lib/container/box.tsx (1 hunks)
  • src/lib/container/card.tsx (1 hunks)
  • src/lib/container/modal.tsx (1 hunks)
  • src/lib/copiable/index.tsx (3 hunks)
  • src/lib/display/icon.tsx (1 hunks)
  • src/lib/display/large.tsx (1 hunks)
  • src/lib/display/small.tsx (1 hunks)
  • src/lib/dot.tsx (1 hunks)
  • src/lib/dropdown/base-item-container.tsx (0 hunks)
  • src/lib/dropdown/base-item.tsx (0 hunks)
  • src/lib/dropdown/button.tsx (0 hunks)
  • src/lib/dropdown/cascader/button.tsx (1 hunks)
  • src/lib/dropdown/cascader/dropdown-container.tsx (1 hunks)
  • src/lib/dropdown/cascader/index.tsx (1 hunks)
  • src/lib/dropdown/cascader/item-container.tsx (0 hunks)
  • src/lib/dropdown/cascader/item.tsx (1 hunks)
  • src/lib/dropdown/cascader/select-button.tsx (1 hunks)
  • src/lib/dropdown/cascader/selector.tsx (0 hunks)
  • src/lib/dropdown/dropdown-container.tsx (0 hunks)
  • src/lib/dropdown/select/button.tsx (0 hunks)
  • src/lib/dropdown/select/dropdown-button.tsx (1 hunks)
  • src/lib/dropdown/select/dropdown-container.tsx (1 hunks)
  • src/lib/dropdown/select/index.tsx (1 hunks)
  • src/lib/dropdown/select/item-container.tsx (0 hunks)
  • src/lib/dropdown/select/item.tsx (1 hunks)
  • src/lib/dropdown/select/simple-button.tsx (1 hunks)
  • src/lib/dropdown/simple-button.tsx (0 hunks)
  • src/lib/form/bignumber-field/index.tsx (1 hunks)
  • src/lib/form/bignumber-field/useBigNumberField.tsx (1 hunks)
  • src/lib/form/checkbox.tsx (1 hunks)
  • src/lib/form/datepicker/arrow-button.tsx (1 hunks)
  • src/lib/form/datepicker/calendar.tsx (1 hunks)
  • src/lib/form/datepicker/date-selector.tsx (0 hunks)
  • src/lib/form/datepicker/datepickerContext.ts (0 hunks)
  • src/lib/form/datepicker/day.tsx (0 hunks)
  • src/lib/form/datepicker/display-button.tsx (1 hunks)
  • src/lib/form/datepicker/dropdown.tsx (0 hunks)
  • src/lib/form/datepicker/index.tsx (1 hunks)
  • src/lib/form/datepicker/month-selector.tsx (0 hunks)
  • src/lib/form/datepicker/month.tsx (0 hunks)
  • src/lib/form/datepicker/time-control.tsx (1 hunks)
  • src/lib/form/datepicker/time-controls.tsx (0 hunks)
  • src/lib/form/datepicker/time-selector.tsx (0 hunks)
  • src/lib/form/field.tsx (0 hunks)
  • src/lib/form/file-uploader.tsx (1 hunks)
  • src/lib/form/index.tsx (1 hunks)
  • src/lib/form/number-field.tsx (1 hunks)
  • src/lib/form/radio-group.tsx (1 hunks)
  • src/lib/form/radio.tsx (0 hunks)
  • src/lib/form/searchbar.tsx (1 hunks)
  • src/lib/form/slider.tsx (1 hunks)
  • src/lib/form/slider/handle.tsx (0 hunks)
  • src/lib/form/slider/index.tsx (0 hunks)
  • src/lib/form/switch.tsx (1 hunks)
  • src/lib/form/text-area.tsx (1 hunks)
  • src/lib/form/text-field.tsx (1 hunks)
  • src/lib/form/textarea.tsx (0 hunks)
  • src/lib/index.ts (2 hunks)
  • src/lib/messages/alert.tsx (1 hunks)
  • src/lib/messages/push.tsx (1 hunks)
  • src/lib/pagination/compact.tsx (1 hunks)
  • src/lib/pagination/tabs.tsx (1 hunks)
  • src/lib/progress/circular/index.tsx (2 hunks)
  • src/lib/progress/linear/index.tsx (1 hunks)
  • src/lib/progress/steps/bullet-circle.tsx (2 hunks)
  • src/lib/progress/steps/bullet.tsx (3 hunks)
  • src/lib/progress/steps/horizontal-bullet.tsx (2 hunks)
  • src/lib/progress/steps/horizontal.tsx (2 hunks)
  • src/lib/progress/steps/index.tsx (1 hunks)
  • src/lib/progress/steps/vertical.tsx (2 hunks)
  • src/lib/progress/timeline/bullet.tsx (2 hunks)
  • src/lib/progress/timeline/custom.tsx (1 hunks)
  • src/lib/progress/timeline/index.tsx (1 hunks)
  • src/lib/progress/timeline/spine.tsx (2 hunks)
  • src/lib/scrollbar.tsx (1 hunks)
  • src/lib/tag/index.tsx (1 hunks)
  • src/lib/theme.ts (1 hunks)
  • src/lib/tooltip/index.tsx (1 hunks)
  • src/stories/KlerosUIComponentsLibrary.mdx (1 hunks)
  • src/stories/alert.stories.tsx (1 hunks)
  • src/stories/bignumber-field.stories.tsx (1 hunks)
  • src/stories/box.stories.tsx (1 hunks)
  • src/stories/card.stories.tsx (1 hunks)
  • src/stories/checkbox.stories.tsx (1 hunks)
  • src/stories/circular-progress.stories.tsx (1 hunks)
  • src/stories/copiable.stories.tsx (1 hunks)
  • src/stories/custom-timeline.stories.tsx (1 hunks)
  • src/stories/datepicker.stories.tsx (1 hunks)
  • src/stories/displayIcon.stories.tsx (1 hunks)
  • src/stories/displayLarge.stories.tsx (1 hunks)
  • src/stories/displaySmall.stories.tsx (1 hunks)
  • src/stories/dropdown-cascader.stories.tsx (1 hunks)
  • src/stories/dropdown-select.stories.tsx (1 hunks)
  • src/stories/fileuploader.stories.tsx (1 hunks)
  • src/stories/form.stories.tsx (1 hunks)
  • src/stories/linear-progress.stories.tsx (1 hunks)
  • src/stories/modal.stories.tsx (1 hunks)
  • src/stories/number-field.stories.tsx (1 hunks)
  • src/stories/push.stories.tsx (1 hunks)
  • src/stories/radioGroup.stories.tsx (1 hunks)
  • src/stories/searchbar.stories.tsx (1 hunks)
  • src/stories/slider.stories.tsx (1 hunks)
  • src/stories/steps.stories.tsx (1 hunks)
  • src/stories/switch.stories.tsx (1 hunks)
  • src/stories/tag.stories.tsx (1 hunks)
  • src/stories/text-area.stories.tsx (1 hunks)
  • src/stories/text-field.stories.tsx (1 hunks)
  • src/stories/timeline.stories.tsx (1 hunks)
  • src/stories/tooltip.stories.tsx (1 hunks)
  • src/styles/common-style.ts (0 hunks)
  • src/styles/global-style.ts (0 hunks)
  • src/styles/global.css (1 hunks)
  • src/styles/theme.css (1 hunks)
  • src/styles/themes.ts (0 hunks)
  • src/utils/index.ts (1 hunks)
  • tsconfig.json (1 hunks)
  • vite.config.theme.ts (1 hunks)
  • vite.config.ts (1 hunks)
💤 Files with no reviewable changes (41)
  • .babelrc
  • src/examples/accordion.tsx
  • src/examples/containers.tsx
  • global.d.ts
  • src/examples/tooltip.tsx
  • src/styles/global-style.ts
  • src/examples/displays.tsx
  • src/lib/dropdown/simple-button.tsx
  • src/examples/buttons.tsx
  • src/lib/dropdown/dropdown-container.tsx
  • src/examples/copiable.tsx
  • src/examples/dropdowns.tsx
  • src/lib/form/datepicker/time-selector.tsx
  • src/lib/form/textarea.tsx
  • src/lib/dropdown/select/button.tsx
  • src/styles/themes.ts
  • src/examples/pagination.tsx
  • src/lib/dropdown/base-item.tsx
  • src/examples/form.tsx
  • src/examples/messages.tsx
  • src/lib/dropdown/cascader/item-container.tsx
  • src/lib/form/datepicker/month.tsx
  • src/lib/form/datepicker/day.tsx
  • src/lib/form/field.tsx
  • src/App.tsx
  • src/examples/timeline.tsx
  • src/lib/dropdown/cascader/selector.tsx
  • src/lib/form/datepicker/time-controls.tsx
  • src/lib/form/datepicker/date-selector.tsx
  • src/lib/dropdown/button.tsx
  • src/examples/input.tsx
  • src/lib/form/datepicker/datepickerContext.ts
  • src/lib/form/slider/index.tsx
  • src/lib/dropdown/select/item-container.tsx
  • src/lib/dropdown/base-item-container.tsx
  • src/lib/form/datepicker/month-selector.tsx
  • src/lib/form/slider/handle.tsx
  • src/lib/form/datepicker/dropdown.tsx
  • src/styles/common-style.ts
  • src/lib/form/radio.tsx
  • src/examples/progress.tsx
✅ Files skipped from review due to trivial changes (27)
  • src/lib/theme.ts
  • src/global.d.ts
  • src/stories/modal.stories.tsx
  • src/stories/displayIcon.stories.tsx
  • src/stories/tag.stories.tsx
  • src/stories/switch.stories.tsx
  • src/stories/push.stories.tsx
  • vite.config.theme.ts
  • src/stories/circular-progress.stories.tsx
  • src/stories/datepicker.stories.tsx
  • src/stories/box.stories.tsx
  • src/stories/displayLarge.stories.tsx
  • src/stories/card.stories.tsx
  • src/stories/linear-progress.stories.tsx
  • src/stories/displaySmall.stories.tsx
  • src/stories/custom-timeline.stories.tsx
  • src/stories/slider.stories.tsx
  • src/lib/form/index.tsx
  • src/styles/theme.css
  • src/stories/alert.stories.tsx
  • src/stories/fileuploader.stories.tsx
  • src/stories/dropdown-cascader.stories.tsx
  • src/stories/checkbox.stories.tsx
  • src/stories/KlerosUIComponentsLibrary.mdx
  • src/stories/text-area.stories.tsx
  • src/stories/tooltip.stories.tsx
  • src/stories/searchbar.stories.tsx
🚧 Files skipped from review as they are similar to previous changes (8)
  • .gitignore
  • src/lib/button/ButtonIcon.tsx
  • src/lib/accordion/index.tsx
  • src/lib/button/ButtonText.tsx
  • tsconfig.json
  • src/lib/dot.tsx
  • eslint.config.mjs
  • src/lib/pagination/compact.tsx
🧰 Additional context used
🧠 Learnings (1)
src/lib/accordion/accordion-item.tsx (1)
Learnt from: Harman-singh-waraich
PR: kleros/ui-components-library#63
File: src/lib/accordion/accordion-item.tsx:47-47
Timestamp: 2025-03-13T04:48:59.431Z
Learning: In this project's Tailwind configuration, `duration-(--cssVariable)` is a valid shorthand syntax for accessing CSS variables, equivalent to `duration-[var(--cssVariable)]`.
🧬 Code Graph Analysis (51)
src/lib/container/box.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/stories/timeline.stories.tsx (1)
src/stories/custom-timeline.stories.tsx (2)
  • Timeline (19-39)
  • TimelineAlignment (113-149)
src/lib/scrollbar.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/switch.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/radio-group.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/accordion/accordion-item.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/container/modal.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/dropdown/cascader/select-button.tsx (3)
src/lib/dropdown/cascader/index.tsx (1)
  • IDropdownCascader (14-19)
src/utils/index.ts (1)
  • isUndefined (8-11)
src/lib/dropdown/cascader/item.tsx (1)
  • IItem (7-12)
src/lib/dropdown/cascader/button.tsx (2)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/dropdown/cascader/item.tsx (1)
  • IItem (7-12)
src/lib/dropdown/select/dropdown-container.tsx (1)
src/lib/dropdown/select/item.tsx (1)
  • IItem (19-23)
src/lib/progress/timeline/index.tsx (3)
src/lib/progress/timeline/bullet.tsx (2)
  • SideProp (7-9)
  • VariantProp (3-3)
src/lib/progress/timeline/spine.tsx (1)
  • VariantProp (7-7)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/text-area.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/stories/dropdown-select.stories.tsx (2)
src/stories/dropdown-cascader.stories.tsx (2)
  • DisabledKeysSelect (84-90)
  • RequiredSelect (93-115)
src/stories/form.stories.tsx (1)
  • Form (19-44)
src/lib/form/text-field.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/display/icon.tsx (3)
src/stories/displayIcon.stories.tsx (1)
  • DisplayIcon (18-27)
src/stories/card.stories.tsx (1)
  • Card (25-33)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/bignumber-field/index.tsx (2)
src/lib/form/bignumber-field/useBigNumberField.tsx (2)
  • BigNumberFieldProps (31-66)
  • useBigNumberField (80-613)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/dropdown/cascader/item.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/slider.tsx (2)
src/stories/slider.stories.tsx (1)
  • Slider (22-34)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/dropdown/select/simple-button.tsx (2)
src/lib/button/index.tsx (1)
  • ButtonProps (26-35)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/progress/timeline/custom.tsx (3)
src/lib/progress/timeline/bullet.tsx (2)
  • VariantProp (3-3)
  • StateProp (11-13)
src/lib/progress/timeline/spine.tsx (1)
  • VariantProp (7-7)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/messages/alert.tsx (4)
src/lib/progress/timeline/bullet.tsx (1)
  • VariantProp (3-3)
src/lib/progress/timeline/spine.tsx (1)
  • VariantProp (7-7)
src/stories/alert.stories.tsx (1)
  • Alert (23-32)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/datepicker/calendar.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/searchbar.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/tooltip/index.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/datepicker/display-button.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/progress/steps/vertical.tsx (2)
src/lib/progress/steps/index.tsx (1)
  • StepsProps (12-18)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/progress/linear/index.tsx (1)
src/utils/index.ts (2)
  • cn (4-6)
  • isUndefined (8-11)
src/lib/display/large.tsx (2)
src/lib/display/icon.tsx (1)
  • DisplayIconProps (7-12)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/progress/timeline/spine.tsx (1)
src/utils/index.ts (1)
  • isUndefined (8-11)
src/lib/form/file-uploader.tsx (2)
src/stories/fileuploader.stories.tsx (1)
  • FileUploader (26-33)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/button/index.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/stories/radioGroup.stories.tsx (1)
src/stories/form.stories.tsx (1)
  • Form (19-44)
src/lib/dropdown/cascader/index.tsx (4)
src/lib/dropdown/select/item.tsx (1)
  • IItem (19-23)
src/lib/dropdown/cascader/item.tsx (1)
  • IItem (7-12)
src/stories/dropdown-cascader.stories.tsx (1)
  • DropdownCascader (31-74)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/container/card.tsx (2)
src/stories/card.stories.tsx (1)
  • Card (25-33)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/dropdown/cascader/dropdown-container.tsx (3)
src/lib/dropdown/cascader/index.tsx (1)
  • IDropdownCascader (14-19)
src/lib/dropdown/cascader/item.tsx (1)
  • IItem (7-12)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/messages/push.tsx (2)
src/stories/push.stories.tsx (1)
  • Push (23-34)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/number-field.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/progress/timeline/bullet.tsx (2)
src/utils/index.ts (2)
  • cn (4-6)
  • isUndefined (8-11)
src/lib/progress/timeline/spine.tsx (1)
  • colorRegex (5-5)
src/lib/pagination/tabs.tsx (2)
src/stories/tabs.stories.tsx (1)
  • Tabs (19-44)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/datepicker/arrow-button.tsx (2)
src/lib/button/index.tsx (1)
  • ButtonProps (26-35)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/dropdown/select/item.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/display/small.tsx (3)
src/stories/displaySmall.stories.tsx (1)
  • DisplaySmall (18-27)
src/lib/display/icon.tsx (1)
  • DisplayIconProps (7-12)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/checkbox.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/stories/text-field.stories.tsx (3)
src/stories/number-field.stories.tsx (6)
  • Default (42-49)
  • Variant (51-56)
  • CustomIcon (58-63)
  • Labelled (65-70)
  • WithDescription (72-78)
  • Required (80-102)
src/stories/text-area.stories.tsx (4)
  • Default (47-54)
  • Variant (56-61)
  • Labelled (63-68)
  • Required (80-102)
src/stories/form.stories.tsx (1)
  • Form (19-44)
src/lib/progress/steps/bullet.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/breadcrumb.tsx (2)
src/utils/index.ts (1)
  • cn (4-6)
src/stories/breadcrumb.stories.tsx (1)
  • Breadcrumb (26-38)
src/lib/dropdown/select/dropdown-button.tsx (3)
src/lib/dropdown/select/item.tsx (1)
  • IItem (19-23)
src/lib/button/index.tsx (1)
  • ButtonProps (26-35)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/tag/index.tsx (3)
src/lib/button/index.tsx (1)
  • ButtonProps (26-35)
src/stories/tag.stories.tsx (1)
  • Tag (22-29)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/progress/steps/horizontal.tsx (2)
src/lib/progress/steps/index.tsx (1)
  • StepsProps (12-18)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/dropdown/select/index.tsx (2)
src/lib/dropdown/select/item.tsx (1)
  • IItem (19-23)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/datepicker/index.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
🪛 Biome (1.9.4)
src/lib/progress/steps/horizontal-bullet.tsx

[error] 75-85: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/lib/progress/timeline/spine.tsx

[error] 5-5: Use a regular expression literal instead of the RegExp constructor.

Regular expression literals avoid some escaping required in a string literal, and are easier to analyze statically.
Safe fix: Use a literal notation instead.

(lint/complexity/useRegexLiterals)

src/lib/form/file-uploader.tsx

[error] 21-21: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

src/lib/messages/push.tsx

[error] 16-16: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

src/lib/progress/timeline/bullet.tsx

[error] 44-44: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 45-45: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)


[error] 74-74: Invalid typeof comparison value: this expression is not a string literal

not a string literal

(lint/suspicious/useValidTypeof)

src/lib/pagination/tabs.tsx

[error] 42-42: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

src/lib/breadcrumb.tsx

[error] 9-9: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

src/styles/global.css

[error] 4-4: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

src/stories/bignumber-field.stories.tsx

[error] 156-156: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🪛 LanguageTool
README.md

[uncategorized] ~82-~82: “the” seems less likely than “to”.
Context: ... ); } ``` ### Theme usage If you wish the use the library's tailwind theme variab...

(AI_HYDRA_LEO_CP_THE_TO)


[grammar] ~89-~89: It seems that a pronoun is missing.
Context: ...variables here. If want to override or edit the defined th...

(IF_VB)


[style] ~185-~185: The phrase ‘feel free to’ is used quite frequently. Consider using a less frequent alternative to set your writing apart from others and make it sound more professional.
Context: ...ontributing Contributions are welcome! Please feel free to submit a Pull Request. 1. Fork the rep...

(FEEL_FREE_TO_STYLE_ME)


[style] ~189-~189: Consider using a more formal and expressive alternative to ‘amazing’.
Context: ...our changes using conventional commits (git commit -m 'feat: add some amazing feature') 4. Push to the branch (`git ...

(AWESOME)

🔇 Additional comments (165)
src/utils/index.ts (1)

1-6: Good implementation of the cn utility function for Tailwind classes.

This is a well-implemented utility function using clsx and tailwind-merge to handle class name composition. The pattern is ideal for components using Tailwind CSS with conditional classes, preventing class conflicts and duplications.

src/lib/container/box.tsx (1)

4-16: Box component successfully migrated to Tailwind CSS.

The component has been cleanly refactored from styled-components to use Tailwind CSS. The implementation is concise and follows best practices for functional components.

src/lib/accordion/accordion-item.tsx (4)

6-7: Good integration of React Aria and utility classes.

The addition of React Aria components and the cn utility function is a significant improvement for accessibility and maintainability.


26-42: Well-structured accordion button with appropriate styling.

The Button component is well-implemented with clear, semantic class structure for styling. The use of cn() for composing classes is clean and maintainable.


43-53: Effective animation implementation for accordion expansion.

The transition approach using height and overflow is appropriate for accordion animation. The component correctly measures content height using useElementSize for smooth transitions.


47-47: Custom Tailwind duration syntax is valid.

The duration-(--klerosUIComponentsTransitionSpeed) syntax is a valid shorthand in this project's Tailwind configuration.

src/lib/messages/alert.tsx (2)

14-14: Good addition of optional className prop.

The addition of an optional className prop improves the component's flexibility and allows for better customization by consumers.


17-63: Excellent refactoring to utility-first CSS.

The component has been successfully migrated from styled-components to utility-first CSS with Tailwind. The implementation is clean and maintains the original design while improving customizability.

src/lib/container/card.tsx (3)

1-2: Import changes look good

The import of the cn utility function from "../../utils" is appropriate for the class name composition pattern being implemented.


4-7: Good interface extension for better component flexibility

Extending React.HTMLAttributes is a good practice that allows consumers to pass any standard HTML div attributes to the Card component, improving its reusability.


9-24: Clean refactoring from styled-components to utility classes

The refactoring from styled-components to utility classes is well-implemented. The use of the cn utility function provides clean conditional class application, and the component properly forwards all props. The conditional classes for hover and rounded corners maintain the original functionality while making the implementation more transparent.

src/lib/button/index.tsx (3)

2-9: Good imports for accessibility-enhanced component

The imports are well-structured, bringing in both the necessary react-aria component and the utility functions for class composition. Importing the button sub-components (ButtonText, KlerosSymbol, ButtonIcon) helps maintain a clean separation of concerns.


11-35: Well-structured props interfaces with proper documentation

The props are well-organized with:

  1. BaseButtonProps for core button properties
  2. ButtonProps extending AriaButtonProps for accessibility
  3. Good JSDoc comments for props

This structure makes the component API clear and provides good TypeScript type safety.


37-84: Excellent implementation of accessible button with utility classes

The button implementation is well-refactored:

  1. Uses AriaButton for accessibility
  2. Applies conditional styling based on variant, size, and state
  3. Properly handles disabled state
  4. Uses composition pattern with subcomponents (KlerosSymbol, ButtonIcon, ButtonText)
  5. Well-structured class organization with the cn utility

This approach makes the component more maintainable and accessible while preserving all the visual styling options.

src/lib/display/icon.tsx (5)

3-5: Good addition of utilities for styling and accessibility

The addition of the cn utility, clsx, and the Label component from react-aria-components provides the necessary tools for both styling composition and accessibility improvements.


11-11: Improved API with optional className prop

Adding the optional className prop enables better component customization, allowing consumers to extend or override the default styling of the component.


14-20: Better component definition with explicit types

Changing from arrow function to a named function with Readonly<DisplayIconProps> improves type safety and readability. The spread of remaining props is maintained for flexibility.


22-25: Good use of Card component with composition pattern

Using the Card component with the cn utility for class composition is a clean approach. The explicit dimensions for the icon container ensure consistent layout.


26-44: Improved text container with better accessibility

The text container implementation:

  1. Uses appropriate flex layout for alignment
  2. Implements proper ARIA attributes with aria-labelledby
  3. Uses the Label component for better accessibility
  4. Maintains consistent typography with utility classes

This significantly improves the component's accessibility while maintaining visual consistency.

src/lib/form/switch.tsx (3)

1-6: Good accessibility-first approach with react-aria

Using the react-aria-components library for the Switch component is an excellent choice. It provides accessibility out-of-the-box and handles state management internally.


7-12: Clean prop type composition

The approach of extending AriaSwitchProps with your custom SwitchBaseProps is clean and allows full access to all the accessibility props from react-aria-components.


13-41: Excellent switch implementation with render props pattern

The switch implementation:

  1. Uses the render props pattern to access the internal isSelected state
  2. Applies conditional styling based on size and selection state
  3. Uses the before pseudo-element for the knob, which is an elegant solution
  4. Implements transitions for smooth state changes
  5. Maintains clean class organization with the cn utility

This is a significant improvement over a manual implementation, providing better accessibility and reliability.

src/lib/tag/index.tsx (2)

2-4: Imports and setup look good.

The use of react-aria-components, cn, and clsx is consistent with the project’s transition to utility-first CSS and accessible primitives.


6-12: Inheritance from ButtonProps is appropriate.

BaseTagProps neatly extends ButtonProps while adding a custom active prop. This approach keeps the component flexible and aligned with React Aria conventions.

src/lib/form/searchbar.tsx (1)

3-12: Adoption of React Aria and utility classes is consistent.

Replacing styled-components with SearchField, Input, Label, etc., ensures native accessibility and keeps styling maintainable using Tailwind and clsx.

src/lib/form/file-uploader.tsx (5)

1-1: Initialization logic is straightforward.

Using React’s useState hook to track the selected file is clear and maintains a simple local state.


8-16: Utility imports align with the refactoring approach.

The imports from react-aria-components and the usage of cn and clsx effectively support the new design strategy.


33-41: Ensure usage of isDisabled is consistent.

The isDisabled prop is properly passed to DropZone to disable drops. Verify that the consuming component or stories handle this prop accurately to avoid unexpected behavior.


47-77: File drop and selection logic look correct.

The approach to filter accepted file types, pick the first matching file, and invoke callback is clear and aligns with standard drop and file selection patterns.

Also applies to: 80-90, 92-110


112-140: Helpful variant icon display.

Conditionally showing different icons and text based on variant improves clarity for success, warning, error, or info states. This is well-structured and keeps the code readable.

Also applies to: 143-143

src/lib/form/slider.tsx (1)

31-35: Confirm that onChange is the intended event.
onChange={callback} will fire for every step the user drags the thumb. If the requirement is to capture only the final value, consider using onChangeEnd or a similar event.

src/lib/form/checkbox.tsx (2)

22-28: Looks good!
Using cn to merge classes is a neat approach, and placing className at the end ensures user-defined overrides.


31-55: Add or confirm test coverage for visual states.
Ensure the “small” vs. default size and the checkmark styles are tested, especially the animation for selected state.

src/lib/tooltip/index.tsx (1)

45-108: Implementation aligns well with react-aria-components.
Tooltips are accessible and properly configured with delay, offset, and arrow placement. Great job!

vite.config.ts (3)

13-15: LGTM! Library configuration is well set up.

The library configuration correctly specifies the entry point, output format (ES modules), and library name.


17-31: Well-structured rollup configuration for a component library.

The configuration properly externalizes React dependencies and preserves module structure, which is good practice for a component library.


32-42: Plugin configuration is comprehensive and well-organized.

The plugins for SVG handling, Tailwind CSS integration, React support, and TypeScript declarations are correctly configured for a modern component library.

src/stories/timeline.stories.tsx (3)

1-15: Well-structured Storybook story setup with proper TypeScript typing.

The story setup includes proper meta configuration, component imports, and TypeScript types, following Storybook best practices.


41-43: Great documentation for the TimelineAlignment story.

The JSDoc comment clearly explains the purpose of the TimelineAlignment story, making it easier for users to understand the component's behavior.


17-39:

✅ Verification successful

Verify Timeline story props against the component interface.

The Timeline story provides props like themeUI, backgroundUI, and items with rightSided property. Ensure these match the Timeline component's interface and that the rightSided property is properly documented.


🏁 Script executed:

#!/bin/bash
# Check if the Timeline component accepts all props used in the story
grep -r "interface.*TimelineProps" --include="*.ts*" src/lib/progress/
grep -r "rightSided" --include="*.ts*" src/lib/progress/timeline

Length of output: 1328


Timeline Story Props Verified Against Component Interface

After reviewing the component, it’s confirmed that:

  • The rightSided property is properly defined as an optional boolean in the Bullet component (e.g., in src/lib/progress/timeline/bullet.tsx) and is used appropriately in src/lib/progress/timeline/index.tsx.
  • The other props (themeUI, backgroundUI, and items) provided in the story align with the Timeline component’s expected interface.

No discrepancies were found, and the property documentation is in line with the component’s usage.

src/lib/progress/steps/index.tsx (3)

5-10: Good addition of JSDoc comments for better code documentation.

Adding descriptive JSDoc comments to the StepItem interface improves code documentation and makes the component more maintainable.


12-18: Improved props interface with className support and documentation.

The addition of the optional className prop and JSDoc documentation for the horizontal flag enhances the component's customizability and clarity.


19-22: Refactored component implementation with better defaults and prop handling.

The change from an arrow function to a named function with explicit default values and proper prop spreading improves readability and maintainability.

src/lib/dropdown/select/dropdown-button.tsx (4)

15-34: Well-structured ItemDisplayContainer for placeholder and selected item rendering.

The ItemDisplayContainer component cleanly handles both placeholder and selected item states, with proper type definitions and conditional rendering.


36-66: Well-implemented DropdownButton with react-aria-components integration.

The DropdownButton component properly uses context, conditional rendering, and accessibility features from react-aria-components, with good management of state and styling.


44-50: Good use of utility-first CSS with Tailwind and cn utility.

The component uses a clean approach to styling with Tailwind utility classes and the custom cn utility function for combining class names.


58-63: Nice animation effect for the dropdown arrow.

The rotation animation for the dropdown arrow when the dropdown is open provides good visual feedback to users.

src/lib/dropdown/select/dropdown-container.tsx (1)

1-35: Accessible dropdown container looks good!

This component implements a fully accessible dropdown container with proper animation and scrolling support using React Aria Components. The implementation correctly handles open/close states with smooth animations.

src/lib/progress/steps/horizontal.tsx (2)

4-4: LGTM! New utility import for class name merging

The addition of the cn utility function import helps with merging Tailwind classes consistently.


12-21: Great accessibility improvements!

The addition of ARIA attributes (aria-orientation, role, aria-label) significantly improves the component's accessibility.

src/lib/progress/steps/vertical.tsx (2)

4-4: LGTM! Added utility function for class name merging

The import of the cn utility function helps with properly merging Tailwind classes.


13-18: Great accessibility improvements!

Adding ARIA attributes (aria-orientation, role, aria-label) significantly enhances the component's accessibility.

src/lib/progress/steps/horizontal-bullet.tsx (1)

50-53: Great accessibility improvements!

Adding ARIA attributes (aria-label, role, aria-current, aria-disabled) significantly enhances the component's accessibility.

src/lib/form/datepicker/time-control.tsx (3)

1-5: Good choice of imports for the new component

The imports look appropriate: react-aria-components for accessibility, clsx for conditional class names, cn utility, and the custom ArrowButton component.


12-20: LGTM! Good semantic HTML and accessibility

Good use of semantic HTML with header and h2 elements, plus the appropriate aria-label attribute for the container.


31-56: Good implementation of DateInput with conditional rendering

The DateInput component with conditional rendering of segments is well-implemented. The focus states and hover states help with accessibility.

src/lib/progress/steps/bullet-circle.tsx (3)

2-2: Good addition of clsx for conditional class names

Adding clsx is appropriate for handling conditional class names in the refactored component.


18-21: Good use of Tailwind flexbox classes for layout

The flexbox layout classes are well-chosen for the vertical arrangement of elements.


22-42: Well-structured conditional styling

The conditional styling for active vs. inactive states using clsx is clear and maintainable.

src/lib/scrollbar.tsx (2)

3-4: Good addition of React import and utility function

Adding the React import and the cn utility function is appropriate for the refactored component.


6-24: Well-structured functional component with Tailwind utility classes

The refactoring to a functional component with Tailwind utility classes is clean and maintainable. Good use of the cn utility to combine classes and the spread operator to forward props.

src/lib/index.ts (4)

1-1: Good addition of global CSS import

Adding the global CSS import at the top of the main index file ensures that styles are available throughout the application.


17-19: Good addition of specific field components

Adding more specific field components (NumberField, BigNumberField, TextField) instead of a generic Field component improves type safety and component clarity.


21-21: Appropriate renaming of TextArea export

Renaming from Textarea to TextArea follows a more consistent naming convention (PascalCase).


26-26:

❓ Verification inconclusive

Ensure that Radio to radio-group change is backward compatible

The change from ./form/radio to ./form/radio-group might affect existing code that expects the old Radio component. Ensure that the new component maintains the same API or that migration instructions are provided.


🏁 Script executed:

#!/bin/bash
# Check for direct imports of the old Radio component
rg -l "from ['\"].*?/form/radio['\"]" --type ts --type tsx

Length of output: 92


Action Required: Verify Backward Compatibility of the Radio Component Change

The change from using ./form/radio to ./form/radio-group may affect parts of the codebase that directly import the old Radio component. To ensure backward compatibility, please verify that no files (in both .ts and .tsx) still reference ./form/radio. It's recommended to re-run the search using a modified command that properly recognizes .tsx files.

Please run the following shell script to check for any lingering imports:

If this search produces no output, it confirms that there are no direct imports of the old Radio component. In that case, please ensure that the new Radio component at ./form/radio-group maintains the same API, or provide migration instructions as needed.


🏁 Script executed:

#!/bin/bash
# Re-run search for direct imports of './form/radio' considering .ts and .tsx files
rg --type-add 'tsx:*.tsx' --type ts --type tsx -l "from ['\"](.*?/form/radio)['\"]"

Length of output: 211


Action Required: Manual Verification Required for Backward Compatibility

The recent search did not conclusively output any instances of imports referencing the old ./form/radio path. However, because the command execution yielded an error related to the `` syntax and produced no output, we cannot fully trust the inference.

Next Steps:

  • Manually verify: Check that no files (both .ts and .tsx) import the old ./form/radio component.
  • Confirm consistency: Ensure that the new export (Radio from ./form/radio-group) fully maintains the expected API. If there are any deviations in behavior or API, please either implement a backward compatibility shim or update the migration instructions accordingly.

Please run the verification manually to ensure confidence in the changes.


Action Required: Verify Backward Compatibility of the Radio Component Change

The new export (Radio from ./form/radio-group) must be confirmed to work seamlessly for any existing code that might still expect the old ./form/radio component. Although an automated search did not return any direct imports of the old path, the search execution encountered syntax issues, so we cannot rely entirely on that output.

Please manually verify that:

  • No .ts or .tsx files are importing ./form/radio.
  • The new Radio component provides the same API as the former component. If there is any change in behavior/API, include either a compatibility shim or clear migration instructions.
src/stories/bignumber-field.stories.tsx (6)

1-5: Well-structured imports with clear dependencies.

The imports are logically organized, starting with Storybook types, then the component being demonstrated, followed by assets and utilities.


7-53: Good metadata configuration with comprehensive controls.

The Storybook metadata is well-structured with appropriate controls for all relevant props. The inclusion of detailed control configurations for numeric and formatting properties provides a good developer experience.


55-56: Proper type definition with extended preview args.

The Story type correctly extends both StoryObj and IPreviewArgs, providing proper typing for theme and background controls.


58-64: LGTM - Default story establishes the baseline configuration.

The Default story provides a clear starting point with essential props that other stories can build upon.


82-89: Good demonstration of BigNumber.js handling large numbers.

This story effectively showcases the component's ability to handle extremely large numbers beyond JavaScript's native number limits.


91-105: Comprehensive demonstration of number formatting options.

The formatting stories effectively showcase both standard and custom formatting with different separators, prefixes, and suffixes.

Also applies to: 107-121

src/lib/progress/timeline/index.tsx (4)

3-4: Good utility imports for CSS class management.

Importing clsx and the custom cn utility function aligns with the migration from styled-components to utility-first CSS.


14-14: Added className prop improves component composability.

The optional className prop allows for custom styling to be applied to the Timeline component.


17-18: Good documentation and prop typing improvement.

The JSDoc comment and Readonly type constraint enhance documentation and type safety.


21-26: Enhanced accessibility with semantic ARIA attributes.

The addition of aria-label and role attributes improves the component's accessibility.

src/stories/steps.stories.tsx (5)

1-6: Clean and concise imports.

The imports are well organized and limited to only what's needed.


7-20: Well-structured Storybook metadata.

Good use of the satisfies operator with Meta type to ensure type safety while maintaining inference.


25-38: Clear default story configuration.

The Default story provides appropriate theme settings and demonstrates horizontal orientation with a specific current step.


40-47: Good JSDoc comment explaining vertical orientation.

The comment clearly explains the purpose of this variant, and the story properly inherits from Default while changing only the necessary props.


49-59: Excellent demonstration of hierarchical steps with subitems.

The SubItems story effectively shows how to implement nested step structures, with clear JSDoc documentation.

src/stories/text-field.stories.tsx (4)

1-10: Complete set of imports for form demonstration.

The imports include not only the component being demonstrated but also Form and Button components for the Required story.


11-36: Comprehensive metadata with appropriate controls.

The metadata configuration provides a good set of controls for the component's props, making it easy to interact with the component in Storybook.


58-63: Good demonstration of icon integration.

The CustomIcon story effectively shows how to add an icon to the text field.


80-101: Form integration demonstrates required field validation.

The Required story effectively shows the component in a form context with proper form submission prevention.

However, the aria-pressed="true" attribute on the Button may not be appropriate for a submit button:

-        aria-pressed="true"

This attribute is typically used for toggle buttons, not submit buttons.

src/lib/form/radio-group.tsx (3)

42-51: Good usage of className composition in AriaRadioGroup.
The flexible orientation classes and merging additional classNames is a clean approach, ensuring the container styles can be extended while preserving default layout.


62-101: Comprehensive styling for radio states is well-implemented.
Your conditional CSS classes effectively handle hover, press, disabled, and selected states, providing clear visual feedback. Great job ensuring that disabled radios remain visually distinct to avoid user confusion.


14-16:

❓ Verification inconclusive

Clarify value requirement in RadioOption.
AriaRadioProps typically includes a value property for each radio. Confirm that the value field is indeed mandatory or gracefully handle cases where value might be missing.

Here's a script you can run to confirm if AriaRadioProps from react-aria-components enforces a required value field:


🏁 Script executed:

#!/bin/bash
# Searching for the definition of RadioProps in the node_modules to see if it includes a required 'value' property
fd "react-aria-components" node_modules --type d --exec rg "interface RadioProps" 

Length of output: 261


Clarify the “value” prop requirement in RadioOption
It isn’t immediately clear from the current code whether the underlying AriaRadioProps enforces a required value property. Our initial search shows that RadioProps extends Omit<AriaRadioProps, 'children'> (see output from node_modules/react-aria-components/src/RadioGroup.tsx), but this doesn’t confirm if value is mandatory. Please double-check the definition of AriaRadioProps in the package (e.g. by searching for the "interface AriaRadioProps" and inspecting any occurrences of a value field) and then either:

  • Explicitly add the required value property to RadioOption if it must always be present, or
  • Implement graceful handling (or documentation) for the case when value is omitted.
src/lib/form/number-field.tsx (2)

57-79: Robust input styling with variant-based borders.
Your approach to combining variant-based borders, placeholders, and focus states is clear and readable. This ensures consistent styling across success, warning, and error states.


132-150: Variant icons are properly placed.
The inline placement of success, warning, error, or a custom icon is handled neatly, preventing overlap with the stepper controls. Great visual clarity and layering.

src/lib/form/datepicker/display-button.tsx (1)

19-55: Overall accessible design using react-aria-components.
You effectively leverage DateInput, DateSegment, and a button with an icon to ensure users can review and edit the date or open the date-relevant UI. This fosters a clear, navigable experience for keyboard and screen-reader usage.

src/stories/radioGroup.stories.tsx (2)

78-90: Good implementation of the form integration.

The RequiredOptions story effectively demonstrates how the RadioGroup component can be used within a form, with proper prevention of default form submission behavior.


91-107: Make sure the Button aria-pressed value is appropriate.

The aria-pressed="true" attribute on the Button suggests it's a toggle button that's currently pressed, but it appears to be a submit button that doesn't maintain a pressed state.

-        aria-pressed="true"
src/lib/form/text-field.tsx (1)

50-69: Excellent comprehensive styling handling all states.

The input styling covers hover, focus, invalid, and variant states with appropriate visual feedback using Tailwind CSS classes. The conditional classes are well-organized.

src/lib/form/text-area.tsx (1)

70-73: Excellent handling of conditional resize functionality.

The resize functionality is well-implemented with conditional classes based on the resizeX and resizeY props, allowing for customizable resizing behavior.

src/lib/progress/steps/bullet.tsx (4)

3-4: Import utilities added for class name management

The addition of clsx and the custom cn utility function enables better management of conditional class names, which is essential for the migration from styled-components to Tailwind CSS utility classes.


13-13: Good addition of className prop for external styling

Adding the optional className prop allows for external customization of the component, following the composable pattern used throughout the codebase's refactoring to Tailwind.


25-31: Enhanced accessibility with proper ARIA attributes

The addition of ARIA attributes (aria-label, role="listitem", aria-current, aria-disabled) significantly improves the component's accessibility for screen readers and assistive technologies.


53-60: Improved accessibility for subitems with descriptive attributes

The addition of aria-label and aria-description attributes to subitems enhances screen reader accessibility, providing better context for each item in the list.

src/styles/global.css (1)

6-23: Standardized typography styling with CSS variables

The base typography styling establishes consistent text colors using CSS variables, which will make theming more maintainable. This is a good practice that aligns with the migration from styled-components to utility-first CSS.

src/stories/dropdown-select.stories.tsx (4)

10-31: Well-structured Storybook meta configuration

The meta configuration is well-organized with appropriate controls for the component's props, making it easy for developers to interact with and test different component states.


37-51: Good base story with comprehensive item examples

The base Select story provides a good foundation with varied item examples (different dot colors and values), which helps demonstrate the component's capabilities.


52-58: Effective use of JSDoc comments for story documentation

The JSDoc comment clearly explains the purpose of this story variant (default selected key). This documentation approach makes it easier for other developers to understand the purpose of each story.


88-111: Well-implemented form integration example

This story effectively demonstrates how to use the select component within a form, including required field validation and form submission prevention. The implementation follows the pattern established in other form-related stories.

src/lib/progress/timeline/spine.tsx (2)

50-64: Well-implemented conditional styling with fallback

The conditional styling based on the variant prop is well-implemented, with appropriate fallbacks and support for custom colors using the regex test. The use of utility classes with conditional application via clsx follows best practices.


67-68: Simplified line element with Tailwind classes

The line element is now cleanly implemented with Tailwind utility classes, making it easier to understand the styling intent compared to styled-components.

src/lib/display/large.tsx (6)

4-5: Good addition of accessibility utilities.

The import of cn for class name composition and Label from react-aria-components enhances both styling flexibility and accessibility.


7-13: Great TypeScript improvements.

Converting to a named function with Readonly<DisplayIconProps> typing improves type safety and prevents accidental prop mutations. The addition of the className prop also improves component composition.


15-22: Clean implementation of Tailwind utility classes.

The Card component now uses utility-first CSS with proper composition through the cn function. The classes are organized logically with positioning, sizing, and layout concerns clearly separated.


23-23: Proper icon implementation with absolute positioning.

The icon is now positioned with absolute positioning and appropriate sizing constraints.


24-29: Excellent accessibility improvement.

Adding the aria-labelledby attribute to connect the heading with its label improves screen reader support, making the component more accessible.


30-35: Enhanced label with accessibility support.

The Label component from react-aria-components with a matching id provides better accessibility than the previous implementation, and the text styling is properly handled.

src/lib/progress/timeline/custom.tsx (6)

2-3: Clean import refactoring.

Imports have been streamlined to remove styled-components dependencies while adding the cn utility for class name composition.


5-10: Improved type definition.

The TimelineItem interface no longer extends SideProp, simplifying the component dependencies and making the props more explicit.


12-15: Added className support for better composition.

The addition of an optional className prop to ICustomTimelineProps enhances component reusability and customization.


17-22: Enhanced documentation and type safety.

The addition of JSDoc comments and Readonly props typing improves documentation and prevents accidental prop mutations.


25-30: Added critical accessibility attributes.

The addition of aria-label="Timeline" and role="list" significantly improves accessibility for screen readers, making the component more inclusive.


34-39: Proper styling for the last bullet item.

The last bullet item now uses utility classes directly rather than styled components, maintaining the same visual appearance with a cleaner implementation.

src/lib/dropdown/cascader/item.tsx (8)

1-6: Good component structure with proper imports.

The imports include necessary React Aria Components for accessibility and the cn utility for class name composition, setting up a solid foundation.


7-12: Well-defined interface for item structure.

The IItem interface clearly defines the expected props with proper typing, including support for nested children items.


14-17: Excellent use of TreeItemContent for accessibility.

Leveraging React Aria's TreeItemContent component provides built-in accessibility features and state management for the dropdown item.


18-26: Clean conditional styling based on component state.

The main container uses utility classes with conditional application based on disabled state and presence of children, resulting in a responsive and accessible UI.


27-37: Proper text handling with accessibility in mind.

The label paragraph uses appropriate width constraints and text styling based on the component's state, ensuring good readability.


39-50: Verify event propagation behavior.

The Button component uses e.continuePropagation() which allows event bubbling while still handling selection. Please verify this is the intended behavior, as it's less common than e.stopPropagation().

Do you want the click event to continue propagating to parent components after selection? If not, consider using:

onPress={(e) => {
  state.selectionManager.setSelectedKeys([id]);
- e.continuePropagation();
+ e.stopPropagation();
}}

51-66: Good visual indicator for nested items.

The children count indicator provides clear feedback about nested items, with appropriate styling changes based on hover, selection, and disabled states.


67-78: Excellent icon implementation with state-based styling.

The arrow icon rotates based on expansion state with smooth transitions and changes fill color based on selection and hover states, providing clear visual cues.

src/lib/copiable/index.tsx (5)

5-6: Good accessibility enhancement with React Aria.

Adding the Button component from react-aria-components improves keyboard navigation and screen reader support.


8-23: Improved documentation and type definitions.

Enhanced JSDoc comments, refined tooltipProps type, and addition of className prop improve documentation and component flexibility.


31-39: Good TypeScript improvements.

Converting to a named function with Readonly<CopiableProps> improves type safety and prevents accidental prop mutations.


53-60: Clean implementation with Tailwind utility classes.

The container div now uses utility-first CSS with proper composition through the cn function, including conditional direction based on iconPlacement.


62-76: Enhanced accessibility with Button component.

Replacing the raw click handler with the Button component and onPress event improves keyboard accessibility and screen reader support.

src/lib/progress/timeline/bullet.tsx (8)

2-2: No issues with the expanded import usage.
Everything appears consistent with Spine, VariantProp, and colorRegex usage in this file.


4-5: Imports for clsx, cn, and isUndefined look good.
These utilities are used correctly for conditional class names and null checks.


22-22: Retaining an optional className prop is a good design choice.
This enables parent components to pass custom styles without complicating the default class merges.


26-27: Destructuring approach is clear and concise.
Grouping the relevant props under restProps helps reduce clutter in the main function signature.


57-73: The structure for the title block is clear and accessible.
Leveraging aria-label with a ref on the <h2> is good for screen reader compatibility.


97-106: Conditional rendering of the party element is well-structured.
Overflow cropping with "inline-flex max-h-8 overflow-hidden" effectively constrains large elements.


108-117: Subtitle block usage and aria-label for date text is appropriate.
This ensures the date is announced correctly by assistive technologies.


118-118: Final container closure ensures a clean layout.
No further concerns here.

src/lib/dropdown/select/item.tsx (4)

1-6: Imports from react-aria-components are appropriate.
This helps provide robust accessibility without extra overhead.


7-9: Inclusion of the Dot and cn utilities is coherent.
They’re used effectively for dynamic styling and color indicators.


11-23: Interfaces are well-defined.
Providing a separate BaseItem ensures clarity in item structure, especially for icons and dots.


25-58: The Item component’s structure is clean and covers all relevant states.

  • Using ListBoxItem for accessibility is a strong choice.
  • textValue={text} assistance ensures proper text extraction in search or screen readers.
  • Conditional rendering of icons and dots is straightforward.
src/lib/dropdown/cascader/index.tsx (4)

1-13: Imports and re-exports align with the new react-aria-components approach.
No immediate concerns here.


14-19: Extended IDropdownCascader interface is clear.
The callback prop returning the entire selected item is especially helpful in parent components.


23-33: Destructuring of props including label, items, callback, etc. is well laid-out.
This approach is consistent and keeps the function signature succinct.


35-63: Declarative use of AriaSelect and the cascader container is a vast improvement.

  • The code is more readable and straightforward.
  • The aria-label fallback is a good accessibility practice.
  • Handing the entire item array down to DropdownContainer for rendering is consistent with the new refactor.
src/lib/display/small.tsx (2)

4-6: Imports look consistent and aligned with project patterns.
No issues found with these import statements; they follow the overall project approach to utility and accessibility libraries.


8-14: Function signature and prop destructuring appear well-organized.
Using Readonly<DisplayIconProps> ensures immutability, and spreading ...props for the container is flexible. This helps keep the component extensible.

src/lib/progress/linear/index.tsx (2)

1-2: Imports are well-selected for progress functionality.
The usage of React hooks and react-aria-components aligns with your new accessibility approach.


36-39: Guard against potential division by zero in progress calculation.
If minValue equals maxValue, maxValue - minValue is zero, leading to Infinity or NaN.

Consider adding a safeguard:

- const progress = useMemo(
-   () => (value / (maxValue - minValue)) * 100,
-   [value, minValue, maxValue],
- );
+ const progress = useMemo(() => {
+   const range = maxValue - minValue;
+   return range !== 0 ? (value / range) * 100 : 0;
+ }, [value, minValue, maxValue]);
src/lib/dropdown/select/index.tsx (2)

1-2: Imports align with the new react-aria-based approach.
No issues found in the updated imports.


38-44: Validate fallback when selected item is not found.
If no matching item is found, the function returns silently. Consider logging a warning or providing a graceful fallback for invalid keys.

src/lib/breadcrumb.tsx (2)

2-4: Imports look good.
No issues with using react-aria-components, clsx, and your own cn utility. This setup is concise and consistent with the rest of the refactor.


15-29: Content component looks well-structured.
The usage of React.ComponentProps<"small"> and conditional utility classes via cn is clear and maintains readability.

src/lib/dropdown/cascader/dropdown-container.tsx (1)

1-22: Modular imports and interface definition look good.
Splitting out the IDropdownContainer interface from IDropdownCascader keeps your component's props decoupled, aligning with best practices in large codebases.

README.md (1)

17-20: Comprehensive introduction and feature list.
The README provides a clear overview of the library's purpose and benefits. It’s helpful for new contributors and users alike.

src/lib/form/bignumber-field/useBigNumberField.tsx (3)

82-92: Question potential performance with large EXPONENTIAL_AT configuration.

Configuring BigNumber with EXPONENTIAL_AT: 1e9 can handle extremely large numbers without exponent notation but may encounter performance bottlenecks for particularly large inputs. Verify that the application’s use case truly requires this magnitude.


183-195: Validate increment/decrement logic.

Your checks are correctly blocking invalid increments/decrements beyond the specified range. This logic effectively prevents out-of-bound values.


420-495:

❓ Verification inconclusive

Verify minus sign handling for mid-string insertion.

You block a minus sign if selectionStart is non-zero. Confirm that all valid negative inputs are allowed (e.g., rewriting a positive number to negative by highlighting and typing a minus) and ensure no unexpected user experience issues.


🏁 Script executed:

#!/bin/bash
# Description: Attempt typed inputs that insert a minus sign in different positions.

# Steps:
# 1) Programmatically simulate user typed values [-, -123, 12->-12 by highlight].
# 2) Confirm correct parse or block as intended.
ast-grep --pattern $'minusSignTest($_)' # Example placeholder pattern

Length of output: 40


Action Required: Confirm Valid Negative Input Scenarios

The current minus sign handling logic blocks insertion if the cursor isn’t at the start. While this prevents mid-string negative sign insertions, please ensure that valid scenarios—such as converting a positive number to negative by fully replacing its value (where the selection start is 0)—work as intended. Since the automated test simulation (using the placeholder minusSignTest pattern) did not produce output, a manual verification or additional unit tests are needed to confirm that rewriting a positive number to a negative one (through full selection) is supported without any unintended side effects.

  • Location: src/lib/form/bignumber-field/useBigNumberField.tsx (Lines: 420–495)
  • Action: Manually verify (or add tests) that a full-field selection and replacement with a minus sign behaves correctly.
src/lib/form/datepicker/index.tsx (1)

49-55: Label rendering looks good.

Hiding the label element when no label is supplied appears consistent with typical accessibility patterns, preventing an empty label from displaying.

package.json (5)

16-23: Exports field is well-structured for ESM and CSS assets.

The exports field correctly exposes ESM JS, types, and CSS assets for consumers. This is a best practice for modern package distribution.


24-33: Scripts align with Vite and Storybook migration.

Build, clean, and Storybook scripts are updated for the new toolchain. No issues found.


37-78: DevDependencies reflect the new stack and are consistent.

All devDependencies are appropriate for the migration to Vite, Tailwind, and Storybook 8.6.4. No version mismatches or redundancies detected.


86-101: Dependencies are up to date and relevant for the new architecture.

No duplicate or unnecessary dependencies found. All packages are relevant to the new stack.


110-115: ESLint config is minimal and appropriate for Storybook integration.

The new eslintConfig extends the recommended Storybook config, which is suitable for this codebase.

tractorss and others added 3 commits April 15, 2025 11:43
coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 15, 2025
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

♻️ Duplicate comments (3)
src/lib/pagination/tabs.tsx (2)

39-50: Proper type definition for callback function

The callback function type has been properly defined with specific parameter types rather than using the generic Function type. This addresses a previous review comment and improves type safety.


52-74: Correct implementation of state management and selection handling

The component correctly:

  • Initializes state with the defaultSelectedKey
  • Uses useCallback for the event handler to prevent unnecessary re-renders
  • Finds the selected item by id (fixing a previous issue where it was found by text)
  • Properly calls the callback with key and value when selection changes

This implementation resolves a previous issue identified in the code review.

src/lib/form/datepicker/index.tsx (1)

76-85: Clarify the "Clear" button's behavior.

"Clear" sets the date to defaultValue rather than an empty or null state, which might confuse users expecting it to remove the selection entirely. Revisit naming or reset logic to align with user expectations.

Consider either:

  1. Renaming the button to "Reset" to more accurately reflect its behavior
  2. Changing the behavior to truly clear the value if that's the expected user experience
-                  Clear
+                  Reset
🧹 Nitpick comments (5)
src/lib/form/datepicker/index.tsx (5)

49-58: Consider more accurate fallback label text.

The component uses "Date" as the fallback label even when the component might be used for time selection. Consider using a conditional fallback based on the time prop value.

-            {label ?? "Date"}
+            {label ?? (time ? "Date & Time" : "Date")}

60-66: Use the cn utility consistently.

The code uses both clsx and cn for className composition. Since cn is already imported and handles Tailwind class conflicts better, consider using it consistently throughout the component.

-          <Popover
-            className={clsx(
+          <Popover
+            className={cn(
              "bg-klerosUIComponentsWhiteBackground shadow-default rounded-base overflow-y-scroll",
              "border-klerosUIComponentsStroke ease-ease scrollbar border transition",
              time ? "w-82.5 lg:w-112.5" : "w-82.5",
            )}
          >

71-74: Use the cn utility consistently.

Similar to the previous comment, replace clsx with cn for consistent utility usage throughout the component.

-              <div
-                className={clsx(
+              <div
+                className={cn(
                  "flex h-16 w-full items-center justify-between px-4",
                  "border-t-klerosUIComponentsStroke border-t",
                )}
              >

77-81: Use the cn utility consistently.

Replace clsx with cn here as well for consistent styling patterns throughout the component.

-                  className={clsx(
+                  className={cn(
                    "text-klerosUIComponentsPrimaryBlue rounded-base text-sm font-semibold",
                    "hover:text-klerosUIComponentsSecondaryBlue hover:cursor-pointer",
                    "focus:outline-klerosUIComponentsPrimaryBlue focus:outline-offset-8",
                  )}

31-38: Consider memoizing callback functions for better performance.

The callback functions for state.setValue(defaultValue) and state.close() are recreated on each render. For performance optimization, consider using useCallback to memoize these functions.

import React from "react";
+import { useCallback } from "react";
import {
  // ... existing imports
} from "react-aria-components";
// ... rest of imports

function DatePicker({
  label,
  time = false,
  minValue,
  defaultValue = now(getLocalTimeZone()),
  shouldCloseOnSelect = false,
  ...props
}: Readonly<DatePickerProps>) {
+  const handleClear = useCallback((state) => {
+    state.setValue(defaultValue);
+  }, [defaultValue]);
+  
+  const handleSelect = useCallback((state) => {
+    state.close();
+  }, []);

  return (
    // ... rest of component

                <Button
                  className={cn(/* ... */)}
-                  onPress={() => state.setValue(defaultValue)}
+                  onPress={() => handleClear(state)}
                >
                  Clear
                </Button>
                <CustomButton
                  small
                  text="Select"
-                  onPress={() => state.close()}
+                  onPress={() => handleSelect(state)}
                  className="focus:outline-klerosUIComponentsPrimaryBlue cursor-pointer focus:outline-offset-2"
                />
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 35f733c and f565779.

📒 Files selected for processing (7)
  • src/lib/dropdown/select/simple-button.tsx (1 hunks)
  • src/lib/form/datepicker/index.tsx (1 hunks)
  • src/lib/form/file-uploader.tsx (1 hunks)
  • src/lib/form/text-area.tsx (1 hunks)
  • src/lib/form/text-field.tsx (1 hunks)
  • src/lib/pagination/tabs.tsx (1 hunks)
  • src/lib/progress/timeline/bullet.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/lib/form/text-field.tsx
  • src/lib/dropdown/select/simple-button.tsx
  • src/lib/form/text-area.tsx
  • src/lib/progress/timeline/bullet.tsx
  • src/lib/form/file-uploader.tsx
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/lib/pagination/tabs.tsx (2)
src/stories/tabs.stories.tsx (1)
  • Tabs (19-44)
src/utils/index.ts (1)
  • cn (4-6)
src/lib/form/datepicker/index.tsx (1)
src/utils/index.ts (1)
  • cn (4-6)
🔇 Additional comments (4)
src/lib/pagination/tabs.tsx (4)

1-15: Good adoption of react-aria-components for accessibility

This refactoring correctly moves from styled-components to react-aria-components, which provides better accessibility support out of the box. The imported components provide ARIA attributes, keyboard navigation, and focus management automatically.


17-37: Well-structured TabsItem interface with improved documentation

The interface has been enhanced with proper JSDoc comments and additional properties:

  • The id property now explicitly required as a unique identifier
  • Addition of the content property for rendering tab panels
  • Well-documented optional properties for granular customization

These changes improve type safety and component flexibility.


75-125: Well-structured tab list with proper styling conditions

The TabList implementation:

  • Uses the cn utility to compose Tailwind classes
  • Properly conditionally applies styling based on selection state and disabled status
  • Correctly renders icons with appropriate styling

The conditional class application is clean and maintainable.


127-142: Clean implementation of tab panels with Collection pattern

Using the Collection component from react-aria-components is a good pattern for maintaining the relationship between tabs and their content. The implementation:

  • Correctly associates tab panels with their respective tabs
  • Handles custom styling effectively with a priority order (panel-specific styles override shared styles)
  • Properly renders the content for each tab

This approach improves accessibility by ensuring proper ARIA relationships.

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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between f565779 and 80475a2.

📒 Files selected for processing (1)
  • package.json (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: TypeCheck
package.json

[error] 1-1: Yarn version mismatch: project requires [email protected] but global version is 1.22.22. Enable Corepack by running 'corepack enable' to resolve this.

🪛 GitHub Actions: ESLint
package.json

[error] 1-1: Yarn version mismatch: package.json specifies [email protected] but global Yarn version is 1.22.22. Corepack must be enabled by running 'corepack enable'.

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

♻️ Duplicate comments (1)
src/lib/breadcrumb.tsx (1)

8-9: Don't use 'Function' as a type.

Using Function as a type reduces type safety and can lead to potential errors. Although you've added an ESLint disable comment, it's better to define a specific function signature instead.

-  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
-  callback?: Function;
+  callback?: (value: any) => void;

This provides better type safety and makes the component's API more self-documenting.

🧰 Tools
🪛 Biome (1.9.4)

[error] 9-9: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🧹 Nitpick comments (2)
src/lib/breadcrumb.tsx (2)

57-58: Consider using the cn utility consistently.

For better consistency with the rest of the codebase, consider using the imported cn utility here instead of clsx directly.

-              className={clsx(clickable ? "cursor-pointer" : "cursor-text")}
+              className={cn(clickable ? "cursor-pointer" : "cursor-text")}

This ensures consistent class name handling throughout the component.


61-63: Consider using the cn utility consistently here as well.

For better consistency with the rest of the codebase, consider using the imported cn utility here instead of clsx.

-                className={clsx(
-                  clickable && "hover:text-klerosUIComponentsPrimaryText",
-                )}
+                className={cn(
+                  clickable && "hover:text-klerosUIComponentsPrimaryText",
+                )}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 80475a2 and b4350c4.

📒 Files selected for processing (16)
  • .github/workflows/eslint.yml (1 hunks)
  • .github/workflows/tsc.yml (1 hunks)
  • src/lib/breadcrumb.tsx (1 hunks)
  • src/lib/dropdown/select/index.tsx (1 hunks)
  • src/lib/progress/linear/index.tsx (1 hunks)
  • src/lib/progress/steps/bullet-circle.tsx (2 hunks)
  • src/lib/progress/steps/bullet.tsx (3 hunks)
  • src/lib/progress/steps/horizontal-bullet.tsx (2 hunks)
  • src/lib/progress/steps/horizontal.tsx (1 hunks)
  • src/lib/progress/steps/vertical.tsx (1 hunks)
  • src/lib/progress/timeline/bullet.tsx (2 hunks)
  • src/lib/progress/timeline/custom.tsx (1 hunks)
  • src/lib/progress/timeline/index.tsx (1 hunks)
  • src/lib/tooltip/index.tsx (1 hunks)
  • src/stories/bignumber-field.stories.tsx (1 hunks)
  • src/stories/custom-timeline.stories.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
  • src/lib/progress/timeline/index.tsx
  • src/lib/progress/steps/horizontal.tsx
  • src/lib/progress/steps/bullet-circle.tsx
  • src/stories/bignumber-field.stories.tsx
  • src/lib/progress/steps/vertical.tsx
  • src/lib/progress/steps/bullet.tsx
  • src/lib/progress/timeline/custom.tsx
  • src/lib/tooltip/index.tsx
  • src/lib/progress/linear/index.tsx
  • src/lib/progress/steps/horizontal-bullet.tsx
  • src/lib/progress/timeline/bullet.tsx
  • src/stories/custom-timeline.stories.tsx
  • src/lib/dropdown/select/index.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/lib/breadcrumb.tsx (2)
src/utils/index.ts (1)
  • cn (4-6)
src/stories/breadcrumb.stories.tsx (1)
  • Breadcrumb (26-38)
🪛 actionlint (1.7.4)
.github/workflows/eslint.yml

9-9: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/tsc.yml

9-9: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 Biome (1.9.4)
src/lib/breadcrumb.tsx

[error] 9-9: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🔇 Additional comments (6)
src/lib/breadcrumb.tsx (4)

2-4: LGTM! Proper imports for the new utility-first approach.

The added imports for utility functions and React Aria components align well with the project's transition from styled-components to Tailwind CSS.


12-12: LGTM! Good addition of variant prop.

Adding the variant prop enhances the component's flexibility and aligns with the new theming approach.


15-29: LGTM! Well-structured Content component.

The new Content component is well-implemented with:

  • Proper TypeScript typing
  • Effective use of the cn utility for class composition
  • Conditional styling based on the variant prop
  • Clean prop forwarding pattern

This encapsulation helps maintain consistent styling across breadcrumb items.


31-77: LGTM! Great refactoring to improve accessibility and styling.

The Breadcrumb component has been nicely refactored:

  • Uses React Aria's Button component for better accessibility
  • Properly implements conditional styling with clsx
  • Maintains the same functionality while improving the implementation
  • Effectively passes the variant prop to nested Content components

This implementation aligns well with the project's move toward utility-first CSS and improved accessibility.

.github/workflows/tsc.yml (1)

10-11: Good practice: Enable Corepack before Yarn install.

Enabling Corepack ensures Yarn 4+ works reliably in CI environments. This is a recommended step for modern Yarn projects.

.github/workflows/eslint.yml (1)

10-11: Good practice: Enable Corepack before Yarn install.

Enabling Corepack ensures Yarn 4+ works reliably in CI environments. This is a recommended step for modern Yarn projects.

coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 15, 2025
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

♻️ Duplicate comments (1)
src/lib/breadcrumb.tsx (1)

8-9: Use a more specific function type instead of Function.

Using Function can lead to reduced type safety and potential errors. Consider specifying the callback signature:

-  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
-  callback?: Function;
+  callback?: (value: unknown) => void;

This change would eliminate the need for the ESLint disable comment while improving type safety.

🧰 Tools
🪛 Biome (1.9.4)

[error] 9-9: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🧹 Nitpick comments (1)
src/lib/breadcrumb.tsx (1)

56-59: Consider conditional callback execution.

The callback function is executed regardless of whether clickable is true or false. This could lead to unexpected behavior.

-              onPress={() => (callback ? callback(value) : null)}
+              onPress={() => (clickable && callback ? callback(value) : null)}

This ensures the callback is only executed when the item is intended to be clickable.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between b4350c4 and 7ddd427.

📒 Files selected for processing (8)
  • src/lib/breadcrumb.tsx (1 hunks)
  • src/lib/progress/steps/bullet.tsx (3 hunks)
  • src/lib/progress/steps/horizontal-bullet.tsx (2 hunks)
  • src/lib/progress/steps/horizontal.tsx (1 hunks)
  • src/lib/progress/steps/vertical.tsx (1 hunks)
  • src/lib/progress/timeline/bullet.tsx (2 hunks)
  • src/lib/progress/timeline/custom.tsx (1 hunks)
  • src/lib/progress/timeline/index.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/lib/progress/steps/horizontal.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/lib/progress/steps/horizontal-bullet.tsx
  • src/lib/progress/steps/vertical.tsx
  • src/lib/progress/timeline/custom.tsx
  • src/lib/progress/steps/bullet.tsx
  • src/lib/progress/timeline/index.tsx
  • src/lib/progress/timeline/bullet.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/lib/breadcrumb.tsx (2)
src/utils/index.ts (1)
  • cn (4-6)
src/stories/breadcrumb.stories.tsx (1)
  • Breadcrumb (26-38)
🪛 Biome (1.9.4)
src/lib/breadcrumb.tsx

[error] 9-9: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🔇 Additional comments (3)
src/lib/breadcrumb.tsx (3)

15-29: Good implementation of the Content component.

The new Content component is well structured with:

  • Proper type definition extending React's component props
  • Efficient use of the cn utility for class name composition
  • Appropriate conditional styling based on the variant prop

This abstraction improves code organization and maintainability.


31-37: Good conversion to named function with Readonly type.

Converting to a named function and using Readonly for props are good practices that improve code quality and type safety.


38-76: Excellent refactoring to utility-first CSS.

The component has been successfully refactored to use:

  • Tailwind utility classes instead of styled-components
  • React-aria-components Button for improved accessibility
  • Proper conditional rendering and styling
  • Semantic HTML structure

This aligns well with the PR's objective of transitioning from styled-components to utility-first CSS.

coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 15, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 15, 2025
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@tractorss tractorss merged commit a994a51 into main Apr 15, 2025
4 of 5 checks passed
@tractorss tractorss deleted the chore/tailwind-migration branch April 15, 2025 11:55
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.

None yet

2 participants