Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

chore: chore: add SVGR to appsmith-icon package, add processing for custom icons, update date-fns #37115

Merged
merged 1 commit into from
Oct 28, 2024

Conversation

KelvinOm
Copy link
Collaborator

@KelvinOm KelvinOm commented Oct 28, 2024

Description

  • chore: add SVGR to appsmith-icon package
  • add processing for custom icons
  • update date-fns

Changes are necessary for this EE PR.

Automation

/ok-to-test tags="@tag.Sanity"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/11551127644
Commit: 44fd968
Cypress dashboard.
Tags: @tag.Sanity
Spec:


Mon, 28 Oct 2024 10:11:55 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced AIAvatarCustomIcon component for enhanced icon customization.
    • Added CustomIcons documentation in Storybook for better visibility of custom icons.
  • Improvements

    • Updated multiple icon components to accept SVG properties, enhancing flexibility and reusability.
    • Enhanced type safety for IconCmp and ThumbnailCmp properties across various interfaces.
    • Expanded functionality in the generateStories function to include stories for custom icons.
  • Chores

    • Improved import statements and export structures for better code organization.
    • Extended cleanup functionality to ensure directories are properly managed.
    • Modified the generateComponents function to utilize a more robust SVG-to-React transformation process.

@KelvinOm KelvinOm added the ok-to-test Required label for CI label Oct 28, 2024
Copy link
Contributor

coderabbitai bot commented Oct 28, 2024

Walkthrough

The pull request introduces several changes across multiple files, primarily focusing on enhancing the handling of SVG components and updating the DatePicker widget tests. Key modifications include updating import statements for React to use namespace imports, adjusting component signatures to accept SVGProps, and enhancing type safety for widget properties. Additionally, the DatePicker test suite has been updated to change the import of the format function from date-fns to a specific path. New dependencies related to SVG handling have also been added.

Changes

File Path Change Summary
app/client/cypress/e2e/Regression/ClientSide/Widgets/Datepicker/DatePicker3_spec.ts Modified import for format function from date-fns to date-fns/format.cjs.
app/client/jest.config.js Updated transformIgnorePatterns to include `
app/client/package.json Updated date-fns dependency version from 2.30.0 to ^4.1.0.
app/client/packages/icons/package.json Added dependencies @svgr/core and @svgr/plugin-jsx to devDependencies.
app/client/packages/icons/src/components/CustomIcons/AIAvatarCustomIcon.tsx Introduced new component AIAvatarCustomIcon accepting SVG props.
app/client/packages/icons/src/components/Icons/*.tsx Updated multiple icon components to use namespace imports for React, accept SVG props, and use named exports.
app/client/packages/icons/src/index.ts Added export for AIAvatarCustomIcon.
app/client/packages/icons/src/stories/CustomIcons.mdx Added new Storybook documentation for custom icons.
app/client/packages/icons/src/utils/cleanup.ts Added calls to fs.emptyDir for additional directories in cleanup function.
app/client/packages/icons/src/utils/generateComponents.ts Removed createReactComponent function, integrated @svgr/core for SVG to React transformation.
app/client/packages/icons/src/utils/generateIndex.ts Added appendExports("CustomIcons") to include custom icons in index generation.
app/client/packages/icons/src/utils/generateStories.ts Added call to generateStory for custom icons.
app/client/src/WidgetProvider/constants.ts Updated IconCmp and ThumbnailCmp in WidgetMethods interface to accept SVGProps.
app/client/src/layoutSystems/anvil/editor/canvasArenas/AnvilDragPreview/index.tsx Updated ThumbnailCmp in DragPreviewConfig interface to accept SVGProps.
app/client/src/widgets/BaseWidget.tsx Updated IconCmp and ThumbnailCmp in WidgetCardProps interface to accept SVGProps.

Possibly related PRs

Suggested labels

Bug, Widgets Product, Low, Production, Community Reported, Needs Triaging, One-click Binding, Widgets & Accelerators Pod, Test

Suggested reviewers

  • ApekshaBhosale
  • sagar-qa007
  • rajatagrawal

🎉 In code we trust, with changes so bright,
Icons and widgets, all set to delight!
From DatePicker tests to SVGs anew,
Our components are ready, all shiny and true!
So let’s merge it in, and watch our app shine,
With every new feature, it’s simply divine! 🌟


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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

Documentation and Community

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

@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Oct 28, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Outside diff range and nitpick comments (50)
app/client/packages/icons/src/components/Icons/HeadingIcon.tsx (1)

3-3: Consider adding accessibility attributes.

While the implementation is correct, consider adding aria-label or role="img" for better accessibility.

-const HeadingIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M.5 1.5h2m2 0h-2m0 0v12m-2 0h4M10.5 1.5h2m2 0h-2m0 0v12m-2 0h4M2.5 7.5h10" /></svg>;
+const HeadingIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" role="img" aria-label="heading" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M.5 1.5h2m2 0h-2m0 0v12m-2 0h4M10.5 1.5h2m2 0h-2m0 0v12m-2 0h4M2.5 7.5h10" /></svg>;
app/client/packages/icons/src/components/Icons/TableIcon.tsx (1)

3-3: Consider adding aria-label for accessibility.

The component correctly accepts SVG props, but could benefit from a default aria-label for better accessibility.

-const TableIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const TableIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" aria-label="Table" {...props}>
app/client/packages/icons/src/components/Thumbnails/IconButtonThumbnail.tsx (1)

3-3: Consider breaking the SVG markup into multiple lines for better readability.

While the logic is correct, the long single-line SVG markup could be harder to maintain.

-const IconButtonThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={31} height={23} x={20.5} y={26.5} fill="#FFEEE5" stroke="#CC3D00" rx={5.5} /><path stroke="#CC3D00" strokeLinecap="round" d="M30.5 37.5h12M36.5 43.5v-12" /></svg>;
+const IconButtonThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <rect width={31} height={23} x={20.5} y={26.5} fill="#FFEEE5" stroke="#CC3D00" rx={5.5} />
+    <path stroke="#CC3D00" strokeLinecap="round" d="M30.5 37.5h12M36.5 43.5v-12" />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/MenuButtonThumbnail.tsx (1)

3-3: Consider improving readability with proper formatting.

While the implementation is correct, the long line could be more readable with proper formatting.

Consider reformatting like this:

-const MenuButtonThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={31} height={23} x={20.5} y={26.5} fill="#FFEEE5" stroke="#CC3D00" rx={5.5} /><path stroke="#CC3D00" strokeLinecap="round" d="M30.5 33.5h12M30.5 37.5h12M30.5 41.5h12" /></svg>;
+const MenuButtonThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={72}
+    height={76}
+    fill="none"
+    {...props}
+  >
+    <rect
+      width={31}
+      height={23}
+      x={20.5}
+      y={26.5}
+      fill="#FFEEE5"
+      stroke="#CC3D00"
+      rx={5.5}
+    />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      d="M30.5 33.5h12M30.5 37.5h12M30.5 41.5h12"
+    />
+  </svg>
+);
app/client/packages/icons/src/stories/CustomIcons.mdx (2)

13-15: Consider adding props documentation for AIAvatarCustomIcon.

The component is rendered without any props, but users of this documentation might need to know what props are available.

Add a props table or description above the Icons component:

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| size | number | 24 | The size of the icon |
| color | string | 'currentColor' | The color of the icon |

7-9: Enhance documentation with usage examples.

The current documentation is minimal. Consider adding:

  1. Installation instructions
  2. Code examples
  3. Best practices

Add more comprehensive documentation:

# CustomIcons

Set of custom icons used throughout the Appsmith application.

## Usage

```jsx
import { AIAvatarCustomIcon } from "@appsmith/icons";

function MyComponent() {
  return <AIAvatarCustomIcon size={24} color="blue" />;
}

Available Icons


</blockquote></details>
<details>
<summary>app/client/packages/icons/src/components/Thumbnails/SectionThumbnail.tsx (1)</summary><blockquote>

`3-3`: **Consider adding ARIA attributes for accessibility**

The SVG could benefit from accessibility attributes.

