@fragments-sdk/cli 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +83 -33
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-WI6SLMSO.js → chunk-5GT62FCB.js} +2 -2
- package/dist/{chunk-CJEGT3WD.js → chunk-BW3ZATBW.js} +20 -3
- package/dist/chunk-BW3ZATBW.js.map +1 -0
- package/dist/{chunk-2JIKCJX3.js → chunk-D7372LQX.js} +13 -6
- package/dist/chunk-D7372LQX.js.map +1 -0
- package/dist/chunk-EZYXYWNF.js +131 -0
- package/dist/chunk-EZYXYWNF.js.map +1 -0
- package/dist/{chunk-NGIMCIK2.js → chunk-GF6OVPIN.js} +2 -2
- package/dist/{chunk-GOVI6COW.js → chunk-NVSPGSKB.js} +12 -4
- package/dist/chunk-NVSPGSKB.js.map +1 -0
- package/dist/core/index.d.ts +105 -3
- package/dist/core/index.js +12 -2
- package/dist/{defineFragment-D0UTve-I.d.ts → defineFragment-CBMS7Bab.d.ts} +21 -1
- package/dist/generate-LQA2R7FN.js +461 -0
- package/dist/generate-LQA2R7FN.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/{init-KSAAS7X3.js → init-2GEGVIUQ.js} +13 -75
- package/dist/init-2GEGVIUQ.js.map +1 -0
- package/dist/mcp-bin.js +4 -3
- package/dist/mcp-bin.js.map +1 -1
- package/dist/{scan-65RH3QMM.js → scan-JGS65S7P.js} +6 -5
- package/dist/{service-A5GIGGGK.js → service-XP2EAJXD.js} +4 -3
- package/dist/{static-viewer-NSODM5VX.js → static-viewer-XCS7UJTO.js} +4 -3
- package/dist/storyFilters-3LUYAFZF.js +15 -0
- package/dist/storyFilters-3LUYAFZF.js.map +1 -0
- package/dist/{test-RPWZAYSJ.js → test-TD6TJNVY.js} +3 -3
- package/dist/{tokens-NIXSZRX7.js → tokens-2EXPCVP3.js} +5 -4
- package/dist/{tokens-NIXSZRX7.js.map → tokens-2EXPCVP3.js.map} +1 -1
- package/dist/{viewer-SBTJDMP7.js → viewer-RFA2KVBG.js} +243 -18
- package/dist/viewer-RFA2KVBG.js.map +1 -0
- package/package.json +1 -1
- package/src/build.ts +12 -2
- package/src/commands/build.ts +16 -2
- package/src/commands/generate.ts +383 -68
- package/src/commands/init.ts +9 -51
- package/src/core/config.ts +15 -2
- package/src/core/generators/typescript-extractor.ts +10 -0
- package/src/core/index.ts +15 -0
- package/src/core/schema.ts +10 -2
- package/src/core/storyFilters.test.ts +350 -0
- package/src/core/storyFilters.ts +253 -0
- package/src/core/types.ts +22 -0
- package/src/migrate/converter.ts +9 -1
- package/src/migrate/parser.ts +2 -0
- package/src/migrate/types.ts +2 -0
- package/src/setup.ts +69 -24
- package/src/viewer/__tests__/viewer-integration.test.ts +1 -1
- package/src/viewer/components/AccessibilityPanel.tsx +305 -312
- package/src/viewer/components/ActionsPanel.tsx +31 -29
- package/src/viewer/components/AllVariantsPreview.tsx +78 -0
- package/src/viewer/components/App.tsx +187 -740
- package/src/viewer/components/BottomPanel.tsx +228 -132
- package/src/viewer/components/CodePanel.tsx +1 -1
- package/src/viewer/components/CommandPalette.tsx +7 -10
- package/src/viewer/components/ComponentDocView.tsx +164 -0
- package/src/viewer/components/ComponentGraph.tsx +111 -142
- package/src/viewer/components/ContractPanel.tsx +6 -6
- package/src/viewer/components/EmptyVariantMessage.tsx +54 -0
- package/src/viewer/components/FigmaEmbed.tsx +20 -18
- package/src/viewer/components/FragmentEditor.tsx +92 -115
- package/src/viewer/components/HeaderSearch.tsx +24 -0
- package/src/viewer/components/HealthDashboard.tsx +16 -2
- package/src/viewer/components/Icons.tsx +9 -0
- package/src/viewer/components/InteractionsPanel.tsx +101 -117
- package/src/viewer/components/IsolatedPreviewFrame.tsx +1 -0
- package/src/viewer/components/LandingPage.tsx +3 -3
- package/src/viewer/components/LeftSidebar.tsx +141 -63
- package/src/viewer/components/LoadErrorMessage.tsx +102 -0
- package/src/viewer/components/MultiViewportPreview.tsx +61 -142
- package/src/viewer/components/NoVariantsMessage.tsx +59 -0
- package/src/viewer/components/PanelShell.tsx +161 -0
- package/src/viewer/components/PerformancePanel.tsx +31 -28
- package/src/viewer/components/PreviewArea.tsx +1 -1
- package/src/viewer/components/PreviewAside.tsx +168 -0
- package/src/viewer/components/PreviewFrameHost.tsx +3 -3
- package/src/viewer/components/PropsEditor.tsx +70 -156
- package/src/viewer/components/ResizablePanel.tsx +103 -263
- package/src/viewer/components/RightSidebar.tsx +3 -9
- package/src/viewer/components/SkeletonLoader.tsx +13 -13
- package/src/viewer/components/TokenStylePanel.tsx +182 -209
- package/src/viewer/components/TopToolbar.tsx +159 -0
- package/src/viewer/components/VariantMatrix.tsx +42 -86
- package/src/viewer/components/VariantTabs.tsx +3 -3
- package/src/viewer/components/ViewerHeader.tsx +69 -0
- package/src/viewer/components/WebMCPDevTools.tsx +17 -23
- package/src/viewer/components/viewer-utils.ts +16 -0
- package/src/viewer/entry.tsx +5 -0
- package/src/viewer/hooks/useAppState.ts +27 -4
- package/src/viewer/hooks/usePreviewBridge.ts +2 -2
- package/src/viewer/preview-frame.html +6 -12
- package/src/viewer/server.ts +169 -2
- package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss +10 -0
- package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss.d.ts +2 -0
- package/src/viewer/vendor/shared/src/ComponentDocContent.tsx +274 -0
- package/src/viewer/vendor/shared/src/DocsHeaderBar.tsx +6 -18
- package/src/viewer/vendor/shared/src/DocsPageShell.tsx +5 -0
- package/src/viewer/vendor/shared/src/DocsSidebarNav.tsx +5 -16
- package/src/viewer/vendor/shared/src/PropsTable.module.scss +68 -0
- package/src/viewer/vendor/shared/src/PropsTable.module.scss.d.ts +2 -0
- package/src/viewer/vendor/shared/src/PropsTable.tsx +76 -0
- package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +122 -0
- package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss.d.ts +2 -0
- package/src/viewer/vendor/shared/src/VariantPreviewCard.tsx +134 -0
- package/src/viewer/vendor/shared/src/index.ts +8 -0
- package/src/viewer/vendor/shared/src/types.ts +12 -0
- package/src/viewer/vite-plugin.ts +109 -4
- package/dist/chunk-2JIKCJX3.js.map +0 -1
- package/dist/chunk-CJEGT3WD.js.map +0 -1
- package/dist/chunk-GOVI6COW.js.map +0 -1
- package/dist/generate-35OIMW4Y.js +0 -252
- package/dist/generate-35OIMW4Y.js.map +0 -1
- package/dist/init-KSAAS7X3.js.map +0 -1
- package/dist/viewer-SBTJDMP7.js.map +0 -1
- /package/dist/{chunk-WI6SLMSO.js.map → chunk-5GT62FCB.js.map} +0 -0
- /package/dist/{chunk-NGIMCIK2.js.map → chunk-GF6OVPIN.js.map} +0 -0
- /package/dist/{scan-65RH3QMM.js.map → scan-JGS65S7P.js.map} +0 -0
- /package/dist/{service-A5GIGGGK.js.map → service-XP2EAJXD.js.map} +0 -0
- /package/dist/{static-viewer-NSODM5VX.js.map → static-viewer-XCS7UJTO.js.map} +0 -0
- /package/dist/{test-RPWZAYSJ.js.map → test-TD6TJNVY.js.map} +0 -0
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
import { useState, useEffect, useCallback, useMemo, useRef } from "react";
|
|
13
13
|
import type { Result, NodeResult, ImpactValue, RunOptions } from "axe-core";
|
|
14
|
-
import { Badge, Tabs, Dialog, Card, Alert, Text, Stack, Box, Button, Chip, EmptyState } from "@fragments-sdk/ui";
|
|
14
|
+
import { Badge, Tabs, Dialog, Card, Alert, Text, Stack, Box, Button, Chip, EmptyState, Input } from "@fragments-sdk/ui";
|
|
15
|
+
import { ShieldCheck, XCircle, Wheelchair } from "@phosphor-icons/react";
|
|
16
|
+
import { PanelShell } from "./PanelShell.js";
|
|
15
17
|
import { BRAND } from "../../core/index.js";
|
|
16
18
|
import {
|
|
17
19
|
updateComponentA11yResult,
|
|
@@ -577,163 +579,178 @@ export function AccessibilityPanel({
|
|
|
577
579
|
|
|
578
580
|
// Check if currently re-scanning due to HMR
|
|
579
581
|
const isReScanning = isScanning && results !== null;
|
|
582
|
+
const isInitialScan = isScanning && !results;
|
|
583
|
+
|
|
584
|
+
// Determine empty config for error / no-results states
|
|
585
|
+
const emptyConfig = (() => {
|
|
586
|
+
if (!isInitialScan && error) {
|
|
587
|
+
return {
|
|
588
|
+
icon: <XCircle size={24} weight="regular" style={{ color: 'var(--color-danger)' }} />,
|
|
589
|
+
title: "Scan failed",
|
|
590
|
+
description: error,
|
|
591
|
+
action: <Button variant="secondary" size="sm" onClick={runScan}>Retry Scan</Button>,
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
if (!isInitialScan && !error && !results) {
|
|
595
|
+
return {
|
|
596
|
+
icon: <Wheelchair size={24} weight="regular" style={{ color: 'var(--text-tertiary)' }} />,
|
|
597
|
+
title: "No scan results",
|
|
598
|
+
description: "Run an accessibility scan to check this component for WCAG violations.",
|
|
599
|
+
action: <Button size="sm" onClick={runScan}>Run Scan</Button>,
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
return undefined;
|
|
603
|
+
})();
|
|
580
604
|
|
|
581
|
-
//
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
<
|
|
585
|
-
<
|
|
605
|
+
// Custom loading skeleton for accessibility scan
|
|
606
|
+
const loadingSkeleton = (
|
|
607
|
+
<Stack gap="md">
|
|
608
|
+
<Box paddingX="md" paddingY="xs" background="secondary" rounded="md">
|
|
609
|
+
<Stack direction="row" align="center" gap="md">
|
|
610
|
+
{[0, 1, 2].map((i) => (
|
|
611
|
+
<div key={i} style={{ width: '90px', height: '28px', borderRadius: '6px', background: 'var(--bg-hover)', animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', animationDelay: `${i * 100}ms` }} />
|
|
612
|
+
))}
|
|
613
|
+
</Stack>
|
|
614
|
+
</Box>
|
|
615
|
+
{[0, 1, 2].map((i) => (
|
|
616
|
+
<Card key={i}>
|
|
617
|
+
<Box padding="sm">
|
|
618
|
+
<Stack direction="row" align="center" gap="sm">
|
|
619
|
+
<div style={{ width: '16px', height: '16px', borderRadius: '4px', background: 'var(--bg-hover)', animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', animationDelay: `${i * 150}ms` }} />
|
|
620
|
+
<div style={{ width: '50px', height: '18px', borderRadius: '9px', background: 'var(--bg-hover)', animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', animationDelay: `${i * 150 + 50}ms` }} />
|
|
621
|
+
<div style={{ flex: 1, height: '14px', borderRadius: '4px', background: 'var(--bg-hover)', animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', animationDelay: `${i * 150 + 100}ms` }} />
|
|
622
|
+
<div style={{ width: '60px', height: '18px', borderRadius: '9px', background: 'var(--bg-hover)', animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', animationDelay: `${i * 150 + 150}ms` }} />
|
|
623
|
+
</Stack>
|
|
624
|
+
</Box>
|
|
625
|
+
</Card>
|
|
626
|
+
))}
|
|
627
|
+
<Stack direction="row" align="center" justify="center" gap="xs">
|
|
628
|
+
<LoadingIcon style={{ width: 14, height: 14, animation: 'spin 1s linear infinite' }} />
|
|
586
629
|
<Text size="xs" color="tertiary">Running accessibility checks...</Text>
|
|
587
630
|
</Stack>
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
// Render error state
|
|
592
|
-
if (error) {
|
|
593
|
-
return (
|
|
594
|
-
<Stack align="center" justify="center" style={{ padding: 32 }}>
|
|
595
|
-
<XIcon style={{ width: 24, height: 24, color: 'var(--color-danger)', marginBottom: 8 }} />
|
|
596
|
-
<Text size="xs" color="secondary" style={{ color: 'var(--color-danger)', marginBottom: 8 }}>{error}</Text>
|
|
597
|
-
<Button variant="ghost" size="sm" onClick={runScan}>Retry Scan</Button>
|
|
598
|
-
</Stack>
|
|
599
|
-
);
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// Render no results state
|
|
603
|
-
if (!results) {
|
|
604
|
-
return (
|
|
605
|
-
<Stack align="center" justify="center" style={{ padding: 32 }}>
|
|
606
|
-
<AccessibilityIcon style={{ width: 32, height: 32, marginBottom: 8, opacity: 0.5, color: 'var(--text-tertiary)' }} />
|
|
607
|
-
<Text size="xs" color="tertiary" style={{ marginBottom: 8 }}>No accessibility scan results</Text>
|
|
608
|
-
<Button size="sm" onClick={runScan}>Run Scan</Button>
|
|
609
|
-
</Stack>
|
|
610
|
-
);
|
|
611
|
-
}
|
|
631
|
+
</Stack>
|
|
632
|
+
);
|
|
612
633
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
<
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
size="sm"
|
|
670
|
-
onClick={() => setShowAISetup(true)}
|
|
671
|
-
title={aiConfig ? "AI fixes enabled" : "Configure AI for fix suggestions"}
|
|
672
|
-
>
|
|
673
|
-
<WandIcon style={{ width: 12, height: 12 }} />
|
|
674
|
-
{aiConfig ? "AI Ready" : "Setup AI"}
|
|
675
|
-
</Button>
|
|
676
|
-
</Stack>
|
|
634
|
+
// Toolbar with tabs, rescan badge, and action buttons (only when results exist)
|
|
635
|
+
const toolbar = results && !error ? (
|
|
636
|
+
<Stack direction="row" align="center" gap="xs" style={{ width: '100%' }}>
|
|
637
|
+
<Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as TabType)}>
|
|
638
|
+
<Tabs.List>
|
|
639
|
+
<Tabs.Tab value="violations">
|
|
640
|
+
<span style={{ color: 'var(--color-danger)' }}>{counts.violations}</span> Violations
|
|
641
|
+
</Tabs.Tab>
|
|
642
|
+
<Tabs.Tab value="passes">
|
|
643
|
+
<span style={{ color: 'var(--color-success)' }}>{counts.passes}</span> Passes
|
|
644
|
+
</Tabs.Tab>
|
|
645
|
+
<Tabs.Tab value="incomplete">
|
|
646
|
+
<span style={{ color: 'var(--color-warning)' }}>{counts.incomplete}</span> Incomplete
|
|
647
|
+
</Tabs.Tab>
|
|
648
|
+
</Tabs.List>
|
|
649
|
+
</Tabs>
|
|
650
|
+
|
|
651
|
+
<Box style={{ flex: 1 }} />
|
|
652
|
+
|
|
653
|
+
{isReScanning && (
|
|
654
|
+
<Badge variant="warning" size="sm">
|
|
655
|
+
<Stack direction="row" align="center" gap="xs">
|
|
656
|
+
<LoadingIcon style={{ width: 12, height: 12, animation: 'spin 1s linear infinite' }} />
|
|
657
|
+
Re-scanning...
|
|
658
|
+
</Stack>
|
|
659
|
+
</Badge>
|
|
660
|
+
)}
|
|
661
|
+
|
|
662
|
+
<Button
|
|
663
|
+
variant="ghost"
|
|
664
|
+
size="sm"
|
|
665
|
+
onClick={runScan}
|
|
666
|
+
disabled={isScanning}
|
|
667
|
+
title="Re-run accessibility scan"
|
|
668
|
+
>
|
|
669
|
+
<LoadingIcon
|
|
670
|
+
style={{
|
|
671
|
+
width: 12,
|
|
672
|
+
height: 12,
|
|
673
|
+
...(isScanning ? { animation: 'spin 1s linear infinite' } : {}),
|
|
674
|
+
}}
|
|
675
|
+
/>
|
|
676
|
+
{isScanning ? "Scanning..." : "Rescan"}
|
|
677
|
+
</Button>
|
|
678
|
+
|
|
679
|
+
<Button
|
|
680
|
+
variant={aiConfig ? "secondary" : "ghost"}
|
|
681
|
+
size="sm"
|
|
682
|
+
onClick={() => setShowAISetup(true)}
|
|
683
|
+
title={aiConfig ? "AI fixes enabled" : "Configure AI for fix suggestions"}
|
|
684
|
+
>
|
|
685
|
+
<WandIcon style={{ width: 12, height: 12 }} />
|
|
686
|
+
{aiConfig ? "AI Ready" : "Setup AI"}
|
|
687
|
+
</Button>
|
|
688
|
+
</Stack>
|
|
689
|
+
) : undefined;
|
|
677
690
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
691
|
+
return (
|
|
692
|
+
<PanelShell
|
|
693
|
+
loading={isInitialScan}
|
|
694
|
+
loadingContent={loadingSkeleton}
|
|
695
|
+
toolbar={toolbar}
|
|
696
|
+
empty={emptyConfig}
|
|
697
|
+
>
|
|
698
|
+
{activeTab === "violations" && (
|
|
699
|
+
<>
|
|
700
|
+
{counts.violations === 0 ? (
|
|
701
|
+
<SuccessMessage message="No accessibility violations found." />
|
|
702
|
+
) : (
|
|
703
|
+
<EnhancedRuleList
|
|
704
|
+
rules={sortedViolations}
|
|
705
|
+
expandedRules={expandedRules}
|
|
706
|
+
onToggleRule={toggleRule}
|
|
707
|
+
onHighlight={highlightElement}
|
|
708
|
+
highlightedElement={highlightedElement}
|
|
709
|
+
onGenerateFix={generateAIFix}
|
|
710
|
+
generatingFix={generatingFix}
|
|
711
|
+
aiFixes={aiFixes}
|
|
712
|
+
aiEnabled={!!aiConfig}
|
|
713
|
+
onCopyFix={copyFix}
|
|
714
|
+
copiedFix={copiedFix}
|
|
715
|
+
type="violation"
|
|
716
|
+
/>
|
|
717
|
+
)}
|
|
718
|
+
</>
|
|
719
|
+
)}
|
|
720
|
+
|
|
721
|
+
{activeTab === "passes" && (
|
|
722
|
+
<>
|
|
723
|
+
{counts.passes === 0 ? (
|
|
724
|
+
<EmptyMessage message="No passing checks to display." />
|
|
725
|
+
) : (
|
|
726
|
+
<RuleList
|
|
727
|
+
rules={results.passes}
|
|
728
|
+
expandedRules={expandedRules}
|
|
729
|
+
onToggleRule={toggleRule}
|
|
730
|
+
onHighlight={highlightElement}
|
|
731
|
+
highlightedElement={highlightedElement}
|
|
732
|
+
type="pass"
|
|
733
|
+
/>
|
|
734
|
+
)}
|
|
735
|
+
</>
|
|
736
|
+
)}
|
|
737
|
+
|
|
738
|
+
{activeTab === "incomplete" && (
|
|
739
|
+
<>
|
|
740
|
+
{counts.incomplete === 0 ? (
|
|
741
|
+
<EmptyMessage message="No incomplete checks requiring manual review." />
|
|
742
|
+
) : (
|
|
743
|
+
<RuleList
|
|
744
|
+
rules={results.incomplete}
|
|
745
|
+
expandedRules={expandedRules}
|
|
746
|
+
onToggleRule={toggleRule}
|
|
747
|
+
onHighlight={highlightElement}
|
|
748
|
+
highlightedElement={highlightedElement}
|
|
749
|
+
type="incomplete"
|
|
750
|
+
/>
|
|
751
|
+
)}
|
|
752
|
+
</>
|
|
753
|
+
)}
|
|
737
754
|
|
|
738
755
|
{/* AI Setup Dialog */}
|
|
739
756
|
<Dialog open={showAISetup} onOpenChange={(open) => !open && setShowAISetup(false)}>
|
|
@@ -745,7 +762,7 @@ export function AccessibilityPanel({
|
|
|
745
762
|
/>
|
|
746
763
|
</Dialog.Content>
|
|
747
764
|
</Dialog>
|
|
748
|
-
</
|
|
765
|
+
</PanelShell>
|
|
749
766
|
);
|
|
750
767
|
}
|
|
751
768
|
|
|
@@ -790,56 +807,49 @@ function EnhancedRuleList({
|
|
|
790
807
|
return (
|
|
791
808
|
<Card key={rule.id} style={{ borderLeft: `4px solid ${impactColors.borderLeft}` }}>
|
|
792
809
|
{/* Rule Header */}
|
|
793
|
-
<
|
|
810
|
+
<Button
|
|
811
|
+
variant="ghost"
|
|
812
|
+
fullWidth
|
|
794
813
|
onClick={() => onToggleRule(rule.id)}
|
|
795
|
-
style={{
|
|
796
|
-
width: '100%',
|
|
797
|
-
display: 'flex',
|
|
798
|
-
alignItems: 'center',
|
|
799
|
-
gap: 8,
|
|
800
|
-
padding: '10px 12px',
|
|
801
|
-
textAlign: 'left',
|
|
802
|
-
background: 'none',
|
|
803
|
-
border: 'none',
|
|
804
|
-
cursor: 'pointer',
|
|
805
|
-
transition: 'background var(--transition-fast)',
|
|
806
|
-
}}
|
|
814
|
+
style={{ justifyContent: 'flex-start', padding: '10px 12px' }}
|
|
807
815
|
>
|
|
808
|
-
{
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
{/* Impact badge */}
|
|
815
|
-
{rule.impact && (
|
|
816
|
-
<Badge variant={impactColors.variant} size="sm">
|
|
817
|
-
{rule.impact}
|
|
818
|
-
</Badge>
|
|
819
|
-
)}
|
|
820
|
-
|
|
821
|
-
{/* Rule ID */}
|
|
822
|
-
<Text font="mono" size="xs" color="tertiary">{rule.id}</Text>
|
|
823
|
-
|
|
824
|
-
{/* Rule description */}
|
|
825
|
-
<Text size="xs" style={{
|
|
826
|
-
flex: 1,
|
|
827
|
-
overflow: 'hidden',
|
|
828
|
-
textOverflow: 'ellipsis',
|
|
829
|
-
whiteSpace: 'nowrap',
|
|
830
|
-
}}>
|
|
831
|
-
{rule.description}
|
|
832
|
-
</Text>
|
|
816
|
+
<Stack direction="row" align="center" gap="sm" style={{ width: '100%' }}>
|
|
817
|
+
{isExpanded ? (
|
|
818
|
+
<ChevronDownIcon style={{ width: 16, height: 16, color: 'var(--text-tertiary)', flexShrink: 0 }} />
|
|
819
|
+
) : (
|
|
820
|
+
<ChevronRightIcon style={{ width: 16, height: 16, color: 'var(--text-tertiary)', flexShrink: 0 }} />
|
|
821
|
+
)}
|
|
833
822
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
823
|
+
{/* Impact badge */}
|
|
824
|
+
{rule.impact && (
|
|
825
|
+
<Badge variant={impactColors.variant} size="sm">
|
|
826
|
+
{rule.impact}
|
|
827
|
+
</Badge>
|
|
828
|
+
)}
|
|
829
|
+
|
|
830
|
+
{/* Rule ID */}
|
|
831
|
+
<Text font="mono" size="xs" color="tertiary">{rule.id}</Text>
|
|
832
|
+
|
|
833
|
+
{/* Rule description */}
|
|
834
|
+
<Text size="xs" style={{
|
|
835
|
+
flex: 1,
|
|
836
|
+
overflow: 'hidden',
|
|
837
|
+
textOverflow: 'ellipsis',
|
|
838
|
+
whiteSpace: 'nowrap',
|
|
839
|
+
}}>
|
|
840
|
+
{rule.description}
|
|
841
|
+
</Text>
|
|
842
|
+
|
|
843
|
+
{/* Element count */}
|
|
844
|
+
<Badge size="sm">
|
|
845
|
+
{rule.nodes.length} element{rule.nodes.length !== 1 ? "s" : ""}
|
|
846
|
+
</Badge>
|
|
847
|
+
</Stack>
|
|
848
|
+
</Button>
|
|
839
849
|
|
|
840
850
|
{/* Expanded content */}
|
|
841
851
|
{isExpanded && (
|
|
842
|
-
<
|
|
852
|
+
<Box borderTop background="secondary">
|
|
843
853
|
{/* Why it matters + WCAG reference */}
|
|
844
854
|
{staticFix && (
|
|
845
855
|
<Box padding="sm" style={{ borderBottom: '1px solid var(--border-subtle)' }}>
|
|
@@ -863,40 +873,31 @@ function EnhancedRuleList({
|
|
|
863
873
|
WCAG {staticFix.wcagCriterion.id} Level {staticFix.wcagCriterion.level}
|
|
864
874
|
</Badge>
|
|
865
875
|
<Text size="xs" color="secondary">{staticFix.wcagCriterion.name}</Text>
|
|
866
|
-
<
|
|
876
|
+
<Button
|
|
877
|
+
as="a"
|
|
878
|
+
variant="ghost"
|
|
879
|
+
size="sm"
|
|
867
880
|
href={staticFix.wcagCriterion.url}
|
|
868
881
|
target="_blank"
|
|
869
882
|
rel="noopener noreferrer"
|
|
870
|
-
style={{
|
|
871
|
-
fontSize: 12,
|
|
872
|
-
color: 'var(--color-accent)',
|
|
873
|
-
marginLeft: 'auto',
|
|
874
|
-
textDecoration: 'none',
|
|
875
|
-
}}
|
|
883
|
+
style={{ marginLeft: 'auto', fontSize: 12 }}
|
|
876
884
|
>
|
|
877
885
|
Learn more
|
|
878
|
-
</
|
|
886
|
+
</Button>
|
|
879
887
|
</Stack>
|
|
880
888
|
)}
|
|
881
889
|
|
|
882
890
|
{/* Before/After examples */}
|
|
883
891
|
{(staticFix.badExample || staticFix.goodExample) && (
|
|
884
|
-
<
|
|
885
|
-
display: 'grid',
|
|
886
|
-
gridTemplateColumns: '1fr 1fr',
|
|
887
|
-
gap: 8,
|
|
888
|
-
marginTop: 8,
|
|
889
|
-
}}>
|
|
892
|
+
<Box display="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 8 }}>
|
|
890
893
|
{staticFix.badExample && (
|
|
891
894
|
<div>
|
|
892
895
|
<Text size="xs" weight="medium" style={{ color: 'var(--color-danger)', marginBottom: 4 }}>
|
|
893
896
|
Before
|
|
894
897
|
</Text>
|
|
895
|
-
<pre style={{
|
|
898
|
+
<Box as="pre" padding="xs" rounded="sm" style={{
|
|
896
899
|
fontSize: 10,
|
|
897
900
|
fontFamily: 'monospace',
|
|
898
|
-
padding: 8,
|
|
899
|
-
borderRadius: 'var(--radius-sm)',
|
|
900
901
|
background: 'var(--color-danger-bg)',
|
|
901
902
|
color: 'var(--color-danger)',
|
|
902
903
|
overflowX: 'auto',
|
|
@@ -904,7 +905,7 @@ function EnhancedRuleList({
|
|
|
904
905
|
margin: 0,
|
|
905
906
|
}}>
|
|
906
907
|
{staticFix.badExample}
|
|
907
|
-
</
|
|
908
|
+
</Box>
|
|
908
909
|
</div>
|
|
909
910
|
)}
|
|
910
911
|
{staticFix.goodExample && (
|
|
@@ -912,11 +913,9 @@ function EnhancedRuleList({
|
|
|
912
913
|
<Text size="xs" weight="medium" style={{ color: 'var(--color-success)', marginBottom: 4 }}>
|
|
913
914
|
After
|
|
914
915
|
</Text>
|
|
915
|
-
<pre style={{
|
|
916
|
+
<Box as="pre" padding="xs" rounded="sm" style={{
|
|
916
917
|
fontSize: 10,
|
|
917
918
|
fontFamily: 'monospace',
|
|
918
|
-
padding: 8,
|
|
919
|
-
borderRadius: 'var(--radius-sm)',
|
|
920
919
|
background: 'var(--color-success-bg)',
|
|
921
920
|
color: 'var(--color-success)',
|
|
922
921
|
overflowX: 'auto',
|
|
@@ -924,10 +923,10 @@ function EnhancedRuleList({
|
|
|
924
923
|
margin: 0,
|
|
925
924
|
}}>
|
|
926
925
|
{staticFix.goodExample}
|
|
927
|
-
</
|
|
926
|
+
</Box>
|
|
928
927
|
</div>
|
|
929
928
|
)}
|
|
930
|
-
</
|
|
929
|
+
</Box>
|
|
931
930
|
)}
|
|
932
931
|
</Stack>
|
|
933
932
|
</Box>
|
|
@@ -938,14 +937,17 @@ function EnhancedRuleList({
|
|
|
938
937
|
<Box padding="sm" style={{ borderBottom: '1px solid var(--border-subtle)' }}>
|
|
939
938
|
<Text size="xs" color="secondary" style={{ marginBottom: 4 }}>{rule.help}</Text>
|
|
940
939
|
{rule.helpUrl && (
|
|
941
|
-
<
|
|
940
|
+
<Button
|
|
941
|
+
as="a"
|
|
942
|
+
variant="ghost"
|
|
943
|
+
size="sm"
|
|
942
944
|
href={rule.helpUrl}
|
|
943
945
|
target="_blank"
|
|
944
946
|
rel="noopener noreferrer"
|
|
945
|
-
style={{ fontSize: 12
|
|
947
|
+
style={{ fontSize: 12 }}
|
|
946
948
|
>
|
|
947
949
|
Learn more about {rule.id}
|
|
948
|
-
</
|
|
950
|
+
</Button>
|
|
949
951
|
)}
|
|
950
952
|
</Box>
|
|
951
953
|
)}
|
|
@@ -1011,20 +1013,18 @@ function EnhancedRuleList({
|
|
|
1011
1013
|
</Stack>
|
|
1012
1014
|
|
|
1013
1015
|
{/* HTML snippet */}
|
|
1014
|
-
<pre style={{
|
|
1016
|
+
<Box as="pre" padding="xs" rounded="sm" style={{
|
|
1015
1017
|
fontSize: 10,
|
|
1016
1018
|
fontFamily: 'monospace',
|
|
1017
1019
|
color: 'var(--text-tertiary)',
|
|
1018
1020
|
background: 'var(--bg-primary)',
|
|
1019
|
-
borderRadius: 'var(--radius-sm)',
|
|
1020
|
-
padding: 8,
|
|
1021
1021
|
overflowX: 'auto',
|
|
1022
1022
|
whiteSpace: 'pre-wrap',
|
|
1023
1023
|
border: '1px solid var(--border-subtle)',
|
|
1024
1024
|
margin: 0,
|
|
1025
1025
|
}}>
|
|
1026
1026
|
{node.html}
|
|
1027
|
-
</
|
|
1027
|
+
</Box>
|
|
1028
1028
|
|
|
1029
1029
|
{/* Failure summary */}
|
|
1030
1030
|
{node.failureSummary && (
|
|
@@ -1054,19 +1054,17 @@ function EnhancedRuleList({
|
|
|
1054
1054
|
<Text size="xs" style={{ color: 'var(--color-info)', marginBottom: 8 }}>
|
|
1055
1055
|
{elementFix.explanation}
|
|
1056
1056
|
</Text>
|
|
1057
|
-
<pre style={{
|
|
1057
|
+
<Box as="pre" padding="xs" rounded="sm" style={{
|
|
1058
1058
|
fontSize: 10,
|
|
1059
1059
|
fontFamily: 'monospace',
|
|
1060
1060
|
color: 'var(--color-info)',
|
|
1061
1061
|
background: 'var(--bg-secondary)',
|
|
1062
|
-
borderRadius: 'var(--radius-sm)',
|
|
1063
|
-
padding: 8,
|
|
1064
1062
|
overflowX: 'auto',
|
|
1065
1063
|
whiteSpace: 'pre-wrap',
|
|
1066
1064
|
margin: 0,
|
|
1067
1065
|
}}>
|
|
1068
1066
|
{elementFix.fixedHtml}
|
|
1069
|
-
</
|
|
1067
|
+
</Box>
|
|
1070
1068
|
</Alert.Content>
|
|
1071
1069
|
</Alert.Body>
|
|
1072
1070
|
</Alert>
|
|
@@ -1074,10 +1072,8 @@ function EnhancedRuleList({
|
|
|
1074
1072
|
|
|
1075
1073
|
{/* AI fix suggestion */}
|
|
1076
1074
|
{aiFixes?.[fixKey] && (
|
|
1077
|
-
<
|
|
1075
|
+
<Box padding="xs" rounded="sm" style={{
|
|
1078
1076
|
marginTop: 8,
|
|
1079
|
-
padding: 8,
|
|
1080
|
-
borderRadius: 'var(--radius-sm)',
|
|
1081
1077
|
background: 'var(--color-accent-subtle)',
|
|
1082
1078
|
border: '1px solid var(--color-accent)',
|
|
1083
1079
|
}}>
|
|
@@ -1087,7 +1083,7 @@ function EnhancedRuleList({
|
|
|
1087
1083
|
AI Fix Suggestion
|
|
1088
1084
|
</Text>
|
|
1089
1085
|
</Stack>
|
|
1090
|
-
<pre style={{
|
|
1086
|
+
<Box as="pre" style={{
|
|
1091
1087
|
fontSize: 10,
|
|
1092
1088
|
fontFamily: 'monospace',
|
|
1093
1089
|
color: 'var(--color-accent)',
|
|
@@ -1095,8 +1091,8 @@ function EnhancedRuleList({
|
|
|
1095
1091
|
margin: 0,
|
|
1096
1092
|
}}>
|
|
1097
1093
|
{aiFixes[fixKey]}
|
|
1098
|
-
</
|
|
1099
|
-
</
|
|
1094
|
+
</Box>
|
|
1095
|
+
</Box>
|
|
1100
1096
|
)}
|
|
1101
1097
|
</Box>
|
|
1102
1098
|
);
|
|
@@ -1118,7 +1114,7 @@ function EnhancedRuleList({
|
|
|
1118
1114
|
</Stack>
|
|
1119
1115
|
</Box>
|
|
1120
1116
|
)}
|
|
1121
|
-
</
|
|
1117
|
+
</Box>
|
|
1122
1118
|
)}
|
|
1123
1119
|
</Card>
|
|
1124
1120
|
);
|
|
@@ -1152,63 +1148,59 @@ function RuleList({
|
|
|
1152
1148
|
return (
|
|
1153
1149
|
<Card key={rule.id}>
|
|
1154
1150
|
{/* Rule Header */}
|
|
1155
|
-
<
|
|
1151
|
+
<Button
|
|
1152
|
+
variant="ghost"
|
|
1153
|
+
fullWidth
|
|
1156
1154
|
onClick={() => onToggleRule(rule.id)}
|
|
1157
|
-
style={{
|
|
1158
|
-
width: '100%',
|
|
1159
|
-
display: 'flex',
|
|
1160
|
-
alignItems: 'center',
|
|
1161
|
-
gap: 8,
|
|
1162
|
-
padding: '8px 12px',
|
|
1163
|
-
textAlign: 'left',
|
|
1164
|
-
background: 'none',
|
|
1165
|
-
border: 'none',
|
|
1166
|
-
cursor: 'pointer',
|
|
1167
|
-
transition: 'background var(--transition-fast)',
|
|
1168
|
-
}}
|
|
1155
|
+
style={{ justifyContent: 'flex-start', padding: '8px 12px' }}
|
|
1169
1156
|
>
|
|
1170
|
-
{
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
{type === "pass" && (
|
|
1177
|
-
<CheckIcon style={{ width: 16, height: 16, color: 'var(--color-success)', flexShrink: 0 }} />
|
|
1178
|
-
)}
|
|
1179
|
-
|
|
1180
|
-
{type === "incomplete" && (
|
|
1181
|
-
<Badge variant="warning" size="sm">Review</Badge>
|
|
1182
|
-
)}
|
|
1183
|
-
|
|
1184
|
-
<Text size="xs" style={{
|
|
1185
|
-
flex: 1,
|
|
1186
|
-
overflow: 'hidden',
|
|
1187
|
-
textOverflow: 'ellipsis',
|
|
1188
|
-
whiteSpace: 'nowrap',
|
|
1189
|
-
}}>
|
|
1190
|
-
{rule.description}
|
|
1191
|
-
</Text>
|
|
1157
|
+
<Stack direction="row" align="center" gap="sm" style={{ width: '100%' }}>
|
|
1158
|
+
{isExpanded ? (
|
|
1159
|
+
<ChevronDownIcon style={{ width: 16, height: 16, color: 'var(--text-tertiary)', flexShrink: 0 }} />
|
|
1160
|
+
) : (
|
|
1161
|
+
<ChevronRightIcon style={{ width: 16, height: 16, color: 'var(--text-tertiary)', flexShrink: 0 }} />
|
|
1162
|
+
)}
|
|
1192
1163
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1164
|
+
{type === "pass" && (
|
|
1165
|
+
<CheckIcon style={{ width: 16, height: 16, color: 'var(--color-success)', flexShrink: 0 }} />
|
|
1166
|
+
)}
|
|
1167
|
+
|
|
1168
|
+
{type === "incomplete" && (
|
|
1169
|
+
<Badge variant="warning" size="sm">Review</Badge>
|
|
1170
|
+
)}
|
|
1171
|
+
|
|
1172
|
+
<Text size="xs" style={{
|
|
1173
|
+
flex: 1,
|
|
1174
|
+
overflow: 'hidden',
|
|
1175
|
+
textOverflow: 'ellipsis',
|
|
1176
|
+
whiteSpace: 'nowrap',
|
|
1177
|
+
}}>
|
|
1178
|
+
{rule.description}
|
|
1179
|
+
</Text>
|
|
1180
|
+
|
|
1181
|
+
<Text size="xs" color="tertiary" style={{ flexShrink: 0 }}>
|
|
1182
|
+
{rule.nodes.length} element{rule.nodes.length !== 1 ? "s" : ""}
|
|
1183
|
+
</Text>
|
|
1184
|
+
</Stack>
|
|
1185
|
+
</Button>
|
|
1197
1186
|
|
|
1198
1187
|
{/* Expanded content */}
|
|
1199
1188
|
{isExpanded && (
|
|
1200
|
-
<
|
|
1189
|
+
<Box borderTop background="secondary">
|
|
1201
1190
|
<Box padding="sm" style={{ borderBottom: '1px solid var(--border-subtle)' }}>
|
|
1202
1191
|
<Text size="xs" color="secondary" style={{ marginBottom: 4 }}>{rule.help}</Text>
|
|
1203
1192
|
{rule.helpUrl && (
|
|
1204
|
-
<
|
|
1193
|
+
<Button
|
|
1194
|
+
as="a"
|
|
1195
|
+
variant="ghost"
|
|
1196
|
+
size="sm"
|
|
1205
1197
|
href={rule.helpUrl}
|
|
1206
1198
|
target="_blank"
|
|
1207
1199
|
rel="noopener noreferrer"
|
|
1208
|
-
style={{ fontSize: 12
|
|
1200
|
+
style={{ fontSize: 12 }}
|
|
1209
1201
|
>
|
|
1210
1202
|
Learn more about {rule.id}
|
|
1211
|
-
</
|
|
1203
|
+
</Button>
|
|
1212
1204
|
)}
|
|
1213
1205
|
</Box>
|
|
1214
1206
|
|
|
@@ -1248,24 +1240,22 @@ function RuleList({
|
|
|
1248
1240
|
{node.target[node.target.length - 1]}
|
|
1249
1241
|
</Button>
|
|
1250
1242
|
|
|
1251
|
-
<pre style={{
|
|
1243
|
+
<Box as="pre" padding="xs" rounded="sm" style={{
|
|
1252
1244
|
fontSize: 10,
|
|
1253
1245
|
fontFamily: 'monospace',
|
|
1254
1246
|
color: 'var(--text-tertiary)',
|
|
1255
1247
|
background: 'var(--bg-primary)',
|
|
1256
|
-
borderRadius: 'var(--radius-sm)',
|
|
1257
|
-
padding: 8,
|
|
1258
1248
|
overflowX: 'auto',
|
|
1259
1249
|
whiteSpace: 'pre-wrap',
|
|
1260
1250
|
margin: 0,
|
|
1261
1251
|
}}>
|
|
1262
1252
|
{node.html}
|
|
1263
|
-
</
|
|
1253
|
+
</Box>
|
|
1264
1254
|
</Box>
|
|
1265
1255
|
);
|
|
1266
1256
|
})}
|
|
1267
1257
|
</div>
|
|
1268
|
-
</
|
|
1258
|
+
</Box>
|
|
1269
1259
|
)}
|
|
1270
1260
|
</Card>
|
|
1271
1261
|
);
|
|
@@ -1278,17 +1268,15 @@ function SuccessMessage({ message }: { message: string }) {
|
|
|
1278
1268
|
return (
|
|
1279
1269
|
<EmptyState>
|
|
1280
1270
|
<EmptyState.Icon>
|
|
1281
|
-
<
|
|
1271
|
+
<Box rounded="full" display="flex" style={{
|
|
1282
1272
|
width: 48,
|
|
1283
1273
|
height: 48,
|
|
1284
|
-
borderRadius: '50%',
|
|
1285
|
-
background: 'var(--color-success-bg)',
|
|
1286
|
-
display: 'flex',
|
|
1287
1274
|
alignItems: 'center',
|
|
1288
1275
|
justifyContent: 'center',
|
|
1276
|
+
background: 'var(--color-success-bg)',
|
|
1289
1277
|
}}>
|
|
1290
|
-
<
|
|
1291
|
-
</
|
|
1278
|
+
<ShieldCheck size={24} weight="regular" style={{ color: 'var(--color-success)' }} />
|
|
1279
|
+
</Box>
|
|
1292
1280
|
</EmptyState.Icon>
|
|
1293
1281
|
<EmptyState.Title style={{ color: 'var(--color-success)' }}>{message}</EmptyState.Title>
|
|
1294
1282
|
<EmptyState.Description>
|
|
@@ -1302,7 +1290,15 @@ function EmptyMessage({ message }: { message: string }) {
|
|
|
1302
1290
|
return (
|
|
1303
1291
|
<EmptyState>
|
|
1304
1292
|
<EmptyState.Icon>
|
|
1305
|
-
<
|
|
1293
|
+
<Box rounded="full" display="flex" style={{
|
|
1294
|
+
width: 48,
|
|
1295
|
+
height: 48,
|
|
1296
|
+
alignItems: 'center',
|
|
1297
|
+
justifyContent: 'center',
|
|
1298
|
+
background: 'var(--bg-hover)',
|
|
1299
|
+
}}>
|
|
1300
|
+
<Wheelchair size={24} weight="regular" style={{ color: 'var(--text-tertiary)' }} />
|
|
1301
|
+
</Box>
|
|
1306
1302
|
</EmptyState.Icon>
|
|
1307
1303
|
<EmptyState.Description>{message}</EmptyState.Description>
|
|
1308
1304
|
</EmptyState>
|
|
@@ -1368,7 +1364,7 @@ function AISetupModalContent({ onSave, onClose, currentConfig }: AISetupModalCon
|
|
|
1368
1364
|
|
|
1369
1365
|
<div>
|
|
1370
1366
|
<Text size="xs" weight="medium" style={{ marginBottom: 4 }}>API Key</Text>
|
|
1371
|
-
<
|
|
1367
|
+
<Input
|
|
1372
1368
|
type="password"
|
|
1373
1369
|
value={apiKey}
|
|
1374
1370
|
onChange={(e) => setApiKey(e.target.value)}
|
|
@@ -1377,38 +1373,35 @@ function AISetupModalContent({ onSave, onClose, currentConfig }: AISetupModalCon
|
|
|
1377
1373
|
? "sk-ant-api03-..."
|
|
1378
1374
|
: "sk-..."
|
|
1379
1375
|
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
padding: '8px 12px',
|
|
1383
|
-
fontSize: 12,
|
|
1384
|
-
borderRadius: 'var(--radius-sm)',
|
|
1385
|
-
border: '1px solid var(--border)',
|
|
1386
|
-
background: 'var(--bg-secondary)',
|
|
1387
|
-
color: 'var(--text-primary)',
|
|
1388
|
-
outline: 'none',
|
|
1389
|
-
boxSizing: 'border-box',
|
|
1390
|
-
}}
|
|
1376
|
+
size="sm"
|
|
1377
|
+
style={{ width: '100%' }}
|
|
1391
1378
|
/>
|
|
1392
1379
|
<Text size="xs" color="tertiary" style={{ marginTop: 4 }}>
|
|
1393
1380
|
Get your API key from{" "}
|
|
1394
1381
|
{provider === "anthropic" ? (
|
|
1395
|
-
<
|
|
1382
|
+
<Button
|
|
1383
|
+
as="a"
|
|
1384
|
+
variant="ghost"
|
|
1385
|
+
size="sm"
|
|
1396
1386
|
href="https://console.anthropic.com/settings/keys"
|
|
1397
1387
|
target="_blank"
|
|
1398
1388
|
rel="noopener noreferrer"
|
|
1399
|
-
style={{
|
|
1389
|
+
style={{ display: 'inline', padding: 0, fontSize: 'inherit' }}
|
|
1400
1390
|
>
|
|
1401
1391
|
console.anthropic.com
|
|
1402
|
-
</
|
|
1392
|
+
</Button>
|
|
1403
1393
|
) : (
|
|
1404
|
-
<
|
|
1394
|
+
<Button
|
|
1395
|
+
as="a"
|
|
1396
|
+
variant="ghost"
|
|
1397
|
+
size="sm"
|
|
1405
1398
|
href="https://platform.openai.com/api-keys"
|
|
1406
1399
|
target="_blank"
|
|
1407
1400
|
rel="noopener noreferrer"
|
|
1408
|
-
style={{
|
|
1401
|
+
style={{ display: 'inline', padding: 0, fontSize: 'inherit' }}
|
|
1409
1402
|
>
|
|
1410
1403
|
platform.openai.com
|
|
1411
|
-
</
|
|
1404
|
+
</Button>
|
|
1412
1405
|
)}
|
|
1413
1406
|
</Text>
|
|
1414
1407
|
</div>
|