diff --git a/.cursor/rules/components/basic_component.mdc b/.cursor/rules/components/basic_component.mdc new file mode 100644 index 000000000..98fcb60db --- /dev/null +++ b/.cursor/rules/components/basic_component.mdc @@ -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. diff --git a/.cursor/rules/icons.mdc b/.cursor/rules/icons.mdc new file mode 100644 index 000000000..5d46a2b8f --- /dev/null +++ b/.cursor/rules/icons.mdc @@ -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) => ( + + + + ); + ``` + - 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 ; + }); + ``` + +#### 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) => ( + + + + ); + ``` + - 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 })), + ``` + +---