@miethe/ui 0.2.0
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/CHANGELOG.md +77 -0
- package/README.md +1536 -0
- package/dist/bulk-actions/Button.d.ts +28 -0
- package/dist/bulk-actions/Button.d.ts.map +1 -0
- package/dist/bulk-actions/Button.js +45 -0
- package/dist/bulk-actions/Button.js.map +1 -0
- package/dist/bulk-actions/bulk-action-bar.d.ts +91 -0
- package/dist/bulk-actions/bulk-action-bar.d.ts.map +1 -0
- package/dist/bulk-actions/bulk-action-bar.js +94 -0
- package/dist/bulk-actions/bulk-action-bar.js.map +1 -0
- package/dist/bulk-actions/index.d.ts +5 -0
- package/dist/bulk-actions/index.d.ts.map +1 -0
- package/dist/bulk-actions/index.js +7 -0
- package/dist/bulk-actions/index.js.map +1 -0
- package/dist/bulk-actions/utils.d.ts +6 -0
- package/dist/bulk-actions/utils.d.ts.map +1 -0
- package/dist/bulk-actions/utils.js +9 -0
- package/dist/bulk-actions/utils.js.map +1 -0
- package/dist/components/ui/alert.d.ts +9 -0
- package/dist/components/ui/alert.d.ts.map +1 -0
- package/dist/components/ui/alert.js +23 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/button.d.ts +12 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +34 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +6 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +7 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +4 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +7 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/content-viewer/ContentPane.d.ts +107 -0
- package/dist/content-viewer/ContentPane.d.ts.map +1 -0
- package/dist/content-viewer/ContentPane.js +247 -0
- package/dist/content-viewer/ContentPane.js.map +1 -0
- package/dist/content-viewer/ContentViewerProvider.d.ts +83 -0
- package/dist/content-viewer/ContentViewerProvider.d.ts.map +1 -0
- package/dist/content-viewer/ContentViewerProvider.js +92 -0
- package/dist/content-viewer/ContentViewerProvider.js.map +1 -0
- package/dist/content-viewer/FileTree.d.ts +71 -0
- package/dist/content-viewer/FileTree.d.ts.map +1 -0
- package/dist/content-viewer/FileTree.js +294 -0
- package/dist/content-viewer/FileTree.js.map +1 -0
- package/dist/content-viewer/adapters.d.ts +101 -0
- package/dist/content-viewer/adapters.d.ts.map +1 -0
- package/dist/content-viewer/adapters.js +32 -0
- package/dist/content-viewer/adapters.js.map +1 -0
- package/dist/content-viewer/index.d.ts +8 -0
- package/dist/content-viewer/index.d.ts.map +1 -0
- package/dist/content-viewer/index.js +5 -0
- package/dist/content-viewer/index.js.map +1 -0
- package/dist/diff/DiffViewer.d.ts +112 -0
- package/dist/diff/DiffViewer.d.ts.map +1 -0
- package/dist/diff/DiffViewer.js +414 -0
- package/dist/diff/DiffViewer.js.map +1 -0
- package/dist/diff/diff.d.ts +32 -0
- package/dist/diff/diff.d.ts.map +1 -0
- package/dist/diff/diff.js +8 -0
- package/dist/diff/diff.js.map +1 -0
- package/dist/diff/index.d.ts +4 -0
- package/dist/diff/index.d.ts.map +1 -0
- package/dist/diff/index.js +3 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/display/FilePreviewPane.d.ts +31 -0
- package/dist/display/FilePreviewPane.d.ts.map +1 -0
- package/dist/display/FilePreviewPane.js +144 -0
- package/dist/display/FilePreviewPane.js.map +1 -0
- package/dist/display/FrontmatterDisplay.d.ts +33 -0
- package/dist/display/FrontmatterDisplay.d.ts.map +1 -0
- package/dist/display/FrontmatterDisplay.js +79 -0
- package/dist/display/FrontmatterDisplay.js.map +1 -0
- package/dist/display/index.d.ts +5 -0
- package/dist/display/index.d.ts.map +1 -0
- package/dist/display/index.js +4 -0
- package/dist/display/index.js.map +1 -0
- package/dist/editor/MarkdownEditor.d.ts +28 -0
- package/dist/editor/MarkdownEditor.d.ts.map +1 -0
- package/dist/editor/MarkdownEditor.js +160 -0
- package/dist/editor/MarkdownEditor.js.map +1 -0
- package/dist/editor/SplitPreview.d.ts +28 -0
- package/dist/editor/SplitPreview.d.ts.map +1 -0
- package/dist/editor/SplitPreview.js +34 -0
- package/dist/editor/SplitPreview.js.map +1 -0
- package/dist/editor/index.d.ts +5 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +4 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/filters/filters-dropdown.d.ts +24 -0
- package/dist/filters/filters-dropdown.d.ts.map +1 -0
- package/dist/filters/filters-dropdown.js +36 -0
- package/dist/filters/filters-dropdown.js.map +1 -0
- package/dist/filters/index.d.ts +9 -0
- package/dist/filters/index.d.ts.map +1 -0
- package/dist/filters/index.js +5 -0
- package/dist/filters/index.js.map +1 -0
- package/dist/filters/sort-dropdown.d.ts +13 -0
- package/dist/filters/sort-dropdown.d.ts.map +1 -0
- package/dist/filters/sort-dropdown.js +20 -0
- package/dist/filters/sort-dropdown.js.map +1 -0
- package/dist/filters/tag-filter-popover.d.ts +39 -0
- package/dist/filters/tag-filter-popover.d.ts.map +1 -0
- package/dist/filters/tag-filter-popover.js +72 -0
- package/dist/filters/tag-filter-popover.js.map +1 -0
- package/dist/filters/tool-filter-popover.d.ts +42 -0
- package/dist/filters/tool-filter-popover.d.ts.map +1 -0
- package/dist/filters/tool-filter-popover.js +67 -0
- package/dist/filters/tool-filter-popover.js.map +1 -0
- package/dist/hooks/use-debounce.d.ts +9 -0
- package/dist/hooks/use-debounce.d.ts.map +1 -0
- package/dist/hooks/use-debounce.js +21 -0
- package/dist/hooks/use-debounce.js.map +1 -0
- package/dist/hooks/use-intersection-observer.d.ts +11 -0
- package/dist/hooks/use-intersection-observer.d.ts.map +1 -0
- package/dist/hooks/use-intersection-observer.js +25 -0
- package/dist/hooks/use-intersection-observer.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/pickers/EntityPickerDialog.d.ts +233 -0
- package/dist/pickers/EntityPickerDialog.d.ts.map +1 -0
- package/dist/pickers/EntityPickerDialog.js +355 -0
- package/dist/pickers/EntityPickerDialog.js.map +1 -0
- package/dist/pickers/EntityPickerViewToggle.d.ts +8 -0
- package/dist/pickers/EntityPickerViewToggle.d.ts.map +1 -0
- package/dist/pickers/EntityPickerViewToggle.js +17 -0
- package/dist/pickers/EntityPickerViewToggle.js.map +1 -0
- package/dist/pickers/index.d.ts +5 -0
- package/dist/pickers/index.d.ts.map +1 -0
- package/dist/pickers/index.js +3 -0
- package/dist/pickers/index.js.map +1 -0
- package/dist/primitives/Badge.d.ts +16 -0
- package/dist/primitives/Badge.d.ts.map +1 -0
- package/dist/primitives/Badge.js +43 -0
- package/dist/primitives/Badge.js.map +1 -0
- package/dist/primitives/BaseArtifactModal.d.ts +114 -0
- package/dist/primitives/BaseArtifactModal.d.ts.map +1 -0
- package/dist/primitives/BaseArtifactModal.js +76 -0
- package/dist/primitives/BaseArtifactModal.js.map +1 -0
- package/dist/primitives/Dialog.d.ts +20 -0
- package/dist/primitives/Dialog.d.ts.map +1 -0
- package/dist/primitives/Dialog.js +24 -0
- package/dist/primitives/Dialog.js.map +1 -0
- package/dist/primitives/DropdownMenu.d.ts +28 -0
- package/dist/primitives/DropdownMenu.d.ts.map +1 -0
- package/dist/primitives/DropdownMenu.js +34 -0
- package/dist/primitives/DropdownMenu.js.map +1 -0
- package/dist/primitives/EnterpriseOwnerBadge.d.ts +9 -0
- package/dist/primitives/EnterpriseOwnerBadge.d.ts.map +1 -0
- package/dist/primitives/EnterpriseOwnerBadge.js +12 -0
- package/dist/primitives/EnterpriseOwnerBadge.js.map +1 -0
- package/dist/primitives/GroupedSelect.d.ts +30 -0
- package/dist/primitives/GroupedSelect.d.ts.map +1 -0
- package/dist/primitives/GroupedSelect.js +47 -0
- package/dist/primitives/GroupedSelect.js.map +1 -0
- package/dist/primitives/Input.d.ts +6 -0
- package/dist/primitives/Input.d.ts.map +1 -0
- package/dist/primitives/Input.js +9 -0
- package/dist/primitives/Input.js.map +1 -0
- package/dist/primitives/LockIcon.d.ts +11 -0
- package/dist/primitives/LockIcon.d.ts.map +1 -0
- package/dist/primitives/LockIcon.js +15 -0
- package/dist/primitives/LockIcon.js.map +1 -0
- package/dist/primitives/MaskedSecretInput.d.ts +16 -0
- package/dist/primitives/MaskedSecretInput.d.ts.map +1 -0
- package/dist/primitives/MaskedSecretInput.js +42 -0
- package/dist/primitives/MaskedSecretInput.js.map +1 -0
- package/dist/primitives/ModalHeader.d.ts +66 -0
- package/dist/primitives/ModalHeader.d.ts.map +1 -0
- package/dist/primitives/ModalHeader.js +58 -0
- package/dist/primitives/ModalHeader.js.map +1 -0
- package/dist/primitives/Popover.d.ts +9 -0
- package/dist/primitives/Popover.d.ts.map +1 -0
- package/dist/primitives/Popover.js +13 -0
- package/dist/primitives/Popover.js.map +1 -0
- package/dist/primitives/ScrollArea.d.ts +6 -0
- package/dist/primitives/ScrollArea.d.ts.map +1 -0
- package/dist/primitives/ScrollArea.js +11 -0
- package/dist/primitives/ScrollArea.js.map +1 -0
- package/dist/primitives/SearchableCombobox.d.ts +30 -0
- package/dist/primitives/SearchableCombobox.d.ts.map +1 -0
- package/dist/primitives/SearchableCombobox.js +124 -0
- package/dist/primitives/SearchableCombobox.js.map +1 -0
- package/dist/primitives/SearchablePickerDialog.d.ts +20 -0
- package/dist/primitives/SearchablePickerDialog.d.ts.map +1 -0
- package/dist/primitives/SearchablePickerDialog.js +78 -0
- package/dist/primitives/SearchablePickerDialog.js.map +1 -0
- package/dist/primitives/StatusBadge.d.ts +21 -0
- package/dist/primitives/StatusBadge.d.ts.map +1 -0
- package/dist/primitives/StatusBadge.js +25 -0
- package/dist/primitives/StatusBadge.js.map +1 -0
- package/dist/primitives/TabNavigation.d.ts +68 -0
- package/dist/primitives/TabNavigation.d.ts.map +1 -0
- package/dist/primitives/TabNavigation.js +74 -0
- package/dist/primitives/TabNavigation.js.map +1 -0
- package/dist/primitives/Tabs.d.ts +8 -0
- package/dist/primitives/Tabs.d.ts.map +1 -0
- package/dist/primitives/Tabs.js +14 -0
- package/dist/primitives/Tabs.js.map +1 -0
- package/dist/primitives/Tooltip.d.ts +8 -0
- package/dist/primitives/Tooltip.d.ts.map +1 -0
- package/dist/primitives/Tooltip.js +12 -0
- package/dist/primitives/Tooltip.js.map +1 -0
- package/dist/primitives/VerticalTabNavigation.d.ts +75 -0
- package/dist/primitives/VerticalTabNavigation.d.ts.map +1 -0
- package/dist/primitives/VerticalTabNavigation.js +166 -0
- package/dist/primitives/VerticalTabNavigation.js.map +1 -0
- package/dist/primitives/ViewModeToggle.d.ts +12 -0
- package/dist/primitives/ViewModeToggle.d.ts.map +1 -0
- package/dist/primitives/ViewModeToggle.js +56 -0
- package/dist/primitives/ViewModeToggle.js.map +1 -0
- package/dist/primitives/WizardShell.d.ts +81 -0
- package/dist/primitives/WizardShell.d.ts.map +1 -0
- package/dist/primitives/WizardShell.js +73 -0
- package/dist/primitives/WizardShell.js.map +1 -0
- package/dist/primitives/index.d.ts +38 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/index.js +24 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/primitives/utils.d.ts +6 -0
- package/dist/primitives/utils.d.ts.map +1 -0
- package/dist/primitives/utils.js +9 -0
- package/dist/primitives/utils.js.map +1 -0
- package/dist/types/index.d.ts +63 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +63 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +345 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/perf-marks.d.ts +28 -0
- package/dist/utils/perf-marks.d.ts.map +1 -0
- package/dist/utils/perf-marks.js +45 -0
- package/dist/utils/perf-marks.js.map +1 -0
- package/dist/utils/readme-utils.d.ts +67 -0
- package/dist/utils/readme-utils.d.ts.map +1 -0
- package/dist/utils/readme-utils.js +164 -0
- package/dist/utils/readme-utils.js.map +1 -0
- package/dist/utils/type-colors.d.ts +70 -0
- package/dist/utils/type-colors.d.ts.map +1 -0
- package/dist/utils/type-colors.js +118 -0
- package/dist/utils/type-colors.js.map +1 -0
- package/package.json +131 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useMemo, lazy, Suspense } from 'react';
|
|
4
|
+
import { FileText, AlertCircle, AlertTriangle, Edit, ChevronRight, Save, X, ExternalLink, } from 'lucide-react';
|
|
5
|
+
import { cn } from '../primitives/utils';
|
|
6
|
+
import { Button } from '../components/ui/button';
|
|
7
|
+
import { ScrollArea } from '../primitives/ScrollArea';
|
|
8
|
+
import { Skeleton } from '../components/ui/skeleton';
|
|
9
|
+
import { Alert, AlertDescription, AlertTitle } from '../components/ui/alert';
|
|
10
|
+
import { FrontmatterDisplay } from '../display/FrontmatterDisplay';
|
|
11
|
+
import { parseFrontmatter, detectFrontmatter, stripFrontmatter } from '../utils/frontmatter';
|
|
12
|
+
/**
|
|
13
|
+
* SplitPreview is lazy-loaded so that the CodeMirror editor bundle is only fetched
|
|
14
|
+
* when a user enters edit mode on a markdown file. Consumers who render ContentPane
|
|
15
|
+
* in read-only mode (or for non-markdown files) will never download the editor chunk.
|
|
16
|
+
*/
|
|
17
|
+
const SplitPreview = lazy(() => import('../editor/SplitPreview').then((m) => ({ default: m.SplitPreview })));
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Helper Functions
|
|
20
|
+
// ============================================================================
|
|
21
|
+
/**
|
|
22
|
+
* Format bytes to human-readable string (e.g., "1.2 MB")
|
|
23
|
+
*/
|
|
24
|
+
function formatBytes(bytes) {
|
|
25
|
+
if (bytes === 0)
|
|
26
|
+
return '0 B';
|
|
27
|
+
const k = 1024;
|
|
28
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
29
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
30
|
+
const size = bytes / Math.pow(k, i);
|
|
31
|
+
// Use 1 decimal place for KB and above, no decimals for bytes
|
|
32
|
+
return i === 0 ? `${bytes} B` : `${size.toFixed(1)} ${sizes[i]}`;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if a file is editable based on its extension
|
|
36
|
+
*/
|
|
37
|
+
function isEditableFile(path) {
|
|
38
|
+
const editableExtensions = [
|
|
39
|
+
'.md',
|
|
40
|
+
'.txt',
|
|
41
|
+
'.json',
|
|
42
|
+
'.ts',
|
|
43
|
+
'.tsx',
|
|
44
|
+
'.js',
|
|
45
|
+
'.jsx',
|
|
46
|
+
'.py',
|
|
47
|
+
'.yml',
|
|
48
|
+
'.yaml',
|
|
49
|
+
'.toml',
|
|
50
|
+
];
|
|
51
|
+
return editableExtensions.some((ext) => path.toLowerCase().endsWith(ext));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if a file should use markdown editor (for .md files)
|
|
55
|
+
*/
|
|
56
|
+
function isMarkdownFile(path) {
|
|
57
|
+
return path.toLowerCase().endsWith('.md');
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Split path into breadcrumb segments
|
|
61
|
+
*/
|
|
62
|
+
function pathToBreadcrumbs(path) {
|
|
63
|
+
return path.split('/').filter(Boolean);
|
|
64
|
+
}
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// Loading Skeletons
|
|
67
|
+
// ============================================================================
|
|
68
|
+
/**
|
|
69
|
+
* Shown inside the Suspense boundary while the SplitPreview (CodeMirror) chunk
|
|
70
|
+
* is being downloaded. Mirrors the two-column split layout so the UI does not
|
|
71
|
+
* shift once the editor mounts.
|
|
72
|
+
*/
|
|
73
|
+
function EditorLoadingSkeleton() {
|
|
74
|
+
return (_jsxs("div", { className: "flex h-full min-w-0 flex-col gap-4 overflow-hidden lg:flex-row", children: [_jsx("div", { className: "min-h-[300px] min-w-0 flex-1 lg:min-h-0", children: _jsx("div", { className: "h-full space-y-2 rounded-md border p-4", children: [...Array(12)].map((_, i) => (_jsx(Skeleton, { className: "h-4", style: { width: `${50 + Math.random() * 50}%` } }, i))) }) }), _jsx("div", { className: "min-h-[300px] min-w-0 flex-1 overflow-hidden lg:min-h-0", children: _jsx("div", { className: "h-full space-y-2 rounded-md border bg-card p-6", children: [...Array(12)].map((_, i) => (_jsx(Skeleton, { className: "h-4", style: { width: `${40 + Math.random() * 60}%` } }, i))) }) })] }));
|
|
75
|
+
}
|
|
76
|
+
function ContentPaneSkeleton() {
|
|
77
|
+
return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsx("div", { className: "border-b p-4", children: _jsx(Skeleton, { className: "h-5 w-48" }) }), _jsx("div", { className: "flex-1 space-y-2 p-4", children: [...Array(20)].map((_, i) => (_jsx(Skeleton, { className: "h-4 w-full", style: { width: `${60 + Math.random() * 40}%` } }, i))) })] }));
|
|
78
|
+
}
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// Empty State
|
|
81
|
+
// ============================================================================
|
|
82
|
+
function EmptyState() {
|
|
83
|
+
return (_jsxs("div", { className: "flex h-full flex-col items-center justify-center py-12 text-center", children: [_jsx(FileText, { className: "mb-4 h-12 w-12 text-muted-foreground opacity-50" }), _jsx("h3", { className: "mb-1 text-sm font-medium text-muted-foreground", children: "No file selected" }), _jsx("p", { className: "max-w-sm text-xs text-muted-foreground", children: "Select a file from the tree on the left to view its contents." })] }));
|
|
84
|
+
}
|
|
85
|
+
function ErrorState({ error }) {
|
|
86
|
+
return (_jsx("div", { className: "flex h-full flex-col items-center justify-center p-4", children: _jsxs(Alert, { variant: "destructive", className: "max-w-md", children: [_jsx(AlertCircle, { className: "h-4 w-4" }), _jsx(AlertDescription, { className: "text-sm", children: error })] }) }));
|
|
87
|
+
}
|
|
88
|
+
function TruncationBanner({ originalSize, fullFileUrl }) {
|
|
89
|
+
const sizeText = originalSize ? formatBytes(originalSize) : 'large file';
|
|
90
|
+
return (_jsxs(Alert, { className: "mb-4 border-amber-500/50 bg-amber-50 dark:bg-amber-950/30", children: [_jsx(AlertTriangle, { className: "h-4 w-4 text-amber-600 dark:text-amber-500" }), _jsx(AlertTitle, { className: "text-amber-800 dark:text-amber-300", children: "Large file truncated" }), _jsxs(AlertDescription, { className: "text-amber-700 dark:text-amber-400", children: [_jsxs("span", { children: ["This file (", sizeText, ") has been truncated. Showing first 10,000 lines."] }), fullFileUrl && (_jsxs("a", { href: fullFileUrl, target: "_blank", rel: "noopener noreferrer", className: "ml-2 inline-flex items-center gap-1 font-medium text-amber-800 underline hover:text-amber-900 dark:text-amber-300 dark:hover:text-amber-200", children: ["View full file on GitHub", _jsx(ExternalLink, { className: "h-3 w-3", "aria-hidden": "true" })] }))] })] }));
|
|
91
|
+
}
|
|
92
|
+
function Breadcrumb({ path, id }) {
|
|
93
|
+
const segments = useMemo(() => pathToBreadcrumbs(path), [path]);
|
|
94
|
+
return (_jsx("nav", { id: id, "aria-label": "File path", className: "flex items-center gap-1 text-sm text-muted-foreground", children: segments.map((segment, index) => (_jsxs("div", { className: "flex items-center gap-1", children: [index > 0 && _jsx(ChevronRight, { className: "h-3 w-3", "aria-hidden": "true" }), _jsx("span", { className: cn(index === segments.length - 1 && 'font-medium text-foreground'), "aria-current": index === segments.length - 1 ? 'page' : undefined, children: segment })] }, index))) }));
|
|
95
|
+
}
|
|
96
|
+
function LineNumbers({ lineCount }) {
|
|
97
|
+
return (_jsx("div", { className: "select-none pr-4 text-right font-mono text-xs text-muted-foreground", children: [...Array(lineCount)].map((_, i) => (_jsx("div", { className: "leading-6", children: i + 1 }, i))) }));
|
|
98
|
+
}
|
|
99
|
+
function ContentDisplay({ content, showLineNumbers = false }) {
|
|
100
|
+
const lines = useMemo(() => content.split('\n'), [content]);
|
|
101
|
+
return (_jsxs("div", { className: "flex", children: [showLineNumbers && _jsx(LineNumbers, { lineCount: lines.length }), _jsx("pre", { className: "flex-1 whitespace-pre-wrap break-words font-mono text-xs leading-6", children: content })] }));
|
|
102
|
+
}
|
|
103
|
+
// ============================================================================
|
|
104
|
+
// Main Component
|
|
105
|
+
// ============================================================================
|
|
106
|
+
/**
|
|
107
|
+
* ContentPane - File content viewer and editor component
|
|
108
|
+
*
|
|
109
|
+
* Displays the contents of a selected file with features like breadcrumb navigation,
|
|
110
|
+
* optional line numbers, and edit functionality for supported file types.
|
|
111
|
+
*
|
|
112
|
+
* ## Bundle cost / optional editor loading
|
|
113
|
+
*
|
|
114
|
+
* The CodeMirror editor (via SplitPreview and MarkdownEditor) is **lazy-loaded**.
|
|
115
|
+
* The editor chunk is only fetched from the network when the component actually
|
|
116
|
+
* needs to render it — that is, when the file is a Markdown file (`*.md`) and the
|
|
117
|
+
* component is mounted. While the chunk loads a skeleton placeholder is shown
|
|
118
|
+
* via a React `Suspense` boundary.
|
|
119
|
+
*
|
|
120
|
+
* - **Read-only mode** (`readOnly={true}`): The SplitPreview/MarkdownEditor module
|
|
121
|
+
* is still lazy-imported for markdown files because the preview panel is always
|
|
122
|
+
* rendered. However, callers that pass `readOnly` avoid the full edit bundle
|
|
123
|
+
* cost for non-markdown file types entirely — only the markdown renderer
|
|
124
|
+
* (react-markdown, which is much lighter) loads in that case.
|
|
125
|
+
*
|
|
126
|
+
* - **Edit mode** (`readOnly={false}`, default): CodeMirror loads on first render
|
|
127
|
+
* of a markdown file. Subsequent renders use the cached module.
|
|
128
|
+
*
|
|
129
|
+
* - **Non-markdown files** (`.ts`, `.json`, `.py`, …): SplitPreview is never
|
|
130
|
+
* rendered; CodeMirror is never loaded regardless of `readOnly`.
|
|
131
|
+
*
|
|
132
|
+
* ## Props controlling edit mode
|
|
133
|
+
*
|
|
134
|
+
* | Prop | Purpose |
|
|
135
|
+
* |----------------|----------------------------------------------------------------------|
|
|
136
|
+
* | `readOnly` | When `true`, hides all edit/save UI and disables edit mode entirely |
|
|
137
|
+
* | `isEditing` | Lifted state — `true` when the user has clicked "Edit" |
|
|
138
|
+
* | `onEditStart` | Called when user clicks the "Edit" button |
|
|
139
|
+
* | `onEditChange` | Called on every keystroke in the editor with the updated content |
|
|
140
|
+
* | `onSave` | Called when the user confirms the save; receives final content |
|
|
141
|
+
* | `onCancel` | Called when the user dismisses the editor without saving |
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```tsx
|
|
145
|
+
* // Editable mode (default) — CodeMirror loads when user opens a .md file
|
|
146
|
+
* <ContentPane
|
|
147
|
+
* path="src/index.ts"
|
|
148
|
+
* content={fileContent}
|
|
149
|
+
* isLoading={isLoading}
|
|
150
|
+
* error={error}
|
|
151
|
+
* onEditStart={() => handleEdit()}
|
|
152
|
+
* onSave={(content) => handleSave(content)}
|
|
153
|
+
* />
|
|
154
|
+
*
|
|
155
|
+
* // Read-only mode — no edit controls rendered; CodeMirror NOT loaded for
|
|
156
|
+
* // non-markdown files; markdown files render preview only (no editor panel)
|
|
157
|
+
* <ContentPane
|
|
158
|
+
* path="README.md"
|
|
159
|
+
* content={fileContent}
|
|
160
|
+
* readOnly={true}
|
|
161
|
+
* />
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export function ContentPane({ path, content, isLoading = false, error = null, readOnly = false, truncationInfo, isEditing = false, editedContent = '', onEditStart, onEditChange, onSave, onCancel, ariaLabel, showFrontmatter: _showFrontmatter = false, }) {
|
|
165
|
+
// Generate unique ID for breadcrumb to use in aria-labelledby
|
|
166
|
+
const breadcrumbId = path
|
|
167
|
+
? `content-pane-breadcrumb-${path.replace(/[^a-zA-Z0-9]/g, '-')}`
|
|
168
|
+
: undefined;
|
|
169
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
170
|
+
// Editing is disabled in read-only mode
|
|
171
|
+
const canEdit = !readOnly && path && (onEditStart || onSave) && isEditableFile(path);
|
|
172
|
+
const isMarkdown = path && isMarkdownFile(path);
|
|
173
|
+
// Check if content is truncated
|
|
174
|
+
const isTruncated = truncationInfo?.truncated === true;
|
|
175
|
+
// Parse frontmatter from content (memoized to avoid reparsing on every render)
|
|
176
|
+
const parsedContent = useMemo(() => {
|
|
177
|
+
if (!content || typeof content !== 'string') {
|
|
178
|
+
return { frontmatter: null, content: content || '' };
|
|
179
|
+
}
|
|
180
|
+
// Only parse if content appears to have frontmatter
|
|
181
|
+
if (!detectFrontmatter(content)) {
|
|
182
|
+
return { frontmatter: null, content };
|
|
183
|
+
}
|
|
184
|
+
return parseFrontmatter(content);
|
|
185
|
+
}, [content]);
|
|
186
|
+
// Content to display: always strip frontmatter when FrontmatterDisplay will be shown
|
|
187
|
+
const displayContent = useMemo(() => {
|
|
188
|
+
if (!content || typeof content !== 'string') {
|
|
189
|
+
return content || '';
|
|
190
|
+
}
|
|
191
|
+
// Always strip frontmatter when FrontmatterDisplay will be shown (when frontmatter exists)
|
|
192
|
+
// This prevents duplication between FrontmatterDisplay and raw content
|
|
193
|
+
if (detectFrontmatter(content)) {
|
|
194
|
+
return stripFrontmatter(content);
|
|
195
|
+
}
|
|
196
|
+
return content;
|
|
197
|
+
}, [content]);
|
|
198
|
+
// Handle edit button click
|
|
199
|
+
const handleEditClick = () => {
|
|
200
|
+
onEditChange?.(content || '');
|
|
201
|
+
onEditStart?.();
|
|
202
|
+
};
|
|
203
|
+
// Handle save button click
|
|
204
|
+
const handleSaveClick = async () => {
|
|
205
|
+
if (!onSave)
|
|
206
|
+
return;
|
|
207
|
+
setIsSaving(true);
|
|
208
|
+
try {
|
|
209
|
+
await onSave(editedContent);
|
|
210
|
+
onCancel?.();
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
console.error('Failed to save:', error);
|
|
214
|
+
// Error handling can be expanded here
|
|
215
|
+
}
|
|
216
|
+
finally {
|
|
217
|
+
setIsSaving(false);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
// Handle cancel button click
|
|
221
|
+
const handleCancelClick = () => {
|
|
222
|
+
onCancel?.();
|
|
223
|
+
};
|
|
224
|
+
// Loading state
|
|
225
|
+
if (isLoading) {
|
|
226
|
+
return _jsx(ContentPaneSkeleton, {});
|
|
227
|
+
}
|
|
228
|
+
// Error state
|
|
229
|
+
if (error) {
|
|
230
|
+
return _jsx(ErrorState, { error: error });
|
|
231
|
+
}
|
|
232
|
+
// Empty state - no file selected
|
|
233
|
+
if (!path) {
|
|
234
|
+
return _jsx(EmptyState, {});
|
|
235
|
+
}
|
|
236
|
+
// Empty content - file is empty or couldn't be loaded
|
|
237
|
+
if (content === null || content === '') {
|
|
238
|
+
return (_jsxs("div", { className: "flex h-full flex-col", role: "region", "aria-label": ariaLabel || `File content: ${path}`, "aria-labelledby": breadcrumbId, "data-testid": "content-pane", children: [_jsxs("div", { className: "flex items-center justify-between border-b bg-muted/20 p-4", children: [_jsx(Breadcrumb, { path: path, id: breadcrumbId }), canEdit && !isEditing && (_jsxs(Button, { variant: "ghost", size: "sm", onClick: handleEditClick, "aria-label": `Edit ${path}`, children: [_jsx(Edit, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }), "Edit"] })), !readOnly && isEditing && (_jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: handleCancelClick, disabled: isSaving, children: [_jsx(X, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }), "Cancel"] }), _jsxs(Button, { variant: "default", size: "sm", onClick: handleSaveClick, disabled: isSaving, children: [_jsx(Save, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }), isSaving ? 'Saving...' : 'Save'] })] }))] }), _jsx("div", { className: "flex flex-1 items-center justify-center text-center", children: _jsxs("div", { children: [_jsx(FileText, { className: "mx-auto mb-2 h-8 w-8 text-muted-foreground opacity-50", "aria-hidden": "true" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "This file is empty" })] }) })] }));
|
|
239
|
+
}
|
|
240
|
+
// Markdown file - always use split preview (shows rendered markdown)
|
|
241
|
+
if (isMarkdown) {
|
|
242
|
+
return (_jsxs("div", { className: "flex h-full w-full flex-col overflow-hidden", role: "region", "aria-label": ariaLabel || `Markdown file: ${path}`, "aria-labelledby": breadcrumbId, "data-testid": "content-pane", children: [_jsxs("div", { className: "flex flex-shrink-0 items-center justify-between border-b bg-muted/20 p-4", children: [_jsx(Breadcrumb, { path: path, id: breadcrumbId }), !readOnly && isEditing ? (_jsxs("div", { className: "flex gap-2", children: [_jsxs(Button, { variant: "ghost", size: "sm", onClick: handleCancelClick, disabled: isSaving, children: [_jsx(X, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }), "Cancel"] }), _jsxs(Button, { variant: "default", size: "sm", onClick: handleSaveClick, disabled: isSaving, children: [_jsx(Save, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }), isSaving ? 'Saving...' : 'Save'] })] })) : (canEdit && (_jsxs(Button, { variant: "ghost", size: "sm", onClick: handleEditClick, "aria-label": `Edit ${path}`, children: [_jsx(Edit, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }), "Edit"] })))] }), _jsxs("div", { className: "min-h-0 min-w-0 flex-1 overflow-auto p-4", children: [isTruncated && (_jsx(TruncationBanner, { originalSize: truncationInfo?.originalSize, fullFileUrl: truncationInfo?.fullFileUrl })), parsedContent.frontmatter && (_jsx(FrontmatterDisplay, { frontmatter: parsedContent.frontmatter, defaultCollapsed: true, className: "mb-4" })), _jsx("div", { className: "min-w-0", children: _jsx(Suspense, { fallback: _jsx(EditorLoadingSkeleton, {}), children: _jsx(SplitPreview, { content: isEditing ? editedContent : displayContent, onChange: (newContent) => onEditChange?.(newContent), isEditing: isEditing }) }) })] })] }));
|
|
243
|
+
}
|
|
244
|
+
// Content display (read-only mode for non-markdown files)
|
|
245
|
+
return (_jsxs("div", { className: "flex h-full w-full flex-col overflow-hidden", role: "region", "aria-label": ariaLabel || `File content: ${path}`, "aria-labelledby": breadcrumbId, "data-testid": "content-pane", children: [_jsxs("div", { className: "flex flex-shrink-0 items-center justify-between border-b bg-muted/20 p-4", children: [_jsx(Breadcrumb, { path: path, id: breadcrumbId }), canEdit && !isEditing && (_jsxs(Button, { variant: "ghost", size: "sm", onClick: handleEditClick, "aria-label": `Edit ${path}`, children: [_jsx(Edit, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }), "Edit"] }))] }), _jsx(ScrollArea, { className: "min-h-0 min-w-0 flex-1", children: _jsxs("div", { className: "p-4", children: [isTruncated && (_jsx(TruncationBanner, { originalSize: truncationInfo?.originalSize, fullFileUrl: truncationInfo?.fullFileUrl })), parsedContent.frontmatter && (_jsx(FrontmatterDisplay, { frontmatter: parsedContent.frontmatter, defaultCollapsed: true, className: "mb-4" })), _jsx("div", { className: "max-w-full", children: _jsx(ContentDisplay, { content: displayContent, showLineNumbers: false }) })] }) })] }));
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=ContentPane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContentPane.js","sourceRoot":"","sources":["../../src/content-viewer/ContentPane.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContentViewerProvider — React context provider for the content-viewer adapter.
|
|
3
|
+
*
|
|
4
|
+
* Decouples content-viewer components from any specific data-fetching
|
|
5
|
+
* implementation. Consumers supply a ContentViewerAdapter that components
|
|
6
|
+
* access via useContentViewerAdapter().
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import {
|
|
11
|
+
* ContentViewerProvider,
|
|
12
|
+
* type ContentViewerAdapter,
|
|
13
|
+
* } from '@skillmeat/content-viewer';
|
|
14
|
+
*
|
|
15
|
+
* // Build an adapter that wraps your application's hooks:
|
|
16
|
+
* const adapter: ContentViewerAdapter = {
|
|
17
|
+
* useFileTree: (artifactId, options) => {
|
|
18
|
+
* const { data, isLoading, error } = useCatalogFileTree(
|
|
19
|
+
* mySourceId,
|
|
20
|
+
* artifactId,
|
|
21
|
+
* { enabled: options?.enabled }
|
|
22
|
+
* );
|
|
23
|
+
* return { data, isLoading, error: error ?? null };
|
|
24
|
+
* },
|
|
25
|
+
* useFileContent: (artifactId, filePath, options) => {
|
|
26
|
+
* const { data, isLoading, error } = useCatalogFileContent(
|
|
27
|
+
* mySourceId,
|
|
28
|
+
* artifactId,
|
|
29
|
+
* filePath,
|
|
30
|
+
* { enabled: options?.enabled }
|
|
31
|
+
* );
|
|
32
|
+
* return { data, isLoading, error: error ?? null };
|
|
33
|
+
* },
|
|
34
|
+
* };
|
|
35
|
+
*
|
|
36
|
+
* function App() {
|
|
37
|
+
* return (
|
|
38
|
+
* <ContentViewerProvider adapter={adapter}>
|
|
39
|
+
* <YourContentViewerTree />
|
|
40
|
+
* </ContentViewerProvider>
|
|
41
|
+
* );
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
import React from 'react';
|
|
46
|
+
import type { ContentViewerAdapter } from './adapters';
|
|
47
|
+
export interface ContentViewerProviderProps {
|
|
48
|
+
/**
|
|
49
|
+
* An object implementing ContentViewerAdapter. Components rendered
|
|
50
|
+
* inside this provider call useContentViewerAdapter() to access it.
|
|
51
|
+
*/
|
|
52
|
+
adapter: ContentViewerAdapter;
|
|
53
|
+
children: React.ReactNode;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Wrap your component tree with ContentViewerProvider to supply a
|
|
57
|
+
* data-fetching adapter to all content-viewer components.
|
|
58
|
+
*
|
|
59
|
+
* You must mount exactly one provider per logical content-viewer subtree.
|
|
60
|
+
* Nesting is allowed — inner providers shadow outer ones for their subtrees.
|
|
61
|
+
*/
|
|
62
|
+
export declare function ContentViewerProvider({ adapter, children, }: ContentViewerProviderProps): React.JSX.Element;
|
|
63
|
+
/**
|
|
64
|
+
* Returns the ContentViewerAdapter injected by the nearest
|
|
65
|
+
* ContentViewerProvider ancestor.
|
|
66
|
+
*
|
|
67
|
+
* Throws a descriptive error when called outside a ContentViewerProvider
|
|
68
|
+
* so misconfiguration is caught at runtime rather than producing silent
|
|
69
|
+
* undefined behaviour.
|
|
70
|
+
*
|
|
71
|
+
* @throws {Error} When called outside a ContentViewerProvider.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* function MyFileTree({ artifactId }: { artifactId: string }) {
|
|
76
|
+
* const { useFileTree } = useContentViewerAdapter();
|
|
77
|
+
* const { data, isLoading, error } = useFileTree(artifactId);
|
|
78
|
+
* // ...
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function useContentViewerAdapter(): ContentViewerAdapter;
|
|
83
|
+
//# sourceMappingURL=ContentViewerProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContentViewerProvider.d.ts","sourceRoot":"","sources":["../../src/content-viewer/ContentViewerProvider.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAoBvD,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,OAAO,EAAE,oBAAoB,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,QAAQ,GACT,EAAE,0BAA0B,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAMhD;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,CAa9D"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* ContentViewerProvider — React context provider for the content-viewer adapter.
|
|
5
|
+
*
|
|
6
|
+
* Decouples content-viewer components from any specific data-fetching
|
|
7
|
+
* implementation. Consumers supply a ContentViewerAdapter that components
|
|
8
|
+
* access via useContentViewerAdapter().
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import {
|
|
13
|
+
* ContentViewerProvider,
|
|
14
|
+
* type ContentViewerAdapter,
|
|
15
|
+
* } from '@skillmeat/content-viewer';
|
|
16
|
+
*
|
|
17
|
+
* // Build an adapter that wraps your application's hooks:
|
|
18
|
+
* const adapter: ContentViewerAdapter = {
|
|
19
|
+
* useFileTree: (artifactId, options) => {
|
|
20
|
+
* const { data, isLoading, error } = useCatalogFileTree(
|
|
21
|
+
* mySourceId,
|
|
22
|
+
* artifactId,
|
|
23
|
+
* { enabled: options?.enabled }
|
|
24
|
+
* );
|
|
25
|
+
* return { data, isLoading, error: error ?? null };
|
|
26
|
+
* },
|
|
27
|
+
* useFileContent: (artifactId, filePath, options) => {
|
|
28
|
+
* const { data, isLoading, error } = useCatalogFileContent(
|
|
29
|
+
* mySourceId,
|
|
30
|
+
* artifactId,
|
|
31
|
+
* filePath,
|
|
32
|
+
* { enabled: options?.enabled }
|
|
33
|
+
* );
|
|
34
|
+
* return { data, isLoading, error: error ?? null };
|
|
35
|
+
* },
|
|
36
|
+
* };
|
|
37
|
+
*
|
|
38
|
+
* function App() {
|
|
39
|
+
* return (
|
|
40
|
+
* <ContentViewerProvider adapter={adapter}>
|
|
41
|
+
* <YourContentViewerTree />
|
|
42
|
+
* </ContentViewerProvider>
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
import { createContext, useContext } from 'react';
|
|
48
|
+
const ContentViewerContext = createContext(undefined);
|
|
49
|
+
ContentViewerContext.displayName = 'ContentViewerContext';
|
|
50
|
+
/**
|
|
51
|
+
* Wrap your component tree with ContentViewerProvider to supply a
|
|
52
|
+
* data-fetching adapter to all content-viewer components.
|
|
53
|
+
*
|
|
54
|
+
* You must mount exactly one provider per logical content-viewer subtree.
|
|
55
|
+
* Nesting is allowed — inner providers shadow outer ones for their subtrees.
|
|
56
|
+
*/
|
|
57
|
+
export function ContentViewerProvider({ adapter, children, }) {
|
|
58
|
+
return (_jsx(ContentViewerContext.Provider, { value: adapter, children: children }));
|
|
59
|
+
}
|
|
60
|
+
// ============================================================
|
|
61
|
+
// Consumer Hook
|
|
62
|
+
// ============================================================
|
|
63
|
+
/**
|
|
64
|
+
* Returns the ContentViewerAdapter injected by the nearest
|
|
65
|
+
* ContentViewerProvider ancestor.
|
|
66
|
+
*
|
|
67
|
+
* Throws a descriptive error when called outside a ContentViewerProvider
|
|
68
|
+
* so misconfiguration is caught at runtime rather than producing silent
|
|
69
|
+
* undefined behaviour.
|
|
70
|
+
*
|
|
71
|
+
* @throws {Error} When called outside a ContentViewerProvider.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* function MyFileTree({ artifactId }: { artifactId: string }) {
|
|
76
|
+
* const { useFileTree } = useContentViewerAdapter();
|
|
77
|
+
* const { data, isLoading, error } = useFileTree(artifactId);
|
|
78
|
+
* // ...
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function useContentViewerAdapter() {
|
|
83
|
+
const ctx = useContext(ContentViewerContext);
|
|
84
|
+
if (ctx === undefined) {
|
|
85
|
+
throw new Error('[content-viewer] useContentViewerAdapter() was called outside of a ' +
|
|
86
|
+
'<ContentViewerProvider>. ' +
|
|
87
|
+
'Wrap the component tree that uses content-viewer components with ' +
|
|
88
|
+
'<ContentViewerProvider adapter={...}> and supply a ContentViewerAdapter.');
|
|
89
|
+
}
|
|
90
|
+
return ctx;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=ContentViewerProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContentViewerProvider.js","sourceRoot":"","sources":["../../src/content-viewer/ContentViewerProvider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAc,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAazD,MAAM,oBAAoB,GAAG,aAAa,CAA4B,SAAS,CAAC,CAAC;AAEjF,oBAAoB,CAAC,WAAW,GAAG,sBAAsB,CAAC;AAe1D;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,OAAO,EACP,QAAQ,GACmB;IAC3B,OAAO,CACL,KAAC,oBAAoB,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAC1C,QAAQ,GACqB,CACjC,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,gBAAgB;AAChB,+DAA+D;AAE/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,GAAG,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAE7C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,qEAAqE;YACnE,2BAA2B;YAC3B,mEAAmE;YACnE,0EAA0E,CAC7E,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { FileNode } from '../types';
|
|
2
|
+
export interface FileTreeProps {
|
|
3
|
+
entityId: string;
|
|
4
|
+
files: FileNode[];
|
|
5
|
+
selectedPath: string | null;
|
|
6
|
+
onSelect: (path: string) => void;
|
|
7
|
+
onAddFile?: () => void;
|
|
8
|
+
onDeleteFile?: (path: string) => void;
|
|
9
|
+
isLoading?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* When true, hides create/delete buttons while keeping
|
|
12
|
+
* file selection and expand/collapse functionality.
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
15
|
+
readOnly?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Accessible label for the file tree.
|
|
18
|
+
* @default "File browser"
|
|
19
|
+
*/
|
|
20
|
+
ariaLabel?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* FileTree - Recursive file browser component
|
|
24
|
+
*
|
|
25
|
+
* Displays a hierarchical tree of files and directories with expand/collapse functionality.
|
|
26
|
+
* Supports keyboard navigation, file selection, and optional delete actions.
|
|
27
|
+
*
|
|
28
|
+
* Features:
|
|
29
|
+
* - Recursive rendering of nested directories
|
|
30
|
+
* - Expandable/collapsible folders with chevron icons
|
|
31
|
+
* - File type icons (markdown, code, JSON, etc.)
|
|
32
|
+
* - Selected file highlighting
|
|
33
|
+
* - Full keyboard navigation (Arrow keys, Enter, Space, Home, End)
|
|
34
|
+
* - ARIA tree pattern for screen reader accessibility
|
|
35
|
+
* - Roving tabindex for efficient keyboard focus management
|
|
36
|
+
* - Optional context actions (delete)
|
|
37
|
+
* - Loading skeleton state
|
|
38
|
+
* - Read-only mode (hides create/delete buttons)
|
|
39
|
+
*
|
|
40
|
+
* Keyboard Controls:
|
|
41
|
+
* - ArrowUp/ArrowDown: Move focus between visible items
|
|
42
|
+
* - ArrowRight: Expand folder (if collapsed) or move to first child
|
|
43
|
+
* - ArrowLeft: Collapse folder (if expanded) or move to parent
|
|
44
|
+
* - Enter/Space: Select file or toggle folder
|
|
45
|
+
* - Home: Move to first item
|
|
46
|
+
* - End: Move to last visible item
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* // Editable mode (default)
|
|
51
|
+
* <FileTree
|
|
52
|
+
* entityId="skill-123"
|
|
53
|
+
* files={fileStructure}
|
|
54
|
+
* selectedPath={selectedPath}
|
|
55
|
+
* onSelect={(path) => setSelectedPath(path)}
|
|
56
|
+
* onDeleteFile={(path) => handleDelete(path)}
|
|
57
|
+
* />
|
|
58
|
+
*
|
|
59
|
+
* // Read-only mode (no create/delete buttons)
|
|
60
|
+
* <FileTree
|
|
61
|
+
* entityId="skill-123"
|
|
62
|
+
* files={fileStructure}
|
|
63
|
+
* selectedPath={selectedPath}
|
|
64
|
+
* onSelect={(path) => setSelectedPath(path)}
|
|
65
|
+
* readOnly
|
|
66
|
+
* ariaLabel="Artifact file browser"
|
|
67
|
+
* />
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare function FileTree({ entityId: _entityId, files, selectedPath, onSelect, onAddFile, onDeleteFile, isLoading, readOnly, ariaLabel, }: FileTreeProps): import("react/jsx-runtime").JSX.Element;
|
|
71
|
+
//# sourceMappingURL=FileTree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileTree.d.ts","sourceRoot":"","sources":["../../src/content-viewer/FileTree.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAMzC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkRD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EAAE,SAAS,EACnB,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,SAAiB,EACjB,QAAgB,EAChB,SAA0B,GAC3B,EAAE,aAAa,2CAmLf"}
|