-
Notifications
You must be signed in to change notification settings - Fork 3
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
Conversation
WalkthroughThis 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
Sequence Diagram(s)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
Suggested reviewers
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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 StylingInputs, 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
⛔ 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 SetupThe 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/postcssThe Tailwind PostCSS plugin is added with version
^4.0.11
, aligning with your Tailwind integration.
48-48
: Parcel Version UpdateThe 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 AddedThe 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 AdditionThe
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 IntegrationAdding
@tailwindcss/postcss
andtailwindcss
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: clsxThe
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 UpdateThe Node version in the Volta configuration has been updated from
16.20.1
to20.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 TailwindCSSThe 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 InclusionThe 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 ImportImporting 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 ThemeWithin 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 VariablesThe 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 ImplementationThe typography rules for headings (
h1
,h2
), paragraphs (p
), andsmall
tags effectively use Tailwind’s@apply
directive to standardize styling.
92-112
: Element Styles ConsistencyThe styles for elements like
hr
,svg
,img
, andbutton
ensure consistent behavior across browsers. The hover effects on buttons are also appropriately defined.
129-132
: Box-Sizing NormalizationThe
.border-box
class along with its universal selector usage ensures consistent box-sizing across your components.
134-141
: Transition EffectsThe classes
.hover-short-transition
and.hover-long-transition
provide useful hover transition durations that enhance interactivity.
143-150
: Hover Background EffectsThe classes
.hover-medium-blue
and.hover-white-background
apply background color changes on hover using predefined custom properties.
152-167
: Fade-In Animation DefinitionThe 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 MappingThe 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.
There was a problem hiding this 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 MethodThe 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 ConsistencyThe 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 CompatibilityThe 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)
📒 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 ConsistencyThe
: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 CheckThe 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.
There was a problem hiding this 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 theimport/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)
⛔ 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:
Themax-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:
Theno-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.
There was a problem hiding this 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 genericFunction
While the ESLint rule has been updated from
ban-types
tono-unsafe-function-type
, using the genericFunction
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 genericFunction
type with a specific function signatureWhile the ESLint rule has been updated from
ban-types
tono-unsafe-function-type
, using the genericFunction
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 genericFunction
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 safelyThe non-null assertion (
!
) onevent.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
: Replaceany
type with a more specific typeThe 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)
⛔ 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 tsLength 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 yourpackage.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.
chore: accordion-migration
There was a problem hiding this 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 issueFix syntax errors in component structure.
There are multiple syntax errors in the component structure, including:
- Duplicated state declaration (lines 31 and 36)
- Component signature is broken (missing function declaration)
- 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 issueFix 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 issueDuplicate prop declaration
The
setExpanded
prop is declared twice in theAccordionItemProps
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 issueInvalid 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:
- The "temporary" comment suggests this is an interim solution
- There's no synchronization of initial state between styled-components and Tailwind themes
- 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 mappingThe 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)
⛔ 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 issueMissing 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 issueRemove 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/upgradeBoth packages are maintained in lockstep, with frequent updates for compatibility and performance[9][10].
Citations:
- 1: https://laravel-news.com/tailwind-css-v4-is-now-released
- 2: https://tailwindcss.com/docs/upgrading-to-v2
- 3: https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md
- 4: https://tailwindcss.com/blog/tailwindcss-v4
- 5: https://tailwindcss.com/docs/installation/using-postcss
- 6: https://dev.to/falselight/tailwindcss-version-400-has-been-released-29pp
- 7: https://www.npmjs.com/package/@tailwindcss/postcss/v/4.0.0-alpha.13
- 8: https://tailwindcss.com/docs/upgrade-guide
- 9: https://www.npmjs.com/package/@tailwindcss%2Fpostcss
- 10: https://github.com/tailwindlabs/tailwindcss/releases
- 11: https://classic.yarnpkg.com/en/package/@tailwindcss/postcss
- 12: https://www.techopt.io/programming/web-programming/when-to-use-and-not-use-tailwind-css-in-2025
- 13: [v4] It looks like you're trying to use
tailwindcss
directly as a PostCSS plugin. tailwindlabs/tailwindcss#15735- 14: https://www.youtube.com/watch?v=Rrowv9BreBg
- 15: https://www.youtube.com/watch?v=sHnG8tIYMB4
- 16: https://tailwindcss.com/blog
- 17: https://www.youtube.com/watch?v=6biMWgD6_JY
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 conversionThe 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 integrationThe 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 stylesThe 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 animationThe 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.
feat: migrate to vite and add storybook
There was a problem hiding this 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 issueFix 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:
- Duplicate
build:
entry- Moves plugins to the correct location in the configuration structure
- Removes extra closing brackets
♻️ Duplicate comments (3)
eslint.config.mjs (1)
67-69
:⚠️ Potential issueAction 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 issueFix 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 issueInvalid 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 classesSince 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" commentThe "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 implementationThe current implementation has a few areas for improvement:
- 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); + } + }, []);
- 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 improvementsSince 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:
- Uses Tailwind utility classes instead of custom CSS
- Adds aria-label for better accessibility
- Allows className prop for additional customization
src/lib/accordion/index.tsx (1)
33-36
: Consider making the width more flexibleThe 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 componentsThe 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 textPageGuidelines
for the best practices listPageTip
for the tip sectionThis would make the main Page component more concise and easier to understand.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
⛔ 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
andfixupPluginRules
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
, andexpect
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
orHeader.css
exists in thesrc/stories
directory. This manual check is critical to ensure that the CSS import insrc/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 refactoringThe 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 interfaceThe 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 integrationThe 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 incorrectfd
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 configurationThe 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 namesUsing clsx is a best practice for managing conditional class names when using utility-first CSS frameworks like Tailwind.
15-15
: LGTM! Proper interface extensionAdding the optional className prop to the interface allows for better component composition and customization.
21-21
: LGTM! Refactored styled component to use Tailwind classesThe 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 storiesThe 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 componentThe 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 andreact-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
toonPress
which is the correct approach when usingreact-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.
Feat: add accordion stories
fix: add toString config to useBigNumberField
Chore/tag migration
There was a problem hiding this 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 ofFunction
.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 ofFunction
.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
: Useitem.id
instead ofitem.text
when matching the selected key.The selected key (from
AriaTabs
) is stored inid
, but your code usestext
for the lookup. This can cause discrepancies iftext
differs fromid
. Consider:- const selectedItem = items.find((item) => item.text === key); + const selectedItem = items.find((item) => item.id === key);package.json (1)
90-90
: Duplicate dependency onclsx
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 renamingisUndefined
for clarity.While functionally correct, the function name
isUndefined
is slightly misleading since it checks for bothundefined
andnull
. A more accurate name might beisNullOrUndefined
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
andclsx
, butcn
already usesclsx
internally. For consistency, consider using just thecn
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 ofclsx
directly, ascn
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 improvementsWhile 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 durationsThe "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 renamingcallback
for clarity.
callback
works, but naming it something likeonValueChange
oronSliderChange
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 theparty
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 ificon
isundefined
butIcon
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 opportunitiesThe Copiable component stories are well-organized with appropriate controls and variants. Consider these improvements:
- There's an inconsistency in the info text between stories - one ends with a period (line 30) while the other doesn't (line 41).
- 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 flexibilityThe 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 UXThe 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 consistentlyThe component uses
clsx
directly here but imports and usescn
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 tooSimilar 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 SelectStateContextThe component accesses
state
from context but only checks forstate?.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 configurableThe 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 configurableThe 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 approachThe 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 renderingAs 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 conditionalThe 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 propsThe interface only accepts
minValue
, but the component might benefit from additional customization options like aclassName
prop for external styling, or adisabled
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 accessibilityThe
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 buttonsThe 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 elementThe 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 selectorsThe 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 thatstate
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 theFieldError
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 whenDatePickerStateContext
is unavailable.
The callback checksif (state) state.open();
. Consider providing a more explicit fallback or warning ifstate
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 clsxWhile the code correctly implements conditional styling, you're using both
cn
(at the root level) andclsx
(for the title element). For consistency, consider using justcn
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 utilitiesUsing
!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 constructorThe 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 renderingThe 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.
Usingcn
to merge base utility classes and additional conditional classes forrightSided
andstate
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
: Ensurelabel
is a valid unique ID for accessibility.
Using thelabel
prop directly as the element’sid
and referencing it viaaria-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.
- The fixed width (
w-[217px]
) may restrict responsiveness; consider using more fluid styles.- 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 whenvalue === 0
. If you want a 0% fill to be visible, consider checking forvalue != null
orvalue > 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 namedonSelectionChange
oronSelectItem
, 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 value239
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 use239
again in theTreeItem
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 toprogress.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 thefiles
array. Iftheme.css
or other theme assets are meant to be published, ensure they're included indist
or add them to thefiles
array.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
⛔ 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 thecn
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 goodThe 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 flexibilityExtending 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 classesThe 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 componentThe 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 documentationThe props are well-organized with:
- BaseButtonProps for core button properties
- ButtonProps extending AriaButtonProps for accessibility
- 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 classesThe button implementation is well-refactored:
- Uses AriaButton for accessibility
- Applies conditional styling based on variant, size, and state
- Properly handles disabled state
- Uses composition pattern with subcomponents (KlerosSymbol, ButtonIcon, ButtonText)
- Well-structured class organization with the
cn
utilityThis 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 accessibilityThe addition of the
cn
utility,clsx
, and theLabel
component from react-aria-components provides the necessary tools for both styling composition and accessibility improvements.
11-11
: Improved API with optional className propAdding 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 typesChanging 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 patternUsing 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 accessibilityThe text container implementation:
- Uses appropriate flex layout for alignment
- Implements proper ARIA attributes with aria-labelledby
- Uses the Label component for better accessibility
- 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-ariaUsing 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 compositionThe 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 patternThe switch implementation:
- Uses the render props pattern to access the internal isSelected state
- Applies conditional styling based on size and selection state
- Uses the before pseudo-element for the knob, which is an elegant solution
- Implements transitions for smooth state changes
- 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
, andclsx
is consistent with the project’s transition to utility-first CSS and accessible primitives.
6-12
: Inheritance from ButtonProps is appropriate.
BaseTagProps
neatly extendsButtonProps
while adding a customactive
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 andclsx
.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 ofcn
andclsx
effectively support the new design strategy.
33-41
: Ensure usage ofisDisabled
is consistent.The
isDisabled
prop is properly passed toDropZone
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 thatonChange
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 usingonChangeEnd
or a similar event.src/lib/form/checkbox.tsx (2)
22-28
: Looks good!
Usingcn
to merge classes is a neat approach, and placingclassName
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 withreact-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
, anditems
withrightSided
property. Ensure these match the Timeline component's interface and that therightSided
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/timelineLength 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., insrc/lib/progress/timeline/bullet.tsx
) and is used appropriately insrc/lib/progress/timeline/index.tsx
.- The other props (
themeUI
,backgroundUI
, anditems
) 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 thehorizontal
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 mergingThe 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 mergingThe 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 componentThe imports look appropriate:
react-aria-components
for accessibility,clsx
for conditional class names,cn
utility, and the customArrowButton
component.
12-20
: LGTM! Good semantic HTML and accessibilityGood use of semantic HTML with
header
andh2
elements, plus the appropriatearia-label
attribute for the container.
31-56
: Good implementation of DateInput with conditional renderingThe 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 namesAdding clsx is appropriate for handling conditional class names in the refactored component.
18-21
: Good use of Tailwind flexbox classes for layoutThe flexbox layout classes are well-chosen for the vertical arrangement of elements.
22-42
: Well-structured conditional stylingThe 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 functionAdding the React import and the cn utility function is appropriate for the refactored component.
6-24
: Well-structured functional component with Tailwind utility classesThe 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 importAdding 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 componentsAdding 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 exportRenaming 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 tsxLength 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 oldRadio
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 newRadio
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 inAriaRadioGroup
.
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 inRadioOption
.
AriaRadioProps typically includes avalue
property for each radio. Confirm that thevalue
field is indeed mandatory or gracefully handle cases wherevalue
might be missing.Here's a script you can run to confirm if
AriaRadioProps
fromreact-aria-components
enforces a requiredvalue
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 underlyingAriaRadioProps
enforces a requiredvalue
property. Our initial search shows thatRadioProps
extendsOmit<AriaRadioProps, 'children'>
(see output from node_modules/react-aria-components/src/RadioGroup.tsx), but this doesn’t confirm ifvalue
is mandatory. Please double-check the definition ofAriaRadioProps
in the package (e.g. by searching for the"interface AriaRadioProps"
and inspecting any occurrences of avalue
field) and then either:
- Explicitly add the required
value
property toRadioOption
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 usingreact-aria-components
.
You effectively leverageDateInput
,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 managementThe addition of
clsx
and the customcn
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 stylingAdding 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 attributesThe 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 attributesThe addition of
aria-label
andaria-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 variablesThe 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 configurationThe 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 examplesThe 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 documentationThe 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 exampleThis 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 fallbackThe 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 classesThe 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 andLabel
fromreact-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 theclassName
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"
androle="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 thane.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 withSpine
,VariantProp
, andcolorRegex
usage in this file.
4-5
: Imports forclsx
,cn
, andisUndefined
look good.
These utilities are used correctly for conditional class names and null checks.
22-22
: Retaining an optionalclassName
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 underrestProps
helps reduce clutter in the main function signature.
57-73
: The structure for the title block is clear and accessible.
Leveragingaria-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 andaria-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 fromreact-aria-components
are appropriate.
This helps provide robust accessibility without extra overhead.
7-9
: Inclusion of theDot
andcn
utilities is coherent.
They’re used effectively for dynamic styling and color indicators.
11-23
: Interfaces are well-defined.
Providing a separateBaseItem
ensures clarity in item structure, especially for icons and dots.
25-58
: TheItem
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 newreact-aria-components
approach.
No immediate concerns here.
14-19
: ExtendedIDropdownCascader
interface is clear.
Thecallback
prop returning the entire selected item is especially helpful in parent components.
23-33
: Destructuring of props includinglabel
,items
,callback
, etc. is well laid-out.
This approach is consistent and keeps the function signature succinct.
35-63
: Declarative use ofAriaSelect
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.
UsingReadonly<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 andreact-aria-components
aligns with your new accessibility approach.
36-39
: Guard against potential division by zero in progress calculation.
IfminValue
equalsmaxValue
,maxValue - minValue
is zero, leading toInfinity
orNaN
.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 usingreact-aria-components
,clsx
, and your owncn
utility. This setup is concise and consistent with the rest of the refactor.
15-29
:Content
component looks well-structured.
The usage ofReact.ComponentProps<"small">
and conditional utility classes viacn
is clear and maintains readability.src/lib/dropdown/cascader/dropdown-container.tsx (1)
1-22
: Modular imports and interface definition look good.
Splitting out theIDropdownContainer
interface fromIDropdownCascader
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
withEXPONENTIAL_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 patternLength 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.
There was a problem hiding this 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 functionThe 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 handlingThe 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:
- Renaming the button to "Reset" to more accurately reflect its behavior
- 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 thecn
utility consistently.The code uses both
clsx
andcn
for className composition. Sincecn
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 thecn
utility consistently.Similar to the previous comment, replace
clsx
withcn
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 thecn
utility consistently.Replace
clsx
withcn
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)
andstate.close()
are recreated on each render. For performance optimization, consider usinguseCallback
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)
📒 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 accessibilityThis 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 documentationThe 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 conditionsThe 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 patternUsing 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.
There was a problem hiding this 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)
📒 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'.
There was a problem hiding this 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 thecn
utility consistently.For better consistency with the rest of the codebase, consider using the imported
cn
utility here instead ofclsx
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 thecn
utility consistently here as well.For better consistency with the rest of the codebase, consider using the imported
cn
utility here instead ofclsx
.- className={clsx( - clickable && "hover:text-klerosUIComponentsPrimaryText", - )} + className={cn( + clickable && "hover:text-klerosUIComponentsPrimaryText", + )}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)
📒 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.
There was a problem hiding this 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 ofFunction
.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)
📒 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 theContent
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.
|
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
src/index.html
to include a stylesheet.Summary by CodeRabbit
New Features
Refactor
Chores
.babelrc
..gitignore
and lint-staged configurations for improved workflow.