Prompt file imported from yakusag/js-sdk (
.cursor/commands/editwidget.md). Fill in{{Pascal}},{{camel}}before use. Copyright stays with the author.
editwidget
Command instructions for editing/creating standard Widgets (script/ui/widget/index). This command follows the rules and templates in specs/002-widget-rules.md.
Target Objects
- Target directory contains the "standard Widget four-piece set":
xxx.script.tsx,xxx.ui.tsx,xxx.widget.tsx,index.ts
Executable Actions
- "Add X and use in Y" in an existing standard Widget
- Create a brand new standard Widget (generate four-piece template)
Usage (Natural language is acceptable)
A. Add fields/logic in standard Widget and use in UI
- Syntax:
- This is a standard Widget:
<folder>. - Add
<X>, use in<Y>.
- This is a standard Widget:
- Behavior:
- In
<folder>/<name>.script.tsx, implement or extend logic inuse{{Pascal}}Script, add fieldXand include it in the return object; if external parameters are needed, extendUse{{Pascal}}ScriptOptionsand input parameters. - In
<folder>/<name>.ui.tsx, ensure{{Pascal}}PropscoversX, and render/use it at positionYin the UI. - If external input parameters need to be passed through, extend
WidgetPropsin<folder>/<name>.widget.tsxand pass options touse{{Pascal}}Script. - If there are new exports, update
<folder>/index.ts.
- In
B. Create a brand new standard Widget
- Syntax:
- Create a Widget, its name is:
<xxxx>. - Directory:
<dir>. (If directory is not provided, it will be confirmed based on context or prompts)
- Create a Widget, its name is:
- Behavior:
- Create folder under
<dir>:camelCase(xxxx); usePascalCase(xxxx)for component and type names in code. - Generate four-piece set:
{{camel}}.script.tsx:use{{Pascal}}Scriptandtype {{Pascal}}State = ReturnType<typeof use{{Pascal}}Script>{{camel}}.ui.tsx:{{Pascal}}component and{{Pascal}}Props{{camel}}.widget.tsx:{{Pascal}}Widgetconnects script and ui (optionally register Dialog/Sheet)index.ts: Unified export of UI/Widget/Script and types
- Create folder under
Examples (Can be copied and modified directly)
Add X, use in Y
-
Simplest:
- This is a standard Widget:
packages/trading/src/components/mobile/fundingRateModal/. - Add
countDown, use in the top right of the UI.
- This is a standard Widget:
-
With external input parameters:
- This is a standard Widget:
packages/trading/src/components/mobile/fundingRateModal/. - Add field
nextFundingTime(from options:symbol: string), use in the bottom hint text.
- This is a standard Widget:
-
Add event:
- This is a standard Widget:
packages/trading/src/components/mobile/someWidget/. - Add
onSubmit: () => void, use on bottom confirm button click.
- This is a standard Widget:
-
Add Dialog/Sheet registration:
- This is a standard Widget:
packages/trading/src/components/mobile/someWidget/. - Add Dialog and Sheet registration, define and export
{{Pascal}}DialogIdand{{Pascal}}SheetId, register usingregisterSimpleDialogandregisterSimpleSheet.
- This is a standard Widget:
Create Widget (four-piece set)
-
Specify directory:
- Create a Widget, its name is:
positionInfo. - Directory:
packages/trading/src/components/mobile/positionInfo.
- Create a Widget, its name is:
-
Directory not specified (confirm based on context/prompts):
- Create a Widget, its name is:
userPnLCard.
- Create a Widget, its name is:
Constraints and Defaults
- UI is pure presentation, no side effects; layout-related
className/stylecan be passed. - Logic and derived calculations go in
script; Dialog/Sheet registration goes inwidget. - Responsibility Separation:
- Script: Responsible for data logic and business logic. Script only provides raw state/data (numbers, booleans, objects, etc.), does NOT handle internationalization (i18n), does NOT preset UI display format. Script returns raw values, and UI decides how to display them (including i18n text selection and formatting).
- UI: Responsible for display logic and translation (i18n). UI receives raw data from script and handles all formatting, translation, and presentation concerns.
- Naming: files use
camelCase, components/types usePascalCase. - Dialog/BottomSheet Registration Requirements: If the created Widget needs to be used as a Dialog or BottomSheet, you must:
- Define and export
{{Pascal}}DialogIdand{{Pascal}}SheetId(or{{Pascal}}BottomSheetId) constants inwidget.tsx - Register using
registerSimpleDialogandregisterSimpleSheet(from@orderly.network/ui) - Export these IDs in
index.ts - Reference example:
packages/ui-tpsl/src/editBracketOrder/editBracketOrder.widget.tsx
- Define and export
- Text should use i18n (only in UI layer, NOT in script); add error fallbacks and
useMemooptimization when necessary. - Numeric Calculations: All numeric calculations (multiplication, division, percentage conversion, etc.) must use
Decimal(from@orderly.network/utils) to avoid floating-point precision issues. - Local Cache Data: When local cache data is needed, must use
useLocalStoragehook (from@orderly.network/hooks). Use inscript.tsx, usage:const [storedValue, setValue] = useLocalStorage<T>(key: string, initialValue: T). Do not directly uselocalStorage.getItem/setItem. - Comment Language: All code comments must be in English.
- Prohibit Generating Any Type of Markdown Documentation: Do not generate README, CHANGELOG, usage instructions, summary documents, or any .md files.
- i18n Key Processing Workflow (only applies to UI layer):
- First search in
@orderly.network/i18npackage to see if a matching key already exists - If it exists, use it directly; if not, create a new key
- Determine which file it should be placed in under
packages/i18n/src/locale/module/based on content nature:- Common text (such as Cancel, Confirm, Save, etc.) →
common.ts - Position-related →
positions.ts - Trading-related →
trading.ts - Order-related →
orders.ts - Other modules follow the same pattern
- Common text (such as Cancel, Confirm, Save, etc.) →
- Key naming format:
module.keyName(e.g.,common.cancel,positions.closeAll) - Only add key to the corresponding .ts file, do not translate to other language json files
- Important: i18n should only be used in
ui.tsx, NOT inscript.tsx. Script provides state, UI decides how to display it.
- First search in
- Confirmation Mechanism: For parts that need confirmation (such as uncertain placement location, uncertain implementation method, etc.), must pause and ask for user opinion before continuing development.
- Component Reusability: If the created View or Node components can be reused in other places, they should be extracted as reusable components. Before creating new components, check if similar components already exist in the codebase that can be reused or extended. Extract common UI patterns into separate components for better maintainability and consistency.
Component Usage Workflow
When components need to be used in UI (especially component names obtained from Figma MCP), the following workflow must be followed:
-
Get Component Name: Get component name from Figma MCP or other design tools (e.g.,
Button,Input,Card, etc.) -
Search Component Index: Search for the component in
packages/ui/doc/components.md- Confirm if the component exists
- Understand the component's basic description and export information
-
Read Detailed Documentation: Read the corresponding detailed documentation based on component name
- Example:
Button→packages/ui/doc/button/button.md - Example:
Input→packages/ui/doc/input/input.md - Get the component's complete API, props, variants, usage examples, etc.
- Example:
-
Use When Generating UI:
- Use components according to the API and best practices in the documentation
- Use correct import paths (e.g.,
import { Button } from "@orderly.network/ui") - Apply correct props, variants, and style configurations
- Follow usage examples and notes in the documentation
Important: Do not directly guess the component's API, must confirm the component's correct usage through documentation.
UI Component Best Practices
-
Displaying Symbol with Icon: When UI needs to display a trading symbol with icon and formatted text, use
Text.formattedcomponent:<Text.formatted size="base" weight="semibold" rule="symbol" formatString="base" showIcon > {symbol} </Text.formatted>This component automatically handles icon display and symbol formatting. Script should only provide the raw
symbolstring (e.g.,"PERP_ETH_USDC"), and UI usesText.formattedto render it with icon and proper formatting. -
Displaying Statistics (Label + Value): When UI needs to display a vertical layout with a text label on top and a numeric value below, use
Statisticcomponent:<Statistic label={i18n.t("portfolio.totalBalance")} valueProps={{ rule: "price", dp: 2, coloring: true }} > {balance} </Statistic>This component automatically handles label/value styling and number formatting. Script should only provide the raw numeric value (e.g.,
12345.67), and UI usesStatisticto render it with proper label and formatting. ThevaluePropscan be used to configure number formatting rules (e.g.,rule: "price",rule: "percentages"), decimal places (dp), coloring, and otherNumeralcomponent props.
References
- Rules and templates:
specs/002-widget-rules.md - Component index:
packages/ui/doc/components.md
