@efolusi/meridian 1.5.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/README.md +12 -0
- package/ai/AgentRun.d.ts +20 -0
- package/ai/AgentRun.js +100 -0
- package/ai/ChatMessage.d.ts +19 -0
- package/ai/ChatMessage.js +81 -0
- package/ai/Citation.d.ts +23 -0
- package/ai/Citation.js +146 -0
- package/ai/Confirmation.d.ts +26 -0
- package/ai/Confirmation.js +84 -0
- package/ai/Conversation.d.ts +15 -0
- package/ai/Conversation.js +81 -0
- package/ai/DocumentCard.d.ts +17 -0
- package/ai/DocumentCard.js +101 -0
- package/ai/FeedbackBar.d.ts +14 -0
- package/ai/FeedbackBar.js +84 -0
- package/ai/GeneratedImage.d.ts +22 -0
- package/ai/GeneratedImage.js +100 -0
- package/ai/ModelSelector.d.ts +21 -0
- package/ai/ModelSelector.js +112 -0
- package/ai/Player.d.ts +18 -0
- package/ai/Player.js +201 -0
- package/ai/PromptComposer.d.ts +28 -0
- package/ai/PromptComposer.js +111 -0
- package/ai/PromptSteps.d.ts +18 -0
- package/ai/PromptSteps.js +167 -0
- package/ai/Reasoning.d.ts +17 -0
- package/ai/Reasoning.js +57 -0
- package/ai/RichComposer.d.ts +25 -0
- package/ai/RichComposer.js +247 -0
- package/ai/Sandbox.d.ts +20 -0
- package/ai/Sandbox.js +96 -0
- package/ai/SelectionQuote.d.ts +15 -0
- package/ai/SelectionQuote.js +123 -0
- package/ai/SourceCard.d.ts +17 -0
- package/ai/SourceCard.js +57 -0
- package/ai/Suggestions.d.ts +10 -0
- package/ai/Suggestions.js +38 -0
- package/ai/Task.d.ts +15 -0
- package/ai/Task.js +49 -0
- package/ai/Todo.d.ts +13 -0
- package/ai/Todo.js +87 -0
- package/ai/ToolCall.d.ts +30 -0
- package/ai/ToolCall.js +147 -0
- package/ai/Transcript.d.ts +27 -0
- package/ai/Transcript.js +96 -0
- package/ai/UsageMeter.d.ts +21 -0
- package/ai/UsageMeter.js +81 -0
- package/ai/WebPreview.d.ts +19 -0
- package/ai/WebPreview.js +179 -0
- package/assets/fonts/BricolageGrotesque-Variable.ttf +0 -0
- package/assets/fonts/Figtree-Italic-Variable.ttf +0 -0
- package/assets/fonts/Figtree-Variable.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Italic-Variable.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Variable.ttf +0 -0
- package/assets/fonts/OFL-BricolageGrotesque.txt +93 -0
- package/assets/fonts/OFL-Figtree.txt +93 -0
- package/assets/fonts/OFL-JetBrainsMono.txt +93 -0
- package/code/CodeBlock.d.ts +17 -0
- package/code/CodeBlock.js +99 -0
- package/code/Console.d.ts +19 -0
- package/code/Console.js +124 -0
- package/code/CopyField.d.ts +10 -0
- package/code/CopyField.js +54 -0
- package/code/Diff.d.ts +26 -0
- package/code/Diff.js +358 -0
- package/code/EnvList.d.ts +14 -0
- package/code/EnvList.js +89 -0
- package/code/Exception.d.ts +25 -0
- package/code/Exception.js +90 -0
- package/code/Terminal.d.ts +20 -0
- package/code/Terminal.js +58 -0
- package/data/BarChart.d.ts +14 -0
- package/data/BarChart.js +44 -0
- package/data/DonutChart.d.ts +17 -0
- package/data/DonutChart.js +114 -0
- package/data/EmptyState.d.ts +13 -0
- package/data/EmptyState.js +39 -0
- package/data/KeyValueList.d.ts +14 -0
- package/data/KeyValueList.js +34 -0
- package/data/LineChart.d.ts +15 -0
- package/data/LineChart.js +85 -0
- package/data/Skeleton.d.ts +11 -0
- package/data/Skeleton.js +49 -0
- package/data/Sparkline.d.ts +14 -0
- package/data/Sparkline.js +42 -0
- package/data/Stat.d.ts +14 -0
- package/data/Stat.js +40 -0
- package/data/StatusDot.d.ts +10 -0
- package/data/StatusDot.js +34 -0
- package/data/Table.d.ts +53 -0
- package/data/Table.js +174 -0
- package/dates/Calendar.d.ts +8 -0
- package/dates/Calendar.js +143 -0
- package/dates/DatePicker.d.ts +12 -0
- package/dates/DatePicker.js +118 -0
- package/display/Accordion.d.ts +15 -0
- package/display/Accordion.js +52 -0
- package/display/AspectRatio.d.ts +8 -0
- package/display/AspectRatio.js +24 -0
- package/display/Avatar.d.ts +17 -0
- package/display/Avatar.js +52 -0
- package/display/Badge.d.ts +10 -0
- package/display/Badge.js +34 -0
- package/display/Card.d.ts +17 -0
- package/display/Card.js +51 -0
- package/display/Carousel.d.ts +16 -0
- package/display/Carousel.js +97 -0
- package/display/Collapsible.d.ts +12 -0
- package/display/Collapsible.js +46 -0
- package/display/Divider.d.ts +9 -0
- package/display/Divider.js +33 -0
- package/display/Kbd.d.ts +7 -0
- package/display/Kbd.js +18 -0
- package/display/Link.d.ts +12 -0
- package/display/Link.js +41 -0
- package/display/ListItem.d.ts +19 -0
- package/display/ListItem.js +61 -0
- package/display/Resizable.d.ts +16 -0
- package/display/Resizable.js +90 -0
- package/display/ScrollArea.d.ts +8 -0
- package/display/ScrollArea.js +28 -0
- package/display/Tag.d.ts +9 -0
- package/display/Tag.js +41 -0
- package/display/Toolbar.d.ts +22 -0
- package/display/Toolbar.js +55 -0
- package/display/TreeList.d.ts +20 -0
- package/display/TreeList.js +101 -0
- package/feedback/Alert.d.ts +14 -0
- package/feedback/Alert.js +56 -0
- package/feedback/Banner.d.ts +15 -0
- package/feedback/Banner.js +49 -0
- package/feedback/ConfirmDialog.d.ts +18 -0
- package/feedback/ConfirmDialog.js +49 -0
- package/feedback/Dialog.d.ts +13 -0
- package/feedback/Dialog.js +107 -0
- package/feedback/Loader.d.ts +12 -0
- package/feedback/Loader.js +41 -0
- package/feedback/Progress.d.ts +15 -0
- package/feedback/Progress.js +48 -0
- package/feedback/Spinner.d.ts +9 -0
- package/feedback/Spinner.js +38 -0
- package/feedback/Toast.d.ts +70 -0
- package/feedback/Toast.js +216 -0
- package/feedback/Tooltip.d.ts +12 -0
- package/feedback/Tooltip.js +86 -0
- package/files/FileDrop.d.ts +15 -0
- package/files/FileDrop.js +75 -0
- package/files/FileTile.d.ts +19 -0
- package/files/FileTile.js +96 -0
- package/files/FileTypeIcon.d.ts +11 -0
- package/files/FileTypeIcon.js +121 -0
- package/finance/PaymentCard.d.ts +17 -0
- package/finance/PaymentCard.js +109 -0
- package/forms/Button.d.ts +15 -0
- package/forms/Button.js +82 -0
- package/forms/ButtonGroup.d.ts +5 -0
- package/forms/ButtonGroup.js +22 -0
- package/forms/ButtonTile.d.ts +21 -0
- package/forms/ButtonTile.js +69 -0
- package/forms/Checkbox.d.ts +6 -0
- package/forms/Checkbox.js +52 -0
- package/forms/Combobox.d.ts +17 -0
- package/forms/Combobox.js +162 -0
- package/forms/DigitEntry.d.ts +15 -0
- package/forms/DigitEntry.js +88 -0
- package/forms/FormField.d.ts +39 -0
- package/forms/FormField.js +127 -0
- package/forms/IconButton.d.ts +11 -0
- package/forms/IconButton.js +41 -0
- package/forms/Input.d.ts +14 -0
- package/forms/Input.js +75 -0
- package/forms/InputGroup.d.ts +15 -0
- package/forms/InputGroup.js +59 -0
- package/forms/Label.d.ts +11 -0
- package/forms/Label.js +29 -0
- package/forms/Radio.d.ts +6 -0
- package/forms/Radio.js +46 -0
- package/forms/Select.d.ts +10 -0
- package/forms/Select.js +68 -0
- package/forms/Slider.d.ts +18 -0
- package/forms/Slider.js +75 -0
- package/forms/Switch.d.ts +6 -0
- package/forms/Switch.js +46 -0
- package/forms/Textarea.d.ts +8 -0
- package/forms/Textarea.js +58 -0
- package/forms/Toggle.d.ts +26 -0
- package/forms/Toggle.js +85 -0
- package/icons/Icon.d.ts +13 -0
- package/icons/Icon.js +54 -0
- package/index.d.ts +106 -0
- package/index.js +106 -0
- package/navigation/Breadcrumbs.d.ts +12 -0
- package/navigation/Breadcrumbs.js +41 -0
- package/navigation/Menubar.d.ts +10 -0
- package/navigation/Menubar.js +173 -0
- package/navigation/PageControl.d.ts +11 -0
- package/navigation/PageControl.js +36 -0
- package/navigation/Pagination.d.ts +9 -0
- package/navigation/Pagination.js +68 -0
- package/navigation/SegmentedControl.d.ts +17 -0
- package/navigation/SegmentedControl.js +42 -0
- package/navigation/SideNav.d.ts +18 -0
- package/navigation/SideNav.js +87 -0
- package/navigation/Steps.d.ts +15 -0
- package/navigation/Steps.js +61 -0
- package/navigation/Tabs.d.ts +17 -0
- package/navigation/Tabs.js +76 -0
- package/navigation/TopNav.d.ts +10 -0
- package/navigation/TopNav.js +26 -0
- package/overlay/CommandPalette.d.ts +21 -0
- package/overlay/CommandPalette.js +164 -0
- package/overlay/ContextMenu.d.ts +11 -0
- package/overlay/ContextMenu.js +140 -0
- package/overlay/Drawer.d.ts +14 -0
- package/overlay/Drawer.js +99 -0
- package/overlay/HoverCard.d.ts +17 -0
- package/overlay/HoverCard.js +74 -0
- package/overlay/Menu.d.ts +24 -0
- package/overlay/Menu.js +153 -0
- package/overlay/Popover.d.ts +16 -0
- package/overlay/Popover.js +96 -0
- package/overlay/Portal.d.ts +10 -0
- package/overlay/Portal.js +127 -0
- package/package.json +41 -0
- package/styles.css +6 -0
- package/tokens/base.css +10 -0
- package/tokens/colors.css +38 -0
- package/tokens/effects.css +22 -0
- package/tokens/fonts.css +5 -0
- package/tokens/spacing.css +12 -0
- package/tokens/typography.css +9 -0
package/code/Console.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { injectEfCss } from "../forms/Button.js";
|
|
4
|
+
import { Icon } from "../icons/Icon.js";
|
|
5
|
+
const CSS = `
|
|
6
|
+
.ef-console{position:relative;display:flex;flex-direction:column;border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--surface-card);overflow:hidden;font-family:var(--font-sans)}
|
|
7
|
+
.ef-console__head{display:flex;align-items:center;gap:8px;padding:8px 13px;border-bottom:1px solid var(--border-default);background:var(--surface-subtle);font-size:12px;color:var(--text-secondary)}
|
|
8
|
+
.ef-console__scroll{overflow-y:auto;font-family:var(--font-mono);font-size:12px;line-height:1.6}
|
|
9
|
+
.ef-console__row{display:flex;align-items:flex-start;gap:9px;padding:6px 13px;border-top:1px solid var(--border-default);color:var(--text-secondary)}
|
|
10
|
+
.ef-console__row:first-child{border-top:none}
|
|
11
|
+
.ef-console__glyph{display:inline-flex;flex:none;width:14px;margin-top:2px;color:var(--text-muted)}
|
|
12
|
+
.ef-console__row--warn .ef-console__glyph,.ef-console__row--warn .ef-console__msg{color:var(--warning-600)}
|
|
13
|
+
.ef-console__row--error .ef-console__glyph,.ef-console__row--error .ef-console__msg{color:var(--danger-600)}
|
|
14
|
+
.ef-console__row--debug .ef-console__glyph{color:var(--text-link)}
|
|
15
|
+
.ef-console__time{flex:none;color:var(--text-muted);font-variant-numeric:tabular-nums}
|
|
16
|
+
.ef-console__msg{flex:1;min-width:0;white-space:pre-wrap;word-break:break-word}
|
|
17
|
+
.ef-console__src{flex:none;margin-left:auto;color:var(--text-muted);font-size:11px}
|
|
18
|
+
.ef-console__stackbtn{display:inline-flex;align-items:center;gap:5px;border:none;background:none;padding:0;cursor:pointer;font:inherit;color:inherit;text-align:left}
|
|
19
|
+
.ef-console__stackbtn:hover{color:var(--text-primary)}
|
|
20
|
+
.ef-console__stackchev{display:inline-flex;margin-top:2px;color:var(--text-muted);transition:transform var(--dur-fast) var(--ease-out)}
|
|
21
|
+
.ef-console__stackchev--open{transform:rotate(90deg)}
|
|
22
|
+
.ef-console__stack{margin:4px 0 0;padding-left:19px;white-space:pre-wrap;color:var(--text-muted);font-size:11.5px}
|
|
23
|
+
.ef-console__jump{position:absolute;right:10px;bottom:10px;display:inline-flex;align-items:center;gap:6px;padding:6px 11px;border:1px solid var(--border-strong);border-radius:var(--radius-full);background:var(--surface-card);box-shadow:var(--shadow-md,0 2px 8px rgba(0,0,0,.08));cursor:pointer;font-family:var(--font-sans);font-size:12px;font-weight:var(--weight-semibold);color:var(--text-primary)}
|
|
24
|
+
`;
|
|
25
|
+
const GLYPH = {
|
|
26
|
+
info: 'info',
|
|
27
|
+
warn: 'triangle-alert',
|
|
28
|
+
error: 'circle-alert',
|
|
29
|
+
debug: 'bug'
|
|
30
|
+
};
|
|
31
|
+
function Row({
|
|
32
|
+
e
|
|
33
|
+
}) {
|
|
34
|
+
const [open, setOpen] = React.useState(false);
|
|
35
|
+
const lvl = e.level || 'log';
|
|
36
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
37
|
+
className: `ef-console__row${lvl !== 'log' ? ' ef-console__row--' + lvl : ''}`
|
|
38
|
+
}, e.time ? /*#__PURE__*/React.createElement("span", {
|
|
39
|
+
className: "ef-console__time"
|
|
40
|
+
}, e.time) : null, /*#__PURE__*/React.createElement("span", {
|
|
41
|
+
className: "ef-console__glyph"
|
|
42
|
+
}, GLYPH[lvl] ? /*#__PURE__*/React.createElement(Icon, {
|
|
43
|
+
name: GLYPH[lvl],
|
|
44
|
+
size: 12
|
|
45
|
+
}) : null), /*#__PURE__*/React.createElement("span", {
|
|
46
|
+
className: "ef-console__msg"
|
|
47
|
+
}, e.stack ? /*#__PURE__*/React.createElement("button", {
|
|
48
|
+
type: "button",
|
|
49
|
+
className: "ef-console__stackbtn",
|
|
50
|
+
"aria-expanded": open,
|
|
51
|
+
onClick: () => setOpen(!open)
|
|
52
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
53
|
+
className: `ef-console__stackchev${open ? ' ef-console__stackchev--open' : ''}`
|
|
54
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
55
|
+
name: "chevron-right",
|
|
56
|
+
size: 11
|
|
57
|
+
})), /*#__PURE__*/React.createElement("span", null, e.text)) : e.text, e.stack && open ? /*#__PURE__*/React.createElement("div", {
|
|
58
|
+
className: "ef-console__stack"
|
|
59
|
+
}, e.stack) : null), e.source ? /*#__PURE__*/React.createElement("span", {
|
|
60
|
+
className: "ef-console__src"
|
|
61
|
+
}, e.source) : null);
|
|
62
|
+
}
|
|
63
|
+
export function Console({
|
|
64
|
+
title = 'Console',
|
|
65
|
+
entries = [],
|
|
66
|
+
height = 240,
|
|
67
|
+
style,
|
|
68
|
+
className,
|
|
69
|
+
...rest
|
|
70
|
+
}) {
|
|
71
|
+
injectEfCss('ef-css-console', CSS);
|
|
72
|
+
const viewport = React.useRef(null);
|
|
73
|
+
const wasBottom = React.useRef(true);
|
|
74
|
+
const [atBottom, setAtBottom] = React.useState(true);
|
|
75
|
+
const recompute = () => {
|
|
76
|
+
const v = viewport.current;
|
|
77
|
+
if (!v) return;
|
|
78
|
+
const b = v.scrollHeight - v.scrollTop - v.clientHeight < 24;
|
|
79
|
+
wasBottom.current = b;
|
|
80
|
+
setAtBottom(b);
|
|
81
|
+
};
|
|
82
|
+
React.useEffect(() => {
|
|
83
|
+
const v = viewport.current;
|
|
84
|
+
if (v && wasBottom.current) v.scrollTop = v.scrollHeight;
|
|
85
|
+
recompute();
|
|
86
|
+
}, [entries.length]);
|
|
87
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
|
|
88
|
+
className: `ef-console${className ? ' ' + className : ''}`,
|
|
89
|
+
style: style
|
|
90
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
91
|
+
className: "ef-console__head"
|
|
92
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
93
|
+
name: "terminal",
|
|
94
|
+
size: 13
|
|
95
|
+
}), title, /*#__PURE__*/React.createElement("span", {
|
|
96
|
+
style: {
|
|
97
|
+
marginLeft: 'auto',
|
|
98
|
+
color: 'var(--text-muted)'
|
|
99
|
+
}
|
|
100
|
+
}, entries.length, " entries")), /*#__PURE__*/React.createElement("div", {
|
|
101
|
+
ref: viewport,
|
|
102
|
+
className: "ef-console__scroll",
|
|
103
|
+
style: {
|
|
104
|
+
height
|
|
105
|
+
},
|
|
106
|
+
onScroll: recompute
|
|
107
|
+
}, entries.map((e, i) => /*#__PURE__*/React.createElement(Row, {
|
|
108
|
+
key: i,
|
|
109
|
+
e: e
|
|
110
|
+
}))), !atBottom ? /*#__PURE__*/React.createElement("button", {
|
|
111
|
+
type: "button",
|
|
112
|
+
className: "ef-console__jump",
|
|
113
|
+
onClick: () => {
|
|
114
|
+
const v = viewport.current;
|
|
115
|
+
if (v) v.scrollTo({
|
|
116
|
+
top: v.scrollHeight,
|
|
117
|
+
behavior: 'smooth'
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
121
|
+
name: "chevron-down",
|
|
122
|
+
size: 12
|
|
123
|
+
}), "Latest") : null);
|
|
124
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface CopyFieldProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
2
|
+
label?: string;
|
|
3
|
+
/** The copyable value (mono) */
|
|
4
|
+
value: string;
|
|
5
|
+
/** Mask with dots + reveal toggle */
|
|
6
|
+
secret?: boolean;
|
|
7
|
+
style?: React.CSSProperties;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function CopyField(props: CopyFieldProps): React.JSX.Element;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Icon } from "../icons/Icon.js";
|
|
4
|
+
import { IconButton } from "../forms/IconButton.js";
|
|
5
|
+
import { injectEfCss } from "../forms/Button.js";
|
|
6
|
+
const CSS = `
|
|
7
|
+
.ef-copyfield{display:flex;flex-direction:column;gap:6px}
|
|
8
|
+
.ef-copyfield__label{font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--text-primary)}
|
|
9
|
+
.ef-copyfield__box{display:flex;align-items:center;gap:8px;height:var(--control-h-md);padding:0 4px 0 12px;border:1px solid var(--border-strong);border-radius:var(--radius-sm);background:var(--surface-sunken)}
|
|
10
|
+
.ef-copyfield__value{flex:1;font-family:var(--font-mono);font-size:13px;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;user-select:all}
|
|
11
|
+
`;
|
|
12
|
+
export function CopyField({
|
|
13
|
+
label,
|
|
14
|
+
value,
|
|
15
|
+
secret,
|
|
16
|
+
style,
|
|
17
|
+
className,
|
|
18
|
+
...rest
|
|
19
|
+
}) {
|
|
20
|
+
injectEfCss('ef-css-copyfield', CSS);
|
|
21
|
+
const [show, setShow] = React.useState(!secret);
|
|
22
|
+
const [copied, setCopied] = React.useState(false);
|
|
23
|
+
const copy = () => {
|
|
24
|
+
if (navigator.clipboard) navigator.clipboard.writeText(value).catch(() => {});
|
|
25
|
+
setCopied(true);
|
|
26
|
+
setTimeout(() => setCopied(false), 1600);
|
|
27
|
+
};
|
|
28
|
+
const shown = show ? value : '•'.repeat(Math.min(24, String(value).length));
|
|
29
|
+
const box = /*#__PURE__*/React.createElement("span", {
|
|
30
|
+
className: "ef-copyfield__box"
|
|
31
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
32
|
+
className: "ef-copyfield__value"
|
|
33
|
+
}, shown), secret ? /*#__PURE__*/React.createElement(IconButton, {
|
|
34
|
+
icon: show ? 'eye-off' : 'eye',
|
|
35
|
+
label: show ? 'Hide' : 'Reveal',
|
|
36
|
+
size: "sm",
|
|
37
|
+
onClick: () => setShow(s => !s)
|
|
38
|
+
}) : null, /*#__PURE__*/React.createElement(IconButton, {
|
|
39
|
+
icon: copied ? 'check' : 'copy',
|
|
40
|
+
label: "Copy",
|
|
41
|
+
size: "sm",
|
|
42
|
+
onClick: copy
|
|
43
|
+
}));
|
|
44
|
+
if (!label) return /*#__PURE__*/React.cloneElement(box, {
|
|
45
|
+
className: 'ef-copyfield__box' + (className ? ' ' + className : ''),
|
|
46
|
+
style
|
|
47
|
+
});
|
|
48
|
+
return /*#__PURE__*/React.createElement("span", _extends({}, rest, {
|
|
49
|
+
className: `ef-copyfield${className ? ' ' + className : ''}`,
|
|
50
|
+
style: style
|
|
51
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
52
|
+
className: "ef-copyfield__label"
|
|
53
|
+
}, label), box);
|
|
54
|
+
}
|
package/code/Diff.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface DiffLine {
|
|
2
|
+
/** @default 'ctx' */
|
|
3
|
+
type?: 'add' | 'del' | 'ctx';
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
export interface DiffProps {
|
|
7
|
+
/** Header: file path etc. Shows +/− counts */
|
|
8
|
+
title?: React.ReactNode;
|
|
9
|
+
/** Pre-computed rows. Omit and pass `from`/`to` instead. */
|
|
10
|
+
lines?: DiffLine[];
|
|
11
|
+
/** Original text; diffed against `to` when `lines` is omitted */
|
|
12
|
+
from?: string;
|
|
13
|
+
/** Changed text */
|
|
14
|
+
to?: string;
|
|
15
|
+
/** Multi-file diff; each file is diffed and collapsible */
|
|
16
|
+
files?: Array<{ name: string; from?: string; to?: string; lines?: DiffLine[]; defaultOpen?: boolean }>;
|
|
17
|
+
/** Highlight changed words inside a changed line @default true */
|
|
18
|
+
wordLevel?: boolean;
|
|
19
|
+
/** Unchanged lines kept around each hunk @default 3 */
|
|
20
|
+
contextLines?: number;
|
|
21
|
+
/** Scroll past this height */
|
|
22
|
+
maxHeight?: number | string;
|
|
23
|
+
style?: React.CSSProperties;
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function Diff(props: DiffProps): React.JSX.Element;
|
package/code/Diff.js
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { injectEfCss } from "../forms/Button.js";
|
|
4
|
+
import { Icon } from "../icons/Icon.js";
|
|
5
|
+
const CSS = `
|
|
6
|
+
.ef-diff{border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--surface-card);overflow:hidden;font-family:var(--font-mono);font-size:12.5px;line-height:1.7}
|
|
7
|
+
.ef-diff__head{display:flex;align-items:center;gap:10px;padding:8px 13px;background:var(--surface-subtle);border-bottom:1px solid var(--border-default);font-size:12px;color:var(--text-secondary);font-family:var(--font-sans)}
|
|
8
|
+
.ef-diff__counts{margin-left:auto;display:inline-flex;gap:8px;font-size:11.5px;font-family:var(--font-mono);font-variant-numeric:tabular-nums}
|
|
9
|
+
.ef-diff__plus{color:var(--success-600,#3D6B4A)}
|
|
10
|
+
.ef-diff__minus{color:var(--danger-600)}
|
|
11
|
+
.ef-diff__scroll{overflow:auto}
|
|
12
|
+
.ef-diff__line{display:flex;white-space:pre}
|
|
13
|
+
.ef-diff__no{flex:none;width:38px;padding:0 8px;text-align:right;color:var(--text-muted);font-size:11px;user-select:none;background:var(--surface-subtle);border-right:1px solid var(--border-default)}
|
|
14
|
+
.ef-diff__sign{flex:none;width:20px;text-align:center;user-select:none;color:var(--text-muted)}
|
|
15
|
+
.ef-diff__text{flex:1;padding-right:14px;color:var(--text-secondary)}
|
|
16
|
+
.ef-diff__line--add{background:var(--success-100,#EAF3EC)}
|
|
17
|
+
.ef-diff__line--add .ef-diff__sign,.ef-diff__line--add .ef-diff__text{color:var(--success-600,#3D6B4A)}
|
|
18
|
+
.ef-diff__line--del{background:var(--danger-100,#F8ECEA)}
|
|
19
|
+
.ef-diff__line--del .ef-diff__sign,.ef-diff__line--del .ef-diff__text{color:var(--danger-600)}
|
|
20
|
+
.ef-diff__word--add{background:var(--success-300,#BFDCC6);border-radius:3px}
|
|
21
|
+
.ef-diff__word--del{background:var(--danger-300);border-radius:3px}
|
|
22
|
+
.ef-diff__skip{display:flex;align-items:center;gap:10px;padding:2px 0;color:var(--text-muted);font-size:11px;user-select:none}
|
|
23
|
+
.ef-diff__skipno{flex:none;width:76px;text-align:center;background:var(--surface-subtle);border-right:1px solid var(--border-default)}
|
|
24
|
+
.ef-diff__file{border-top:1px solid var(--border-default)}
|
|
25
|
+
.ef-diff__file:first-child{border-top:none}
|
|
26
|
+
.ef-diff__filehead{display:flex;align-items:center;gap:9px;width:100%;padding:8px 13px;border:none;background:var(--surface-subtle);cursor:pointer;text-align:left;font-family:var(--font-mono);font-size:12px;color:var(--text-primary)}
|
|
27
|
+
.ef-diff__filehead:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
28
|
+
.ef-diff__filechev{display:inline-flex;color:var(--text-muted);transition:transform var(--dur-fast) var(--ease-out)}
|
|
29
|
+
.ef-diff__filechev--open{transform:rotate(90deg)}
|
|
30
|
+
`;
|
|
31
|
+
function lcsOps(a, b) {
|
|
32
|
+
const m = a.length,
|
|
33
|
+
n = b.length;
|
|
34
|
+
if (m * n > 400000) {
|
|
35
|
+
const ops = [];
|
|
36
|
+
a.forEach(v => ops.push(['del', v]));
|
|
37
|
+
b.forEach(v => ops.push(['add', v]));
|
|
38
|
+
return ops;
|
|
39
|
+
}
|
|
40
|
+
const w = n + 1,
|
|
41
|
+
dp = new Uint16Array((m + 1) * w);
|
|
42
|
+
for (let i = m - 1; i >= 0; i--) for (let j = n - 1; j >= 0; j--) dp[i * w + j] = a[i] === b[j] ? dp[(i + 1) * w + j + 1] + 1 : Math.max(dp[(i + 1) * w + j], dp[i * w + j + 1]);
|
|
43
|
+
const ops = [];
|
|
44
|
+
let i = 0,
|
|
45
|
+
j = 0;
|
|
46
|
+
while (i < m && j < n) {
|
|
47
|
+
if (a[i] === b[j]) {
|
|
48
|
+
ops.push(['ctx', a[i]]);
|
|
49
|
+
i++;
|
|
50
|
+
j++;
|
|
51
|
+
} else if (dp[(i + 1) * w + j] >= dp[i * w + j + 1]) {
|
|
52
|
+
ops.push(['del', a[i]]);
|
|
53
|
+
i++;
|
|
54
|
+
} else {
|
|
55
|
+
ops.push(['add', b[j]]);
|
|
56
|
+
j++;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
while (i < m) {
|
|
60
|
+
ops.push(['del', a[i]]);
|
|
61
|
+
i++;
|
|
62
|
+
}
|
|
63
|
+
while (j < n) {
|
|
64
|
+
ops.push(['add', b[j]]);
|
|
65
|
+
j++;
|
|
66
|
+
}
|
|
67
|
+
return ops;
|
|
68
|
+
}
|
|
69
|
+
function wordSegs(del, add) {
|
|
70
|
+
const ta = del.split(/(\s+)/).filter(s => s !== ''),
|
|
71
|
+
tb = add.split(/(\s+)/).filter(s => s !== '');
|
|
72
|
+
const ops = lcsOps(ta, tb),
|
|
73
|
+
d = [],
|
|
74
|
+
a = [];
|
|
75
|
+
for (const [t, v] of ops) {
|
|
76
|
+
if (t === 'ctx') {
|
|
77
|
+
d.push({
|
|
78
|
+
v
|
|
79
|
+
});
|
|
80
|
+
a.push({
|
|
81
|
+
v
|
|
82
|
+
});
|
|
83
|
+
} else if (t === 'del') d.push({
|
|
84
|
+
v,
|
|
85
|
+
m: 1
|
|
86
|
+
});else a.push({
|
|
87
|
+
v,
|
|
88
|
+
m: 1
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
d,
|
|
93
|
+
a
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function splitLines(s) {
|
|
97
|
+
const arr = String(s).split('\n');
|
|
98
|
+
if (arr[arr.length - 1] === '') arr.pop();
|
|
99
|
+
return arr;
|
|
100
|
+
}
|
|
101
|
+
export function computeDiff(from, to, {
|
|
102
|
+
wordLevel = true,
|
|
103
|
+
contextLines = 3
|
|
104
|
+
} = {}) {
|
|
105
|
+
const ops = lcsOps(splitLines(from), splitLines(to));
|
|
106
|
+
const rows = [];
|
|
107
|
+
let oldNo = 0,
|
|
108
|
+
newNo = 0,
|
|
109
|
+
adds = 0,
|
|
110
|
+
dels = 0;
|
|
111
|
+
for (let i = 0; i < ops.length; i++) {
|
|
112
|
+
const [t, text] = ops[i];
|
|
113
|
+
if (t === 'ctx') {
|
|
114
|
+
oldNo++;
|
|
115
|
+
newNo++;
|
|
116
|
+
rows.push({
|
|
117
|
+
type: 'ctx',
|
|
118
|
+
text,
|
|
119
|
+
oldNo,
|
|
120
|
+
newNo
|
|
121
|
+
});
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (t === 'del') {
|
|
125
|
+
const delRun = [];
|
|
126
|
+
while (i < ops.length && ops[i][0] === 'del') {
|
|
127
|
+
delRun.push(ops[i][1]);
|
|
128
|
+
i++;
|
|
129
|
+
}
|
|
130
|
+
const addRun = [];
|
|
131
|
+
while (i < ops.length && ops[i][0] === 'add') {
|
|
132
|
+
addRun.push(ops[i][1]);
|
|
133
|
+
i++;
|
|
134
|
+
}
|
|
135
|
+
i--;
|
|
136
|
+
const max = Math.max(delRun.length, addRun.length);
|
|
137
|
+
for (let k = 0; k < max; k++) {
|
|
138
|
+
const dl = delRun[k],
|
|
139
|
+
al = addRun[k];
|
|
140
|
+
const pair = wordLevel && dl !== undefined && al !== undefined ? wordSegs(dl, al) : null;
|
|
141
|
+
if (dl !== undefined) {
|
|
142
|
+
oldNo++;
|
|
143
|
+
dels++;
|
|
144
|
+
rows.push({
|
|
145
|
+
type: 'del',
|
|
146
|
+
text: dl,
|
|
147
|
+
oldNo,
|
|
148
|
+
segs: pair && pair.d
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (al !== undefined) {
|
|
152
|
+
newNo++;
|
|
153
|
+
adds++;
|
|
154
|
+
rows.push({
|
|
155
|
+
type: 'add',
|
|
156
|
+
text: al,
|
|
157
|
+
newNo,
|
|
158
|
+
segs: pair && pair.a
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
newNo++;
|
|
165
|
+
adds++;
|
|
166
|
+
rows.push({
|
|
167
|
+
type: 'add',
|
|
168
|
+
text,
|
|
169
|
+
newNo
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
if (contextLines != null) {
|
|
173
|
+
const out = [];
|
|
174
|
+
let run = [];
|
|
175
|
+
const flush = (leading, trailing) => {
|
|
176
|
+
const keepStart = leading ? 0 : contextLines;
|
|
177
|
+
const keepEnd = trailing ? 0 : contextLines;
|
|
178
|
+
const skip = run.length - keepStart - keepEnd;
|
|
179
|
+
if (skip > (leading || trailing ? 0 : 1)) {
|
|
180
|
+
for (let k = 0; k < keepStart; k++) out.push(run[k]);
|
|
181
|
+
out.push({
|
|
182
|
+
type: 'skip',
|
|
183
|
+
count: skip
|
|
184
|
+
});
|
|
185
|
+
for (let k = run.length - keepEnd; k < run.length; k++) out.push(run[k]);
|
|
186
|
+
} else run.forEach(r => out.push(r));
|
|
187
|
+
run = [];
|
|
188
|
+
};
|
|
189
|
+
let seenChange = false;
|
|
190
|
+
rows.forEach((r, idx) => {
|
|
191
|
+
if (r.type === 'ctx') {
|
|
192
|
+
run.push(r);
|
|
193
|
+
if (idx === rows.length - 1) flush(!seenChange, true);
|
|
194
|
+
} else {
|
|
195
|
+
if (run.length) flush(!seenChange, false);
|
|
196
|
+
seenChange = true;
|
|
197
|
+
out.push(r);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
if (run.length) flush(!seenChange, true);
|
|
201
|
+
return {
|
|
202
|
+
rows: out,
|
|
203
|
+
adds,
|
|
204
|
+
dels
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
rows,
|
|
209
|
+
adds,
|
|
210
|
+
dels
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function Rows({
|
|
214
|
+
rows
|
|
215
|
+
}) {
|
|
216
|
+
return rows.map((l, i) => {
|
|
217
|
+
if (l.type === 'skip') return /*#__PURE__*/React.createElement("div", {
|
|
218
|
+
key: i,
|
|
219
|
+
className: "ef-diff__skip"
|
|
220
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
221
|
+
className: "ef-diff__skipno"
|
|
222
|
+
}, "\u22EF"), /*#__PURE__*/React.createElement("span", null, l.count, " unchanged lines"));
|
|
223
|
+
const t = l.type || 'ctx';
|
|
224
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
225
|
+
key: i,
|
|
226
|
+
className: `ef-diff__line${t !== 'ctx' ? ' ef-diff__line--' + t : ''}`
|
|
227
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
228
|
+
className: "ef-diff__no"
|
|
229
|
+
}, t === 'add' ? '' : l.oldNo), /*#__PURE__*/React.createElement("span", {
|
|
230
|
+
className: "ef-diff__no"
|
|
231
|
+
}, t === 'del' ? '' : l.newNo), /*#__PURE__*/React.createElement("span", {
|
|
232
|
+
className: "ef-diff__sign"
|
|
233
|
+
}, t === 'add' ? '+' : t === 'del' ? '−' : ''), /*#__PURE__*/React.createElement("span", {
|
|
234
|
+
className: "ef-diff__text"
|
|
235
|
+
}, l.segs ? l.segs.map((s, k) => s.m ? /*#__PURE__*/React.createElement("span", {
|
|
236
|
+
key: k,
|
|
237
|
+
className: `ef-diff__word--${t}`
|
|
238
|
+
}, s.v) : s.v) : l.text));
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function Counts({
|
|
242
|
+
adds,
|
|
243
|
+
dels
|
|
244
|
+
}) {
|
|
245
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
246
|
+
className: "ef-diff__counts"
|
|
247
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
248
|
+
className: "ef-diff__plus"
|
|
249
|
+
}, "+", adds), /*#__PURE__*/React.createElement("span", {
|
|
250
|
+
className: "ef-diff__minus"
|
|
251
|
+
}, "\u2212", dels));
|
|
252
|
+
}
|
|
253
|
+
function DiffFile({
|
|
254
|
+
file,
|
|
255
|
+
wordLevel,
|
|
256
|
+
contextLines
|
|
257
|
+
}) {
|
|
258
|
+
const [open, setOpen] = React.useState(file.defaultOpen !== false);
|
|
259
|
+
const r = React.useMemo(() => file.lines ? legacy(file.lines) : computeDiff(file.from || '', file.to || '', {
|
|
260
|
+
wordLevel,
|
|
261
|
+
contextLines
|
|
262
|
+
}), [file, wordLevel, contextLines]);
|
|
263
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
264
|
+
className: "ef-diff__file"
|
|
265
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
266
|
+
type: "button",
|
|
267
|
+
className: "ef-diff__filehead",
|
|
268
|
+
"aria-expanded": open,
|
|
269
|
+
onClick: () => setOpen(!open)
|
|
270
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
271
|
+
className: `ef-diff__filechev${open ? ' ef-diff__filechev--open' : ''}`
|
|
272
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
273
|
+
name: "chevron-right",
|
|
274
|
+
size: 12
|
|
275
|
+
})), /*#__PURE__*/React.createElement("span", {
|
|
276
|
+
style: {
|
|
277
|
+
flex: 1,
|
|
278
|
+
minWidth: 0,
|
|
279
|
+
overflow: 'hidden',
|
|
280
|
+
textOverflow: 'ellipsis'
|
|
281
|
+
}
|
|
282
|
+
}, file.name), /*#__PURE__*/React.createElement(Counts, {
|
|
283
|
+
adds: r.adds,
|
|
284
|
+
dels: r.dels
|
|
285
|
+
})), open ? /*#__PURE__*/React.createElement("div", {
|
|
286
|
+
className: "ef-diff__scroll"
|
|
287
|
+
}, /*#__PURE__*/React.createElement(Rows, {
|
|
288
|
+
rows: r.rows
|
|
289
|
+
})) : null);
|
|
290
|
+
}
|
|
291
|
+
function legacy(lines) {
|
|
292
|
+
let oldNo = 0,
|
|
293
|
+
newNo = 0,
|
|
294
|
+
adds = 0,
|
|
295
|
+
dels = 0;
|
|
296
|
+
const rows = lines.map(l => {
|
|
297
|
+
const t = l.type || 'ctx';
|
|
298
|
+
if (t !== 'add') oldNo++;
|
|
299
|
+
if (t !== 'del') newNo++;
|
|
300
|
+
if (t === 'add') adds++;
|
|
301
|
+
if (t === 'del') dels++;
|
|
302
|
+
return {
|
|
303
|
+
type: t,
|
|
304
|
+
text: l.text,
|
|
305
|
+
oldNo,
|
|
306
|
+
newNo
|
|
307
|
+
};
|
|
308
|
+
});
|
|
309
|
+
return {
|
|
310
|
+
rows,
|
|
311
|
+
adds,
|
|
312
|
+
dels
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
export function Diff({
|
|
316
|
+
title,
|
|
317
|
+
lines,
|
|
318
|
+
from,
|
|
319
|
+
to,
|
|
320
|
+
files,
|
|
321
|
+
wordLevel = true,
|
|
322
|
+
contextLines = 3,
|
|
323
|
+
maxHeight,
|
|
324
|
+
style,
|
|
325
|
+
className,
|
|
326
|
+
...rest
|
|
327
|
+
}) {
|
|
328
|
+
injectEfCss('ef-css-diff', CSS);
|
|
329
|
+
const single = React.useMemo(() => {
|
|
330
|
+
if (files) return null;
|
|
331
|
+
if (lines) return legacy(lines);
|
|
332
|
+
return computeDiff(from || '', to || '', {
|
|
333
|
+
wordLevel,
|
|
334
|
+
contextLines: from !== undefined ? contextLines : null
|
|
335
|
+
});
|
|
336
|
+
}, [lines, from, to, files, wordLevel, contextLines]);
|
|
337
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
|
|
338
|
+
className: `ef-diff${className ? ' ' + className : ''}`,
|
|
339
|
+
style: style
|
|
340
|
+
}), title && single ? /*#__PURE__*/React.createElement("div", {
|
|
341
|
+
className: "ef-diff__head"
|
|
342
|
+
}, title, /*#__PURE__*/React.createElement(Counts, {
|
|
343
|
+
adds: single.adds,
|
|
344
|
+
dels: single.dels
|
|
345
|
+
})) : null, files ? files.map((f, i) => /*#__PURE__*/React.createElement(DiffFile, {
|
|
346
|
+
key: f.name || i,
|
|
347
|
+
file: f,
|
|
348
|
+
wordLevel: wordLevel,
|
|
349
|
+
contextLines: contextLines
|
|
350
|
+
})) : /*#__PURE__*/React.createElement("div", {
|
|
351
|
+
className: "ef-diff__scroll",
|
|
352
|
+
style: maxHeight ? {
|
|
353
|
+
maxHeight
|
|
354
|
+
} : null
|
|
355
|
+
}, /*#__PURE__*/React.createElement(Rows, {
|
|
356
|
+
rows: single.rows
|
|
357
|
+
})));
|
|
358
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface EnvVar {
|
|
2
|
+
name: string;
|
|
3
|
+
value: string;
|
|
4
|
+
/** Masked until revealed */
|
|
5
|
+
secret?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface EnvListProps {
|
|
8
|
+
title?: string;
|
|
9
|
+
vars: EnvVar[];
|
|
10
|
+
defaultVisible?: boolean;
|
|
11
|
+
style?: React.CSSProperties;
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function EnvList(props: EnvListProps): React.JSX.Element;
|
package/code/EnvList.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { injectEfCss } from "../forms/Button.js";
|
|
4
|
+
import { Icon } from "../icons/Icon.js";
|
|
5
|
+
const CSS = `
|
|
6
|
+
.ef-env{border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--surface-card);font-family:var(--font-sans)}
|
|
7
|
+
.ef-env__head{display:flex;align-items:center;gap:9px;padding:10px 14px}
|
|
8
|
+
.ef-env__glyph{display:inline-flex;color:var(--text-muted)}
|
|
9
|
+
.ef-env__title{flex:1;min-width:0;font-size:13.5px;font-weight:var(--weight-semibold);color:var(--text-primary)}
|
|
10
|
+
.ef-env__btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:none;background:none;cursor:pointer;color:var(--text-muted);border-radius:var(--radius-sm);transition:color var(--dur-fast) var(--ease-out),background var(--dur-fast) var(--ease-out)}
|
|
11
|
+
.ef-env__btn:hover{color:var(--text-primary);background:var(--surface-subtle)}
|
|
12
|
+
.ef-env__btn:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
13
|
+
.ef-env__btn--done{color:var(--success-600)}
|
|
14
|
+
.ef-env__list{padding:0 6px 6px}
|
|
15
|
+
.ef-env__row{display:flex;align-items:center;gap:12px;padding:5px 8px;border-radius:var(--radius-sm)}
|
|
16
|
+
.ef-env__row:hover{background:var(--surface-subtle)}
|
|
17
|
+
.ef-env__name{flex:none;font-family:var(--font-mono);font-size:12.5px;color:var(--text-muted)}
|
|
18
|
+
.ef-env__val{flex:1;min-width:0;margin-left:auto;text-align:right;font-family:var(--font-mono);font-size:12.5px;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
19
|
+
.ef-env__row .ef-env__btn{opacity:0;width:24px;height:24px}
|
|
20
|
+
.ef-env__row:hover .ef-env__btn,.ef-env__row .ef-env__btn:focus-visible,.ef-env__row .ef-env__btn--done{opacity:1}
|
|
21
|
+
`;
|
|
22
|
+
const MASK = '••••••••';
|
|
23
|
+
function Row({
|
|
24
|
+
v,
|
|
25
|
+
visible
|
|
26
|
+
}) {
|
|
27
|
+
const [copied, setCopied] = React.useState(false);
|
|
28
|
+
const masked = v.secret && !visible;
|
|
29
|
+
const copy = () => {
|
|
30
|
+
if (navigator.clipboard) navigator.clipboard.writeText(v.value).catch(() => {});
|
|
31
|
+
setCopied(true);
|
|
32
|
+
setTimeout(() => setCopied(false), 1200);
|
|
33
|
+
};
|
|
34
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
35
|
+
className: "ef-env__row"
|
|
36
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
37
|
+
className: "ef-env__name"
|
|
38
|
+
}, v.name), /*#__PURE__*/React.createElement("span", {
|
|
39
|
+
className: "ef-env__val"
|
|
40
|
+
}, masked ? MASK : v.value), /*#__PURE__*/React.createElement("button", {
|
|
41
|
+
type: "button",
|
|
42
|
+
className: `ef-env__btn${copied ? ' ef-env__btn--done' : ''}`,
|
|
43
|
+
"aria-label": 'Copy ' + v.name,
|
|
44
|
+
onClick: copy
|
|
45
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
46
|
+
name: copied ? 'check' : 'copy',
|
|
47
|
+
size: 13
|
|
48
|
+
})));
|
|
49
|
+
}
|
|
50
|
+
export function EnvList({
|
|
51
|
+
title = 'Environment',
|
|
52
|
+
vars = [],
|
|
53
|
+
defaultVisible = false,
|
|
54
|
+
style,
|
|
55
|
+
className,
|
|
56
|
+
...rest
|
|
57
|
+
}) {
|
|
58
|
+
injectEfCss('ef-css-env', CSS);
|
|
59
|
+
const [visible, setVisible] = React.useState(!!defaultVisible);
|
|
60
|
+
const hasSecrets = vars.some(v => v.secret);
|
|
61
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
|
|
62
|
+
className: `ef-env${className ? ' ' + className : ''}`,
|
|
63
|
+
style: style
|
|
64
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
65
|
+
className: "ef-env__head"
|
|
66
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
67
|
+
className: "ef-env__glyph"
|
|
68
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
69
|
+
name: "key",
|
|
70
|
+
size: 14
|
|
71
|
+
})), /*#__PURE__*/React.createElement("span", {
|
|
72
|
+
className: "ef-env__title"
|
|
73
|
+
}, title), hasSecrets ? /*#__PURE__*/React.createElement("button", {
|
|
74
|
+
type: "button",
|
|
75
|
+
className: "ef-env__btn",
|
|
76
|
+
"aria-label": visible ? 'Hide secrets' : 'Reveal secrets',
|
|
77
|
+
"aria-pressed": visible,
|
|
78
|
+
onClick: () => setVisible(!visible)
|
|
79
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
80
|
+
name: visible ? 'eye-off' : 'eye',
|
|
81
|
+
size: 14
|
|
82
|
+
})) : null), /*#__PURE__*/React.createElement("div", {
|
|
83
|
+
className: "ef-env__list"
|
|
84
|
+
}, vars.map((v, i) => /*#__PURE__*/React.createElement(Row, {
|
|
85
|
+
key: i,
|
|
86
|
+
v: v,
|
|
87
|
+
visible: visible
|
|
88
|
+
}))));
|
|
89
|
+
}
|