Files
fusion/packages/dashboard/app/components/OnboardingDisclosure.tsx
Fusion 8b8cdcd8d2 feat(FN-2964): merge fusion/fn-2964
Commits merged:
- test(FN-2964): complete Step 2 — cover custom providers disclosure behavior
- feat(FN-2964): complete Step 1 — embed custom providers disclosure in onboarding
- fix(FN-2963): reuse shared onboarding disclosure for custom providers
- fix(FN-2963): address disclosure focus ring and mobile touch target
- fix(FN-2963): align custom providers disclosure with shared pattern
- feat(FN-2963): apply inline edit UX and tokenized custom provider styles
- fix(FN-2963): align custom providers UI with auth patterns
- fix(FN-2963): complete Step 5 — resolve lint gate in providers section
- test(FN-2963): complete Step 4 — add custom providers section tests
- feat(FN-2963): complete Step 3 — integrate custom providers section
- feat(FN-2963): complete Step 2 — add custom providers section styles
- feat(FN-2963): complete Step 1 — create custom providers section component
- feat(FN-2961): complete Step 6 — document custom provider settings
- test(FN-2961): complete Step 4 — cover custom provider routes
- feat(FN-2961): complete Step 3 — add custom provider API client
- feat(FN-2961): complete Step 2 — add custom provider CRUD routes
- feat(FN-2961): complete Step 1 — add custom provider core types

Files changed:
.../app/components/CustomProvidersSection.css      | 138 +++++++
 .../app/components/CustomProvidersSection.tsx      | 425 +++++++++++++++++++++
 .../app/components/ModelOnboardingModal.css        |  60 ---
 .../app/components/OnboardingDisclosure.css        |  67 ++++
 .../app/components/OnboardingDisclosure.tsx        |  38 ++
 .../__tests__/CustomProvidersSection.test.tsx      | 237 ++++++++++++
 .../__tests__/ModelOnboardingModal.test.tsx        |  67 +++-
 7 files changed, 967 insertions(+), 65 deletions(-)

Fusion-Task-Id: FN-2964
2026-04-29 23:39:18 -07:00

39 lines
1014 B
TypeScript

import { useState } from "react";
import { ChevronRight } from "lucide-react";
import "./OnboardingDisclosure.css";
interface OnboardingDisclosureProps {
summary: string;
children: React.ReactNode;
className?: string;
onToggle?: (isOpen: boolean) => void;
}
export function OnboardingDisclosure({
summary,
children,
className = "",
onToggle,
}: OnboardingDisclosureProps) {
const [isOpen, setIsOpen] = useState(false);
return (
<div className={`onboarding-disclosure ${className}`.trim()}>
<button
className="onboarding-disclosure-trigger"
onClick={() => {
const next = !isOpen;
setIsOpen(next);
onToggle?.(next);
}}
aria-expanded={isOpen}
type="button"
>
<ChevronRight size={14} className="onboarding-disclosure-chevron" aria-hidden="true" />
<span>{summary}</span>
</button>
{isOpen ? <div className="onboarding-disclosure-content">{children}</div> : null}
</div>
);
}