mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-06 16:31:12 +08:00
- Introduced Role Analysis Reviewer Agent to validate role analysis outputs against templates and quality standards. - Created a detailed validation ruleset for the system-architect role, including mandatory and recommended sections. - Added JSON validation report structure for output. - Implemented execution command for validation process. test: Add UX tests for HookCard component - Created comprehensive tests for HookCard component, focusing on delete confirmation UX pattern. - Verified confirmation dialog appearance, deletion functionality, and button interactions. - Ensured proper handling of state updates and visual feedback for enabled/disabled status. test: Add UX tests for ThemeSelector component - Developed tests for ThemeSelector component, emphasizing delete confirmation UX pattern. - Validated confirmation dialog display, deletion actions, and toast notifications for undo functionality. - Ensured proper management of theme slots and state updates. feat: Implement useDebounce hook - Added useDebounce hook to delay expensive computations or API calls, enhancing performance. feat: Create System Architect Analysis Template - Developed a comprehensive template for system architect role analysis, covering required sections such as architecture overview, data model, state machine, error handling strategy, observability requirements, configuration model, and boundary scenarios. - Included examples and templates for each section to guide users in producing SPEC.md-level precision modeling.
96 lines
3.3 KiB
TypeScript
96 lines
3.3 KiB
TypeScript
// ========================================
|
|
// A2UI TextField Component Renderer
|
|
// ========================================
|
|
// Maps A2UI TextField component to shadcn/ui Input
|
|
|
|
import { useState, useCallback, useEffect } from 'react';
|
|
import { Input } from '@/components/ui/Input';
|
|
import { cn } from '@/lib/utils';
|
|
import type { ComponentRenderer } from '../../core/A2UIComponentRegistry';
|
|
import { resolveLiteralOrBinding } from '../A2UIRenderer';
|
|
import type { TextFieldComponent } from '../../core/A2UITypes';
|
|
|
|
export const A2UITextField: ComponentRenderer = ({ component, onAction, resolveBinding }) => {
|
|
const fieldComp = component as TextFieldComponent;
|
|
const { TextField: fieldConfig } = fieldComp;
|
|
|
|
const initialValue = fieldConfig.value
|
|
? String(resolveLiteralOrBinding(fieldConfig.value, resolveBinding) ?? '')
|
|
: '';
|
|
|
|
const [localValue, setLocalValue] = useState(initialValue);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [touched, setTouched] = useState(false);
|
|
|
|
const validate = useCallback((value: string) => {
|
|
if (fieldConfig.required && !value) {
|
|
return 'This field is required.';
|
|
}
|
|
if (fieldConfig.minLength && value.length < fieldConfig.minLength) {
|
|
return `Must be at least ${fieldConfig.minLength} characters.`;
|
|
}
|
|
if (fieldConfig.maxLength && value.length > fieldConfig.maxLength) {
|
|
return `Must be at most ${fieldConfig.maxLength} characters.`;
|
|
}
|
|
if (fieldConfig.pattern && !new RegExp(fieldConfig.pattern).test(value)) {
|
|
return 'Invalid format.';
|
|
}
|
|
// `validator` is a placeholder for a more complex validation logic if needed
|
|
if (fieldConfig.validator) {
|
|
// Assuming validator is a regex string for simplicity
|
|
try {
|
|
if (!new RegExp(fieldConfig.validator).test(value)) {
|
|
return 'Custom validation failed.';
|
|
}
|
|
} catch (e) {
|
|
console.error('Invalid validator regex:', fieldConfig.validator);
|
|
}
|
|
}
|
|
return null;
|
|
}, [fieldConfig.required, fieldConfig.minLength, fieldConfig.maxLength, fieldConfig.pattern, fieldConfig.validator]);
|
|
|
|
useEffect(() => {
|
|
setLocalValue(initialValue);
|
|
// Re-validate when initial value changes
|
|
if (touched) {
|
|
setError(validate(initialValue));
|
|
}
|
|
}, [initialValue, touched, validate]);
|
|
|
|
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
|
const newValue = e.target.value;
|
|
setLocalValue(newValue);
|
|
setError(validate(newValue));
|
|
|
|
onAction(fieldConfig.onChange.actionId, {
|
|
value: newValue,
|
|
...(fieldConfig.onChange.parameters || {}),
|
|
});
|
|
}, [fieldConfig.onChange, onAction, validate]);
|
|
|
|
const handleBlur = useCallback(() => {
|
|
setTouched(true);
|
|
setError(validate(localValue));
|
|
}, [localValue, validate]);
|
|
|
|
return (
|
|
<div>
|
|
<Input
|
|
type={fieldConfig.type || 'text'}
|
|
value={localValue}
|
|
onChange={handleChange}
|
|
onBlur={handleBlur}
|
|
placeholder={fieldConfig.placeholder}
|
|
className={cn(touched && error && 'border-destructive')}
|
|
maxLength={fieldConfig.maxLength}
|
|
minLength={fieldConfig.minLength}
|
|
required={fieldConfig.required}
|
|
pattern={fieldConfig.pattern}
|
|
/>
|
|
{touched && error && (
|
|
<p className="text-xs text-destructive mt-1">{error}</p>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|