- Unify API: lib/api.ts uses /api/v1, inbox uses /api/inbox (rewrites) - Remove localhost refs: openapi, inbox page - Add rewrites: /api/inbox|tmc -> inbox-server, /api/v1 -> FastAPI - Add stub routes: knowledge/insights, recommendations, search, log-error - Transfer from PAPA: prompts (inspection, tmc), scripts, supabase, data/tmc-requests - Fix inbox-server: ORDER BY created_at, package.json - Remove redundant app/api/inbox/files route (rewrites handle it) - knowledge/ in gitignore (large PDFs) Co-authored-by: Cursor <cursoragent@cursor.com>
72 lines
1.7 KiB
TypeScript
72 lines
1.7 KiB
TypeScript
/**
|
||
* Доступное поле ввода с поддержкой ARIA
|
||
*/
|
||
'use client';
|
||
|
||
import { InputHTMLAttributes, useId } from 'react';
|
||
import { getFormFieldAriaProps } from '@/lib/accessibility/aria';
|
||
import FormField from './FormField';
|
||
|
||
interface AccessibleInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'aria-label' | 'aria-describedby'> {
|
||
label: string;
|
||
error?: string;
|
||
hint?: string;
|
||
required?: boolean;
|
||
}
|
||
|
||
export default function AccessibleInput({
|
||
label,
|
||
error,
|
||
hint,
|
||
required = false,
|
||
id,
|
||
...inputProps
|
||
}: AccessibleInputProps) {
|
||
const generatedId = useId();
|
||
const inputId = id || `input-${generatedId}`;
|
||
const errorId = error ? `error-${generatedId}` : undefined;
|
||
const hintId = hint ? `hint-${generatedId}` : undefined;
|
||
|
||
const ariaProps = getFormFieldAriaProps({
|
||
labelId: `${inputId}-label`,
|
||
describedBy: [hintId, errorId].filter(Boolean).join(' ') || undefined,
|
||
required,
|
||
invalid: !!error,
|
||
errorId,
|
||
});
|
||
|
||
return (
|
||
<FormField
|
||
label={label}
|
||
name={inputId}
|
||
error={error}
|
||
required={required}
|
||
hint={hint}
|
||
>
|
||
<input
|
||
{...inputProps}
|
||
{...ariaProps}
|
||
id={inputId}
|
||
style={{
|
||
width: '100%',
|
||
padding: '10px',
|
||
border: `1px solid ${error ? '#f44336' : '#ccc'}`,
|
||
borderRadius: '4px',
|
||
fontSize: '14px',
|
||
...inputProps.style,
|
||
}}
|
||
/>
|
||
{hint && (
|
||
<div id={hintId} style={{ display: 'none' }}>
|
||
{hint}
|
||
</div>
|
||
)}
|
||
{error && (
|
||
<div id={errorId} style={{ display: 'none' }}>
|
||
{error}
|
||
</div>
|
||
)}
|
||
</FormField>
|
||
);
|
||
}
|