Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples/react/src/ExpressionExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,20 @@
// <h3 style={{ marginTop: 0 }}>Template Expressions Features:</h3>
// <ul>
// <li>✅ Use {'{{ $externalContext.* }}'} in schema values</li>
// <li>✅ Use {'{{ $formState.* }}'} for dynamic form values</li>
// <li>✅ Use {'{{ $formValues.* }}'} for dynamic form values</li>
// <li>✅ Automatic processing of all template expressions</li>
// <li>✅ Recursive processing in nested objects</li>
// </ul>
// </div>

// <div style={{ border: '1px solid #ddd', padding: '24px', borderRadius: '8px' }}>
// <h3 style={{ marginTop: 0 }}>Template Form (with {'{{ $externalContext.* }}'} and {'{{ $formState.* }}'})</h3>
// <h3 style={{ marginTop: 0 }}>Template Form (with {'{{ $externalContext.* }}'} and {'{{ $formValues.* }}'})</h3>
// <p style={{ fontSize: '13px', color: '#666', marginBottom: '16px' }}>
// This example demonstrates two key template expression features you can observe:
// <br />
// <strong>1. $externalContext expressions:</strong> The First Name label uses {'{{ $externalContext.user.name }}'} which resolves to <strong>"Test User"</strong> from the factory's externalContext prop.
// <br />
// <strong>2. $formState expressions:</strong> The Email field's placeholder uses {'{{ $formState.personalInfo.firstName }}'} which dynamically updates to show the current value of the First Name field as you type.
// <strong>2. $formValues expressions:</strong> The Email field's placeholder uses {'{{ $formValues.personalInfo.firstName }}'} which dynamically updates to show the current value of the First Name field as you type.
// </p>
// <FormFactory
// schema={templateFormSchema}
Expand Down
41 changes: 41 additions & 0 deletions instances/form/complex-form.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,47 @@
}
}
}
},
"maritalStatus": {
"type": "object",
"x-component": "FormField",
"x-ui": {
"order": 5
},
"properties": {
"maritalStatus": {
"type": "string",
"x-component": "InputSelect",
"x-component-props": {
"label": "Marital Status",
"placeholder": "Select marital status",
"options": [
{ "value": "single", "label": "Single" },
{ "value": "married", "label": "Married" },
{ "value": "divorced", "label": "Divorced" },
{ "value": "widowed", "label": "Widowed" }
]
}
}
}
},
"spouseName": {
"type": "object",
"x-component": "FormField",
"x-ui": {
"order": 6,
"visible": "{{ $formValues.userInfo.maritalStatus === 'married' }}"
},
"properties": {
"spouseName": {
"type": "string",
"x-component": "InputText",
"x-component-props": {
"label": "Spouse Name",
"placeholder": "Enter your spouse name"
}
}
}
}
}
},
Expand Down
121 changes: 0 additions & 121 deletions instances/form/template-form.json

This file was deleted.

4 changes: 2 additions & 2 deletions packages/adapters/react/src/native-form-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,9 @@ export class NativeReactFormAdapter implements FormAdapter {
*
* @example
* ```tsx
* const [formState, setFormState] = useState({});
* const [formValues, setFormValues] = useState({});
* const [errors, setErrors] = useState({});
* const adapter = createNativeReactFormAdapter(formState, setFormState, errors, setErrors);
* const adapter = createNativeReactFormAdapter(formValues, setFormValues, errors, setErrors);
* ```
*/
export function createNativeReactFormAdapter(
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/expressions/template-detector.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ describe('Template Detector', () => {
});

it('should detect multiple template expressions', () => {
const str = '{{ $externalContext.user.name }} and {{ $formState.email }}';
const str = '{{ $externalContext.user.name }} and {{ $formValues.email }}';
const result = detectTemplateExpressions(str);
expect(result).toEqual(['$externalContext.user.name', '$formState.email']);
expect(result).toEqual(['$externalContext.user.name', '$formValues.email']);
});

it('should handle whitespace in templates', () => {
Expand Down Expand Up @@ -50,8 +50,8 @@ describe('Template Detector', () => {
});

it('should handle whitespace', () => {
const result = extractExpression('{{ $formState.email }}');
expect(result).toBe('$formState.email');
const result = extractExpression('{{ $formValues.email }}');
expect(result).toBe('$formValues.email');
});

it('should return original string if no template found', () => {
Expand Down Expand Up @@ -110,15 +110,15 @@ describe('Template Detector', () => {
label: '{{ $externalContext.user.name }}',
placeholder: 'Enter {{ $externalContext.fieldName }}',
nested: {
text: '{{ $formState.email }}',
text: '{{ $formValues.email }}',
},
};

const result = getAllTemplateExpressions(value);
expect(result).toHaveLength(3);
expect(result).toContain('$externalContext.user.name');
expect(result).toContain('$externalContext.fieldName');
expect(result).toContain('$formState.email');
expect(result).toContain('$formValues.email');
});

it('should return unique expressions only', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expressions/template-detector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

/**
* Regular expression to match template expressions {{ ... }}
* Matches: {{ $externalContext.user.name }}, {{ $formState.field }}, etc.
* Matches: {{ $externalContext.user.name }}, {{ $formValues.field }}, etc.
*/
const TEMPLATE_REGEX = /\{\{\s*([^}]+)\s*\}\}/g;

Expand Down Expand Up @@ -66,7 +66,7 @@ export function extractExpression(template: string): string {
*
* @example
* hasTemplateExpressions("{{ $externalContext.user.name }}") // true
* hasTemplateExpressions({ label: "{{ $formState.field }}" }) // true
* hasTemplateExpressions({ label: "{{ $formValues.field }}" }) // true
* hasTemplateExpressions(["{{ $externalContext.api }}", "static"]) // true
* hasTemplateExpressions("static text") // false
*/
Expand Down
Loading