feat: Adds our first Cursor rules (#7973)
* icon rules * update component rules and add dark mode * Update rules * Update .cursor/rules/components/basic_component.mdc Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> * Update .cursor/rules/components/basic_component.mdc Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org> * pr feedback --------- Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
parent
0da7fa5aeb
commit
073659d5f4
2 changed files with 208 additions and 0 deletions
78
.cursor/rules/components/basic_component.mdc
Normal file
78
.cursor/rules/components/basic_component.mdc
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
---
|
||||
description: Rules and checklist for creating a basic Langflow Component
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
# Rule: How to Create a Basic Langflow Component
|
||||
|
||||
## Purpose
|
||||
Guide for Creating a Langflow Component
|
||||
|
||||
---
|
||||
|
||||
### 1. Gather Requirements
|
||||
|
||||
Ask the user for:
|
||||
- **Component Name:** What should the component be called?
|
||||
- **Description:** What does the component do?
|
||||
- **Inputs:** What are the required inputs? (e.g., text, dropdown, boolean, etc.)
|
||||
- **Outputs:** What should the component output? (e.g., a message, a value, etc.)
|
||||
- **Category:** Which component category should this component be stored under in `langflow/src/backend/base/langflow/components`
|
||||
|
||||
### 2. Define the Component
|
||||
|
||||
- Inherit from `Component`.
|
||||
- Set `display_name`, `description`, `icon`.
|
||||
- Define the `inputs` and `outputs` as lists of input/output field objects (e.g., `DropdownInput`, `MessageTextInput`, `Output`).
|
||||
- Implement the main logic as a method (e.g., `get_current_date`, `true_response`, etc.).
|
||||
|
||||
### 3. Example: Conditional If-Else Component
|
||||
|
||||
```python
|
||||
class ConditionalRouterComponent(Component):
|
||||
display_name = "If-Else"
|
||||
description = "Routes an input message to a corresponding output based on text comparison."
|
||||
icon = "split"
|
||||
name = "ConditionalRouter"
|
||||
inputs = [
|
||||
# Define your inputs here
|
||||
]
|
||||
outputs = [
|
||||
# Define your outputs here
|
||||
]
|
||||
# Implement your logic methods here
|
||||
```
|
||||
|
||||
### 4. Example: Current Date Component
|
||||
|
||||
```python
|
||||
class CurrentDateComponent(Component):
|
||||
display_name = "Current Date"
|
||||
description = "Returns the current date and time in the selected timezone."
|
||||
icon = "clock"
|
||||
name = "CurrentDate"
|
||||
inputs = [
|
||||
# Define your inputs here
|
||||
]
|
||||
outputs = [
|
||||
# Define your outputs here
|
||||
]
|
||||
# Implement your logic methods here
|
||||
```
|
||||
|
||||
### 5. Best Practices
|
||||
|
||||
- Use clear and descriptive names for inputs and outputs.
|
||||
- Provide helpful `info` for each input to guide users.
|
||||
- Handle errors gracefully and provide meaningful error messages.
|
||||
- Use appropriate icons to visually represent the component's function.
|
||||
- Use a Lucide icon or if you want a custom icon follow the icon rules (`./cursor/rules/icons.mdc`)
|
||||
|
||||
---
|
||||
|
||||
## Checklist for Creating a Component
|
||||
- [ ] Ask the user for component name, description, inputs, and outputs.
|
||||
- [ ] Define the component class with the required fields.
|
||||
- [ ] Implement the main logic.
|
||||
- [ ] Add helpful info and error handling.
|
||||
- [ ] Test the component.
|
||||
130
.cursor/rules/icons.mdc
Normal file
130
.cursor/rules/icons.mdc
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
---
|
||||
description: Rules and checklist for adding and using langflow component icons.
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
# Component Icon Rules
|
||||
|
||||
## Purpose
|
||||
To ensure consistent, clear, and functional icon usage for components, covering both backend (Python) and frontend (React/TypeScript) steps.
|
||||
|
||||
---
|
||||
|
||||
## 1. Backend (Python) — Setting the Icon Name
|
||||
|
||||
- **Where:** In your component class (e.g., in `src/backend/base/langflow/components/vectorstores/astradb.py`)
|
||||
- **How:**
|
||||
Set the `icon` attribute to a string matching the icon you want to use.
|
||||
```python
|
||||
icon = "AstraDB"
|
||||
```
|
||||
- **Tip:**
|
||||
The string must match the frontend icon mapping exactly (case-sensitive).
|
||||
|
||||
---
|
||||
|
||||
## 2. Frontend (React/TypeScript) — Adding the Icon
|
||||
|
||||
### a. Create the Icon Component
|
||||
|
||||
- **Where:**
|
||||
In a new directory for your icon, e.g., `src/frontend/src/icons/AstraDB/`.
|
||||
- **How:**
|
||||
- Add your SVG as a React component, e.g., `AstraSVG` in `AstraDB.jsx`.
|
||||
```jsx
|
||||
const AstraSVG = (props) => (
|
||||
<svg {...props}>
|
||||
<path
|
||||
// ...
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
```
|
||||
- Create an `index.tsx` that exports your icon using `forwardRef`:
|
||||
```tsx
|
||||
import { useDarkStore } from "@/stores/darkStore";
|
||||
import React, { forwardRef } from "react";
|
||||
import AstraSVG from "./AstraDB";
|
||||
|
||||
export const AstraDBIcon = forwardRef<
|
||||
SVGSVGElement,
|
||||
React.PropsWithChildren<{}>
|
||||
>((props, ref) => {
|
||||
const isdark = useDarkStore((state) => state.dark).toString();
|
||||
return <AstraSVG ref={ref} isdark={isdark} {...props} />;
|
||||
});
|
||||
```
|
||||
|
||||
#### Supporting Light and Dark Mode Icons
|
||||
|
||||
- **How:**
|
||||
- In your SVG component (e.g., `AstraDB.jsx`), use the `isdark` prop to switch colors:
|
||||
```jsx
|
||||
const AstraSVG = (props) => (
|
||||
<svg {...props}>
|
||||
<path
|
||||
fill={stringToBool(props.isdark) ? "#ffffff" : "#0A0A0A"}
|
||||
// ...
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
```
|
||||
- The `isdark` prop is passed from the icon wrapper (see above) and should be used to toggle between light and dark color schemes.
|
||||
- You can use a utility like `stringToBool` to ensure the prop is interpreted correctly.
|
||||
|
||||
### b. Add to Lazy Icon Imports
|
||||
|
||||
- **Where:**
|
||||
In `src/frontend/src/icons/lazyIconImports.ts`
|
||||
- **How:**
|
||||
Add an entry to the `lazyIconsMapping` object:
|
||||
```ts
|
||||
AstraDB: () =>
|
||||
import("@/icons/AstraDB").then((mod) => ({ default: mod.AstraDBIcon })),
|
||||
```
|
||||
- **Tip:**
|
||||
The key (`AstraDB`) must match the string used in the backend.
|
||||
|
||||
---
|
||||
|
||||
## 3. Best Practices
|
||||
|
||||
- **Naming:**
|
||||
Use clear, recognizable names (e.g., `"AstraDB"`, `"Postgres"`, `"OpenAI"`).
|
||||
- **Consistency:**
|
||||
Always use the same icon name for the same service across backend and frontend.
|
||||
- **Missing Icon:**
|
||||
If no icon exists, use a [lucide icon](https://lucide.dev/icons)
|
||||
- **Light/Dark Mode:**
|
||||
Always support both light and dark mode for custom icons by using the `isdark` prop in your SVG.
|
||||
|
||||
---
|
||||
|
||||
## 4. Checklist for Adding a New Icon
|
||||
|
||||
- [ ] Decide on a clear, descriptive icon name (e.g., `AstraDB`).
|
||||
- [ ] In your Python component, set `icon = "YourIconName"`.
|
||||
- [ ] Create a new icon directory in `src/frontend/src/icons/YourIconName/`.
|
||||
- [ ] Add your SVG as a React component (e.g., `YourIconNameIcon.jsx`).
|
||||
- [ ] Create an `index.tsx` that exports your icon using `forwardRef` and passes the `isdark` prop.
|
||||
- [ ] Add your icon to `lazyIconsMapping` in `src/frontend/src/icons/lazyIconImports.ts` with the exact same name.
|
||||
- [ ] Verify the icon appears correctly in the UI in both light and dark mode.
|
||||
- [ ] If no suitable icon exists, use a generic icon and request a new one if needed.
|
||||
|
||||
---
|
||||
|
||||
**Example for AstraDB:**
|
||||
- Backend:
|
||||
```python
|
||||
icon = "AstraDB"
|
||||
```
|
||||
- Frontend:
|
||||
- `src/icons/AstraDB/AstraDB.jsx` (SVG as React component, uses `isdark` prop)
|
||||
- `src/icons/AstraDB/index.tsx` (exports `AstraDBIcon` and passes `isdark`)
|
||||
- Add to `lazyIconImports.ts`:
|
||||
```ts
|
||||
AstraDB: () =>
|
||||
import("@/icons/AstraDB").then((mod) => ({ default: mod.AstraDBIcon })),
|
||||
```
|
||||
|
||||
---
|
||||
Loading…
Add table
Add a link
Reference in a new issue