@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
|
@@ -0,0 +1,61 @@
|
|
|
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 { injectEfCss } from "../forms/Button.js";
|
|
5
|
+
const CSS = `
|
|
6
|
+
.ef-listitem{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:var(--radius-sm);text-align:left;width:100%;border:none;background:none;font-family:var(--font-sans);color:var(--text-primary)}
|
|
7
|
+
button.ef-listitem,a.ef-listitem{cursor:pointer;transition:background var(--dur-fast) var(--ease-out);text-decoration:none}
|
|
8
|
+
button.ef-listitem:hover,a.ef-listitem:hover{background:var(--surface-sunken)}
|
|
9
|
+
button.ef-listitem:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
10
|
+
.ef-listitem__media{display:inline-flex;align-items:center;justify-content:center;flex:none;width:32px;height:32px;border-radius:var(--radius-sm);background:var(--surface-sunken);color:var(--text-secondary)}
|
|
11
|
+
.ef-listitem__title{font-size:var(--text-md);font-weight:var(--weight-medium);line-height:1.35}
|
|
12
|
+
.ef-listitem__desc{font-size:var(--text-sm);color:var(--text-muted);line-height:1.4;margin-top:1px}
|
|
13
|
+
.ef-listitem__trailing{margin-left:auto;flex:none;display:inline-flex;align-items:center;gap:8px;color:var(--text-muted)}
|
|
14
|
+
`;
|
|
15
|
+
export function ListItem({
|
|
16
|
+
icon,
|
|
17
|
+
media,
|
|
18
|
+
title,
|
|
19
|
+
description,
|
|
20
|
+
trailing,
|
|
21
|
+
chevron,
|
|
22
|
+
onClick,
|
|
23
|
+
href,
|
|
24
|
+
style,
|
|
25
|
+
className,
|
|
26
|
+
...rest
|
|
27
|
+
}) {
|
|
28
|
+
injectEfCss('ef-css-listitem', CSS);
|
|
29
|
+
const Tag = href ? 'a' : onClick ? 'button' : 'div';
|
|
30
|
+
return /*#__PURE__*/React.createElement(Tag, _extends({}, rest, {
|
|
31
|
+
href: href,
|
|
32
|
+
onClick: onClick,
|
|
33
|
+
className: `ef-listitem${className ? ' ' + className : ''}`,
|
|
34
|
+
style: style
|
|
35
|
+
}), media ? media : icon ? /*#__PURE__*/React.createElement("span", {
|
|
36
|
+
className: "ef-listitem__media"
|
|
37
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
38
|
+
name: icon,
|
|
39
|
+
size: 16
|
|
40
|
+
})) : null, /*#__PURE__*/React.createElement("span", {
|
|
41
|
+
style: {
|
|
42
|
+
minWidth: 0,
|
|
43
|
+
flex: 1
|
|
44
|
+
}
|
|
45
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
46
|
+
className: "ef-listitem__title",
|
|
47
|
+
style: {
|
|
48
|
+
display: 'block'
|
|
49
|
+
}
|
|
50
|
+
}, title), description ? /*#__PURE__*/React.createElement("span", {
|
|
51
|
+
className: "ef-listitem__desc",
|
|
52
|
+
style: {
|
|
53
|
+
display: 'block'
|
|
54
|
+
}
|
|
55
|
+
}, description) : null), /*#__PURE__*/React.createElement("span", {
|
|
56
|
+
className: "ef-listitem__trailing"
|
|
57
|
+
}, trailing, chevron ? /*#__PURE__*/React.createElement(Icon, {
|
|
58
|
+
name: "chevron-right",
|
|
59
|
+
size: 15
|
|
60
|
+
}) : null));
|
|
61
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ResizableProps {
|
|
2
|
+
/** @default 'horizontal' */
|
|
3
|
+
direction?: 'horizontal' | 'vertical';
|
|
4
|
+
/** First pane share, 0-1 @default 0.5 */
|
|
5
|
+
defaultRatio?: number;
|
|
6
|
+
/** @default 0.15 */
|
|
7
|
+
min?: number;
|
|
8
|
+
/** @default 0.85 */
|
|
9
|
+
max?: number;
|
|
10
|
+
onRatioChange?: (ratio: number) => void;
|
|
11
|
+
/** Exactly two panes */
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
style?: React.CSSProperties;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function Resizable(props: ResizableProps): React.JSX.Element;
|
|
@@ -0,0 +1,90 @@
|
|
|
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
|
+
const CSS = `
|
|
5
|
+
.ef-resizable{display:flex;width:100%;height:100%;min-height:0;min-width:0}
|
|
6
|
+
.ef-resizable--vertical{flex-direction:column}
|
|
7
|
+
.ef-resizable__pane{min-width:0;min-height:0;overflow:auto}
|
|
8
|
+
.ef-resizable__handle{flex:none;position:relative;background:transparent;border:none;padding:0;cursor:col-resize;touch-action:none}
|
|
9
|
+
.ef-resizable--horizontal>.ef-resizable__handle{width:9px}
|
|
10
|
+
.ef-resizable--vertical>.ef-resizable__handle{height:9px;cursor:row-resize}
|
|
11
|
+
.ef-resizable__handle::after{content:'';position:absolute;background:var(--border-default);transition:background var(--dur-fast) var(--ease-out)}
|
|
12
|
+
.ef-resizable--horizontal>.ef-resizable__handle::after{left:4px;top:0;bottom:0;width:1px}
|
|
13
|
+
.ef-resizable--vertical>.ef-resizable__handle::after{top:4px;left:0;right:0;height:1px}
|
|
14
|
+
.ef-resizable__handle:hover::after,.ef-resizable__handle--drag::after{background:var(--accent)}
|
|
15
|
+
.ef-resizable__handle:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
16
|
+
`;
|
|
17
|
+
export function Resizable({
|
|
18
|
+
direction = 'horizontal',
|
|
19
|
+
defaultRatio = 0.5,
|
|
20
|
+
min = 0.15,
|
|
21
|
+
max = 0.85,
|
|
22
|
+
onRatioChange,
|
|
23
|
+
children,
|
|
24
|
+
style,
|
|
25
|
+
className,
|
|
26
|
+
...rest
|
|
27
|
+
}) {
|
|
28
|
+
injectEfCss('ef-css-resizable', CSS);
|
|
29
|
+
const [ratio, setRatio] = React.useState(defaultRatio);
|
|
30
|
+
const [drag, setDrag] = React.useState(false);
|
|
31
|
+
const ref = React.useRef(null);
|
|
32
|
+
const clamp = v => Math.min(max, Math.max(min, v));
|
|
33
|
+
const apply = v => {
|
|
34
|
+
const r = clamp(v);
|
|
35
|
+
setRatio(r);
|
|
36
|
+
if (onRatioChange) onRatioChange(r);
|
|
37
|
+
};
|
|
38
|
+
const down = e => {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
setDrag(true);
|
|
41
|
+
const move = ev => {
|
|
42
|
+
const rect = ref.current.getBoundingClientRect();
|
|
43
|
+
apply(direction === 'horizontal' ? (ev.clientX - rect.left) / rect.width : (ev.clientY - rect.top) / rect.height);
|
|
44
|
+
};
|
|
45
|
+
const up = () => {
|
|
46
|
+
setDrag(false);
|
|
47
|
+
window.removeEventListener('pointermove', move);
|
|
48
|
+
window.removeEventListener('pointerup', up);
|
|
49
|
+
};
|
|
50
|
+
window.addEventListener('pointermove', move);
|
|
51
|
+
window.addEventListener('pointerup', up);
|
|
52
|
+
};
|
|
53
|
+
const key = e => {
|
|
54
|
+
const d = {
|
|
55
|
+
ArrowLeft: -0.02,
|
|
56
|
+
ArrowRight: 0.02,
|
|
57
|
+
ArrowUp: -0.02,
|
|
58
|
+
ArrowDown: 0.02
|
|
59
|
+
}[e.key];
|
|
60
|
+
if (d === undefined) return;
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
apply(ratio + d);
|
|
63
|
+
};
|
|
64
|
+
const kids = React.Children.toArray(children);
|
|
65
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
|
|
66
|
+
ref: ref,
|
|
67
|
+
className: `ef-resizable ef-resizable--${direction}${className ? ' ' + className : ''}`,
|
|
68
|
+
style: style
|
|
69
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
70
|
+
className: "ef-resizable__pane",
|
|
71
|
+
style: {
|
|
72
|
+
flexBasis: ratio * 100 + '%',
|
|
73
|
+
flexGrow: 0,
|
|
74
|
+
flexShrink: 0
|
|
75
|
+
}
|
|
76
|
+
}, kids[0]), /*#__PURE__*/React.createElement("button", {
|
|
77
|
+
type: "button",
|
|
78
|
+
role: "separator",
|
|
79
|
+
"aria-orientation": direction === 'horizontal' ? 'vertical' : 'horizontal',
|
|
80
|
+
"aria-label": "Resize panes",
|
|
81
|
+
className: `ef-resizable__handle${drag ? ' ef-resizable__handle--drag' : ''}`,
|
|
82
|
+
onPointerDown: down,
|
|
83
|
+
onKeyDown: key
|
|
84
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
85
|
+
className: "ef-resizable__pane",
|
|
86
|
+
style: {
|
|
87
|
+
flex: 1
|
|
88
|
+
}
|
|
89
|
+
}, kids[1]));
|
|
90
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ScrollAreaProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
2
|
+
/** Scroll past this height */
|
|
3
|
+
maxHeight?: number | string;
|
|
4
|
+
/** Fixed height */
|
|
5
|
+
height?: number | string;
|
|
6
|
+
children?: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export declare function ScrollArea(props: ScrollAreaProps): React.JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
const CSS = `
|
|
5
|
+
.ef-scrollarea{overflow:auto;scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}
|
|
6
|
+
.ef-scrollarea::-webkit-scrollbar{width:9px;height:9px}
|
|
7
|
+
.ef-scrollarea::-webkit-scrollbar-track{background:transparent}
|
|
8
|
+
.ef-scrollarea::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:var(--radius-full);border:2px solid transparent;background-clip:content-box}
|
|
9
|
+
.ef-scrollarea::-webkit-scrollbar-thumb:hover{background:var(--text-muted);border:2px solid transparent;background-clip:content-box}
|
|
10
|
+
`;
|
|
11
|
+
export function ScrollArea({
|
|
12
|
+
maxHeight,
|
|
13
|
+
height,
|
|
14
|
+
children,
|
|
15
|
+
style,
|
|
16
|
+
className,
|
|
17
|
+
...rest
|
|
18
|
+
}) {
|
|
19
|
+
injectEfCss('ef-css-scrollarea', CSS);
|
|
20
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
|
21
|
+
className: `ef-scrollarea${className ? ' ' + className : ''}`,
|
|
22
|
+
style: {
|
|
23
|
+
maxHeight,
|
|
24
|
+
height,
|
|
25
|
+
...style
|
|
26
|
+
}
|
|
27
|
+
}, rest), children);
|
|
28
|
+
}
|
package/display/Tag.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
2
|
+
/** Lucide icon name, leading */
|
|
3
|
+
icon?: string;
|
|
4
|
+
/** Shows a remove ✕ button */
|
|
5
|
+
onRemove?: (e: React.MouseEvent) => void;
|
|
6
|
+
onClick?: (e: React.MouseEvent) => void;
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare function Tag(props: TagProps): React.JSX.Element;
|
package/display/Tag.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
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 { injectEfCss } from "../forms/Button.js";
|
|
5
|
+
const CSS = `
|
|
6
|
+
.ef-tag{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 10px;border-radius:var(--radius-sm);background:transparent;border:1px solid var(--border-strong);color:var(--text-secondary);font-size:var(--text-sm);font-weight:var(--weight-medium);white-space:nowrap;transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}
|
|
7
|
+
.ef-tag--interactive{cursor:pointer}
|
|
8
|
+
.ef-tag--interactive:hover{background:var(--surface-sunken);border-color:var(--sand-400)}
|
|
9
|
+
.ef-tag__x{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;margin-right:-4px;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--text-muted);cursor:pointer;padding:0;transition:background var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out)}
|
|
10
|
+
.ef-tag__x:hover{background:var(--sand-200);color:var(--text-primary)}
|
|
11
|
+
.ef-tag__x:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
12
|
+
`;
|
|
13
|
+
export function Tag({
|
|
14
|
+
icon,
|
|
15
|
+
onRemove,
|
|
16
|
+
onClick,
|
|
17
|
+
children,
|
|
18
|
+
style,
|
|
19
|
+
className,
|
|
20
|
+
...rest
|
|
21
|
+
}) {
|
|
22
|
+
injectEfCss('ef-css-tag', CSS);
|
|
23
|
+
return /*#__PURE__*/React.createElement("span", _extends({
|
|
24
|
+
className: `ef-tag${onClick ? ' ef-tag--interactive' : ''}${className ? ' ' + className : ''}`,
|
|
25
|
+
onClick: onClick,
|
|
26
|
+
style: style
|
|
27
|
+
}, rest), icon ? /*#__PURE__*/React.createElement(Icon, {
|
|
28
|
+
name: icon,
|
|
29
|
+
size: 13
|
|
30
|
+
}) : null, children, onRemove ? /*#__PURE__*/React.createElement("button", {
|
|
31
|
+
className: "ef-tag__x",
|
|
32
|
+
"aria-label": "Remove",
|
|
33
|
+
onClick: e => {
|
|
34
|
+
e.stopPropagation();
|
|
35
|
+
onRemove(e);
|
|
36
|
+
}
|
|
37
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
38
|
+
name: "x",
|
|
39
|
+
size: 12
|
|
40
|
+
})) : null);
|
|
41
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ToolbarItem {
|
|
2
|
+
id: string;
|
|
3
|
+
/** Lucide icon */
|
|
4
|
+
icon?: string;
|
|
5
|
+
label?: React.ReactNode;
|
|
6
|
+
/** Tooltip text */
|
|
7
|
+
tip?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface ToolbarProps {
|
|
12
|
+
/** Items; 'separator' inserts a divider */
|
|
13
|
+
items: Array<ToolbarItem | 'separator'>;
|
|
14
|
+
/** Active id or ids (toggle styling) */
|
|
15
|
+
value?: string | string[];
|
|
16
|
+
onChange?: (id: string) => void;
|
|
17
|
+
/** aria-label */
|
|
18
|
+
label?: string;
|
|
19
|
+
style?: React.CSSProperties;
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function Toolbar(props: ToolbarProps): React.JSX.Element;
|
|
@@ -0,0 +1,55 @@
|
|
|
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 { Tooltip } from "../feedback/Tooltip.js";
|
|
5
|
+
import { injectEfCss } from "../forms/Button.js";
|
|
6
|
+
const CSS = `
|
|
7
|
+
.ef-toolbar{display:inline-flex;align-items:center;gap:2px;padding:3px;background:var(--surface-card);border:1px solid var(--border-strong);border-radius:var(--radius-md)}
|
|
8
|
+
.ef-toolbar__btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:28px;min-width:28px;padding:0 7px;border:none;border-radius:6px;background:none;cursor:pointer;color:var(--text-secondary);font-family:var(--font-sans);font-size:var(--text-sm);font-weight:var(--weight-medium);transition:background var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out)}
|
|
9
|
+
.ef-toolbar__btn:hover:not(:disabled){background:var(--surface-sunken);color:var(--text-primary)}
|
|
10
|
+
.ef-toolbar__btn--active{background:var(--accent);color:var(--accent-contrast)}
|
|
11
|
+
.ef-toolbar__btn--active:hover:not(:disabled){background:var(--accent-hover);color:var(--accent-contrast)}
|
|
12
|
+
.ef-toolbar__btn:disabled{opacity:.4;cursor:not-allowed}
|
|
13
|
+
.ef-toolbar__btn:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
14
|
+
.ef-toolbar__sep{width:1px;height:18px;background:var(--border-default);margin:0 4px}
|
|
15
|
+
`;
|
|
16
|
+
export function Toolbar({
|
|
17
|
+
items,
|
|
18
|
+
value,
|
|
19
|
+
onChange,
|
|
20
|
+
label,
|
|
21
|
+
style,
|
|
22
|
+
className,
|
|
23
|
+
...rest
|
|
24
|
+
}) {
|
|
25
|
+
injectEfCss('ef-css-toolbar', CSS);
|
|
26
|
+
const active = Array.isArray(value) ? value : value != null ? [value] : [];
|
|
27
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
|
|
28
|
+
role: "toolbar",
|
|
29
|
+
"aria-label": label,
|
|
30
|
+
className: `ef-toolbar${className ? ' ' + className : ''}`,
|
|
31
|
+
style: style
|
|
32
|
+
}), items.map((it, i) => {
|
|
33
|
+
if (it === 'separator') return /*#__PURE__*/React.createElement("span", {
|
|
34
|
+
key: 's' + i,
|
|
35
|
+
className: "ef-toolbar__sep"
|
|
36
|
+
});
|
|
37
|
+
const btn = /*#__PURE__*/React.createElement("button", {
|
|
38
|
+
key: it.id,
|
|
39
|
+
disabled: it.disabled,
|
|
40
|
+
"aria-pressed": active.includes(it.id) || undefined,
|
|
41
|
+
className: `ef-toolbar__btn${active.includes(it.id) ? ' ef-toolbar__btn--active' : ''}`,
|
|
42
|
+
onClick: () => {
|
|
43
|
+
if (onChange) onChange(it.id);
|
|
44
|
+
if (it.onClick) it.onClick();
|
|
45
|
+
}
|
|
46
|
+
}, it.icon ? /*#__PURE__*/React.createElement(Icon, {
|
|
47
|
+
name: it.icon,
|
|
48
|
+
size: 15
|
|
49
|
+
}) : null, it.label || null);
|
|
50
|
+
return it.tip ? /*#__PURE__*/React.createElement(Tooltip, {
|
|
51
|
+
key: it.id,
|
|
52
|
+
label: it.tip
|
|
53
|
+
}, btn) : btn;
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface TreeNode {
|
|
2
|
+
id: string;
|
|
3
|
+
label: React.ReactNode;
|
|
4
|
+
/** Lucide icon */
|
|
5
|
+
icon?: string;
|
|
6
|
+
/** Right-aligned mono count */
|
|
7
|
+
count?: number;
|
|
8
|
+
children?: TreeNode[];
|
|
9
|
+
}
|
|
10
|
+
export interface TreeListProps {
|
|
11
|
+
nodes: TreeNode[];
|
|
12
|
+
/** Controlled selected id */
|
|
13
|
+
value?: string;
|
|
14
|
+
onSelect?: (id: string, node: TreeNode) => void;
|
|
15
|
+
/** Branch ids open initially (default: all top-level) */
|
|
16
|
+
defaultOpen?: string[];
|
|
17
|
+
style?: React.CSSProperties;
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function TreeList(props: TreeListProps): React.JSX.Element;
|
|
@@ -0,0 +1,101 @@
|
|
|
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 { injectEfCss } from "../forms/Button.js";
|
|
5
|
+
const CSS = `
|
|
6
|
+
.ef-tree{display:flex;flex-direction:column;gap:1px;font-size:var(--text-sm)}
|
|
7
|
+
.ef-tree__row{display:flex;align-items:center;gap:7px;height:30px;padding:0 8px;border:none;border-radius:var(--radius-sm);background:none;cursor:pointer;text-align:left;font-family:var(--font-sans);font-size:var(--text-sm);color:var(--text-secondary);width:100%;transition:background var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out)}
|
|
8
|
+
.ef-tree__row:hover{background:var(--surface-sunken);color:var(--text-primary)}
|
|
9
|
+
.ef-tree__row--sel{background:var(--accent-subtle);color:var(--brand-700);font-weight:var(--weight-semibold)}
|
|
10
|
+
.ef-tree__row--sel:hover{background:var(--accent-subtle);color:var(--brand-700)}
|
|
11
|
+
.ef-tree__row:focus-visible{outline:none;box-shadow:var(--focus-ring)}
|
|
12
|
+
.ef-tree__chev{display:inline-flex;color:var(--text-muted);transition:transform var(--dur-fast) var(--ease-out);flex:none}
|
|
13
|
+
.ef-tree__chev--open{transform:rotate(90deg)}
|
|
14
|
+
.ef-tree__icon{display:inline-flex;flex:none;color:var(--text-muted)}
|
|
15
|
+
.ef-tree__row--sel .ef-tree__icon{color:inherit}
|
|
16
|
+
.ef-tree__count{margin-left:auto;font-family:var(--font-mono);font-size:11px;color:var(--text-muted)}
|
|
17
|
+
`;
|
|
18
|
+
function Node({
|
|
19
|
+
node,
|
|
20
|
+
depth,
|
|
21
|
+
open,
|
|
22
|
+
sel,
|
|
23
|
+
toggle,
|
|
24
|
+
select
|
|
25
|
+
}) {
|
|
26
|
+
const kids = node.children || [];
|
|
27
|
+
const isOpen = open.includes(node.id);
|
|
28
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("button", {
|
|
29
|
+
className: `ef-tree__row${sel === node.id ? ' ef-tree__row--sel' : ''}`,
|
|
30
|
+
style: {
|
|
31
|
+
paddingLeft: 8 + depth * 18
|
|
32
|
+
},
|
|
33
|
+
onClick: () => {
|
|
34
|
+
if (kids.length) toggle(node.id);
|
|
35
|
+
select(node.id, node);
|
|
36
|
+
}
|
|
37
|
+
}, kids.length ? /*#__PURE__*/React.createElement("span", {
|
|
38
|
+
className: `ef-tree__chev${isOpen ? ' ef-tree__chev--open' : ''}`
|
|
39
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
40
|
+
name: "chevron-right",
|
|
41
|
+
size: 13
|
|
42
|
+
})) : /*#__PURE__*/React.createElement("span", {
|
|
43
|
+
style: {
|
|
44
|
+
width: 13,
|
|
45
|
+
flex: 'none'
|
|
46
|
+
}
|
|
47
|
+
}), node.icon ? /*#__PURE__*/React.createElement("span", {
|
|
48
|
+
className: "ef-tree__icon"
|
|
49
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
50
|
+
name: node.icon,
|
|
51
|
+
size: 15
|
|
52
|
+
})) : null, /*#__PURE__*/React.createElement("span", {
|
|
53
|
+
style: {
|
|
54
|
+
whiteSpace: 'nowrap',
|
|
55
|
+
overflow: 'hidden',
|
|
56
|
+
textOverflow: 'ellipsis'
|
|
57
|
+
}
|
|
58
|
+
}, node.label), node.count != null ? /*#__PURE__*/React.createElement("span", {
|
|
59
|
+
className: "ef-tree__count"
|
|
60
|
+
}, node.count) : null), isOpen && kids.map(k => /*#__PURE__*/React.createElement(Node, {
|
|
61
|
+
key: k.id,
|
|
62
|
+
node: k,
|
|
63
|
+
depth: depth + 1,
|
|
64
|
+
open: open,
|
|
65
|
+
sel: sel,
|
|
66
|
+
toggle: toggle,
|
|
67
|
+
select: select
|
|
68
|
+
})));
|
|
69
|
+
}
|
|
70
|
+
export function TreeList({
|
|
71
|
+
nodes,
|
|
72
|
+
value,
|
|
73
|
+
onSelect,
|
|
74
|
+
defaultOpen,
|
|
75
|
+
style,
|
|
76
|
+
className,
|
|
77
|
+
...rest
|
|
78
|
+
}) {
|
|
79
|
+
injectEfCss('ef-css-tree', CSS);
|
|
80
|
+
const [open, setOpen] = React.useState(defaultOpen || nodes.filter(n => n.children).map(n => n.id));
|
|
81
|
+
const [innerSel, setInnerSel] = React.useState(null);
|
|
82
|
+
const sel = value != null ? value : innerSel;
|
|
83
|
+
const toggle = id => setOpen(o => o.includes(id) ? o.filter(x => x !== id) : [...o, id]);
|
|
84
|
+
const select = (id, node) => {
|
|
85
|
+
if (value == null) setInnerSel(id);
|
|
86
|
+
if (onSelect) onSelect(id, node);
|
|
87
|
+
};
|
|
88
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
|
|
89
|
+
role: "tree",
|
|
90
|
+
className: `ef-tree${className ? ' ' + className : ''}`,
|
|
91
|
+
style: style
|
|
92
|
+
}), nodes.map(n => /*#__PURE__*/React.createElement(Node, {
|
|
93
|
+
key: n.id,
|
|
94
|
+
node: n,
|
|
95
|
+
depth: 0,
|
|
96
|
+
open: open,
|
|
97
|
+
sel: sel,
|
|
98
|
+
toggle: toggle,
|
|
99
|
+
select: select
|
|
100
|
+
})));
|
|
101
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface AlertProps {
|
|
2
|
+
/** @default 'info' */
|
|
3
|
+
tone?: 'info' | 'success' | 'warning' | 'danger';
|
|
4
|
+
/** Override the tone icon (Lucide name) */
|
|
5
|
+
icon?: string;
|
|
6
|
+
title?: React.ReactNode;
|
|
7
|
+
description?: React.ReactNode;
|
|
8
|
+
/** Right-aligned slot (button/link) */
|
|
9
|
+
action?: React.ReactNode;
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
style?: React.CSSProperties;
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function Alert(props: AlertProps): React.JSX.Element;
|
|
@@ -0,0 +1,56 @@
|
|
|
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 { injectEfCss } from "../forms/Button.js";
|
|
5
|
+
const CSS = `
|
|
6
|
+
.ef-alert{display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border:1px solid var(--border-strong);border-radius:var(--radius-md);background:var(--surface-card)}
|
|
7
|
+
.ef-alert__icon{display:inline-flex;margin-top:1px;flex:none}
|
|
8
|
+
.ef-alert--info .ef-alert__icon{color:var(--brand-700)}
|
|
9
|
+
.ef-alert--success .ef-alert__icon{color:var(--success-600)}
|
|
10
|
+
.ef-alert--warning .ef-alert__icon{color:var(--warning-600)}
|
|
11
|
+
.ef-alert--danger .ef-alert__icon{color:var(--danger-600)}
|
|
12
|
+
.ef-alert--danger{border-color:var(--danger-300)}
|
|
13
|
+
.ef-alert__title{font-size:var(--text-md);font-weight:var(--weight-semibold);color:var(--text-primary);line-height:1.4}
|
|
14
|
+
.ef-alert__desc{font-size:var(--text-sm);color:var(--text-secondary);line-height:1.5;margin-top:2px}
|
|
15
|
+
.ef-alert__action{margin-left:auto;flex:none}
|
|
16
|
+
`;
|
|
17
|
+
const ICONS = {
|
|
18
|
+
info: 'info',
|
|
19
|
+
success: 'circle-check',
|
|
20
|
+
warning: 'triangle-alert',
|
|
21
|
+
danger: 'circle-alert'
|
|
22
|
+
};
|
|
23
|
+
export function Alert({
|
|
24
|
+
tone = 'info',
|
|
25
|
+
icon,
|
|
26
|
+
title,
|
|
27
|
+
description,
|
|
28
|
+
action,
|
|
29
|
+
children,
|
|
30
|
+
style,
|
|
31
|
+
className,
|
|
32
|
+
...rest
|
|
33
|
+
}) {
|
|
34
|
+
injectEfCss('ef-css-alert', CSS);
|
|
35
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
|
|
36
|
+
role: "status",
|
|
37
|
+
className: `ef-alert ef-alert--${tone}${className ? ' ' + className : ''}`,
|
|
38
|
+
style: style
|
|
39
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
40
|
+
className: "ef-alert__icon"
|
|
41
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
42
|
+
name: icon || ICONS[tone],
|
|
43
|
+
size: 16
|
|
44
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
45
|
+
style: {
|
|
46
|
+
flex: 1,
|
|
47
|
+
minWidth: 0
|
|
48
|
+
}
|
|
49
|
+
}, title ? /*#__PURE__*/React.createElement("div", {
|
|
50
|
+
className: "ef-alert__title"
|
|
51
|
+
}, title) : null, description ? /*#__PURE__*/React.createElement("div", {
|
|
52
|
+
className: "ef-alert__desc"
|
|
53
|
+
}, description) : null, children), action ? /*#__PURE__*/React.createElement("div", {
|
|
54
|
+
className: "ef-alert__action"
|
|
55
|
+
}, action) : null);
|
|
56
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface BannerProps {
|
|
2
|
+
/** @default 'neutral' */
|
|
3
|
+
tone?: 'neutral' | 'brand' | 'warning' | 'danger';
|
|
4
|
+
/** Lucide icon name */
|
|
5
|
+
icon?: string;
|
|
6
|
+
/** Underlined action label */
|
|
7
|
+
action?: string;
|
|
8
|
+
onAction?: () => void;
|
|
9
|
+
/** Shows a dismiss ✕ */
|
|
10
|
+
onDismiss?: () => void;
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
style?: React.CSSProperties;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function Banner(props: BannerProps): React.JSX.Element;
|
|
@@ -0,0 +1,49 @@
|
|
|
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-banner{display:flex;align-items:center;gap:10px;padding:9px 16px;font-size:var(--text-sm);border-bottom:1px solid var(--border-default)}
|
|
8
|
+
.ef-banner--neutral{background:var(--surface-sunken);color:var(--text-primary)}
|
|
9
|
+
.ef-banner--brand{background:var(--cream-50);color:var(--cocoa-700)}
|
|
10
|
+
.ef-banner--warning{background:var(--warning-100);color:var(--warning-600);border-color:var(--warning-300)}
|
|
11
|
+
.ef-banner--danger{background:var(--danger-100);color:var(--danger-600);border-color:var(--danger-300)}
|
|
12
|
+
.ef-banner__icon{display:inline-flex;flex:none}
|
|
13
|
+
.ef-banner__text{flex:1;min-width:0}
|
|
14
|
+
.ef-banner__text strong{font-weight:var(--weight-semibold)}
|
|
15
|
+
.ef-banner__action{flex:none;font-weight:var(--weight-semibold);font-size:var(--text-sm);color:inherit;text-decoration:underline;text-underline-offset:3px;background:none;border:none;cursor:pointer;font-family:var(--font-sans);padding:0}
|
|
16
|
+
`;
|
|
17
|
+
export function Banner({
|
|
18
|
+
tone = 'neutral',
|
|
19
|
+
icon,
|
|
20
|
+
action,
|
|
21
|
+
onAction,
|
|
22
|
+
onDismiss,
|
|
23
|
+
children,
|
|
24
|
+
style,
|
|
25
|
+
className,
|
|
26
|
+
...rest
|
|
27
|
+
}) {
|
|
28
|
+
injectEfCss('ef-css-banner', CSS);
|
|
29
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, rest, {
|
|
30
|
+
role: "status",
|
|
31
|
+
className: `ef-banner ef-banner--${tone}${className ? ' ' + className : ''}`,
|
|
32
|
+
style: style
|
|
33
|
+
}), icon ? /*#__PURE__*/React.createElement("span", {
|
|
34
|
+
className: "ef-banner__icon"
|
|
35
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
36
|
+
name: icon,
|
|
37
|
+
size: 15
|
|
38
|
+
})) : null, /*#__PURE__*/React.createElement("span", {
|
|
39
|
+
className: "ef-banner__text"
|
|
40
|
+
}, children), action ? /*#__PURE__*/React.createElement("button", {
|
|
41
|
+
className: "ef-banner__action",
|
|
42
|
+
onClick: onAction
|
|
43
|
+
}, action) : null, onDismiss ? /*#__PURE__*/React.createElement(IconButton, {
|
|
44
|
+
icon: "x",
|
|
45
|
+
label: "Dismiss",
|
|
46
|
+
size: "sm",
|
|
47
|
+
onClick: onDismiss
|
|
48
|
+
}) : null);
|
|
49
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ConfirmDialogProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onClose?: () => void;
|
|
4
|
+
/** Called on confirm (dialog closes itself after) */
|
|
5
|
+
onConfirm?: () => void;
|
|
6
|
+
title: React.ReactNode;
|
|
7
|
+
description?: React.ReactNode;
|
|
8
|
+
/** @default 'Delete' */
|
|
9
|
+
confirmLabel?: string;
|
|
10
|
+
/** @default 'Cancel' */
|
|
11
|
+
cancelLabel?: string;
|
|
12
|
+
/** 'danger' (red confirm) or 'primary' @default 'danger' */
|
|
13
|
+
tone?: 'danger' | 'primary';
|
|
14
|
+
/** Require typing this string to enable confirm */
|
|
15
|
+
typeToConfirm?: string;
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export declare function ConfirmDialog(props: ConfirmDialogProps): React.JSX.Element;
|
|
@@ -0,0 +1,49 @@
|
|
|
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 { Dialog } from "./Dialog.js";
|
|
4
|
+
import { Button } from "../forms/Button.js";
|
|
5
|
+
import { Input } from "../forms/Input.js";
|
|
6
|
+
export function ConfirmDialog({
|
|
7
|
+
open,
|
|
8
|
+
onClose,
|
|
9
|
+
onConfirm,
|
|
10
|
+
title,
|
|
11
|
+
description,
|
|
12
|
+
confirmLabel = 'Delete',
|
|
13
|
+
cancelLabel = 'Cancel',
|
|
14
|
+
tone = 'danger',
|
|
15
|
+
typeToConfirm,
|
|
16
|
+
children,
|
|
17
|
+
...rest
|
|
18
|
+
}) {
|
|
19
|
+
const [typed, setTyped] = React.useState('');
|
|
20
|
+
React.useEffect(() => {
|
|
21
|
+
if (!open) setTyped('');
|
|
22
|
+
}, [open]);
|
|
23
|
+
const blocked = typeToConfirm ? typed !== typeToConfirm : false;
|
|
24
|
+
return /*#__PURE__*/React.createElement(Dialog, _extends({}, rest, {
|
|
25
|
+
open: open,
|
|
26
|
+
onClose: onClose,
|
|
27
|
+
title: title,
|
|
28
|
+
description: description,
|
|
29
|
+
footer: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
|
|
30
|
+
variant: "ghost",
|
|
31
|
+
onClick: onClose
|
|
32
|
+
}, cancelLabel), /*#__PURE__*/React.createElement(Button, {
|
|
33
|
+
variant: tone === 'danger' ? 'danger' : 'primary',
|
|
34
|
+
disabled: blocked,
|
|
35
|
+
onClick: () => {
|
|
36
|
+
if (onConfirm) onConfirm();
|
|
37
|
+
if (onClose) onClose();
|
|
38
|
+
}
|
|
39
|
+
}, confirmLabel))
|
|
40
|
+
}), children, typeToConfirm ? /*#__PURE__*/React.createElement(Input, {
|
|
41
|
+
label: `Type “${typeToConfirm}” to confirm`,
|
|
42
|
+
value: typed,
|
|
43
|
+
onChange: e => setTyped(e.target.value),
|
|
44
|
+
placeholder: typeToConfirm,
|
|
45
|
+
style: children ? {
|
|
46
|
+
marginTop: 14
|
|
47
|
+
} : undefined
|
|
48
|
+
}) : null);
|
|
49
|
+
}
|