- 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>
73 lines
1.5 KiB
TypeScript
73 lines
1.5 KiB
TypeScript
/**
|
||
* Доступная кнопка с поддержкой ARIA и клавиатуры
|
||
*/
|
||
'use client';
|
||
|
||
import { ReactNode, KeyboardEvent } from 'react';
|
||
import { getButtonAriaProps } from '@/lib/accessibility/aria';
|
||
import { createActivationHandler } from '@/lib/accessibility/keyboard';
|
||
|
||
interface AccessibleButtonProps {
|
||
children: ReactNode;
|
||
onClick: () => void;
|
||
ariaLabel?: string;
|
||
ariaDescribedBy?: string;
|
||
disabled?: boolean;
|
||
pressed?: boolean;
|
||
expanded?: boolean;
|
||
controls?: string;
|
||
className?: string;
|
||
style?: React.CSSProperties;
|
||
type?: 'button' | 'submit' | 'reset';
|
||
}
|
||
|
||
export default function AccessibleButton({
|
||
children,
|
||
onClick,
|
||
ariaLabel,
|
||
ariaDescribedBy,
|
||
disabled = false,
|
||
pressed,
|
||
expanded,
|
||
controls,
|
||
className,
|
||
style,
|
||
type = 'button',
|
||
}: AccessibleButtonProps) {
|
||
const ariaProps = getButtonAriaProps({
|
||
label: ariaLabel,
|
||
describedBy: ariaDescribedBy,
|
||
pressed,
|
||
expanded,
|
||
controls,
|
||
disabled,
|
||
});
|
||
|
||
const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {
|
||
const handler = createActivationHandler(() => {
|
||
if (!disabled) {
|
||
onClick();
|
||
}
|
||
});
|
||
handler(event.nativeEvent);
|
||
};
|
||
|
||
return (
|
||
<button
|
||
type={type}
|
||
onClick={onClick}
|
||
onKeyDown={handleKeyDown}
|
||
disabled={disabled}
|
||
className={className}
|
||
style={{
|
||
cursor: disabled ? 'not-allowed' : 'pointer',
|
||
opacity: disabled ? 0.6 : 1,
|
||
...style,
|
||
}}
|
||
{...ariaProps}
|
||
>
|
||
{children}
|
||
</button>
|
||
);
|
||
}
|