Entry point
Base architecture
Use this structure as the default starting point for reusable controls.
import React from 'react';
export class CodeInApplication implements CodeInComp {
description() {
return 'Short description shown in Yeeflow.';
}
requiredFields(params?: CodeInParams) {
return [];
}
inputParameters(): InputParameter[] {
return [];
}
render(context: CodeInContext, fieldsValues: any, readonly: boolean) {
return (
<CustomControl
context={context}
fieldsValues={fieldsValues || {}}
readonly={readonly}
params={(context && context.params) || {}}
/>
);
}
}Class contract
Core methods
- CodeInApplication implements CodeInComp
- The required exported class Yeeflow uses to identify the custom code entry point. Missing this export can cause errors such as No exports found.
- description()
- Returns a short admin-facing description. Use it to identify the component, not to hold setup documentation.
- requiredFields(params?)
- Declares current-form field dependencies such as year, month, department, status, or output target fields captured from parameters.
- inputParameters()
- Defines builder-facing configuration fields such as labels, list IDs, filter values, writable targets, numeric config, and boolean behavior.
- render(context, fieldsValues, readonly)
- Receives runtime data and returns the visual component. Keep render small and move business logic into the React component or helpers.
Runtime data
Parameters and field values
| Source | Use | Guidance |
|---|---|---|
context.params | Values configured through inputParameters(). | Read defensively and normalize expression values before use. |
fieldsValues | Current form values available to the control. | Values may be primitives, arrays, objects, lookups, or JSON strings. |
context.getFieldValue() | Fallback field reads when the field name is known. | Read fieldsValues first, then getFieldValue(), then a safe fallback. |
context.modules.yeeSDKClient | Yeeflow platform APIs such as data list queries. | Check availability before calling lists.queryItems(...). |
function readFieldValue(context: any, fieldsValues: any, fieldName: string, fallback: any) {
if (!fieldName) {
return fallback;
}
if (fieldsValues && fieldsValues[fieldName] !== undefined) {
return fieldsValues[fieldName];
}
if (context && typeof context.getFieldValue === 'function') {
const value = context.getFieldValue(fieldName);
return value === undefined || value === null ? fallback : value;
}
return fallback;
}React runtime
React component and style pattern
For broad Yeeflow runtime compatibility, prefer React.Component, predictable state transitions, and callback refs when a ref is needed. Avoid hooks, React.createRef(), forwardRef, andmemo unless the target tenant has already proven support.
class CustomControl extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
loading: false,
errorText: '',
};
}
render() {
const styles = [
'.yf-custom-control{font-family:Inter,Arial,sans-serif;color:#1f2937;}',
'.yf-custom-control__title{font-size:14px;font-weight:600;margin-bottom:8px;}',
].join('');
return (
<div className="yf-custom-control">
<style>{styles}</style>
<div className="yf-custom-control__title">Title</div>
</div>
);
}
}Production quality
Ant Design, defensive coding, and output
Ant Design is appropriate where Yeeflow already supports it and where it improves consistency: tables, tags, cards, progress indicators, alerts, loading states, buttons, and inputs.
A small custom control may be clearer with plain HTML and CSS. A table or dashboard-heavy module may benefit from Ant Design.
Separate displayed UI state, the value to save, and the resolved writable target. Test form field, dashboard variable, and temp-variable save paths separately because render success does not guarantee persistence.
Examples
Use templates as complete examples
After learning the structure, explore reusable Custom Code templates to see complete TSX examples with guides and example configuration.