```diff
-const SectionThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={53} height={29} x={9.5} y={23.5} fill="#fff" stroke="#CC3D00" rx={2} /><path stroke="#CC3D00" d="M62.5 9v4.5a2 2 0 0 1-2 2h-49a2 2 0 0 1-2-2V9M62.5 67v-4.5a2 2 0 0 0-2-2h-49a2 2 0 0 0-2 2V67" /></svg>;
+const SectionThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" role="img" aria-label="Section thumbnail" {...props}><rect width={53} height={29} x={9.5} y={23.5} fill="#fff" stroke="#CC3D00" rx={2} /><path stroke="#CC3D00" d="M62.5 9v4.5a2 2 0 0 1-2 2h-49a2 2 0 0 1-2-2V9M62.5 67v-4.5a2 2 0 0 0-2-2h-49a2 2 0 0 0-2 2V67" /></svg>;
app/client/packages/icons/src/components/Icons/SwitchIcon.tsx (1)

3-3: Consider improving readability with multi-line formatting.

While the implementation is correct, the long line makes it harder to read and maintain.

Consider this more readable format:

-const SwitchIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M10.5 4.5h-6a3 3 0 0 0 0 6h6a3 3 0 1 0 0-6" /><path fill="#000" fillOpacity={0.15} fillRule="evenodd" d="M1.5 7.5a3 3 0 0 1 3-3h6a3 3 0 0 0 0 6h-6a3 3 0 0 1-3-3" clipRule="evenodd" /><circle cx={10.5} cy={7.5} r={3} stroke="#000" /></svg>;
+const SwitchIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={16}
+    height={16}
+    fill="none"
+    {...props}
+  >
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M10.5 4.5h-6a3 3 0 0 0 0 6h6a3 3 0 1 0 0-6"
+    />
+    <path
+      fill="#000"
+      fillOpacity={0.15}
+      fillRule="evenodd"
+      d="M1.5 7.5a3 3 0 0 1 3-3h6a3 3 0 0 0 0 6h-6a3 3 0 0 1-3-3"
+      clipRule="evenodd"
+    />
+    <circle cx={10.5} cy={7.5} r={3} stroke="#000" />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/CheckboxThumbnail.tsx (1)

3-3: Consider adding aria-label for accessibility.

The SVG implementation looks good with proper props spreading, but could benefit from accessibility improvements.

-const CheckboxThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+const CheckboxThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" aria-label="Checkbox thumbnail" role="img" {...props}>
app/client/packages/icons/src/components/Icons/ModalIcon.tsx (1)

3-3: Consider improving SVG markup readability

While the implementation is correct, the single-line format makes it difficult to read and maintain.

Consider reformatting like this:

-const ModalIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M12.5 2.5a1 1 0 0 1 1 1v7a3 3 0 0 1-3 3h-7a1 1 0 0 1-1-1v0" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M10.5.5h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2M7.5 5.5l2-2m0 2-2-2" /></svg>;
+const ModalIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={16}
+    height={16}
+    fill="none"
+    {...props}
+  >
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      strokeOpacity={0.25}
+      d="M12.5 2.5a1 1 0 0 1 1 1v7a3 3 0 0 1-3 3h-7a1 1 0 0 1-1-1v0"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M10.5.5h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2M7.5 5.5l2-2m0 2-2-2"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx (1)

3-3: Consider adding explicit viewBox attribute.

The component correctly implements SVG props spreading and follows React naming conventions.

-const ComboboxSelectIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const ComboboxSelectIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 16 16" fill="none" {...props}>
app/client/packages/icons/src/components/Thumbnails/SelectThumbnail.tsx (1)

3-3: Consider improving SVG readability.

While the implementation is correct, the SVG markup could benefit from formatting for better maintainability.

-const SelectThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} /><path stroke="#CC3D00" strokeLinecap="round" strokeLinejoin="round" d="m14.5 44.5 1.833-4m9.167 4-1.833-4m-7.334 0 3.667-8 3.667 8m-7.334 0h7.334" /><path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" d="m56.5 36.5-3 3-3-3" /></svg>;
+const SelectThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="m14.5 44.5 1.833-4m9.167 4-1.833-4m-7.334 0 3.667-8 3.667 8m-7.334 0h7.334"
+    />
+    <path
+      stroke="#6A7585"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="m56.5 36.5-3 3-3-3"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/PasswordInputIcon.tsx (1)

3-3: Consider enhancing accessibility attributes.

The component correctly accepts SVG props and uses proper camelCase attributes. However, for better accessibility, consider adding role="img" and aria-label attributes.

-const PasswordInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const PasswordInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" role="img" aria-label="Password input" {...props}>
app/client/packages/icons/src/components/Thumbnails/InputThumbnail.tsx (1)

3-3: Consider adding aria-label for accessibility.

The SVG implementation is correct with proper props spreading, but could benefit from accessibility improvements.

-const InputThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+const InputThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" aria-label="Input thumbnail" role="img" {...props}>
app/client/packages/icons/src/components/Icons/InputIcon.tsx (1)

3-3: Consider adding aria-label for accessibility

While the SVG implementation is correct, adding an aria-label would improve accessibility for screen readers.

-const InputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const InputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" aria-label="Input field" {...props}>
app/client/packages/icons/src/components/Icons/IconButtonIcon.tsx (1)

3-3: Add aria-label for better accessibility.

While the SVG implementation is correct, consider adding an aria-label for screen readers.

-const IconButtonIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const IconButtonIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" aria-label="button icon" role="img" {...props}>
app/client/packages/icons/src/components/Thumbnails/RadioGroupThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the implementation is correct, the single-line SVG markup could be harder to maintain.

-const RadioGroupThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><circle cx={22} cy={29} r={6.5} fill="#FFBFA1" stroke="#CC3D00" /><circle cx={22} cy={29} r={3.5} fill="#fff" stroke="#CC3D00" /><rect width={20} height={8} x={34} y={25} fill="#CDD5DF" rx={1} /><rect width={11} height={11} x={16.5} y={41.5} fill="#fff" stroke="#CDD5DF" rx={5.5} /><rect width={22} height={8} x={34} y={43} fill="#CDD5DF" rx={1} /></svg>;
+const RadioGroupThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <circle cx={22} cy={29} r={6.5} fill="#FFBFA1" stroke="#CC3D00" />
+    <circle cx={22} cy={29} r={3.5} fill="#fff" stroke="#CC3D00" />
+    <rect width={20} height={8} x={34} y={25} fill="#CDD5DF" rx={1} />
+    <rect width={11} height={11} x={16.5} y={41.5} fill="#fff" stroke="#CDD5DF" rx={5.5} />
+    <rect width={22} height={8} x={34} y={43} fill="#CDD5DF" rx={1} />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/KeyValueIcon.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While functionally correct, the SVG markup is quite dense.

Consider reformatting like this:

-const KeyValueIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} strokeWidth={2} d="M2 3h6" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M1.5 11.5h1m1 0h-1m-1-3 1-1v4M8.5 11.5h-3v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v0a1 1 0 0 0-1-1h-2M10.5 7.5h2a1 1 0 0 1 1 1v0a1 1 0 0 1-1 1h-1M10.5 11.5h2a1 1 0 0 0 1-1v0a1 1 0 0 0-1-1h-1" /></svg>;
+const KeyValueIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={16}
+    height={16}
+    fill="none"
+    {...props}
+  >
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      strokeOpacity={0.25}
+      strokeWidth={2}
+      d="M2 3h6"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M1.5 11.5h1m1 0h-1m-1-3 1-1v4M8.5 11.5h-3v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v0a1 1 0 0 0-1-1h-2M10.5 7.5h2a1 1 0 0 1 1 1v0a1 1 0 0 1-1 1h-1M10.5 11.5h2a1 1 0 0 0 1-1v0a1 1 0 0 0-1-1h-1"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/MenuButtonIcon.tsx (1)

3-3: Consider adding aria-label for accessibility

The SVG implementation is correct with proper props spreading, but could benefit from accessibility improvements.

-const MenuButtonIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const MenuButtonIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" aria-label="Menu button" role="img" {...props}>
app/client/packages/icons/src/components/Icons/SectionIcon.tsx (1)

3-3: Add viewBox attribute to SVG element.

The SVG element has width and height but lacks a viewBox attribute. This might affect scaling behavior in different contexts.

-const SectionIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const SectionIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 16 16" fill="none" {...props}>
app/client/packages/icons/src/components/Thumbnails/PhoneInputThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the implementation is correct, the SVG markup could be more maintainable if formatted across multiple lines.

-const PhoneInputThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} /><path stroke="#CC3D00" strokeLinecap="round" d="M15.5 38.5h8M19.5 42.5v-8" /><path stroke="#CC3D00" strokeLinecap="round" strokeLinejoin="round" d="M27 43.5h2.5m2.5 0h-2.5m-2.5-8 2.5-2v10" /><path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" d="M51.5 43.5h2m2 0h-2m0 0v12m-2 0h4" /></svg>;
+const PhoneInputThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} />
+    <path stroke="#CC3D00" strokeLinecap="round" d="M15.5 38.5h8M19.5 42.5v-8" />
+    <path stroke="#CC3D00" strokeLinecap="round" strokeLinejoin="round" d="M27 43.5h2.5m2.5 0h-2.5m-2.5-8 2.5-2v10" />
+    <path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" d="M51.5 43.5h2m2 0h-2m0 0v12m-2 0h4" />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/ZoneIcon.tsx (1)

3-3: LGTM! Well-structured SVG component.

The component correctly implements SVG props spreading and includes proper accessibility attributes (xmlns, width, height).

Consider adding an aria-label prop with a default value for better accessibility:

-const ZoneIcon = (props: SVGProps<SVGSVGElement>) =>
+const ZoneIcon = ({ 'aria-label': ariaLabel = 'Zone icon', ...props }: SVGProps<SVGSVGElement>) =>
-  <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+  <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" aria-label={ariaLabel} {...props}>
app/client/packages/icons/src/components/Thumbnails/HeadingThumbnail.tsx (1)

3-3: Consider extracting SVG dimensions as constants

The hardcoded width and height values (72 and 76) could be extracted as named constants for better maintainability.

+const THUMBNAIL_WIDTH = 72;
+const THUMBNAIL_HEIGHT = 76;
-const HeadingThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+const HeadingThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={THUMBNAIL_WIDTH} height={THUMBNAIL_HEIGHT} fill="none" {...props}>
app/client/packages/icons/src/components/Icons/CurrencyInputIcon.tsx (1)

3-3: Consider adding ARIA attributes for accessibility.

While the SVG props implementation is correct, consider adding aria-label or role="img" for better accessibility.

-const CurrencyInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const CurrencyInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" role="img" aria-label="currency input" {...props}>
app/client/packages/icons/src/components/Thumbnails/CurrencyInputThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the component logic is correct, the SVG markup is quite dense.

Consider reformatting like this:

-const CurrencyInputThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} /><path stroke="#CC3D00" strokeLinecap="round" strokeLinejoin="round" d="M17 38.5a2.5 2.5 0 0 1 0-5M22 43.5a2.5 2.5 0 0 0 0-5M23.5 35.5a2 2 0 0 0-2-2M14.5 41.5a2 2 0 0 0 2 2M19.5 31.5v14M17 33.5h4.5m-4.5 5h5m-5.5 5H22" /><path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" d="M51.5 43.5h2m2 0h-2m0 0v12m-2 0h4" /></svg>;
+const CurrencyInputThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M17 38.5a2.5 2.5 0 0 1 0-5M22 43.5a2.5 2.5 0 0 0 0-5M23.5 35.5a2 2 0 0 0-2-2M14.5 41.5a2 2 0 0 0 2 2M19.5 31.5v14M17 33.5h4.5m-4.5 5h5m-5.5 5H22"
+    />
+    <path
+      stroke="#6A7585"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M51.5 43.5h2m2 0h-2m0 0v12m-2 0h4"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/NumberInputIcon.tsx (1)

3-3: Consider breaking down the SVG markup for better readability

While the implementation is correct, the single-line SVG markup could be harder to maintain.

Consider reformatting like this:

-const NumberInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M3.5 9.5h1m1 0h-1m-1-3 1-1v4M9.5 9.5h1m1 0h-1m-1-3 1-1v4" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7" /><path stroke="#000" strokeLinecap="round" d="M7.5 9.5v.01" /></svg>;
+const NumberInputIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={16}
+    height={16}
+    fill="none"
+    {...props}
+  >
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M3.5 9.5h1m1 0h-1m-1-3 1-1v4M9.5 9.5h1m1 0h-1m-1-3 1-1v4"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      strokeOpacity={0.25}
+      d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      d="M7.5 9.5v.01"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/EmailInputThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the implementation is correct, the long inline SVG markup could be harder to maintain.

Consider reformatting like this:

-const EmailInputThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} /><path stroke="#CC3D00" strokeLinecap="round" d="M21.5 40.5H19a1.5 1.5 0 0 1-1.5-1.5v-2a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v3.5Zm0 0 1.026.342a1.5 1.5 0 0 0 1.974-1.423V36.5a4 4 0 0 0-4-4h-2a4 4 0 0 0-4 4v3a4 4 0 0 0 4 4H23" /><path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" d="M51.5 43.5h2m2 0h-2m0 0v12m-2 0h4" /></svg>;
+const EmailInputThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      d="M21.5 40.5H19a1.5 1.5 0 0 1-1.5-1.5v-2a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v3.5Zm0 0 1.026.342a1.5 1.5 0 0 0 1.974-1.423V36.5a4 4 0 0 0-4-4h-2a4 4 0 0 0-4 4v3a4 4 0 0 0 4 4H23"
+    />
+    <path
+      stroke="#6A7585"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M51.5 43.5h2m2 0h-2m0 0v12m-2 0h4"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/InlineButtonsThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the implementation is correct, the single-line SVG markup makes it harder to maintain.

Consider reformatting like this:

-const InlineButtonsThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={59} height={23} x={6.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={5.5} /><rect width={24} height={15} x={37.5} y={30.5} fill="#FFEEE5" stroke="#CC3D00" rx={2.5} /><rect width={24} height={15} x={10.5} y={30.5} fill="#E3E8EF" stroke="#6A7585" rx={2.5} /><path stroke="#CC3D00" strokeLinecap="round" strokeLinejoin="round" d="m45.5 37.5 3 3 5-5" /><path stroke="#6A7585" strokeLinecap="round" d="m20 35 6 6m0-6-6 6" /></svg>;
+const InlineButtonsThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={72}
+    height={76}
+    fill="none"
+    {...props}
+  >
+    <rect
+      width={59}
+      height={23}
+      x={6.5}
+      y={26.5}
+      fill="#fff"
+      stroke="#CDD5DF"
+      rx={5.5}
+    />
+    <rect
+      width={24}
+      height={15}
+      x={37.5}
+      y={30.5}
+      fill="#FFEEE5"
+      stroke="#CC3D00"
+      rx={2.5}
+    />
+    <rect
+      width={24}
+      height={15}
+      x={10.5}
+      y={30.5}
+      fill="#E3E8EF"
+      stroke="#6A7585"
+      rx={2.5}
+    />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="m45.5 37.5 3 3 5-5"
+    />
+    <path
+      stroke="#6A7585"
+      strokeLinecap="round"
+      d="m20 35 6 6m0-6-6 6"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/SwitchGroupThumbnail.tsx (1)

3-3: Consider adding aria-label for accessibility.

The SVG implementation looks good with proper props spreading, but could benefit from accessibility improvements.

-const SwitchGroupThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+const SwitchGroupThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" aria-label="Switch Group Thumbnail" role="img" {...props}>
app/client/packages/icons/src/components/Icons/EmailInputIcon.tsx (1)

3-3: Consider adding aria-label for accessibility.

The component correctly accepts and spreads SVG props, but could benefit from a default aria-label.

-const EmailInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const EmailInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" aria-label="Email input" {...props}>
app/client/packages/icons/src/components/Icons/ToolbarButtonsIcon.tsx (1)

3-3: Consider extracting SVG path data to constants.

While the implementation is correct, the SVG path data makes the line quite long. Consider extracting the path data to named constants for better readability.

+const TOOLBAR_PATH_1 = "M5 5.5a.5.5 0 0 0-1 0V7H2.5a.5.5 0 0 0 0 1H4v1.5a.5.5 0 0 0 1 0V8h1.5a.5.5 0 0 0 0-1H5z";
+const TOOLBAR_PATH_2 = "M13.854 5.854a.5.5 0 0 0-.708-.708l-3 3a.5.5 0 0 0 .708.708z";
+const TOOLBAR_PATH_3 = "M9.775 9.765a.375.375 0 1 0-.53-.53l-.01.01a.375.375 0 0 0 .53.53z";
+const TOOLBAR_PATH_4 = "M13.5 3.5h-11a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2";

 const ToolbarButtonsIcon = (props: SVGProps<SVGSVGElement>) => (
   <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
-    <path fill="#000" fillRule="evenodd" d="M5 5.5a.5.5 0 0 0-1 0V7H2.5a.5.5 0 0 0 0 1H4v1.5a.5.5 0 0 0 1 0V8h1.5a.5.5 0 0 0 0-1H5z" clipRule="evenodd" />
-    <path fill="#000" fillRule="evenodd" d="M13.854 5.854a.5.5 0 0 0-.708-.708l-3 3a.5.5 0 0 0 .708.708z" clipRule="evenodd" />
-    <path fill="#000" fillRule="evenodd" d="M9.775 9.765a.375.375 0 1 0-.53-.53l-.01.01a.375.375 0 0 0 .53.53z" clipRule="evenodd" />
-    <path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.5} d="M13.5 3.5h-11a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2" />
+    <path fill="#000" fillRule="evenodd" d={TOOLBAR_PATH_1} clipRule="evenodd" />
+    <path fill="#000" fillRule="evenodd" d={TOOLBAR_PATH_2} clipRule="evenodd" />
+    <path fill="#000" fillRule="evenodd" d={TOOLBAR_PATH_3} clipRule="evenodd" />
+    <path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.5} d={TOOLBAR_PATH_4} />
   </svg>
 );
app/client/packages/icons/src/components/Icons/SwitchGroupIcon.tsx (1)

3-3: Consider adding ARIA attributes for accessibility.

While the implementation is correct, consider adding role="img" and aria-label for better accessibility.

-const SwitchGroupIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const SwitchGroupIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" role="img" aria-label="Switch group" {...props}>
app/client/packages/icons/src/components/Thumbnails/KeyValueThumbnail.tsx (1)

3-3: Consider adding prop types documentation.

The component correctly accepts SVG props, but adding JSDoc comments would improve maintainability.

+/**
+ * KeyValueThumbnail icon component
+ * @param props - Standard SVG properties
+ */
const KeyValueThumbnail = (props: SVGProps<SVGSVGElement>) => <svg
app/client/packages/icons/src/components/Thumbnails/DatePickerThumbnail.tsx (1)

3-3: Consider improving readability by breaking down the SVG structure.

While functionally correct, the single-line implementation could be split for better readability.

Consider reformatting like this:

-const DatePickerThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={55} height={23} x={8.5} y={26.5} fill="#fff" rx={2.5} /><rect width={55} height={23} x={8.5} y={26.5} stroke="#CDD5DF" rx={2.5} /><path stroke="#CC3D00" strokeLinecap="round" strokeLinejoin="round" d="M25.5 32.5h-10a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1v-10a1 1 0 0 0-1-1M22.5 36.5v8M18.5 36.5v8M14.5 36.5h12M14.5 40.5h12M17.5 34.5v-3m6 3v-3" /><path stroke="#99A4B3" strokeLinecap="round" strokeLinejoin="round" d="m56.5 36.5-3 3-3-3" /></svg>;
+const DatePickerThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={72}
+    height={76}
+    fill="none"
+    {...props}
+  >
+    <rect width={55} height={23} x={8.5} y={26.5} fill="#fff" rx={2.5} />
+    <rect width={55} height={23} x={8.5} y={26.5} stroke="#CDD5DF" rx={2.5} />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M25.5 32.5h-10a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1v-10a1 1 0 0 0-1-1M22.5 36.5v8M18.5 36.5v8M14.5 36.5h12M14.5 40.5h12M17.5 34.5v-3m6 3v-3"
+    />
+    <path
+      stroke="#99A4B3"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="m56.5 36.5-3 3-3-3"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/MultilineInputIcon.tsx (1)

3-3: Consider improving SVG readability through formatting.

While the implementation is correct, the SVG could be more readable if formatted across multiple lines.

-const MultilineInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="m7.5 7.5-.5-1m-3.5 1 .5-1m0 0 1.5-3 1.5 3m-3 0h3" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M14.5 1.5h-12a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h7" /><path stroke="#000" strokeLinecap="round" d="M3.5 12v-2a.5.5 0 0 1 .5-.5h2a1.5 1.5 0 0 1 0 3H4a.5.5 0 0 1-.5-.5Z" /></svg>;
+const MultilineInputIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      d="m7.5 7.5-.5-1m-3.5 1 .5-1m0 0 1.5-3 1.5 3m-3 0h3" 
+    />
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      strokeOpacity={0.25} 
+      d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2" 
+    />
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      d="M14.5 1.5h-12a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h7" 
+    />
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      d="M3.5 12v-2a.5.5 0 0 1 .5-.5h2a1.5 1.5 0 0 1 0 3H4a.5.5 0 0 1-.5-.5Z" 
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/ModalThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability

While the component logic is correct, the SVG markup is quite dense.

Consider reformatting like this:

-const ModalThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={56} height={56} x={9} y={12} fill="#E3E8EF" rx={4} /><rect width={56} height={56} x={7} y={10} fill="#fff" rx={3} /><rect width={28} height={9} x={15} y={18} fill="#E3E8EF" rx={1} /><rect width={40} height={6} x={15} y={36} fill="#E3E8EF" rx={1} /><rect width={40} height={6} x={15} y={44} fill="#E3E8EF" rx={1} /><rect width={24} height={6} x={15} y={52} fill="#E3E8EF" rx={1} /><path stroke="#CC3D00" strokeLinecap="round" strokeWidth={1.5} d="m48.5 19.5 6 6m0-6-6 6" /></svg>;
+const ModalThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <rect width={56} height={56} x={9} y={12} fill="#E3E8EF" rx={4} />
+    <rect width={56} height={56} x={7} y={10} fill="#fff" rx={3} />
+    <rect width={28} height={9} x={15} y={18} fill="#E3E8EF" rx={1} />
+    <rect width={40} height={6} x={15} y={36} fill="#E3E8EF" rx={1} />
+    <rect width={40} height={6} x={15} y={44} fill="#E3E8EF" rx={1} />
+    <rect width={24} height={6} x={15} y={52} fill="#E3E8EF" rx={1} />
+    <path 
+      stroke="#CC3D00" 
+      strokeLinecap="round" 
+      strokeWidth={1.5} 
+      d="m48.5 19.5 6 6m0-6-6 6" 
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/StatsBoxIcon.tsx (1)

3-3: Consider adding prop types documentation.

While the implementation is correct, adding JSDoc comments would help developers understand available customization options.

+/**
+ * StatsBoxIcon component that renders a stats box SVG icon
+ * @param props - Standard SVG properties that can be spread onto the SVG element
+ */
const StatsBoxIcon = (props: SVGProps<SVGSVGElement>) => <svg
app/client/packages/icons/src/components/Thumbnails/CheckboxGroupThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the implementation is correct, the SVG markup could be more maintainable.

-const CheckboxGroupThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><path fill="#fff" stroke="#CC3D00" strokeLinecap="square" d="M26.5 23.5h-9a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1v-9a1 1 0 0 0-1-1Z" /><path fill="#fff" stroke="#CDD5DF" strokeLinecap="square" d="M26.5 41.5h-9a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1v-9a1 1 0 0 0-1-1Z" /><path stroke="#CC3D00" strokeLinecap="round" strokeLinejoin="round" d="m19 29 2 2 4-4" /><rect width={22} height={8} x={34} y={25} fill="#CDD5DF" rx={1} /><rect width={22} height={8} x={34} y={43} fill="#CDD5DF" rx={1} /></svg>;
+const CheckboxGroupThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <path
+      fill="#fff"
+      stroke="#CC3D00"
+      strokeLinecap="square"
+      d="M26.5 23.5h-9a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1v-9a1 1 0 0 0-1-1Z"
+    />
+    <path
+      fill="#fff"
+      stroke="#CDD5DF"
+      strokeLinecap="square"
+      d="M26.5 41.5h-9a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1v-9a1 1 0 0 0-1-1Z"
+    />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="m19 29 2 2 4-4"
+    />
+    <rect width={22} height={8} x={34} y={25} fill="#CDD5DF" rx={1} />
+    <rect width={22} height={8} x={34} y={43} fill="#CDD5DF" rx={1} />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/InlineButtonsIcon.tsx (1)

3-3: Consider breaking down the SVG definition for better readability

While functionally correct, the single-line SVG definition could be harder to maintain.

Consider reformatting like this:

-const InlineButtonsIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="m11.5 7.5 1 1 1-2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.75} d="m3.5 8.5 2-2m0 2-2-2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M13.5 4.5h-2a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.75} d="M5.5 4.5h-2a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2" /></svg>;
+const InlineButtonsIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg 
+    xmlns="http://www.w3.org/2000/svg" 
+    width={16} 
+    height={16} 
+    fill="none" 
+    {...props}
+  >
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      d="m11.5 7.5 1 1 1-2" 
+    />
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      strokeOpacity={0.75} 
+      d="m3.5 8.5 2-2m0 2-2-2" 
+    />
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      d="M13.5 4.5h-2a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2" 
+    />
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      strokeOpacity={0.75} 
+      d="M5.5 4.5h-2a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2" 
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/RadioGroupIcon.tsx (1)

3-3: Consider adding accessibility attributes.

While the implementation is correct, consider adding role="img" and aria-label for better accessibility.

-const RadioGroupIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const RadioGroupIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" role="img" aria-label="radio group icon" {...props}>
app/client/packages/icons/src/components/Thumbnails/NumberInputThumbnail.tsx (1)

3-3: Consider adding aria-label for accessibility.

The SVG implementation looks good with proper props spreading, but could benefit from an accessibility enhancement.

-const NumberInputThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+const NumberInputThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" aria-label="Number input thumbnail" {...props}>
app/client/packages/icons/src/components/Thumbnails/StatsBoxThumbnail.tsx (1)

3-3: Consider improving readability by breaking down the SVG markup.

While the implementation is functionally correct, the long line makes it harder to maintain. Consider breaking it down into multiple lines for better readability.

-const StatsBoxThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={32} height={6} x={16} y={24} fill="#E3E8EF" rx={1} /><path stroke="#CC3D00" strokeLinecap="round" strokeLinejoin="round" d="M16 50.5h2.5m2.5 0h-2.5m-2.5-8 2.5-2v10M28.5 50.5h-5v-2.646a2 2 0 0 1 1.257-1.857l2.486-.994a2 2 0 0 0 1.257-1.857V42.5a2 2 0 0 0-2-2h-3M31.5 40.5h3a2 2 0 0 1 2 2v1a2 2 0 0 1-2 2h-1.715M31.5 50.5h3a2 2 0 0 0 2-2v-1a2 2 0 0 0-2-2h-2" /><rect width={12} height={12} x={43.5} y={39.5} fill="#FFEEE5" stroke="#CC3D00" rx={1.5} /><path stroke="#CC3D00" strokeLinecap="round" d="m47 48 4-4" /><path stroke="#CC3D00" strokeLinecap="round" strokeLinejoin="round" d="M48.5 43.5h3v3" /></svg>;
+const StatsBoxThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={72}
+    height={76}
+    fill="none"
+    {...props}
+  >
+    <rect width={32} height={6} x={16} y={24} fill="#E3E8EF" rx={1} />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M16 50.5h2.5m2.5 0h-2.5m-2.5-8 2.5-2v10M28.5 50.5h-5v-2.646a2 2 0 0 1 1.257-1.857l2.486-.994a2 2 0 0 0 1.257-1.857V42.5a2 2 0 0 0-2-2h-3M31.5 40.5h3a2 2 0 0 1 2 2v1a2 2 0 0 1-2 2h-1.715M31.5 50.5h3a2 2 0 0 0 2-2v-1a2 2 0 0 0-2-2h-2"
+    />
+    <rect
+      width={12}
+      height={12}
+      x={43.5}
+      y={39.5}
+      fill="#FFEEE5"
+      stroke="#CC3D00"
+      rx={1.5}
+    />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      d="m47 48 4-4"
+    />
+    <path
+      stroke="#CC3D00"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M48.5 43.5h3v3"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/ToolbarButtonsThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the implementation is correct, the SVG markup is quite dense.

Consider reformatting like this:

-const ToolbarButtonsThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={18} height={16} x={5.5} y={30.5} fill="#FFEEE5" stroke="#CC3D00" rx={2.5} /><path stroke="#CC3D00" strokeLinecap="round" d="M10.5 38.5h8M14.5 42.5v-8" /><rect width={18} height={16} x={26.5} y={30.5} fill="#E3E8EF" stroke="#6A7585" rx={2.5} /><path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" d="m38 35-5.5 5.5 1 1L39 36a.707.707 0 0 0-1-1" /><rect width={19} height={16} x={48.5} y={30.5} fill="#E3E8EF" stroke="#6A7585" rx={2.5} /><path stroke="#6A7585" strokeLinecap="round" strokeWidth={2} d="M54 38h.01M58 38h.01M62 38h.01" /><path fill="#6A7585" stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" strokeWidth={0.75} d="m32 41.5.5.5-1 .5z" /></svg>;
+const ToolbarButtonsThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <rect width={18} height={16} x={5.5} y={30.5} fill="#FFEEE5" stroke="#CC3D00" rx={2.5} />
+    <path stroke="#CC3D00" strokeLinecap="round" d="M10.5 38.5h8M14.5 42.5v-8" />
+    <rect width={18} height={16} x={26.5} y={30.5} fill="#E3E8EF" stroke="#6A7585" rx={2.5} />
+    <path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" 
+      d="m38 35-5.5 5.5 1 1L39 36a.707.707 0 0 0-1-1" />
+    <rect width={19} height={16} x={48.5} y={30.5} fill="#E3E8EF" stroke="#6A7585" rx={2.5} />
+    <path stroke="#6A7585" strokeLinecap="round" strokeWidth={2} 
+      d="M54 38h.01M58 38h.01M62 38h.01" />
+    <path fill="#6A7585" stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" 
+      strokeWidth={0.75} d="m32 41.5.5.5-1 .5z" />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/TableThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the implementation is correct, the long inline SVG markup could be harder to maintain.

Consider this structure:

const TableThumbnail = (props: SVGProps<SVGSVGElement>) => (
  <svg 
    xmlns="http://www.w3.org/2000/svg" 
    width={72} 
    height={76} 
    fill="none" 
    {...props}
  >
    <rect 
      width={56} 
      height={43} 
      x={7.5} 
      y={16.5} 
      fill="#fff" 
      stroke="#6A7585" 
      rx={1.5} 
    />
    {/* ... remaining paths */}
  </svg>
);
app/client/packages/icons/src/utils/generateIndex.ts (2)

Line range hint 19-41: Consider improving async/Promise handling.

The current implementation using callbacks could be refactored to use async/await for better error handling and readability.

-async function appendExports(dir: string) {
-  await fs.readdir(`./src/components/${dir}/`, async (err, files) => {
-    if (err) {
-      // eslint-disable-next-line no-console
-      return console.error(err);
-    }
+async function appendExports(dir: string) {
+  try {
+    const files = await fs.readdir(`./src/components/${dir}/`);
+    let importList = '';
-    let importList = ``;
+    files.forEach((file) => {
+      const name = file.replace(".tsx", "");
+      importList += createImportListString(name, dir);
+    });

-    files.forEach((file) => {
-      const name = file.replace(".tsx", "");
-
-      importList += createImportListString(name, dir);
-    });
-
-    await fs.appendFile(`./src/index.ts`, importList, "utf8", function (err) {
-      if (err) {
-        // eslint-disable-next-line no-console
-        return console.error(err);
-      }
-    });
-  });
+    await fs.appendFile(`./src/index.ts`, importList, "utf8");
+  } catch (err) {
+    // eslint-disable-next-line no-console
+    console.error(err);
+  }
}

Line range hint 1-41: Consider adding validation and error recovery.

The script could benefit from additional robustness:

  1. Validate directory existence before processing
  2. Check if index.ts already exists and handle appropriately
  3. Add error recovery mechanism

Would you like me to provide a more robust implementation that includes these improvements?

app/client/packages/icons/src/components/Icons/AIChatIcon.tsx (1)

3-3: Consider adding accessibility attributes

While the implementation is correct, consider adding role="img" and aria-label for better accessibility.

-const AIChatIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={17} fill="none" {...props}>
+const AIChatIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={17} fill="none" role="img" aria-label="AI Chat Icon" {...props}>
app/client/packages/icons/src/utils/generateStories.ts (2)

Line range hint 54-83: Consider modernizing the async file operations

The generateStory function mixes callbacks with async/await, which could lead to race conditions. Consider refactoring to use promises consistently.

-async function generateStory(title: string, description: string) {
-  await fs.readdir(`./src/components/${title}/`, async (err, files) => {
-    if (err) {
-      return console.error(err);
-    }
+async function generateStory(title: string, description: string) {
+  try {
+    const files = await fs.readdir(`./src/components/${title}/`);
+    
     let importList = ``;
     let componentList = ``;
 
     files.forEach((file) => {
       const name = file.replace(".tsx", "");
       importList += createImportListString(name, title);
       componentList += createComponentListString(name);
     });
 
-    await fs.writeFile(
+    await fs.writeFile(
       `./src/stories/${title}.mdx`,
       createStory(title, description, importList, componentList),
-      "utf8",
-      function (err) {
-        if (err) return console.error(err);
-      },
+      "utf8"
     );
-  });
+  } catch (error) {
+    console.error(`Error generating story for ${title}:`, error);
+  }
 }

Line range hint 54-55: Consider extracting path constants

Hardcoded paths like ./src/components/ and ./src/stories/ should be extracted as constants for better maintainability.

+const PATHS = {
+  COMPONENTS: './src/components',
+  STORIES: './src/stories',
+} as const;

 async function generateStory(title: string, description: string) {
-  await fs.readdir(`./src/components/${title}/`, async (err, files) => {
+  await fs.readdir(`${PATHS.COMPONENTS}/${title}/`, async (err, files) => {
app/client/packages/icons/src/index.ts (1)

30-30: Consider grouping CustomIcons exports together

While the export statement is correct, consider maintaining consistent organization by grouping it with other CustomIcons (if any exist) or creating a new section with a comment delimiter for CustomIcons exports.

+ // Custom Icons
 export { AIAvatarCustomIcon } from "./components/CustomIcons/AIAvatarCustomIcon";
+ 
+ // Icons
 export { AIChatIcon } from "./components/Icons/AIChatIcon";
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 437f689 and 54d6817.

⛔ Files ignored due to path filters (3)
  • app/client/packages/icons/src/icons/CustomIcons/AIAvatar.svg is excluded by !**/*.svg
  • app/client/packages/icons/src/icons/Thumbnails/AIChat.svg is excluded by !**/*.svg
  • app/client/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (71)
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/Datepicker/DatePicker3_spec.ts (1 hunks)
  • app/client/jest.config.js (1 hunks)
  • app/client/package.json (1 hunks)
  • app/client/packages/icons/package.json (1 hunks)
  • app/client/packages/icons/src/components/CustomIcons/AIAvatarCustomIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/AIChatIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ButtonIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/CheckboxGroupIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/CheckboxIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/CurrencyInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/DatePickerIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/EmailInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/HeadingIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/IconButtonIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/InlineButtonsIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/InputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/KeyValueIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/MenuButtonIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ModalIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/MultilineInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/NumberInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ParagraphIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/PasswordInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/PhoneInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/RadioGroupIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/SectionIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/StatsBoxIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/SwitchGroupIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/SwitchIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/TableIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ToolbarButtonsIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ZoneIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/AIChatThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ButtonThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/CheckboxGroupThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/CheckboxThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ComboboxSelectThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/CurrencyInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/DatePickerThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/EmailInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/HeadingThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/IconButtonThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/InlineButtonsThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/InputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/KeyValueThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/MenuButtonThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ModalThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/MultilineInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/NumberInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ParagraphThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/PasswordInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/PhoneInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/RadioGroupThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/SectionThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/SelectThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/StatsBoxThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/SwitchGroupThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/SwitchThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/TableThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ToolbarButtonsThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ZoneThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/index.ts (1 hunks)
  • app/client/packages/icons/src/stories/CustomIcons.mdx (1 hunks)
  • app/client/packages/icons/src/utils/cleanup.ts (1 hunks)
  • app/client/packages/icons/src/utils/generateComponents.ts (2 hunks)
  • app/client/packages/icons/src/utils/generateIndex.ts (2 hunks)
  • app/client/packages/icons/src/utils/generateStories.ts (1 hunks)
  • app/client/src/WidgetProvider/constants.ts (2 hunks)
  • app/client/src/layoutSystems/anvil/editor/canvasArenas/AnvilDragPreview/index.tsx (2 hunks)
  • app/client/src/widgets/BaseWidget.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/Datepicker/DatePicker3_spec.ts
🔇 Additional comments (146)
app/client/packages/icons/src/components/Icons/HeadingIcon.tsx (2)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import follow TypeScript best practices.


4-4: LGTM! Clean export syntax.

The named export follows modern ES6+ conventions.

app/client/packages/icons/src/components/Icons/TableIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export syntax.

The named export syntax is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Thumbnails/IconButtonThumbnail.tsx (2)

1-2: LGTM! Import statements follow React best practices.

The namespace import for React and explicit type import for SVGProps align with modern React patterns.


4-4: LGTM! Export statement follows the consistent pattern.

The named export aligns with the standardization effort across icon components.

app/client/packages/icons/src/components/Thumbnails/MenuButtonThumbnail.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import follow best practices.


4-4: LGTM! Clean export syntax.

The named export syntax is consistent with modern JavaScript practices.

app/client/packages/icons/src/stories/CustomIcons.mdx (2)

1-3: LGTM: Imports are appropriate and well-organized.

The imports are correctly structured, bringing in necessary components from Storybook, WDS, and the custom icon component.


1-19: Verify custom icons integration.

Let's ensure all custom icons are properly documented and exported.

✅ Verification successful

All custom icons are properly integrated and exported

The verification shows that:

  • AIAvatarCustomIcon is the only custom icon component in the codebase
  • It is correctly exported in the index.ts file
  • The documentation in CustomIcons.mdx accurately reflects the current state
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for other custom icons that should be included
echo "Checking for other custom icons..."
fd --type f --glob '*CustomIcon.tsx' app/client/packages/icons/src/components

# Verify exports
echo "Verifying exports..."
rg "export.*CustomIcon" app/client/packages/icons/src/index.ts

Length of output: 432

app/client/packages/icons/src/components/Icons/DatePickerIcon.tsx (3)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export syntax.

The named export syntax is consistent with modern JavaScript practices.


3-3: Verify SVG accessibility attributes.

The SVG implementation looks good with proper props spreading. However, let's ensure it meets accessibility standards.

Consider adding accessibility attributes:

-const DatePickerIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const DatePickerIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" role="img" aria-label="date picker" {...props}>
app/client/packages/icons/src/components/Thumbnails/SectionThumbnail.tsx (1)

1-2: LGTM: Improved type safety with SVGProps

The addition of proper SVG prop types enhances component type safety and reusability.

app/client/packages/icons/src/utils/cleanup.ts (1)

6-6: LGTM: CustomIcons cleanup additions are consistent with existing patterns.

The new cleanup operations for CustomIcons directories align well with the existing cleanup strategy.

Also applies to: 9-9

app/client/packages/icons/src/components/Thumbnails/SwitchThumbnail.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and the explicit SVGProps type import enhance type safety.


4-4: LGTM! Clean export statement.

The named export follows modern JavaScript best practices.

app/client/packages/icons/src/components/Icons/CheckboxIcon.tsx (3)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export syntax.

The named export syntax is explicit and maintainable.


3-3: Props spreading implementation looks good.

The component correctly accepts and spreads SVG props while maintaining default attributes.

Let's verify if other icon components follow the same pattern:

✅ Verification successful

Props spreading implementation is consistent across icon components

The verification confirms that all icon components in the codebase follow the same pattern of accepting and spreading SVG props while maintaining default attributes. This is evident from the consistent implementation across 27 icon components, including CheckboxIcon, TableIcon, ButtonIcon, etc., which all use the pattern:

const ComponentIcon = (props: SVGProps<SVGSVGElement>) => <svg {...props}>
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if other icon components use similar props pattern
ast-grep --pattern 'const $_Icon = (props: SVGProps<SVGSVGElement>) => <svg'

Length of output: 78


Script:

#!/bin/bash
# Let's try a different pattern to match icon components with props spreading
rg -U "const \w+Icon = \(props: SVGProps<SVGSVGElement>\)" --type ts -A 1

Length of output: 21179

app/client/packages/icons/src/components/Thumbnails/ButtonThumbnail.tsx (3)

1-2: LGTM! Clean type imports.

The namespace import for React and explicit SVGProps type import improve type safety.


3-3: LGTM! Well-typed SVG component.

The component correctly implements SVGProps spreading, enabling customization while maintaining type safety.


4-4: LGTM! Clean export syntax.

The named export syntax follows modern ES6+ conventions.

app/client/packages/icons/src/components/Icons/SwitchIcon.tsx (2)

1-2: LGTM! Clean and type-safe imports.

The namespace import for React and explicit SVGProps type import enhance type safety and follow modern React practices.


4-4: LGTM! Clear and explicit export.

The named export syntax is consistent with modern JavaScript practices and makes imports more explicit.

app/client/packages/icons/src/components/Thumbnails/CheckboxThumbnail.tsx (2)

1-2: LGTM! Proper TypeScript imports and type safety.

The namespace import and SVGProps type import follow TypeScript best practices.


4-4: LGTM! Proper named export.

The named export style is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/ParagraphIcon.tsx (2)

1-2: LGTM! Clean import statements following React best practices.

The namespace import for React and explicit type import from react improve type safety and bundle size optimization.


4-4: LGTM! Clean named export.

The named export syntax is correct and follows modern JavaScript best practices.

app/client/packages/icons/src/components/Icons/ModalIcon.tsx (2)

1-2: LGTM! Clean and modern import statements.

The namespace import for React and separate type import follow best practices.


4-4: LGTM! Consistent export syntax.

The named export aligns with the standardization effort across icon components.

app/client/packages/icons/src/components/Thumbnails/ComboboxSelectThumbnail.tsx (2)

1-2: LGTM! Modern React import approach.

The namespace import and explicit SVGProps type import improve type safety.


4-4: LGTM! Named export follows modern practices.

The named export approach is preferred for better tree-shaking.

app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import follow best practices.


4-4: LGTM! Clean export statement.

The named export follows modern ES6+ conventions and enables tree-shaking.

app/client/packages/icons/src/components/Thumbnails/ParagraphThumbnail.tsx (3)

1-2: LGTM! Clean type imports.

The namespace import for React and explicit SVGProps type import improve type safety and follow best practices.


3-3: LGTM! Well-typed component with proper props spreading.

The component correctly accepts and spreads SVG props, enabling customization while maintaining type safety.


4-4: LGTM! Clean named export.

The named export follows modern ES6+ practices and makes imports more explicit.

app/client/packages/icons/src/components/Thumbnails/SelectThumbnail.tsx (2)

1-2: LGTM! Proper React imports and types.

The namespace import for React and SVGProps type import are correctly implemented.


4-4: LGTM! Proper named export.

The named export syntax is correctly implemented and supports tree-shaking.

app/client/packages/icons/src/components/Icons/PasswordInputIcon.tsx (2)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import enhance type safety.


4-4: LGTM! Clean export syntax.

The named export follows modern ES6 conventions.

app/client/packages/icons/src/components/Thumbnails/InputThumbnail.tsx (2)

1-2: LGTM! Clean type imports.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export syntax.

The named export follows modern JavaScript conventions.

app/client/packages/icons/src/components/Icons/InputIcon.tsx (3)

1-2: LGTM: Import statements follow best practices

The namespace import for React and explicit SVGProps type import align with modern React practices.


4-4: LGTM: Export statement follows convention

The named export aligns with the project's standardization efforts.


1-4: Verify icon dimensions across usage

The icon uses fixed dimensions (16x16). Let's verify this is consistent with other usage contexts.

✅ Verification successful

The previous search might have been too specific. Let's broaden our search to find usage patterns of the InputIcon component and any dimension-related props being passed to it.


Fixed dimensions (16x16) are consistent across all input-related icons

From the search results, all input-related icons (InputIcon, NumberInputIcon, PhoneInputIcon, MultilineInputIcon, PasswordInputIcon, EmailInputIcon, CurrencyInputIcon) consistently use the same 16x16 dimensions in their SVG definitions. No overriding dimensions were found in their usage contexts.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for InputIcon usage to verify dimension consistency
rg -l 'InputIcon' | xargs rg -A 2 -B 2 'width.*height.*InputIcon'

Length of output: 65


Script:

#!/bin/bash
# Let's first find all files that import or use InputIcon
rg -l "InputIcon"

# Then let's look for any props being passed to InputIcon
rg "InputIcon.*?>" -A 1

Length of output: 7913

app/client/packages/icons/src/components/Icons/IconButtonIcon.tsx (2)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean named export.

The named export follows modern ES6+ practices.

app/client/packages/icons/src/components/Thumbnails/RadioGroupThumbnail.tsx (2)

1-2: LGTM! Clean import statements following best practices.

The namespace import for React and explicit SVGProps type import enhance type safety and maintainability.


4-4: LGTM! Clean named export.

The named export follows the recommended pattern for React components.

app/client/packages/icons/src/components/Icons/KeyValueIcon.tsx (2)

1-2: LGTM! Proper React imports with type safety.

The namespace import and explicit SVGProps type import follow React's recommended patterns.


4-4: LGTM! Clean named export.

The named export follows the consistent pattern used across other icon components.

app/client/packages/icons/src/components/Icons/MenuButtonIcon.tsx (2)

1-2: LGTM: Proper TypeScript imports and type safety

The namespace import for React and explicit SVGProps type import enhance type safety and follow best practices.


4-4: LGTM: Clean named export

The named export follows modern JavaScript conventions.

app/client/packages/icons/src/components/Icons/SectionIcon.tsx (1)

1-4: Implementation looks good!

The component follows React best practices with proper TypeScript types, correct SVG attribute casing, and consistent export pattern.

app/client/packages/icons/src/components/Thumbnails/PhoneInputThumbnail.tsx (2)

1-2: LGTM! Clean import statements with proper types.

The namespace import and SVGProps type import follow TypeScript best practices.


4-4: LGTM! Clean named export.

The named export syntax is clear and consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/ZoneIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export statement.

The named export style is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/CheckboxGroupIcon.tsx (3)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import follow best practices.


3-3: LGTM! Well-structured SVG component.

The component correctly implements SVG props spreading and maintains proper SVG attributes.


4-4: LGTM! Clean export syntax.

Named export is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Thumbnails/HeadingThumbnail.tsx (3)

1-2: LGTM: Import statements follow best practices

The namespace import for React and explicit SVGProps type import improve type safety and maintainability.


4-4: LGTM: Export statement is correct

The named export aligns with the module's usage pattern.


1-4: Verify SVG props spreading implementation across icon components

The pattern of accepting and spreading SVG props should be consistent across all icon components.

✅ Verification successful

The previous pattern might have been too specific. Let's examine all icon components to verify the SVG props implementation pattern.


Based on the examination of all icon components in the codebase, I can provide a final response:

SVG props spreading pattern is consistent across all icon components

All icon components in both Icons and Thumbnails directories follow the same pattern of accepting and spreading SVG props:

const ComponentName = (props: SVGProps<SVGSVGElement>) => <svg {...props}>
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if other icon components follow the same pattern
ast-grep --pattern 'const $_ = (props: SVGProps<SVGSVGElement>) => <svg $$${...props}$$$>'

Length of output: 92


Script:

#!/bin/bash
# Let's try a different pattern to check SVG components implementation
# First, find all icon components
fd -e tsx -e ts -e jsx -e js . app/client/packages/icons/src/components

# Then check the content of these files for SVG props pattern
fd -e tsx -e ts -e jsx -e js . app/client/packages/icons/src/components -x cat {}

Length of output: 45459

app/client/packages/icons/src/components/Thumbnails/ZoneThumbnail.tsx (3)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import enhance type safety and follow React best practices.


3-3: LGTM! Well-structured SVG component.

The component correctly implements SVGProps typing and properly spreads props to the SVG element, allowing for customization while maintaining type safety.


4-4: LGTM! Clean export statement.

The named export follows the consistent pattern being established across icon components.

app/client/packages/icons/src/components/Icons/CurrencyInputIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export syntax.

The named export syntax is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/PhoneInputIcon.tsx (3)

1-2: LGTM: Clean import statements

The namespace import and SVGProps type import follow TypeScript best practices.


3-3: LGTM: Well-structured SVG component

The component properly accepts and spreads SVG props, enabling customization while maintaining type safety.


4-4: LGTM: Clean export statement

Named export follows the consistent pattern used across the icon components.

app/client/packages/icons/src/components/Thumbnails/CurrencyInputThumbnail.tsx (2)

1-2: LGTM! Clean import statements following best practices.

The namespace import for React and explicit SVGProps type import improve tree-shaking and type safety.


4-4: LGTM! Clean named export.

The named export is explicit and follows modern JavaScript best practices.

app/client/packages/icons/src/components/Icons/NumberInputIcon.tsx (2)

1-2: LGTM: Import statements follow React best practices

The namespace import for React and explicit type import from react are correct.


4-4: LGTM: Named export is appropriate

The named export aligns with the component naming and modern React practices.

app/client/packages/icons/src/components/Thumbnails/EmailInputThumbnail.tsx (2)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import improve type safety and follow best practices.


4-4: LGTM! Clean export statement.

The named export follows modern ES6+ conventions.

app/client/packages/icons/src/components/Thumbnails/InlineButtonsThumbnail.tsx (2)

1-2: LGTM! Import statements follow TypeScript best practices.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Named export is appropriate here.

The named export aligns with the component's purpose and makes imports more explicit.

app/client/packages/icons/src/components/Thumbnails/SwitchGroupThumbnail.tsx (2)

1-2: LGTM! Clean import statements following TypeScript best practices.

The namespace import for React and explicit SVGProps type import improve type safety and maintainability.


4-4: LGTM! Clean named export.

The named export follows modern ES6+ conventions.

app/client/packages/icons/src/components/Icons/EmailInputIcon.tsx (2)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import improve type safety and follow best practices.


4-4: LGTM! Clean export syntax.

The named export syntax is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/ToolbarButtonsIcon.tsx (2)

1-2: LGTM! Clean import statements following React best practices.

The namespace import for React and explicit SVGProps type import enhance type safety and maintainability.


4-4: LGTM! Clean named export.

The named export syntax is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/SwitchGroupIcon.tsx (2)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export syntax.

The named export is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Thumbnails/KeyValueThumbnail.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import follow best practices.


4-4: LGTM! Clean export statement.

The named export follows modern JavaScript practices.

app/client/packages/icons/src/components/Thumbnails/DatePickerThumbnail.tsx (2)

1-2: LGTM! Clean and proper imports.

The namespace import for React and explicit type import follow best practices.


4-4: LGTM! Proper named export.

The named export follows the consistent pattern used across icon components.

app/client/packages/icons/src/components/Icons/ButtonIcon.tsx (3)

1-2: LGTM: Proper TypeScript imports and type definitions.

The namespace import for React and explicit SVGProps type import follow TypeScript best practices.


3-3: LGTM: Well-structured SVG component with proper prop handling.

The component correctly implements SVG props spreading while maintaining the default attributes.


4-4: LGTM: Clean named export.

The named export syntax aligns with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/MultilineInputIcon.tsx (2)

1-2: LGTM! Clean import statements with proper types.

The namespace import and SVGProps type import follow React best practices.


4-4: LGTM! Proper named export.

The named export follows modern JavaScript practices and enables better tree-shaking.

app/client/packages/icons/src/components/Thumbnails/ModalThumbnail.tsx (2)

1-2: LGTM: Import statements follow best practices

The namespace import for React and explicit SVGProps type import enhance type safety and maintainability.


4-4: LGTM: Export statement is clean and explicit

The named export syntax is appropriate for this component.

app/client/packages/icons/src/components/Icons/StatsBoxIcon.tsx (2)

1-2: LGTM! Clean import statements with proper typing.

The namespace import for React and explicit SVGProps type import improve type safety and follow best practices.


4-4: LGTM! Clean named export.

The named export syntax is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Thumbnails/CheckboxGroupThumbnail.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export statement.

The named export is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/InlineButtonsIcon.tsx (2)

1-2: LGTM: Import statements follow best practices

The namespace import for React and explicit type import for SVGProps enhance type safety and maintainability.


4-4: LGTM: Export statement follows module conventions

The named export is consistent with modern JavaScript module patterns.

app/client/packages/icons/src/components/Icons/RadioGroupIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import follow best practices.


4-4: LGTM! Clean export syntax.

The named export follows modern JavaScript practices.

app/client/packages/icons/src/components/Thumbnails/NumberInputThumbnail.tsx (2)

1-2: LGTM! Clean import statements with proper types.

The namespace import for React and explicit SVGProps type import improve type safety and follow best practices.


4-4: LGTM! Clean named export.

The named export follows the consistent pattern being established across icon components.

app/client/packages/icons/src/components/Thumbnails/StatsBoxThumbnail.tsx (2)

1-2: LGTM! Clean import statements following best practices.

The namespace import for React and explicit SVGProps type import enhance type safety and maintainability.


4-4: LGTM! Consistent export pattern.

The named export aligns with the package's standardization efforts.

app/client/packages/icons/src/components/Thumbnails/ToolbarButtonsThumbnail.tsx (2)

1-2: LGTM! Clean import statements following best practices.

The namespace import for React and explicit SVGProps type import improve type safety and maintainability.


4-4: LGTM! Clean named export.

The named export syntax is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Thumbnails/TableThumbnail.tsx (2)

1-2: LGTM! Proper TypeScript imports and type definitions.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean named export.

The named export style is consistent with modern JavaScript conventions.

app/client/packages/icons/src/utils/generateIndex.ts (2)

35-38: LGTM! Error handling looks good.

The error handling restructuring improves readability while maintaining the same functionality.


11-11: Verify CustomIcons directory existence.

The new export for CustomIcons looks good, but we should verify the directory exists before attempting to read it.

✅ Verification successful

CustomIcons directory exists and is properly structured

The directory app/client/packages/icons/src/components/CustomIcons/ exists, so the new export addition is safe to use.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if CustomIcons directory exists
fd -t d "CustomIcons$" app/client/packages/icons/src/components

Length of output: 119

app/client/packages/icons/package.json (2)

21-22: LGTM: Addition of SVGR dependencies

The addition of @svgr/core and @svgr/plugin-jsx as devDependencies aligns with the PR objective to process SVG files as React components.


Line range hint 7-7: Verify build process with new dependencies

Since new dependencies were added that affect the build process, please ensure the build script executes successfully.

✅ Verification successful

The initial results show that SVGR is properly referenced in the code. Let me check the build configuration to ensure everything is properly set up.


Build configuration is properly set up with SVGR dependencies

The build process is well-configured with all necessary scripts and dependencies:

  • SVGR packages are correctly listed in devDependencies
  • Build script includes all required steps (cleanup, icon optimization, component generation)
  • Component generation utility properly uses SVGR packages
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the build script references the new SVGR packages
rg -A 2 "@svgr" app/client/packages/icons/src/utils/generateComponents.ts

Length of output: 261


Script:

#!/bin/bash
# Check if the build script exists and its content
cat app/client/packages/icons/package.json

# Check if there are any build-related files
fd -t f "build|rollup|webpack" app/client/packages/icons/

Length of output: 1160

app/client/packages/icons/src/components/CustomIcons/AIAvatarCustomIcon.tsx (2)

1-2: LGTM! Clean and proper imports.

The imports follow React best practices with proper type separation.


4-4: LGTM! Proper export statement.

The named export is appropriate for this component.

app/client/packages/icons/src/components/Thumbnails/MultilineInputThumbnail.tsx (3)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export statement.

The named export follows modern JavaScript practices.


3-3: Props spreading implementation looks good.

The component correctly accepts and spreads SVG props while maintaining proper TypeScript types.

Let's verify if this pattern is consistent across other icon components:

✅ Verification successful

The previous command might have failed due to syntax issues with the pattern. Let's try a different approach by first locating the icon components and then examining their implementation pattern.


Based on the examination of all thumbnail components in the codebase, I can now provide the final response:

Props spreading pattern is consistently implemented across all icon components

All thumbnail components in the app/client/packages/icons/src/components/Thumbnails/ directory follow the same pattern of accepting and spreading SVG props with proper TypeScript types (SVGProps<SVGSVGElement>).

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if other icon components follow the same pattern
ast-grep --pattern 'const $_ = (props: SVGProps<SVGSVGElement>) => <svg $$$'

Length of output: 78


Script:

#!/bin/bash
# Let's try a different approach to check icon components
# First, find all icon components
fd ".*Thumbnail\.tsx$" app/client/packages/icons/src/components

# Then examine their content
fd ".*Thumbnail\.tsx$" app/client/packages/icons/src/components -x cat {}

Length of output: 24297

app/client/packages/icons/src/components/Icons/AIChatIcon.tsx (2)

1-2: LGTM! Clean import statements

The namespace import and SVGProps type import follow React best practices.


4-4: LGTM! Proper export statement

Named export is the preferred approach for better tree-shaking support.

app/client/packages/icons/src/components/Thumbnails/PasswordInputThumbnail.tsx (3)

1-2: LGTM: Clean import statements

The namespace import for React and explicit SVGProps type import follow TypeScript best practices.


3-3: LGTM: Well-structured SVG component

The component correctly implements SVGProps and properly spreads props to the root SVG element, allowing for flexible customization while maintaining type safety.


4-4: LGTM: Clean export syntax

The named export follows a consistent pattern for icon components.

app/client/src/layoutSystems/anvil/editor/canvasArenas/AnvilDragPreview/index.tsx (2)

1-1: LGTM: Clean import addition

The SVGProps import is correctly added and follows TypeScript best practices.


11-11: LGTM: Enhanced type safety for ThumbnailCmp

The update to accept SVGProps improves type safety for SVG components. Let's verify that all implementations of ThumbnailCmp are compatible with this change.

✅ Verification successful

Type change for ThumbnailCmp is safe and properly implemented

The update to accept SVGProps is consistent across the codebase. All implementations and usages are compatible:

  • Base type definition in BaseWidget.tsx and constants.ts already use SVGProps
  • All thumbnail components in packages/icons/src/components/Thumbnails/ are SVG-based
  • Usage in WidgetCard and AnvilDragPreview components properly handle the SVG components
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find all files that might implement ThumbnailCmp
rg -l "ThumbnailCmp.*=.*props.*=>" 

# Find potential usages that might need updates
rg "ThumbnailCmp.*\(\)" 

Length of output: 62


Script:

#!/bin/bash
# Search for ThumbnailCmp in a broader context
rg -A 5 "ThumbnailCmp" 

# Search for files containing SVG-related props or components
rg -l "SVGProps|SVGElement"

# Look for interface or type definitions related to ThumbnailCmp
ast-grep --pattern 'interface $_ {
  ThumbnailCmp$_
}'

Length of output: 21618

app/client/packages/icons/src/utils/generateStories.ts (2)

48-48: LGTM: CustomIcons story addition

The addition aligns with the PR objective of supporting custom icons processing.


Line range hint 1-85: Verify the impact on existing story generation

The addition of CustomIcons should not affect the generation of existing Thumbnails and Icons stories.

✅ Verification successful

Let me verify the impact on the component imports by checking the structure of the component directories.


Story generation is working correctly for all icon types

The verification shows that:

  • All three story files (Thumbnails.mdx, Icons.mdx, CustomIcons.mdx) are generated successfully
  • Each story file correctly imports its corresponding components
  • Component imports match exactly with the files present in their respective directories
  • The addition of CustomIcons hasn't affected the generation of existing Thumbnails and Icons stories
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of generated stories

# Test: Check if all story files are generated
ls -la app/client/packages/icons/src/stories/*.mdx

# Test: Verify the content structure of each story
for story in app/client/packages/icons/src/stories/*.mdx; do
  echo "=== $story ==="
  grep -A 2 "^# " "$story" # Check title and description
  grep -c "<Meta title=\"Appsmith Icons/" "$story" # Verify Meta tag
done

Length of output: 1761


Script:

#!/bin/bash
# Check the structure and files in component directories
echo "=== Component Directories ==="
ls -la app/client/packages/icons/src/components/*/

# Verify imports in story files match the component files
for dir in app/client/packages/icons/src/components/*/; do
  dirname=$(basename "$dir")
  echo -e "\n=== $dirname Components vs Story Imports ==="
  echo "Components in directory:"
  ls "$dir" | grep ".tsx$" | sed 's/.tsx$//'
  
  echo -e "\nImports in story:"
  grep "^import.*from.*components/$dirname/" "app/client/packages/icons/src/stories/$dirname.mdx"
done

Length of output: 11745

app/client/packages/icons/src/components/Thumbnails/AIChatThumbnail.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import follow best practices.


4-4: LGTM! Clean export statement.

The named export is consistent with the icon library standardization effort.

app/client/jest.config.js (1)

24-24: LGTM! Necessary change for date-fns v4 compatibility.

The addition of date-fns to transformIgnorePatterns is correct and aligns with the package upgrade.

Let's verify the Jest configuration works with the new date-fns version:

✅ Verification successful

Confirmed: Jest configuration change is necessary for date-fns v4

The verification shows:

  • Package upgraded to date-fns v4.1.0
  • Mixed import patterns found:
    • ESM imports in DatePicker component
    • CommonJS import (.cjs) in Cypress tests

The transformIgnorePatterns addition is required to handle these mixed module formats correctly in the test environment.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify date-fns imports in test files

# Test: Check for date-fns imports in test files
rg -t ts -t tsx "from 'date-fns'" "app/client"

# Test: Check for potential CommonJS/ESM mixing issues
rg -t ts -t tsx "require.*date-fns" "app/client"

Length of output: 157


Script:

#!/bin/bash
# Let's try with correct file extensions and patterns
# Check for date-fns imports in test files
rg "from ['|\"]date-fns" app/client

# Check package.json for date-fns version
cat app/client/package.json | grep date-fns

# Look for test files that might use date-fns
rg -g "*.test.*" -g "*.spec.*" "date-fns" app/client

Length of output: 512

app/client/package.json (1)

128-128: Verify breaking changes in date-fns v4 upgrade.

The major version upgrade from v2.30.0 to v4.1.0 likely includes breaking changes. While the DatePicker tests have been updated, other components using date-fns might need attention.

Let's check for other date-fns usages that might need updates:

✅ Verification successful

Breaking changes in date-fns v4 are manageable

The codebase has limited date-fns usage, primarily in:

  • DatePicker component: imports getYear and getMonth
  • DatePicker tests: imports format

These functions have remained stable in v4, and the test suite has already been updated. No other components are using date-fns functionality that would be affected by breaking changes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for date-fns imports and usages
echo "Searching for date-fns imports..."
rg "from ['|\"]date-fns" -A 2

echo "\nSearching for specific date-fns function calls..."
rg "format\(|parse\(|add\w+\(|sub\w+\(" --type ts --type tsx

Length of output: 1105


Script:

#!/bin/bash
# Search for date-fns imports and usages with correct file types
echo "Searching for date-fns imports..."
rg "from ['|\"]date-fns" -t ts -t tsx -A 2

echo "\nSearching for specific date-fns function calls..."
rg "format\(|parse\(|add\w+\(|sub\w+\(" -t ts -t tsx

echo "\nSearching for other date-fns imports (including submodules)..."
rg "from ['|\"]date-fns/\w+" -t ts -t tsx

Length of output: 560


Script:

#!/bin/bash
# Search for date-fns imports and usages without file type flags
echo "Searching for date-fns imports..."
rg "from ['|\"]date-fns" --type-add 'ts:*.{ts,tsx}' -t ts

echo "\nSearching for specific date-fns function calls..."
rg "format\(|parse\(|add\w+\(|sub\w+\(" --type-add 'ts:*.{ts,tsx}' -t ts

echo "\nSearching for other date-fns imports (including submodules)..."
rg "import .+ from ['|\"]date-fns/" --type-add 'ts:*.{ts,tsx}' -t ts

Length of output: 132900

app/client/src/WidgetProvider/constants.ts (2)

14-14: LGTM: Clean import of SVG types

The addition of SVGProps import is appropriate for the subsequent type definitions.


154-155: LGTM: Improved type safety for SVG components

The updated method signatures properly type the SVG component props, which enhances type safety and aligns with React's typing system.

Let's verify the usage of these methods across the codebase:

✅ Verification successful

SVG component types are correctly implemented across the codebase

The search results confirm that all implementations of IconCmp and ThumbnailCmp across the codebase are consistent with the type definition. The components are properly used in widget configurations and UI components, maintaining type safety with SVG props.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for implementations of IconCmp and ThumbnailCmp to ensure they're compatible with the new signatures
rg -t typescript -t javascript "IconCmp.*=.*props.*=>" 
rg -t typescript -t javascript "ThumbnailCmp.*=.*props.*=>"

Length of output: 188


Script:

#!/bin/bash
# Search for implementations using ripgrep with correct file type flags
rg --type-add 'ts:*.{ts,tsx}' --type-add 'js:*.{js,jsx}' -t ts -t js "IconCmp.*=.*props.*=>" 
rg --type-add 'ts:*.{ts,tsx}' --type-add 'js:*.{js,jsx}' -t ts -t js "ThumbnailCmp.*=.*props.*=>"

# Search for any usage of these components
rg --type-add 'ts:*.{ts,tsx}' --type-add 'js:*.{js,jsx}' -t ts -t js "IconCmp" -A 2
rg --type-add 'ts:*.{ts,tsx}' --type-add 'js:*.{js,jsx}' -t ts -t js "ThumbnailCmp" -A 2

Length of output: 21988

app/client/src/widgets/BaseWidget.tsx (2)

21-21: LGTM: Clean import addition

The addition of SVGProps to React imports is appropriate for the SVG component typing requirements.


590-591: LGTM: Type-safe SVG component props

The updated signatures for IconCmp and ThumbnailCmp properly type SVG component props, improving type safety.

Let's verify that all implementations of these components are updated to handle the SVG props:

✅ Verification successful

LGTM: SVG component props are correctly implemented

All implementations of IconCmp and ThumbnailCmp are correctly used as SVG components across the codebase. The components are consistently used in:

  • Widget method configurations (methodsConfig.ts files)
  • Widget class implementations (index.tsx files)
  • UI components that render these icons (WidgetCard, WidgetEntity, AnvilDragPreview)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for IconCmp and ThumbnailCmp implementations
rg -l "IconCmp.*=|ThumbnailCmp.*=" --type ts --type tsx

Length of output: 85


Script:

#!/bin/bash
# Search for IconCmp and ThumbnailCmp implementations with correct file type
rg -l "IconCmp.*=|ThumbnailCmp.*=" -t typescript -t javascriptreact -t typescriptreact

# Also search for any usage of these props
rg "IconCmp|ThumbnailCmp" -t typescript -t javascriptreact -t typescriptreact -A 2

Length of output: 243


Script:

#!/bin/bash
# Search for IconCmp and ThumbnailCmp implementations using basic grep
rg "IconCmp|ThumbnailCmp" --type-add 'ts:*.{ts,tsx}' -t ts -C 2

# Also search in the widget directory specifically
cd app/client/src/widgets && rg "IconCmp|ThumbnailCmp" --type-add 'ts:*.{ts,tsx}' -t ts -C 2

Length of output: 24236

app/client/packages/icons/src/utils/generateComponents.ts (3)

5-5: Import '@svgr/core' added correctly


27-29: 'CustomIcons' case handled appropriately


34-43: ⚠️ Potential issue

Fix incorrect use of 'await' with callbacks in 'fs.writeFile'

Using await with fs.writeFile while also providing a callback function can lead to unexpected behavior. Since fs-extra supports Promises, you can omit the callback and use await properly.

Apply this diff to fix the issue:

  await fs.writeFile(
    `./src/components/${dir}/${name}.tsx`,
    await transform(
      file,
      {
        plugins: ["@svgr/plugin-jsx"],
        typescript: true,
        exportType: "named",
        namedExport: name,
      },
      { componentName: name },
    ),
    "utf8"
-   function (err) {
-     // eslint-disable-next-line no-console
-     if (err) return console.error(err);
-   },
  );

Likely invalid or redundant comment.

Comment on lines +11 to +17
export const Icons = () => {
return (
<Flex gap="spacing-4" wrap="wrap">
<AIAvatarCustomIcon />
</Flex>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider enhancing the Icons showcase component.

The current implementation shows only one icon. If this is meant to be a showcase of custom icons, consider:

  1. Adding more custom icons as they become available
  2. Including examples with different sizes/colors

Here's a suggested enhancement:

 export const Icons = () => {
   return (
-    <Flex gap="spacing-4" wrap="wrap">
-      <AIAvatarCustomIcon />
+    <Flex direction="column" gap="spacing-6">
+      <Flex gap="spacing-4" wrap="wrap">
+        <AIAvatarCustomIcon />
+      </Flex>
+      <Flex gap="spacing-4" wrap="wrap">
+        <AIAvatarCustomIcon size={16} />
+        <AIAvatarCustomIcon size={24} />
+        <AIAvatarCustomIcon size={32} />
+      </Flex>
     </Flex>
   );
 };
📝 Committable suggestion

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

Suggested change
export const Icons = () => {
return (
<Flex gap="spacing-4" wrap="wrap">
<AIAvatarCustomIcon />
</Flex>
);
};
export const Icons = () => {
return (
<Flex direction="column" gap="spacing-6">
<Flex gap="spacing-4" wrap="wrap">
<AIAvatarCustomIcon />
</Flex>
<Flex gap="spacing-4" wrap="wrap">
<AIAvatarCustomIcon size={16} />
<AIAvatarCustomIcon size={24} />
<AIAvatarCustomIcon size={32} />
</Flex>
</Flex>
);
};

Comment on lines 3 to 12
async function cleanup() {
await fs.emptyDirSync("./src/icons/Icons");
await fs.emptyDirSync("./src/icons/Thumbnails");
await fs.emptyDirSync("./src/icons/CustomIcons");
await fs.emptyDirSync("./src/components/Icons");
await fs.emptyDirSync("./src/components/Thumbnails");
await fs.emptyDirSync("./src/components/CustomIcons");
await fs.emptyDirSync("./src/stories");
await fs.writeFile(`./src/index.ts`, "");
}
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 28, 2024

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider improving error handling and async operations.

  1. emptyDirSync is synchronous, so await is unnecessary
  2. Add try-catch for better error handling

Consider this implementation:

-async function cleanup() {
+function cleanup() {
+  try {
-  await fs.emptyDirSync("./src/icons/Icons");
-  await fs.emptyDirSync("./src/icons/Thumbnails");
-  await fs.emptyDirSync("./src/icons/CustomIcons");
-  await fs.emptyDirSync("./src/components/Icons");
-  await fs.emptyDirSync("./src/components/Thumbnails");
-  await fs.emptyDirSync("./src/components/CustomIcons");
-  await fs.emptyDirSync("./src/stories");
-  await fs.writeFile(`./src/index.ts`, "");
+    fs.emptyDirSync("./src/icons/Icons");
+    fs.emptyDirSync("./src/icons/Thumbnails");
+    fs.emptyDirSync("./src/icons/CustomIcons");
+    fs.emptyDirSync("./src/components/Icons");
+    fs.emptyDirSync("./src/components/Thumbnails");
+    fs.emptyDirSync("./src/components/CustomIcons");
+    fs.emptyDirSync("./src/stories");
+    fs.writeFileSync("./src/index.ts", "");
+  } catch (error) {
+    console.error("Failed to cleanup directories:", error);
+    process.exit(1);
+  }
}
📝 Committable suggestion

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

Suggested change
async function cleanup() {
await fs.emptyDirSync("./src/icons/Icons");
await fs.emptyDirSync("./src/icons/Thumbnails");
await fs.emptyDirSync("./src/icons/CustomIcons");
await fs.emptyDirSync("./src/components/Icons");
await fs.emptyDirSync("./src/components/Thumbnails");
await fs.emptyDirSync("./src/components/CustomIcons");
await fs.emptyDirSync("./src/stories");
await fs.writeFile(`./src/index.ts`, "");
}
function cleanup() {
try {
fs.emptyDirSync("./src/icons/Icons");
fs.emptyDirSync("./src/icons/Thumbnails");
fs.emptyDirSync("./src/icons/CustomIcons");
fs.emptyDirSync("./src/components/Icons");
fs.emptyDirSync("./src/components/Thumbnails");
fs.emptyDirSync("./src/components/CustomIcons");
fs.emptyDirSync("./src/stories");
fs.writeFileSync("./src/index.ts", "");
} catch (error) {
console.error("Failed to cleanup directories:", error);
process.exit(1);
}
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Replaced it with an async function.

Copy link
Contributor

Choose a reason for hiding this comment

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

@KelvinOm, understood.

(;_;)

export const SwitchThumbnail = () => <svg xmlns="http://www.w3.org/2000/svg" width="72" height="76" fill="none"><rect width="22" height="8" x="14" y="34" fill="#CDD5DF" rx="1"/><rect width="17" height="11" x="40.5" y="32.5" fill="#FFBFA1" stroke="#CC3D00" rx="5.5"/><circle cx="52" cy="38" r="5.5" fill="#fff" stroke="#CC3D00"/></svg>;
import * as React from "react";
import type { SVGProps } from "react";
const SwitchThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={22} height={8} x={14} y={34} fill="#CDD5DF" rx={1} /><rect width={17} height={11} x={40.5} y={32.5} fill="#FFBFA1" stroke="#CC3D00" rx={5.5} /><circle cx={52} cy={38} r={5.5} fill="#fff" stroke="#CC3D00" /></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider making the SVG dimensions configurable.

The hardcoded width and height might limit component reusability. Consider using props with default values.

-const SwitchThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+const SwitchThumbnail = ({ width = 72, height = 76, ...props }: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fill="none" {...props}>
📝 Committable suggestion

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

Suggested change
const SwitchThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={22} height={8} x={14} y={34} fill="#CDD5DF" rx={1} /><rect width={17} height={11} x={40.5} y={32.5} fill="#FFBFA1" stroke="#CC3D00" rx={5.5} /><circle cx={52} cy={38} r={5.5} fill="#fff" stroke="#CC3D00" /></svg>;
const SwitchThumbnail = ({ width = 72, height = 76, ...props }: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fill="none" {...props}><rect width={22} height={8} x={14} y={34} fill="#CDD5DF" rx={1} /><rect width={17} height={11} x={40.5} y={32.5} fill="#FFBFA1" stroke="#CC3D00" rx={5.5} /><circle cx={52} cy={38} r={5.5} fill="#fff" stroke="#CC3D00" /></svg>;

export const ParagraphIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path stroke="#000" stroke-linecap="round" stroke-linejoin="round" d="M1.5 1.5h1m0 0h2a1 1 0 0 1 1 1v0a1 1 0 0 1-1 1h-2m0-2v2m1 2h-2 1v-2"/><path stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".5" d="M7.5 1.5h6M7.5 3.5h6M7.5 5.5h6M1.5 7.5h12M1.5 9.5h12M1.5 11.5h12M1.5 13.5h7"/></svg>;
import * as React from "react";
import type { SVGProps } from "react";
const ParagraphIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M1.5 1.5h1m0 0h2a1 1 0 0 1 1 1v0a1 1 0 0 1-1 1h-2m0-2v2m1 2h-2 1v-2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.5} d="M7.5 1.5h6M7.5 3.5h6M7.5 5.5h6M1.5 7.5h12M1.5 9.5h12M1.5 11.5h12M1.5 13.5h7" /></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider extracting SVG path data to constants.

While the implementation is correct, having the SVG path data inline makes the component less maintainable.

Consider applying this refactor:

+const MAIN_PATH = "M1.5 1.5h1m0 0h2a1 1 0 0 1 1 1v0a1 1 0 0 1-1 1h-2m0-2v2m1 2h-2 1v-2";
+const SECONDARY_PATH = "M7.5 1.5h6M7.5 3.5h6M7.5 5.5h6M1.5 7.5h12M1.5 9.5h12M1.5 11.5h12M1.5 13.5h7";

const ParagraphIcon = (props: SVGProps<SVGSVGElement>) => (
  <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
-   <path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M1.5 1.5h1m0 0h2a1 1 0 0 1 1 1v0a1 1 0 0 1-1 1h-2m0-2v2m1 2h-2 1v-2" />
-   <path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.5} d="M7.5 1.5h6M7.5 3.5h6M7.5 5.5h6M1.5 7.5h12M1.5 9.5h12M1.5 11.5h12M1.5 13.5h7" />
+   <path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d={MAIN_PATH} />
+   <path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.5} d={SECONDARY_PATH} />
  </svg>
);
📝 Committable suggestion

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

Suggested change
const ParagraphIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M1.5 1.5h1m0 0h2a1 1 0 0 1 1 1v0a1 1 0 0 1-1 1h-2m0-2v2m1 2h-2 1v-2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.5} d="M7.5 1.5h6M7.5 3.5h6M7.5 5.5h6M1.5 7.5h12M1.5 9.5h12M1.5 11.5h12M1.5 13.5h7" /></svg>;
const MAIN_PATH = "M1.5 1.5h1m0 0h2a1 1 0 0 1 1 1v0a1 1 0 0 1-1 1h-2m0-2v2m1 2h-2 1v-2";
const SECONDARY_PATH = "M7.5 1.5h6M7.5 3.5h6M7.5 5.5h6M1.5 7.5h12M1.5 9.5h12M1.5 11.5h12M1.5 13.5h7";
const ParagraphIcon = (props: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
<path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d={MAIN_PATH} />
<path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.5} d={SECONDARY_PATH} />
</svg>
);

export const ComboboxSelectThumbnail = () => <svg xmlns="http://www.w3.org/2000/svg" width="72" height="76" fill="none"><rect width="55" height="23" x="8.5" y="26.5" fill="#fff" stroke="#CDD5DF" rx="2.5"/><path stroke="#6A7585" stroke-linecap="round" stroke-linejoin="round" d="m56.5 36.5-3 3-3-3"/><circle cx="19" cy="37" r="4.5" stroke="#CC3D00"/><path stroke="#CC3D00" stroke-linecap="round" d="m22.5 40.5 2 2"/></svg>;
import * as React from "react";
import type { SVGProps } from "react";
const ComboboxSelectThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} /><path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" d="m56.5 36.5-3 3-3-3" /><circle cx={19} cy={37} r={4.5} stroke="#CC3D00" /><path stroke="#CC3D00" strokeLinecap="round" d="m22.5 40.5 2 2" /></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider making the SVG dimensions configurable.

The hardcoded width and height might limit reusability. Consider making them configurable while maintaining aspect ratio.

-const ComboboxSelectThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+const ComboboxSelectThumbnail = ({ width = 72, height = 76, ...props }: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fill="none" viewBox="0 0 72 76" {...props}>
📝 Committable suggestion

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

Suggested change
const ComboboxSelectThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} /><path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" d="m56.5 36.5-3 3-3-3" /><circle cx={19} cy={37} r={4.5} stroke="#CC3D00" /><path stroke="#CC3D00" strokeLinecap="round" d="m22.5 40.5 2 2" /></svg>;
const ComboboxSelectThumbnail = ({ width = 72, height = 76, ...props }: SVGProps<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fill="none" viewBox="0 0 72 76" {...props}><rect width={55} height={23} x={8.5} y={26.5} fill="#fff" stroke="#CDD5DF" rx={2.5} /><path stroke="#6A7585" strokeLinecap="round" strokeLinejoin="round" d="m56.5 36.5-3 3-3-3" /><circle cx={19} cy={37} r={4.5} stroke="#CC3D00" /><path stroke="#CC3D00" strokeLinecap="round" d="m22.5 40.5 2 2" /></svg>
);

@@ -0,0 +1,4 @@
import * as React from "react";
import type { SVGProps } from "react";
const AIAvatarCustomIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} fill="none" {...props}><rect width={23} height={23} x={0.5} y={0.5} fill="#FFF7F4" rx={1.5} /><rect width={23} height={23} x={0.5} y={0.5} stroke="#FFE9E0" rx={1.5} /><path fill="#FF6D2D" d="M4.5 11a2 2 0 1 0 0 4v-4M19.5 11a2 2 0 1 1 0 4v-4" /><rect width={15} height={10} x={4.5} y={8} fill="#fff" stroke="#000" strokeMiterlimit={10} strokeWidth={0.149} rx={3} /><rect width={12} height={7} x={6} y={9.5} fill="#fff" stroke="#000" strokeMiterlimit={10} strokeWidth={0.5} rx={1.5} /><circle cx={9} cy={12} r={1} fill="#000" /><circle cx={15} cy={12} r={1} fill="#000" /><path fill="#000" d="M11.5 5.5h1V8h-1z" /><circle cx={12} cy={4.5} r={1.5} fill="#fff" stroke="#000" strokeMiterlimit={10} strokeWidth={0.149} /><path stroke="#000" strokeLinecap="round" strokeWidth={0.5} d="m10 14 .209.232A2.426 2.426 0 0 0 14 14v0" /></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve SVG readability and accessibility.

The current implementation could benefit from better formatting and accessibility support.

Consider applying these improvements:

-const AIAvatarCustomIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} fill="none" {...props}><rect width={23} height={23} x={0.5} y={0.5} fill="#FFF7F4" rx={1.5} /><rect width={23} height={23} x={0.5} y={0.5} stroke="#FFE9E0" rx={1.5} /><path fill="#FF6D2D" d="M4.5 11a2 2 0 1 0 0 4v-4M19.5 11a2 2 0 1 1 0 4v-4" /><rect width={15} height={10} x={4.5} y={8} fill="#fff" stroke="#000" strokeMiterlimit={10} strokeWidth={0.149} rx={3} /><rect width={12} height={7} x={6} y={9.5} fill="#fff" stroke="#000" strokeMiterlimit={10} strokeWidth={0.5} rx={1.5} /><circle cx={9} cy={12} r={1} fill="#000" /><circle cx={15} cy={12} r={1} fill="#000" /><path fill="#000" d="M11.5 5.5h1V8h-1z" /><circle cx={12} cy={4.5} r={1.5} fill="#fff" stroke="#000" strokeMiterlimit={10} strokeWidth={0.149} /><path stroke="#000" strokeLinecap="round" strokeWidth={0.5} d="m10 14 .209.232A2.426 2.426 0 0 0 14 14v0" /></svg>;
+const AIAvatarCustomIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={24}
+    height={24}
+    viewBox="0 0 24 24"
+    fill="none"
+    aria-label="AI Avatar"
+    role="img"
+    {...props}
+  >
+    <rect width={23} height={23} x={0.5} y={0.5} fill="#FFF7F4" rx={1.5} />
+    <rect width={23} height={23} x={0.5} y={0.5} stroke="#FFE9E0" rx={1.5} />
+    <path fill="#FF6D2D" d="M4.5 11a2 2 0 1 0 0 4v-4M19.5 11a2 2 0 1 1 0 4v-4" />
+    <rect
+      width={15}
+      height={10}
+      x={4.5}
+      y={8}
+      fill="#fff"
+      stroke="#000"
+      strokeMiterlimit={10}
+      strokeWidth={0.149}
+      rx={3}
+    />
+    <rect
+      width={12}
+      height={7}
+      x={6}
+      y={9.5}
+      fill="#fff"
+      stroke="#000"
+      strokeMiterlimit={10}
+      strokeWidth={0.5}
+      rx={1.5}
+    />
+    <circle cx={9} cy={12} r={1} fill="#000" />
+    <circle cx={15} cy={12} r={1} fill="#000" />
+    <path fill="#000" d="M11.5 5.5h1V8h-1z" />
+    <circle
+      cx={12}
+      cy={4.5}
+      r={1.5}
+      fill="#fff"
+      stroke="#000"
+      strokeMiterlimit={10}
+      strokeWidth={0.149}
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeWidth={0.5}
+      d="m10 14 .209.232A2.426 2.426 0 0 0 14 14v0"
+    />
+  </svg>
+);
📝 Committable suggestion

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

Suggested change
const AIAvatarCustomIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={24} height={24} fill="none" {...props}><rect width={23} height={23} x={0.5} y={0.5} fill="#FFF7F4" rx={1.5} /><rect width={23} height={23} x={0.5} y={0.5} stroke="#FFE9E0" rx={1.5} /><path fill="#FF6D2D" d="M4.5 11a2 2 0 1 0 0 4v-4M19.5 11a2 2 0 1 1 0 4v-4" /><rect width={15} height={10} x={4.5} y={8} fill="#fff" stroke="#000" strokeMiterlimit={10} strokeWidth={0.149} rx={3} /><rect width={12} height={7} x={6} y={9.5} fill="#fff" stroke="#000" strokeMiterlimit={10} strokeWidth={0.5} rx={1.5} /><circle cx={9} cy={12} r={1} fill="#000" /><circle cx={15} cy={12} r={1} fill="#000" /><path fill="#000" d="M11.5 5.5h1V8h-1z" /><circle cx={12} cy={4.5} r={1.5} fill="#fff" stroke="#000" strokeMiterlimit={10} strokeWidth={0.149} /><path stroke="#000" strokeLinecap="round" strokeWidth={0.5} d="m10 14 .209.232A2.426 2.426 0 0 0 14 14v0" /></svg>;
const AIAvatarCustomIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
aria-label="AI Avatar"
role="img"
{...props}
>
<rect width={23} height={23} x={0.5} y={0.5} fill="#FFF7F4" rx={1.5} />
<rect width={23} height={23} x={0.5} y={0.5} stroke="#FFE9E0" rx={1.5} />
<path fill="#FF6D2D" d="M4.5 11a2 2 0 1 0 0 4v-4M19.5 11a2 2 0 1 1 0 4v-4" />
<rect
width={15}
height={10}
x={4.5}
y={8}
fill="#fff"
stroke="#000"
strokeMiterlimit={10}
strokeWidth={0.149}
rx={3}
/>
<rect
width={12}
height={7}
x={6}
y={9.5}
fill="#fff"
stroke="#000"
strokeMiterlimit={10}
strokeWidth={0.5}
rx={1.5}
/>
<circle cx={9} cy={12} r={1} fill="#000" />
<circle cx={15} cy={12} r={1} fill="#000" />
<path fill="#000" d="M11.5 5.5h1V8h-1z" />
<circle
cx={12}
cy={4.5}
r={1.5}
fill="#fff"
stroke="#000"
strokeMiterlimit={10}
strokeWidth={0.149}
/>
<path
stroke="#000"
strokeLinecap="round"
strokeWidth={0.5}
d="m10 14 .209.232A2.426 2.426 0 0 0 14 14v0"
/>
</svg>
);

export const AIChatThumbnail = () => <svg xmlns="http://www.w3.org/2000/svg" width="72" height="76" fill="none"><mask id="a" fill="#fff"><path fill-rule="evenodd" d="M40 21a3 3 0 0 1 3 3v18a3 3 0 0 1-3 3H21l-7.257 8.063c-.613.681-1.743.247-1.743-.669V45H9a3 3 0 0 1-3-3V24a3 3 0 0 1 3-3z" clip-rule="evenodd"/></mask><path fill="#fff" fill-rule="evenodd" d="M40 21a3 3 0 0 1 3 3v18a3 3 0 0 1-3 3H21l-7.257 8.063c-.613.681-1.743.247-1.743-.669V45H9a3 3 0 0 1-3-3V24a3 3 0 0 1 3-3z" clip-rule="evenodd"/><path fill="#CDD5DF" d="m21 45-.743-.669.298-.331H21zm-7.257 8.063.744.669zM12 45v-1h1v1zm30-21a2 2 0 0 0-2-2v-2a4 4 0 0 1 4 4zm0 18V24h2v18zm-2 2a2 2 0 0 0 2-2h2a4 4 0 0 1-4 4zm-19 0h19v2H21zm-8 8.394 7.257-8.063 1.486 1.338-7.256 8.063zm0 0 1.487 1.338C13.26 55.094 11 54.227 11 52.394zM13 45v7.394h-2V45zm-4-1h3v2H9zm-2-2a2 2 0 0 0 2 2v2a4 4 0 0 1-4-4zm0-18v18H5V24zm2-2a2 2 0 0 0-2 2H5a4 4 0 0 1 4-4zm31 0H9v-2h31z" mask="url(#a)"/><mask id="b" fill="#fff"><path fill-rule="evenodd" d="M32 29a3 3 0 0 0-3 3v18a3 3 0 0 0 3 3h19l7.257 8.063c.613.681 1.743.247 1.743-.669V53h3a3 3 0 0 0 3-3V32a3 3 0 0 0-3-3z" clip-rule="evenodd"/></mask><path fill="#FFBFA1" fill-rule="evenodd" d="M32 29a3 3 0 0 0-3 3v18a3 3 0 0 0 3 3h19l7.257 8.063c.613.681 1.743.247 1.743-.669V53h3a3 3 0 0 0 3-3V32a3 3 0 0 0-3-3z" clip-rule="evenodd"/><path fill="#CC3D00" d="m51 53 .743-.669-.298-.331H51zm7.257 8.063-.744.669zM60 53v-1h-1v1zM30 32a2 2 0 0 1 2-2v-2a4 4 0 0 0-4 4zm0 18V32h-2v18zm2 2a2 2 0 0 1-2-2h-2a4 4 0 0 0 4 4zm19 0H32v2h19zm8 8.394-7.257-8.063-1.486 1.338 7.256 8.063zm0 0-1.487 1.338C58.74 63.094 61 62.227 61 60.394zM59 53v7.394h2V53zm4-1h-3v2h3zm2-2a2 2 0 0 1-2 2v2a4 4 0 0 0 4-4zm0-18v18h2V32zm-2-2a2 2 0 0 1 2 2h2a4 4 0 0 0-4-4zm-31 0h31v-2H32z" mask="url(#b)"/><path fill="#fff" stroke="#CC3D00" d="M41.434 42.657a8.5 8.5 0 0 0 4.223-4.223 8.5 8.5 0 0 0 4.223 4.223 8.5 8.5 0 0 0-4.223 4.223 8.5 8.5 0 0 0-4.223-4.223ZM51.17 34.263l.073-.145.072.145a6.5 6.5 0 0 0 2.907 2.907l.145.073-.145.072a6.5 6.5 0 0 0-2.907 2.907l-.072.145-.073-.145a6.5 6.5 0 0 0-2.907-2.907l-.145-.072.145-.073a6.5 6.5 0 0 0 2.907-2.907Z"/></svg>;
import * as React from "react";
import type { SVGProps } from "react";
const AIChatThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><mask id="a" fill="#fff"><path fillRule="evenodd" d="M40 21a3 3 0 0 1 3 3v18a3 3 0 0 1-3 3H21l-7.257 8.063c-.613.681-1.743.247-1.743-.669V45H9a3 3 0 0 1-3-3V24a3 3 0 0 1 3-3z" clipRule="evenodd" /></mask><path fill="#fff" fillRule="evenodd" d="M40 21a3 3 0 0 1 3 3v18a3 3 0 0 1-3 3H21l-7.257 8.063c-.613.681-1.743.247-1.743-.669V45H9a3 3 0 0 1-3-3V24a3 3 0 0 1 3-3z" clipRule="evenodd" /><path fill="#CDD5DF" d="m21 45-.743-.669.298-.331H21zm-7.257 8.063.744.669zM12 45v-1h1v1zm30-21a2 2 0 0 0-2-2v-2a4 4 0 0 1 4 4zm0 18V24h2v18zm-2 2a2 2 0 0 0 2-2h2a4 4 0 0 1-4 4zm-19 0h19v2H21zm-8 8.394 7.257-8.063 1.486 1.338-7.256 8.063zm0 0 1.487 1.338C13.26 55.094 11 54.227 11 52.394zM13 45v7.394h-2V45zm-4-1h3v2H9zm-2-2a2 2 0 0 0 2 2v2a4 4 0 0 1-4-4zm0-18v18H5V24zm2-2a2 2 0 0 0-2 2H5a4 4 0 0 1 4-4zm31 0H9v-2h31z" mask="url(#a)" /><mask id="b" fill="#fff"><path fillRule="evenodd" d="M32 29a3 3 0 0 0-3 3v18a3 3 0 0 0 3 3h19l7.257 8.063c.613.681 1.743.247 1.743-.669V53h3a3 3 0 0 0 3-3V32a3 3 0 0 0-3-3z" clipRule="evenodd" /></mask><path fill="#FFBFA1" fillRule="evenodd" d="M32 29a3 3 0 0 0-3 3v18a3 3 0 0 0 3 3h19l7.257 8.063c.613.681 1.743.247 1.743-.669V53h3a3 3 0 0 0 3-3V32a3 3 0 0 0-3-3z" clipRule="evenodd" /><path fill="#CC3D00" d="m51 53 .743-.669-.298-.331H51zm7.257 8.063-.744.669zM60 53v-1h-1v1zM30 32a2 2 0 0 1 2-2v-2a4 4 0 0 0-4 4zm0 18V32h-2v18zm2 2a2 2 0 0 1-2-2h-2a4 4 0 0 0 4 4zm19 0H32v2h19zm8 8.394-7.257-8.063-1.486 1.338 7.256 8.063zm0 0-1.487 1.338C58.74 63.094 61 62.227 61 60.394zM59 53v7.394h2V53zm4-1h-3v2h3zm2-2a2 2 0 0 1-2 2v2a4 4 0 0 0 4-4zm0-18v18h2V32zm-2-2a2 2 0 0 1 2 2h2a4 4 0 0 0-4-4zm-31 0h31v-2H32z" mask="url(#b)" /><path fill="#fff" stroke="#CC3D00" d="M41.434 43.657a8.5 8.5 0 0 0 4.223-4.223 8.5 8.5 0 0 0 4.223 4.223 8.5 8.5 0 0 0-4.223 4.223 8.5 8.5 0 0 0-4.223-4.223ZM51.17 35.263l.073-.145.072.145a6.5 6.5 0 0 0 2.907 2.907l.145.073-.145.072a6.5 6.5 0 0 0-2.907 2.907l-.072.145-.073-.145a6.5 6.5 0 0 0-2.907-2.907l-.145-.072.145-.073a6.5 6.5 0 0 0 2.907-2.907Z" /></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding type safety for required SVG attributes.

The implementation looks good, but we could enhance type safety for the width and height attributes.

-const AIChatThumbnail = (props: SVGProps<SVGSVGElement>) =>
+const AIChatThumbnail = ({ width = 72, height = 76, ...props }: SVGProps<SVGSVGElement>) =>
-<svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+<svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fill="none" {...props}>
📝 Committable suggestion

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

Suggested change
const AIChatThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><mask id="a" fill="#fff"><path fillRule="evenodd" d="M40 21a3 3 0 0 1 3 3v18a3 3 0 0 1-3 3H21l-7.257 8.063c-.613.681-1.743.247-1.743-.669V45H9a3 3 0 0 1-3-3V24a3 3 0 0 1 3-3z" clipRule="evenodd" /></mask><path fill="#fff" fillRule="evenodd" d="M40 21a3 3 0 0 1 3 3v18a3 3 0 0 1-3 3H21l-7.257 8.063c-.613.681-1.743.247-1.743-.669V45H9a3 3 0 0 1-3-3V24a3 3 0 0 1 3-3z" clipRule="evenodd" /><path fill="#CDD5DF" d="m21 45-.743-.669.298-.331H21zm-7.257 8.063.744.669zM12 45v-1h1v1zm30-21a2 2 0 0 0-2-2v-2a4 4 0 0 1 4 4zm0 18V24h2v18zm-2 2a2 2 0 0 0 2-2h2a4 4 0 0 1-4 4zm-19 0h19v2H21zm-8 8.394 7.257-8.063 1.486 1.338-7.256 8.063zm0 0 1.487 1.338C13.26 55.094 11 54.227 11 52.394zM13 45v7.394h-2V45zm-4-1h3v2H9zm-2-2a2 2 0 0 0 2 2v2a4 4 0 0 1-4-4zm0-18v18H5V24zm2-2a2 2 0 0 0-2 2H5a4 4 0 0 1 4-4zm31 0H9v-2h31z" mask="url(#a)" /><mask id="b" fill="#fff"><path fillRule="evenodd" d="M32 29a3 3 0 0 0-3 3v18a3 3 0 0 0 3 3h19l7.257 8.063c.613.681 1.743.247 1.743-.669V53h3a3 3 0 0 0 3-3V32a3 3 0 0 0-3-3z" clipRule="evenodd" /></mask><path fill="#FFBFA1" fillRule="evenodd" d="M32 29a3 3 0 0 0-3 3v18a3 3 0 0 0 3 3h19l7.257 8.063c.613.681 1.743.247 1.743-.669V53h3a3 3 0 0 0 3-3V32a3 3 0 0 0-3-3z" clipRule="evenodd" /><path fill="#CC3D00" d="m51 53 .743-.669-.298-.331H51zm7.257 8.063-.744.669zM60 53v-1h-1v1zM30 32a2 2 0 0 1 2-2v-2a4 4 0 0 0-4 4zm0 18V32h-2v18zm2 2a2 2 0 0 1-2-2h-2a4 4 0 0 0 4 4zm19 0H32v2h19zm8 8.394-7.257-8.063-1.486 1.338 7.256 8.063zm0 0-1.487 1.338C58.74 63.094 61 62.227 61 60.394zM59 53v7.394h2V53zm4-1h-3v2h3zm2-2a2 2 0 0 1-2 2v2a4 4 0 0 0 4-4zm0-18v18h2V32zm-2-2a2 2 0 0 1 2 2h2a4 4 0 0 0-4-4zm-31 0h31v-2H32z" mask="url(#b)" /><path fill="#fff" stroke="#CC3D00" d="M41.434 43.657a8.5 8.5 0 0 0 4.223-4.223 8.5 8.5 0 0 0 4.223 4.223 8.5 8.5 0 0 0-4.223 4.223 8.5 8.5 0 0 0-4.223-4.223ZM51.17 35.263l.073-.145.072.145a6.5 6.5 0 0 0 2.907 2.907l.145.073-.145.072a6.5 6.5 0 0 0-2.907 2.907l-.072.145-.073-.145a6.5 6.5 0 0 0-2.907-2.907l-.145-.072.145-.073a6.5 6.5 0 0 0 2.907-2.907Z" /></svg>;
const AIChatThumbnail = ({ width = 72, height = 76, ...props }: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fill="none" {...props}><mask id="a" fill="#fff"><path fillRule="evenodd" d="M40 21a3 3 0 0 1 3 3v18a3 3 0 0 1-3 3H21l-7.257 8.063c-.613.681-1.743.247-1.743-.669V45H9a3 3 0 0 1-3-3V24a3 3 0 0 1 3-3z" clipRule="evenodd" /></mask><path fill="#fff" fillRule="evenodd" d="M40 21a3 3 0 0 1 3 3v18a3 3 0 0 1-3 3H21l-7.257 8.063c-.613.681-1.743.247-1.743-.669V45H9a3 3 0 0 1-3-3V24a3 3 0 0 1 3-3z" clipRule="evenodd" /><path fill="#CDD5DF" d="m21 45-.743-.669.298-.331H21zm-7.257 8.063.744.669zM12 45v-1h1v1zm30-21a2 2 0 0 0-2-2v-2a4 4 0 0 1 4 4zm0 18V24h2v18zm-2 2a2 2 0 0 0 2-2h2a4 4 0 0 1-4 4zm-19 0h19v2H21zm-8 8.394 7.257-8.063 1.486 1.338-7.256 8.063zm0 0 1.487 1.338C13.26 55.094 11 54.227 11 52.394zM13 45v7.394h-2V45zm-4-1h3v2H9zm-2-2a2 2 0 0 0 2 2v2a4 4 0 0 1-4-4zm0-18v18H5V24zm2-2a2 2 0 0 0-2 2H5a4 4 0 0 1 4-4zm31 0H9v-2h31z" mask="url(#a)" /><mask id="b" fill="#fff"><path fillRule="evenodd" d="M32 29a3 3 0 0 0-3 3v18a3 3 0 0 0 3 3h19l7.257 8.063c.613.681 1.743.247 1.743-.669V53h3a3 3 0 0 0 3-3V32a3 3 0 0 0-3-3z" clipRule="evenodd" /></mask><path fill="#FFBFA1" fillRule="evenodd" d="M32 29a3 3 0 0 0-3 3v18a3 3 0 0 0 3 3h19l7.257 8.063c.613.681 1.743.247 1.743-.669V53h3a3 3 0 0 0 3-3V32a3 3 0 0 0-3-3z" clipRule="evenodd" /><path fill="#CC3D00" d="m51 53 .743-.669-.298-.331H51zm7.257 8.063-.744.669zM60 53v-1h-1v1zM30 32a2 2 0 0 1 2-2v-2a4 4 0 0 0-4 4zm0 18V32h-2v18zm2 2a2 2 0 0 1-2-2h-2a4 4 0 0 0 4 4zm19 0H32v2h19zm8 8.394-7.257-8.063-1.486 1.338 7.256 8.063zm0 0-1.487 1.338C58.74 63.094 61 62.227 61 60.394zM59 53v7.394h2V53zm4-1h-3v2h3zm2-2a2 2 0 0 1-2 2v2a4 4 0 0 0 4-4zm0-18v18h2V32zm-2-2a2 2 0 0 1 2 2h2a4 4 0 0 0-4-4zm-31 0h31v-2H32z" mask="url(#b)" /><path fill="#fff" stroke="#CC3D00" d="M41.434 43.657a8.5 8.5 0 0 0 4.223-4.223 8.5 8.5 0 0 0 4.223 4.223 8.5 8.5 0 0 0-4.223 4.223 8.5 8.5 0 0 0-4.223-4.223ZM51.17 35.263l.073-.145.072.145a6.5 6.5 0 0 0 2.907 2.907l.145.073-.145.072a6.5 6.5 0 0 0-2.907 2.907l-.072.145-.073-.145a6.5 6.5 0 0 0-2.907-2.907l-.145-.072.145-.073a6.5 6.5 0 0 0 2.907-2.907Z" /></svg>;

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (18)
app/client/packages/icons/src/components/Icons/CheckboxIcon.tsx (1)

3-3: Add viewBox attribute for better scaling support.

The SVG element is missing the viewBox attribute which could affect scaling behavior in different contexts.

-const CheckboxIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const CheckboxIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 16 16" fill="none" {...props}>
app/client/packages/icons/src/components/Icons/ModalIcon.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the implementation is functionally correct, the inline SVG markup could be more maintainable if formatted across multiple lines.

-const ModalIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M12.5 2.5a1 1 0 0 1 1 1v7a3 3 0 0 1-3 3h-7a1 1 0 0 1-1-1v0" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M10.5.5h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2M7.5 5.5l2-2m0 2-2-2" /></svg>;
+const ModalIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      strokeOpacity={0.25}
+      d="M12.5 2.5a1 1 0 0 1 1 1v7a3 3 0 0 1-3 3h-7a1 1 0 0 1-1-1v0"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M10.5.5h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2M7.5 5.5l2-2m0 2-2-2"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx (1)

3-3: Consider adding documentation for the SVG paths.

While the implementation is correct, adding a brief comment describing what the SVG paths represent would improve maintainability.

+// Icon representing a combobox select dropdown with a circular button and arrow
 const ComboboxSelectIcon = (props: SVGProps<SVGSVGElement>) => <svg
app/client/packages/icons/src/components/Icons/InputIcon.tsx (1)

3-3: Consider formatting the SVG for better readability.

While functionally correct, the SVG markup could be more maintainable if formatted across multiple lines.

-const InputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="m7.5 9.5-.5-1m-3.5 1 .5-1m0 0 1.5-3 1.5 3m-3 0h3" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7" /></svg>;
+const InputIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      d="m7.5 9.5-.5-1m-3.5 1 .5-1m0 0 1.5-3 1.5 3m-3 0h3" 
+    />
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      strokeOpacity={0.25} 
+      d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2" 
+    />
+    <path 
+      stroke="#000" 
+      strokeLinecap="round" 
+      strokeLinejoin="round" 
+      d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7" 
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/IconButtonIcon.tsx (1)

3-3: Consider adding aria-label for better accessibility.

While the SVG implementation is correct, adding an aria-label would improve accessibility for screen readers.

-const IconButtonIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const IconButtonIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" aria-label="button icon" {...props}>
app/client/packages/icons/src/components/Thumbnails/RadioGroupThumbnail.tsx (1)

3-3: Consider formatting the SVG markup for better readability.

While the implementation is correct, the long line could be split for better maintainability.

-const RadioGroupThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><circle cx={22} cy={29} r={6.5} fill="#FFBFA1" stroke="#CC3D00" /><circle cx={22} cy={29} r={3.5} fill="#fff" stroke="#CC3D00" /><rect width={20} height={8} x={34} y={25} fill="#CDD5DF" rx={1} /><rect width={11} height={11} x={16.5} y={41.5} fill="#fff" stroke="#CDD5DF" rx={5.5} /><rect width={22} height={8} x={34} y={43} fill="#CDD5DF" rx={1} /></svg>;
+const RadioGroupThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={72}
+    height={76}
+    fill="none"
+    {...props}
+  >
+    <circle cx={22} cy={29} r={6.5} fill="#FFBFA1" stroke="#CC3D00" />
+    <circle cx={22} cy={29} r={3.5} fill="#fff" stroke="#CC3D00" />
+    <rect width={20} height={8} x={34} y={25} fill="#CDD5DF" rx={1} />
+    <rect
+      width={11}
+      height={11}
+      x={16.5}
+      y={41.5}
+      fill="#fff"
+      stroke="#CDD5DF"
+      rx={5.5}
+    />
+    <rect width={22} height={8} x={34} y={43} fill="#CDD5DF" rx={1} />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/MenuButtonIcon.tsx (1)

3-3: Consider improving readability with multi-line format

While functionally correct, the single-line SVG component could be more maintainable.

Consider reformatting like this:

-const MenuButtonIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M12.5 2.5h-10a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M14.5 8.5v3a2 2 0 0 1-2 2h-10a2 2 0 0 1-2-2v-3" /><path stroke="#000" strokeLinecap="round" d="M5.5 7.5h4M5.5 9.5h4M5.5 5.5h4" /></svg>;
+const MenuButtonIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={16}
+    height={16}
+    fill="none"
+    {...props}
+  >
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M12.5 2.5h-10a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      strokeOpacity={0.25}
+      d="M14.5 8.5v3a2 2 0 0 1-2 2h-10a2 2 0 0 1-2-2v-3"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      d="M5.5 7.5h4M5.5 9.5h4M5.5 5.5h4"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/CheckboxGroupIcon.tsx (1)

3-3: Consider improving SVG readability through formatting.

The implementation is correct, but the line length makes it harder to read.

Consider formatting the SVG for better readability:

-const CheckboxGroupIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M5 6.5H2A1.5 1.5 0 0 1 .5 5V2A1.5 1.5 0 0 1 2 .5h3A1.5 1.5 0 0 1 6.5 2v3A1.5 1.5 0 0 1 5 6.5" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="m2.5 3.5 1 1 1-2M8.5 2.5h6M8.5 12.5h4M5 14.5H2A1.5 1.5 0 0 1 .5 13v-3A1.5 1.5 0 0 1 2 8.5h3A1.5 1.5 0 0 1 6.5 10v3A1.5 1.5 0 0 1 5 14.5M8.5 4.5h4M8.5 10.5h6" /></svg>;
+const CheckboxGroupIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={16}
+    height={16}
+    fill="none"
+    {...props}
+  >
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M5 6.5H2A1.5 1.5 0 0 1 .5 5V2A1.5 1.5 0 0 1 2 .5h3A1.5 1.5 0 0 1 6.5 2v3A1.5 1.5 0 0 1 5 6.5"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="m2.5 3.5 1 1 1-2M8.5 2.5h6M8.5 12.5h4M5 14.5H2A1.5 1.5 0 0 1 .5 13v-3A1.5 1.5 0 0 1 2 8.5h3A1.5 1.5 0 0 1 6.5 10v3A1.5 1.5 0 0 1 5 14.5M8.5 4.5h4M8.5 10.5h6"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/SwitchGroupThumbnail.tsx (1)

3-3: Consider breaking down the SVG markup for better readability

While the implementation is correct, the SVG markup is quite dense on a single line.

-const SwitchGroupThumbnail = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}><rect width={17} height={11} x={40.5} y={23.5} fill="#FFBFA1" stroke="#CC3D00" rx={5.5} /><rect width={17} height={11} x={40.5} y={41.5} fill="#CDD5DF" stroke="#CDD5DF" rx={5.5} /><circle cx={52} cy={29} r={5.5} fill="#fff" stroke="#CC3D00" /><circle cx={46} cy={47} r={5.5} fill="#fff" stroke="#CDD5DF" /><rect width={22} height={8} x={14} y={25} fill="#CDD5DF" rx={1} /><rect width={18} height={8} x={14} y={43} fill="#CDD5DF" rx={1} /></svg>;
+const SwitchGroupThumbnail = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+    <rect width={17} height={11} x={40.5} y={23.5} fill="#FFBFA1" stroke="#CC3D00" rx={5.5} />
+    <rect width={17} height={11} x={40.5} y={41.5} fill="#CDD5DF" stroke="#CDD5DF" rx={5.5} />
+    <circle cx={52} cy={29} r={5.5} fill="#fff" stroke="#CC3D00" />
+    <circle cx={46} cy={47} r={5.5} fill="#fff" stroke="#CDD5DF" />
+    <rect width={22} height={8} x={14} y={25} fill="#CDD5DF" rx={1} />
+    <rect width={18} height={8} x={14} y={43} fill="#CDD5DF" rx={1} />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/ToolbarButtonsIcon.tsx (1)

3-3: Consider adding aria-label for accessibility.

The SVG icon should include an aria-label for screen readers.

-const ToolbarButtonsIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const ToolbarButtonsIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" aria-label="toolbar buttons" role="img" {...props}>
app/client/packages/icons/src/components/Icons/ButtonIcon.tsx (1)

3-3: Consider adding prop types documentation

While the implementation is correct, adding JSDoc comments would improve component documentation and IDE support.

+/** Button icon component that accepts standard SVG properties */
 const ButtonIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
app/client/packages/icons/src/components/Icons/MultilineInputIcon.tsx (1)

3-3: Consider improving SVG readability.

While the implementation is correct, the SVG markup could be more readable by breaking it into multiple lines.

-const MultilineInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="m7.5 7.5-.5-1m-3.5 1 .5-1m0 0 1.5-3 1.5 3m-3 0h3" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M14.5 1.5h-12a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h7" /><path stroke="#000" strokeLinecap="round" d="M3.5 12v-2a.5.5 0 0 1 .5-.5h2a1.5 1.5 0 0 1 0 3H4a.5.5 0 0 1-.5-.5Z" /></svg>;
+const MultilineInputIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="m7.5 7.5-.5-1m-3.5 1 .5-1m0 0 1.5-3 1.5 3m-3 0h3"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      strokeOpacity={0.25}
+      d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M14.5 1.5h-12a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h7"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      d="M3.5 12v-2a.5.5 0 0 1 .5-.5h2a1.5 1.5 0 0 1 0 3H4a.5.5 0 0 1-.5-.5Z"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Icons/RadioGroupIcon.tsx (1)

3-3: Consider breaking down the SVG markup for better readability.

While the implementation is correct, the long line makes it harder to read and maintain.

Consider reformatting like this:

-const RadioGroupIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M8.5 2.5h6M8.5 10.5h6M8.5 4.5h4M8.5 12.5h4" /><circle cx={3.5} cy={11.5} r={3} stroke="#000" strokeLinejoin="round" transform="rotate(-90 3.5 11.5)" /><path fill="#000" fillOpacity={0.1} fillRule="evenodd" d="M6.5 3.5a3 3 0 1 0-6 0 3 3 0 0 0 6 0M5 3.5a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0" clipRule="evenodd" /><circle cx={3.5} cy={3.5} r={3} stroke="#000" strokeLinejoin="round" transform="rotate(-90 3.5 3.5)" /><circle cx={3.5} cy={3.5} r={1} stroke="#000" strokeLinejoin="round" transform="rotate(-90 3.5 3.5)" /></svg>;
+const RadioGroupIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={16}
+    height={16}
+    fill="none"
+    {...props}
+  >
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M8.5 2.5h6M8.5 10.5h6M8.5 4.5h4M8.5 12.5h4"
+    />
+    <circle
+      cx={3.5}
+      cy={11.5}
+      r={3}
+      stroke="#000"
+      strokeLinejoin="round"
+      transform="rotate(-90 3.5 11.5)"
+    />
+    <path
+      fill="#000"
+      fillOpacity={0.1}
+      fillRule="evenodd"
+      d="M6.5 3.5a3 3 0 1 0-6 0 3 3 0 0 0 6 0M5 3.5a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0"
+      clipRule="evenodd"
+    />
+    <circle
+      cx={3.5}
+      cy={3.5}
+      r={3}
+      stroke="#000"
+      strokeLinejoin="round"
+      transform="rotate(-90 3.5 3.5)"
+    />
+    <circle
+      cx={3.5}
+      cy={3.5}
+      r={1}
+      stroke="#000"
+      strokeLinejoin="round"
+      transform="rotate(-90 3.5 3.5)"
+    />
+  </svg>
+);
app/client/packages/icons/src/components/Thumbnails/NumberInputThumbnail.tsx (1)

1-4: Consider adding JSDoc documentation

Adding JSDoc documentation would improve component discoverability and usage understanding.

+/**
+ * Thumbnail component for the Number Input widget
+ * @param props - Standard SVG properties
+ */
 const NumberInputThumbnail = (props: SVGProps<SVGSVGElement>) => <svg
app/client/packages/icons/src/components/Thumbnails/ToolbarButtonsThumbnail.tsx (1)

3-3: Consider extracting SVG dimensions to constants.

While the implementation is correct, consider extracting the hardcoded width/height values (72/76) to named constants for better maintainability.

+const THUMBNAIL_WIDTH = 72;
+const THUMBNAIL_HEIGHT = 76;
 const ToolbarButtonsThumbnail = (props: SVGProps<SVGSVGElement>) => 
-  <svg xmlns="http://www.w3.org/2000/svg" width={72} height={76} fill="none" {...props}>
+  <svg xmlns="http://www.w3.org/2000/svg" width={THUMBNAIL_WIDTH} height={THUMBNAIL_HEIGHT} fill="none" {...props}>
app/client/packages/icons/src/components/Thumbnails/MultilineInputThumbnail.tsx (1)

3-3: Consider adding JSDoc documentation.

The component implementation is correct with proper props typing and SVG attribute handling.

Consider adding JSDoc documentation to describe the component's purpose and props:

+/**
+ * Thumbnail component representing a multiline input visualization.
+ * @param props - Standard SVG properties
+ */
const MultilineInputThumbnail = (props: SVGProps<SVGSVGElement>) => <svg
app/client/packages/icons/src/utils/generateComponents.ts (2)

34-43: Consider extracting SVGR configuration

While the transformation setup is correct, consider extracting the configuration object to a constant for reusability and easier maintenance.

+const svgrConfig = {
+  plugins: ["@svgr/plugin-jsx"],
+  typescript: true,
+  exportType: "named",
+  namedExport: name,
+};

 await fs.writeFile(
   `./src/components/${dir}/${name}.tsx`,
-  await transform(
-    file,
-    {
-      plugins: ["@svgr/plugin-jsx"],
-      typescript: true,
-      exportType: "named",
-      namedExport: name,
-    },
-    { componentName: name },
-  ),
+  await transform(file, svgrConfig, { componentName: name }),

Line range hint 44-48: Enhance error handling for file operations

Consider adding more specific error handling and logging for better debugging.

-function (err) {
-  // eslint-disable-next-line no-console
-  if (err) return console.error(err);
-},
+function (err) {
+  if (err) {
+    console.error(`Failed to write component ${name}:`, err);
+    return;
+  }
+  console.log(`Successfully generated component: ${name}`);
+},
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 54d6817 and 44fd968.

⛔ Files ignored due to path filters (3)
  • app/client/packages/icons/src/icons/CustomIcons/AIAvatar.svg is excluded by !**/*.svg
  • app/client/packages/icons/src/icons/Thumbnails/AIChat.svg is excluded by !**/*.svg
  • app/client/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (71)
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/Datepicker/DatePicker3_spec.ts (1 hunks)
  • app/client/jest.config.js (1 hunks)
  • app/client/package.json (1 hunks)
  • app/client/packages/icons/package.json (1 hunks)
  • app/client/packages/icons/src/components/CustomIcons/AIAvatarCustomIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/AIChatIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ButtonIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/CheckboxGroupIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/CheckboxIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/CurrencyInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/DatePickerIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/EmailInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/HeadingIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/IconButtonIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/InlineButtonsIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/InputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/KeyValueIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/MenuButtonIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ModalIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/MultilineInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/NumberInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ParagraphIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/PasswordInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/PhoneInputIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/RadioGroupIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/SectionIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/StatsBoxIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/SwitchGroupIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/SwitchIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/TableIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ToolbarButtonsIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Icons/ZoneIcon.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/AIChatThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ButtonThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/CheckboxGroupThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/CheckboxThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ComboboxSelectThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/CurrencyInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/DatePickerThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/EmailInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/HeadingThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/IconButtonThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/InlineButtonsThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/InputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/KeyValueThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/MenuButtonThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ModalThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/MultilineInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/NumberInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ParagraphThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/PasswordInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/PhoneInputThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/RadioGroupThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/SectionThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/SelectThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/StatsBoxThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/SwitchGroupThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/SwitchThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/TableThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ToolbarButtonsThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/components/Thumbnails/ZoneThumbnail.tsx (1 hunks)
  • app/client/packages/icons/src/index.ts (1 hunks)
  • app/client/packages/icons/src/stories/CustomIcons.mdx (1 hunks)
  • app/client/packages/icons/src/utils/cleanup.ts (1 hunks)
  • app/client/packages/icons/src/utils/generateComponents.ts (2 hunks)
  • app/client/packages/icons/src/utils/generateIndex.ts (2 hunks)
  • app/client/packages/icons/src/utils/generateStories.ts (1 hunks)
  • app/client/src/WidgetProvider/constants.ts (2 hunks)
  • app/client/src/layoutSystems/anvil/editor/canvasArenas/AnvilDragPreview/index.tsx (2 hunks)
  • app/client/src/widgets/BaseWidget.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (42)
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/Datepicker/DatePicker3_spec.ts
  • app/client/jest.config.js
  • app/client/package.json
  • app/client/packages/icons/package.json
  • app/client/packages/icons/src/components/CustomIcons/AIAvatarCustomIcon.tsx
  • app/client/packages/icons/src/components/Icons/DatePickerIcon.tsx
  • app/client/packages/icons/src/components/Icons/HeadingIcon.tsx
  • app/client/packages/icons/src/components/Icons/InlineButtonsIcon.tsx
  • app/client/packages/icons/src/components/Icons/KeyValueIcon.tsx
  • app/client/packages/icons/src/components/Icons/NumberInputIcon.tsx
  • app/client/packages/icons/src/components/Icons/PhoneInputIcon.tsx
  • app/client/packages/icons/src/components/Icons/StatsBoxIcon.tsx
  • app/client/packages/icons/src/components/Icons/SwitchGroupIcon.tsx
  • app/client/packages/icons/src/components/Icons/SwitchIcon.tsx
  • app/client/packages/icons/src/components/Thumbnails/CheckboxGroupThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/CheckboxThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/ComboboxSelectThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/CurrencyInputThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/DatePickerThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/EmailInputThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/HeadingThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/IconButtonThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/InlineButtonsThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/InputThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/KeyValueThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/MenuButtonThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/ModalThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/PasswordInputThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/PhoneInputThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/SectionThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/SelectThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/StatsBoxThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/SwitchThumbnail.tsx
  • app/client/packages/icons/src/components/Thumbnails/ZoneThumbnail.tsx
  • app/client/packages/icons/src/index.ts
  • app/client/packages/icons/src/stories/CustomIcons.mdx
  • app/client/packages/icons/src/utils/cleanup.ts
  • app/client/packages/icons/src/utils/generateIndex.ts
  • app/client/packages/icons/src/utils/generateStories.ts
  • app/client/src/WidgetProvider/constants.ts
  • app/client/src/layoutSystems/anvil/editor/canvasArenas/AnvilDragPreview/index.tsx
  • app/client/src/widgets/BaseWidget.tsx
🔇 Additional comments (66)
app/client/packages/icons/src/components/Icons/TableIcon.tsx (2)

1-2: LGTM! Clean type imports

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Modern export syntax

The named export syntax follows modern ES6+ conventions.

app/client/packages/icons/src/components/Icons/CheckboxIcon.tsx (2)

1-2: LGTM! Clean import declarations.

The namespace import and SVGProps type import follow React best practices.


4-4: LGTM! Clean export syntax.

The named export follows modern ES6 conventions.

app/client/packages/icons/src/components/Thumbnails/ButtonThumbnail.tsx (3)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve code organization.


3-3: Well-typed SVG component implementation.

The component correctly implements SVGProps type, enabling proper type checking for SVG attributes.


4-4: LGTM! Clean export syntax.

The named export is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/ParagraphIcon.tsx (3)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve clarity and type safety.


3-3: Component needs refactoring for better maintainability.

The previous review comment about extracting SVG paths to constants is still valid. This would improve code maintainability and readability.


4-4: LGTM! Clean export statement.

The named export follows modern JavaScript conventions.

app/client/packages/icons/src/components/Icons/ModalIcon.tsx (2)

1-2: LGTM! Import statements follow React best practices.

The namespace import and SVGProps type import enhance type safety and follow React team's recommendations.


4-4: LGTM! Export syntax follows modern ES6+ practices.

app/client/packages/icons/src/components/Icons/ComboboxSelectIcon.tsx (2)

1-2: LGTM! Clean import statements following React best practices.

The namespace import for React and explicit type import for SVGProps provide proper type safety.


4-4: LGTM! Clean named export.

The named export follows modern JavaScript best practices and enables better tree-shaking.

app/client/packages/icons/src/components/Thumbnails/ParagraphThumbnail.tsx (3)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import follow TypeScript best practices.


4-4: LGTM! Clean named export.

The named export style is consistent with modern JavaScript module patterns.


3-3: LGTM! Well-typed component with proper prop handling.

The component correctly implements SVGProps type safety and prop spreading, allowing for flexible SVG attribute customization.

✅ Verification successful

The previous command might have failed due to syntax. Let's search for SVGProps usage patterns in the icons directory to verify consistent typing across components.


SVGProps type is consistently used across icon components

The verification confirms that all icon components in the codebase consistently use the SVGProps<SVGSVGElement> type for prop handling, following the same pattern as ParagraphThumbnail. This ensures type safety and proper prop spreading across the icon system.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify consistent SVGProps usage across icon components
ast-grep --pattern 'const $_ = (props: SVGProps<SVGSVGElement>) => <svg $$$'

Length of output: 78


Script:

#!/bin/bash
# Let's try a different approach to verify SVGProps usage
rg "SVGProps.*SVGSVGElement.*=>" -A 1 app/client/packages/icons/src/components/

Length of output: 45575

app/client/packages/icons/src/components/Icons/PasswordInputIcon.tsx (2)

1-2: LGTM: Import statements follow best practices

The namespace import for React and explicit SVGProps type import enhance type safety and maintainability.


4-4: LGTM: Export statement follows best practices

The named export improves module clarity and maintainability.

app/client/packages/icons/src/components/Icons/InputIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import follow best practices.


4-4: LGTM! Clean export statement.

The named export follows the standardization pattern being implemented across icon components.

app/client/packages/icons/src/components/Icons/IconButtonIcon.tsx (2)

1-2: LGTM! Proper TypeScript imports and type safety.

The namespace import and SVGProps type import follow TypeScript best practices and enable proper type checking for SVG attributes.


4-4: LGTM! Modern ES6 named export.

The named export follows modern ES6 practices and maintains consistency with other icon components.

app/client/packages/icons/src/components/Thumbnails/RadioGroupThumbnail.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import follow best practices.


4-4: LGTM! Proper export statement.

The named export is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/MenuButtonIcon.tsx (2)

1-2: LGTM! Clean import statements

The namespace import for React and explicit SVGProps type import follow best practices.


4-4: LGTM! Proper named export

The named export is consistent with modern JavaScript practices and makes imports more explicit.

app/client/packages/icons/src/components/Icons/SectionIcon.tsx (4)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import follow TypeScript best practices.


3-3: LGTM! Well-typed SVG component.

The component correctly implements SVGProps typing and follows React conventions for SVG attributes.


4-4: LGTM! Clean export syntax.

Named export follows modern ES6+ conventions.


1-4: Verify SVG dimensions across usage.

The SVG has fixed dimensions (16x16). Ensure this doesn't conflict with any existing usages where different sizes might be needed.

✅ Verification successful

Let me search for more usage patterns of SectionIcon to ensure we have a complete picture.


Fixed dimensions (16x16) in SectionIcon are appropriate for its usage

The icon is correctly implemented with fixed dimensions as it's part of an icon library where consistent sizing is expected. The SVG accepts props (including width/height) which can override the defaults if needed. Current usage in storybook documentation and as a widget icon shows no conflicts.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for SectionIcon usage to verify dimension constraints
rg -l 'SectionIcon' | xargs rg -A 2 -B 2 'width|height.*SectionIcon'

Length of output: 943


Script:

#!/bin/bash
# Search for SectionIcon imports and usage patterns
rg -A 3 "import.*SectionIcon|from.*SectionIcon"

# Also search for any direct usage of SectionIcon component
rg -A 2 "<SectionIcon"

Length of output: 1607

app/client/packages/icons/src/components/Icons/ZoneIcon.tsx (2)

1-2: LGTM! Clean import statements following best practices.

The namespace import for React and explicit SVGProps type import enhance type safety and follow modern React conventions.


4-4: LGTM! Consistent export pattern.

The named export aligns with the codebase's conventions and makes imports more explicit.

app/client/packages/icons/src/components/Icons/CheckboxGroupIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import and explicit SVGProps type import follow React best practices.


4-4: LGTM! Clean export statement.

The named export follows modern JavaScript conventions.

app/client/packages/icons/src/components/Icons/CurrencyInputIcon.tsx (3)

1-2: LGTM! Clean type imports

The namespace import and SVGProps type import follow TypeScript best practices for React components.


3-3: LGTM! Well-structured SVG component

The component correctly implements:

  • Proper TypeScript typing with SVGProps
  • Props spreading for SVG attribute passthrough
  • Consistent SVG attributes and viewBox

4-4: LGTM! Clean export

Named export follows module best practices.

app/client/packages/icons/src/components/Thumbnails/SwitchGroupThumbnail.tsx (2)

1-2: LGTM: Import statements follow React best practices

The namespace import for React and explicit SVGProps type import enhance type safety and maintainability.


4-4: LGTM: Export statement follows modern ES6+ syntax

The named export is appropriate for this component.

app/client/packages/icons/src/components/Icons/EmailInputIcon.tsx (3)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Clean export syntax.

The named export syntax is consistent with modern JavaScript practices.


3-3: Props spreading implementation looks good.

The component correctly accepts and spreads SVG props while maintaining proper TypeScript types.

✅ Verification successful

Props spreading implementation is consistent across icon components

The implementation of SVG props spreading in EmailInputIcon follows the same pattern used across all icon components in the codebase, with proper TypeScript types and consistent prop handling.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify consistent SVG props handling across icon components
ast-grep --pattern 'const $_Icon = (props: SVGProps<SVGSVGElement>) => <svg $_$$$ {...props}>'

Length of output: 96


Script:

#!/bin/bash
# Let's try a different pattern to match SVG components with props spreading
ast-grep --pattern 'const $_: React.FC<SVGProps<SVGSVGElement>> = props => <svg $_$$$ {...props}>'

# Also try another variation of the pattern
ast-grep --pattern 'const $_ = (props: SVGProps<SVGSVGElement>): JSX.Element => <svg $_$$$ {...props}>'

# Let's also check the specific file content to verify the implementation
cat "app/client/packages/icons/src/components/Icons/EmailInputIcon.tsx"

# Search for other icon components in the same directory
fd "Icon.tsx$" app/client/packages/icons/src/components/Icons/ --exec cat {}

Length of output: 19247

app/client/packages/icons/src/components/Icons/ToolbarButtonsIcon.tsx (1)

1-4: LGTM! Clean implementation with proper TypeScript types.

The changes follow React best practices with proper namespace imports and SVG prop types.

app/client/packages/icons/src/components/Icons/ButtonIcon.tsx (3)

1-2: LGTM: Import statements follow best practices

The namespace import for React and explicit SVGProps type import enhance type safety and maintainability.


4-4: LGTM: Export statement follows modern syntax

The named export syntax is consistent with modern JavaScript practices.


3-3: Verify SVG attribute overrides

The component spreads props after defining default attributes. Ensure this ordering is consistent across all icon components for predictable prop overriding behavior.

✅ Verification successful

SVG prop spreading pattern is consistent across icon components

Based on the search results, all icon components in the codebase follow the same pattern of spreading props after defining default attributes. The ButtonIcon component follows this consistent pattern, ensuring predictable prop overriding behavior.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check SVG prop spreading pattern across icon components
ast-grep --pattern 'const $_Icon = (props: SVGProps<SVGSVGElement>) => <svg $$${...props}$$$>'

Length of output: 96


Script:

#!/bin/bash
# Let's try a different pattern to match SVG components with props spreading
rg -U "const \w+Icon.*=.*props.*=>.*<svg.*{\.\.\.props}" --type ts

# Also check for different component declaration patterns
rg -U "export (const|function) \w+Icon.*=.*props.*=>.*<svg.*{\.\.\.props}" --type ts

Length of output: 525


Script:

#!/bin/bash
# Search for SVG components with props spreading, escaping the dots properly
rg -U "const \w+Icon.*=.*props.*=>.*<svg.*\{\.\.\." --type ts

# Also look for the specific file to verify its content
cat "app/client/packages/icons/src/components/Icons/ButtonIcon.tsx"

Length of output: 19204

app/client/packages/icons/src/components/Icons/MultilineInputIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import and SVGProps type import follow React best practices.


4-4: LGTM! Proper export statement.

The named export follows modern JavaScript practices.

app/client/packages/icons/src/components/Icons/RadioGroupIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import and explicit type import enhance type safety and follow React best practices.


4-4: LGTM! Clean export statement.

The named export follows consistent patterns and makes imports more explicit.

app/client/packages/icons/src/components/Thumbnails/NumberInputThumbnail.tsx (1)

1-3: LGTM! Good improvements in type safety

The changes to use namespace import and SVGProps type improve type safety and follow React best practices.

app/client/packages/icons/src/components/Thumbnails/ToolbarButtonsThumbnail.tsx (2)

1-2: LGTM! Clean import declarations.

The namespace import for React and explicit SVGProps type import follow TypeScript best practices.


4-4: LGTM! Clean named export.

The named export style is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Thumbnails/TableThumbnail.tsx (3)

1-2: LGTM! Clean type imports

The namespace import for React and explicit SVGProps type import improve type safety.


3-3: LGTM! Well-typed SVG component

The component correctly implements SVGProps typing and uses proper number literals for width/height attributes.


4-4: LGTM! Clean export syntax

Named export follows modern JavaScript conventions.

app/client/packages/icons/src/components/Thumbnails/MultilineInputThumbnail.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import follow best practices.


4-4: LGTM! Clean export statement.

The named export style is consistent with modern JavaScript practices.

app/client/packages/icons/src/components/Icons/AIChatIcon.tsx (2)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit SVGProps type import improve type safety.


4-4: LGTM! Named export is appropriate.

The named export allows for better tree-shaking and is consistent with modern module practices.

app/client/packages/icons/src/utils/generateComponents.ts (2)

5-5: LGTM: Good choice using @svgr/core

The addition of SVGR transform is appropriate for handling SVG to React component conversion.


27-29: LGTM: Consistent naming convention for CustomIcons

The CustomIcons case follows the established pattern of other icon types.

app/client/packages/icons/src/components/Thumbnails/AIChatThumbnail.tsx (3)

1-2: LGTM! Clean import statements.

The namespace import for React and explicit type import for SVGProps follow best practices.


3-3: Consider adding type safety for width and height props.

The previous review comment about adding type safety for width and height attributes is still valid and hasn't been addressed.


4-4: LGTM! Clean named export.

The named export follows the consistent pattern being applied across the codebase.

export const TableIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path stroke="#000" stroke-linecap="round" stroke-linejoin="round" d="M11.5 1.5h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2M7.5 5.5v8M1.5 5.5h12M1.5 9.5h12"/></svg>;
import * as React from "react";
import type { SVGProps } from "react";
const TableIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M11.5 1.5h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2M7.5 5.5v8M1.5 5.5h12M1.5 9.5h12" /></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider making dimensions configurable

While the SVG has fixed dimensions (16x16), consider making these configurable through props with these as defaults.

-const TableIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}>
+const TableIcon = ({ width = 16, height = 16, ...props }: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fill="none" {...props}>
📝 Committable suggestion

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

Suggested change
const TableIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M11.5 1.5h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2M7.5 5.5v8M1.5 5.5h12M1.5 9.5h12" /></svg>;
const TableIcon = ({ width = 16, height = 16, ...props }: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M11.5 1.5h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2M7.5 5.5v8M1.5 5.5h12M1.5 9.5h12" /></svg>;

export const PasswordInputIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".25" d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2"/><path stroke="#000" stroke-linecap="round" stroke-linejoin="round" d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7"/><path stroke="#000" stroke-linecap="round" stroke-width="2.1" d="M4 7h.01M7 7h.01M10 7h.01"/></svg>;
import * as React from "react";
import type { SVGProps } from "react";
const PasswordInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7" /><path stroke="#000" strokeLinecap="round" strokeWidth={2.1} d="M4 7h.01M7 7h.01M10 7h.01" /></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider breaking down the SVG paths for better readability

While the implementation is correct, the long inline SVG makes the code harder to read and maintain.

Consider refactoring like this:

-const PasswordInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7" /><path stroke="#000" strokeLinecap="round" strokeWidth={2.1} d="M4 7h.01M7 7h.01M10 7h.01" /></svg>;
+const PasswordInputIcon = (props: SVGProps<SVGSVGElement>) => (
+  <svg
+    xmlns="http://www.w3.org/2000/svg"
+    width={16}
+    height={16}
+    fill="none"
+    {...props}
+  >
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      strokeOpacity={0.25}
+      d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeLinejoin="round"
+      d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7"
+    />
+    <path
+      stroke="#000"
+      strokeLinecap="round"
+      strokeWidth={2.1}
+      d="M4 7h.01M7 7h.01M10 7h.01"
+    />
+  </svg>
+);
📝 Committable suggestion

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

Suggested change
const PasswordInputIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7" /><path stroke="#000" strokeLinecap="round" strokeWidth={2.1} d="M4 7h.01M7 7h.01M10 7h.01" /></svg>;
const PasswordInputIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={16}
height={16}
fill="none"
{...props}
>
<path
stroke="#000"
strokeLinecap="round"
strokeLinejoin="round"
strokeOpacity={0.25}
d="M12.5 6.5h1m1 0h-1m0 0v8m-1 0h2"
/>
<path
stroke="#000"
strokeLinecap="round"
strokeLinejoin="round"
d="M14.5 2.5h-12a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7"
/>
<path
stroke="#000"
strokeLinecap="round"
strokeWidth={2.1}
d="M4 7h.01M7 7h.01M10 7h.01"
/>
</svg>
);

export const ZoneIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path stroke="#000" stroke-linecap="round" stroke-linejoin="round" d="M2.5 4v7A1.5 1.5 0 0 0 4 12.5h7a1.5 1.5 0 0 0 1.5-1.5V4A1.5 1.5 0 0 0 11 2.5H4A1.5 1.5 0 0 0 2.5 4"/><path stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".25" d="M.5 4v-.5a3 3 0 0 1 3-3H4M.5 11v.5a3 3 0 0 0 3 3H4M14.5 4v-.5a3 3 0 0 0-3-3H11M14.5 11v.5a3 3 0 0 1-3 3H11M.5 6.5v2M14.5 6.5v2M6.5.5h2M6.5 14.5h2"/></svg>;
import * as React from "react";
import type { SVGProps } from "react";
const ZoneIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} fill="none" {...props}><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M2.5 4v7A1.5 1.5 0 0 0 4 12.5h7a1.5 1.5 0 0 0 1.5-1.5V4A1.5 1.5 0 0 0 11 2.5H4A1.5 1.5 0 0 0 2.5 4" /><path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M.5 4v-.5a3 3 0 0 1 3-3H4M.5 11v.5a3 3 0 0 0 3 3H4M14.5 4v-.5a3 3 0 0 0-3-3H11M14.5 11v.5a3 3 0 0 1-3 3H11M.5 6.5v2M14.5 6.5v2M6.5.5h2M6.5 14.5h2" /></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider memoizing the component for better performance.

While the implementation is correct, wrapping the component with React.memo could optimize re-renders when used in lists or frequently updating parents.

-const ZoneIcon = (props: SVGProps<SVGSVGElement>) => <svg
+const ZoneIcon = React.memo((props: SVGProps<SVGSVGElement>) => <svg
   xmlns="http://www.w3.org/2000/svg"
   width={16}
   height={16}
   fill="none"
   {...props}
 >
   <path stroke="#000" strokeLinecap="round" strokeLinejoin="round" d="M2.5 4v7A1.5 1.5 0 0 0 4 12.5h7a1.5 1.5 0 0 0 1.5-1.5V4A1.5 1.5 0 0 0 11 2.5H4A1.5 1.5 0 0 0 2.5 4" />
   <path stroke="#000" strokeLinecap="round" strokeLinejoin="round" strokeOpacity={0.25} d="M.5 4v-.5a3 3 0 0 1 3-3H4M.5 11v.5a3 3 0 0 0 3 3H4M14.5 4v-.5a3 3 0 0 0-3-3H11M14.5 11v.5a3 3 0 0 1-3 3H11M.5 6.5v2M14.5 6.5v2M6.5.5h2M6.5 14.5h2" />
-</svg>;
+</svg>);

Committable suggestion was skipped due to low confidence.

export const AIChatIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" fill="none"><path fill="#000" fill-opacity=".25" fill-rule="evenodd" d="M1.5 1A1.5 1.5 0 0 0 0 2.5v8A1.5 1.5 0 0 0 1.5 12H2V4.5A1.5 1.5 0 0 1 3.5 3H13v-.5A1.5 1.5 0 0 0 11.5 1z" clip-rule="evenodd"/><mask id="a" fill="#fff"><path fill-rule="evenodd" d="M3.5 3A1.5 1.5 0 0 0 2 4.5v8A1.5 1.5 0 0 0 3.5 14H10l2.146 2.146a.5.5 0 0 0 .854-.353V14h.5a1.5 1.5 0 0 0 1.5-1.5v-8A1.5 1.5 0 0 0 13.5 3z" clip-rule="evenodd"/></mask><path fill="#000" d="m10 14 .707-.707-.293-.293H10zm3 0v-1h-1v1zM3 4.5a.5.5 0 0 1 .5-.5V2A2.5 2.5 0 0 0 1 4.5zm0 8v-8H1v8zm.5.5a.5.5 0 0 1-.5-.5H1A2.5 2.5 0 0 0 3.5 15zm6.5 0H3.5v2H10zm2.854 2.44-2.147-2.147-1.414 1.414 2.146 2.147zm-.854.353a.5.5 0 0 1 .854-.354l-1.415 1.415c.945.945 2.561.275 2.561-1.061zM12 14v1.793h2V14zm1.5-1H13v2h.5zm.5-.5a.5.5 0 0 1-.5.5v2a2.5 2.5 0 0 0 2.5-2.5zm0-8v8h2v-8zm-.5-.5a.5.5 0 0 1 .5.5h2A2.5 2.5 0 0 0 13.5 2zm-10 0h10V2h-10z" mask="url(#a)"/><path stroke="#000" stroke-opacity=".75" d="m8.536 6.27.6 1.402.08.184.183.078 1.403.602-1.403.6-.184.08-.078.183-.601 1.403-.602-1.403-.078-.184-.184-.078-1.403-.601 1.403-.602.184-.078.078-.184z"/></svg>;
import * as React from "react";
import type { SVGProps } from "react";
const AIChatIcon = (props: SVGProps<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" width={16} height={17} fill="none" {...props}><path fill="#000" fillOpacity={0.25} fillRule="evenodd" d="M1.5 1A1.5 1.5 0 0 0 0 2.5v8A1.5 1.5 0 0 0 1.5 12H2V4.5A1.5 1.5 0 0 1 3.5 3H13v-.5A1.5 1.5 0 0 0 11.5 1z" clipRule="evenodd" /><mask id="a" fill="#fff"><path fillRule="evenodd" d="M3.5 3A1.5 1.5 0 0 0 2 4.5v8A1.5 1.5 0 0 0 3.5 14H10l2.146 2.146a.5.5 0 0 0 .854-.353V14h.5a1.5 1.5 0 0 0 1.5-1.5v-8A1.5 1.5 0 0 0 13.5 3z" clipRule="evenodd" /></mask><path fill="#000" d="m10 14 .707-.707-.293-.293H10zm3 0v-1h-1v1zM3 4.5a.5.5 0 0 1 .5-.5V2A2.5 2.5 0 0 0 1 4.5zm0 8v-8H1v8zm.5.5a.5.5 0 0 1-.5-.5H1A2.5 2.5 0 0 0 3.5 15zm6.5 0H3.5v2H10zm2.854 2.44-2.147-2.147-1.414 1.414 2.146 2.147zm-.854.353a.5.5 0 0 1 .854-.354l-1.415 1.415c.945.945 2.561.275 2.561-1.061zM12 14v1.793h2V14zm1.5-1H13v2h.5zm.5-.5a.5.5 0 0 1-.5.5v2a2.5 2.5 0 0 0 2.5-2.5zm0-8v8h2v-8zm-.5-.5a.5.5 0 0 1 .5.5h2A2.5 2.5 0 0 0 13.5 2zm-10 0h10V2h-10z" mask="url(#a)" /><path stroke="#000" strokeOpacity={0.75} d="m8.536 6.27.6 1.402.08.184.183.078 1.403.602-1.403.6-.184.08-.078.183-.601 1.403-.602-1.403-.078-.184-.184-.078-1.403-.601 1.403-.602.184-.078.078-.184z" /></svg>;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider memoizing the static SVG component.

Since this is a static SVG component, wrapping it with React.memo could prevent unnecessary re-renders when used in parent components.

-const AIChatIcon = (props: SVGProps<SVGSVGElement>) => <svg
+const AIChatIcon = React.memo((props: SVGProps<SVGSVGElement>) => <svg
 xmlns="http://www.w3.org/2000/svg" width={16} height={17} fill="none" {...props}><path fill="#000" fillOpacity={0.25} fillRule="evenodd" d="M1.5 1A1.5 1.5 0 0 0 0 2.5v8A1.5 1.5 0 0 0 1.5 12H2V4.5A1.5 1.5 0 0 1 3.5 3H13v-.5A1.5 1.5 0 0 0 11.5 1z" clipRule="evenodd" /><mask id="a" fill="#fff"><path fillRule="evenodd" d="M3.5 3A1.5 1.5 0 0 0 2 4.5v8A1.5 1.5 0 0 0 3.5 14H10l2.146 2.146a.5.5 0 0 0 .854-.353V14h.5a1.5 1.5 0 0 0 1.5-1.5v-8A1.5 1.5 0 0 0 13.5 3z" clipRule="evenodd" /></mask><path fill="#000" d="m10 14 .707-.707-.293-.293H10zm3 0v-1h-1v1zM3 4.5a.5.5 0 0 1 .5-.5V2A2.5 2.5 0 0 0 1 4.5zm0 8v-8H1v8zm.5.5a.5.5 0 0 1-.5-.5H1A2.5 2.5 0 0 0 3.5 15zm6.5 0H3.5v2H10zm2.854 2.44-2.147-2.147-1.414 1.414 2.146 2.147zm-.854.353a.5.5 0 0 1 .854-.354l-1.415 1.415c.945.945 2.561.275 2.561-1.061zM12 14v1.793h2V14zm1.5-1H13v2h.5zm.5-.5a.5.5 0 0 1-.5.5v2a2.5 2.5 0 0 0 2.5-2.5zm0-8v8h2v-8zm-.5-.5a.5.5 0 0 1 .5.5h2A2.5 2.5 0 0 0 13.5 2zm-10 0h10V2h-10z" mask="url(#a)" /><path stroke="#000" strokeOpacity={0.75} d="m8.536 6.27.6 1.402.08.184.183.078 1.403.602-1.403.6-.184.08-.078.183-.601 1.403-.602-1.403-.078-.184-.184-.078-1.403-.601 1.403-.602.184-.078.078-.184z" /></svg>);

Committable suggestion was skipped due to low confidence.

@KelvinOm KelvinOm merged commit 5da5a1e into release Oct 28, 2024
45 checks passed
@KelvinOm KelvinOm deleted the fix/ai-chat branch October 28, 2024 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ok-to-test Required label for CI skip-changelog Adding this label to a PR prevents it from being listed in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants