diff --git a/src-tauri/plugins/hello-world/index.js b/src-tauri/plugins/hello-world/index.js
index d84dec2f..bb1ab725 100644
--- a/src-tauri/plugins/hello-world/index.js
+++ b/src-tauri/plugins/hello-world/index.js
@@ -2,4 +2,6 @@ import { hello } from './hello.js';
export function entrypoint() {
hello();
+ console.log('Try JSON parse', JSON.parse(`{ "hello": 123 }`).hello);
+ console.log('Try RegExp', '123'.match(/[\d]+/));
}
diff --git a/src-web/components/EnvironmentActionsDropdown.tsx b/src-web/components/EnvironmentActionsDropdown.tsx
index e5d7a7f2..2f52bd48 100644
--- a/src-web/components/EnvironmentActionsDropdown.tsx
+++ b/src-web/components/EnvironmentActionsDropdown.tsx
@@ -67,7 +67,7 @@ export const EnvironmentActionsDropdown = memo(function EnvironmentActionsDropdo
onSelect: showEnvironmentDialog,
},
],
- [activeEnvironment, environments, routes, prompt, createEnvironment, showEnvironmentDialog],
+ [activeEnvironment, environments, routes, createEnvironment, showEnvironmentDialog],
);
return (
diff --git a/src-web/components/EnvironmentEditDialog.tsx b/src-web/components/EnvironmentEditDialog.tsx
index d9eb5e3e..5aa318b6 100644
--- a/src-web/components/EnvironmentEditDialog.tsx
+++ b/src-web/components/EnvironmentEditDialog.tsx
@@ -12,12 +12,13 @@ import { useUpdateEnvironment } from '../hooks/useUpdateEnvironment';
import { HStack, VStack } from './core/Stacks';
import { IconButton } from './core/IconButton';
import { useDeleteEnvironment } from '../hooks/useDeleteEnvironment';
-import type { GenericCompletionConfig } from './core/Editor/genericCompletion';
import type { DropdownItem } from './core/Dropdown';
import { Dropdown } from './core/Dropdown';
import { Icon } from './core/Icon';
import { usePrompt } from '../hooks/usePrompt';
import { InlineCode } from './core/InlineCode';
+import { useWindowSize } from 'react-use';
+import type { GenericCompletionConfig } from './core/Editor/genericCompletion';
export const EnvironmentEditDialog = function () {
const routes = useAppRoutes();
@@ -25,36 +26,48 @@ export const EnvironmentEditDialog = function () {
const createEnvironment = useCreateEnvironment();
const activeEnvironment = useActiveEnvironment();
+ const windowSize = useWindowSize();
+ const showSidebar = windowSize.width > 500;
+
return (
-
-
-
- {environments.map((e) => (
-
- ))}
-
-
-
+
+ {showSidebar && (
+
+ )}
{activeEnvironment != null &&
}
);
@@ -113,6 +126,12 @@ const EnvironmentEditor = function ({ environment }: { environment: Environment
[deleteEnvironment, updateEnvironment, environment.name, prompt],
);
+ const validateName = useCallback((name: string) => {
+ // Empty just means the variable doesn't have a name yet, and is unusable
+ if (name === '') return true;
+ return name.match(/^[a-z_][a-z0-9_]*$/i) != null;
+ }, []);
+
return (
@@ -124,6 +143,9 @@ const EnvironmentEditor = function ({ environment }: { environment: Environment
void;
zIndex?: keyof typeof zIndexes;
+ variant?: 'default' | 'transparent';
}
const zIndexes: Record = {
@@ -20,7 +21,14 @@ const zIndexes: Record = {
50: 'z-50',
};
-export function Overlay({ zIndex = 30, open, onClose, portalName, children }: Props) {
+export function Overlay({
+ variant = 'default',
+ zIndex = 30,
+ open,
+ onClose,
+ portalName,
+ children,
+}: Props) {
return (
{open && (
@@ -33,14 +41,19 @@ export function Overlay({ zIndex = 30, open, onClose, portalName, children }: Pr
{/* Add region to still be able to drag the window */}
-
- {children}
+ {variant !== 'transparent' && (
+
+ )}
+ {children}
- )}
+ )}
);
}
diff --git a/src-web/components/RecentResponsesDropdown.tsx b/src-web/components/RecentResponsesDropdown.tsx
index 5ec5af4d..0742b465 100644
--- a/src-web/components/RecentResponsesDropdown.tsx
+++ b/src-web/components/RecentResponsesDropdown.tsx
@@ -42,9 +42,9 @@ export const RecentResponsesDropdown = function ResponsePane({
...responses.slice(0, 20).map((r) => ({
key: r.id,
label: (
-
+
- • {r.elapsed}ms
+ • {r.elapsed}ms
),
leftSlot: activeResponse?.id === r.id ? : ,
diff --git a/src-web/components/Workspace.tsx b/src-web/components/Workspace.tsx
index fa21a09c..3b591ea6 100644
--- a/src-web/components/Workspace.tsx
+++ b/src-web/components/Workspace.tsx
@@ -83,7 +83,7 @@ export default function Workspace() {
document.documentElement.addEventListener('mouseup', moveState.current.up);
setIsResizing(true);
},
- [setWidth, width],
+ [setWidth, resetWidth, width, hide, show],
);
const sideWidth = hidden ? 0 : width;
@@ -121,7 +121,7 @@ export default function Workspace() {
)}
>
{floating ? (
-
+
(function Button(
() =>
classNames(
className,
- 'flex-shrink-0 outline-none whitespace-nowrap',
- 'focus-visible-or-class:ring',
- 'rounded-md flex items-center',
+ 'whitespace-nowrap outline-none',
+ 'flex-shrink-0 flex items-center',
+ 'focus-visible-or-class:ring rounded-md',
disabled ? 'pointer-events-none opacity-disabled' : 'pointer-events-auto',
colorStyles[color || 'default'],
justify === 'start' && 'justify-start',
@@ -70,7 +70,7 @@ const _Button = forwardRef(function Button(
) : leftSlot ? (
{leftSlot}
) : null}
- {children}
+ {children}
{rightSlot && {rightSlot}
}
{forDropdown && }
diff --git a/src-web/components/core/Dialog.tsx b/src-web/components/core/Dialog.tsx
index f4cd7730..c69b4c86 100644
--- a/src-web/components/core/Dialog.tsx
+++ b/src-web/components/core/Dialog.tsx
@@ -59,7 +59,7 @@ export function Dialog({
'dark:border border-highlight shadow shadow-black/10',
size === 'sm' && 'w-[25rem] max-h-[80vh]',
size === 'md' && 'w-[45rem] max-h-[80vh]',
- size === 'full' && 'w-[calc(100vw-8em)] h-[calc(100vh-8em)]',
+ size === 'full' && 'w-[95vw] h-[calc(100vh-6em)]',
size === 'dynamic' && 'min-w-[30vw] max-w-[80vw]',
)}
>
diff --git a/src-web/components/core/Dropdown.tsx b/src-web/components/core/Dropdown.tsx
index f8a0bdfb..3c4765dd 100644
--- a/src-web/components/core/Dropdown.tsx
+++ b/src-web/components/core/Dropdown.tsx
@@ -1,5 +1,4 @@
import classNames from 'classnames';
-import FocusTrap from 'focus-trap-react';
import { motion } from 'framer-motion';
import type { CSSProperties, HTMLAttributes, MouseEvent, ReactElement, ReactNode } from 'react';
import React, {
@@ -13,11 +12,11 @@ import React, {
useRef,
useState,
} from 'react';
-import { useKey, useKeyPressEvent } from 'react-use';
-import { Portal } from '../Portal';
+import { useKey, useKeyPressEvent, useWindowSize } from 'react-use';
import { Button } from './Button';
import { Separator } from './Separator';
import { VStack } from './Stacks';
+import { Overlay } from '../Overlay';
export type DropdownItemSeparator = {
type: 'separator';
@@ -65,7 +64,7 @@ export const Dropdown = forwardRef(function Dropdown
useImperativeHandle(ref, () => ({
...menuRef.current,
isOpen: open,
- toggle (activeIndex?: number) {
+ toggle(activeIndex?: number) {
if (!open) this.open(activeIndex);
else setOpen(false);
},
@@ -107,10 +106,12 @@ export const Dropdown = forwardRef(function Dropdown
buttonRef.current?.setAttribute('aria-expanded', open.toString());
}, [open]);
+ const windowSize = useWindowSize();
const triggerRect = useMemo(() => {
+ windowSize; // Make TS happy with this dep
if (!open) return null;
return buttonRef.current?.getBoundingClientRect();
- }, [open]);
+ }, [open, windowSize]);
return (
<>
@@ -267,61 +268,59 @@ const Menu = forwardRef, MenuPro
if (items.length === 0) return null;
return (
-
-
-
-
-
-
- {containerStyles && (
-
- {items.map((item, i) => {
- if (item.type === 'separator') {
- return ;
- }
- if (item.hidden) {
- return null;
- }
- return (
-
- );
- })}
-
- )}
-
-
-
-
+
+
+
+
+
+ {containerStyles && (
+
+ {items.map((item, i) => {
+ if (item.type === 'separator') {
+ return ;
+ }
+ if (item.hidden) {
+ return null;
+ }
+ return (
+
+ );
+ })}
+
+ )}
+
+
+
);
});
@@ -359,6 +358,8 @@ function MenuItem({ className, focused, onFocus, item, onSelect, ...props }: Men
onFocus={handleFocus}
onClick={handleClick}
justify="start"
+ leftSlot={item.leftSlot && {item.leftSlot}
}
+ rightSlot={item.rightSlot && {item.rightSlot}
}
className={classNames(
className,
'min-w-[8rem] outline-none px-2 mx-1.5 flex text-sm text-gray-700 whitespace-nowrap',
@@ -367,7 +368,6 @@ function MenuItem({ className, focused, onFocus, item, onSelect, ...props }: Men
)}
{...props}
>
- {item.leftSlot && {item.leftSlot}
}
{item.label}
- {item.rightSlot && {item.rightSlot}
}
);
}
diff --git a/src-web/components/core/PairEditor.tsx b/src-web/components/core/PairEditor.tsx
index 01e1e547..60ee71ed 100644
--- a/src-web/components/core/PairEditor.tsx
+++ b/src-web/components/core/PairEditor.tsx
@@ -154,6 +154,8 @@ export const PairEditor = memo(function PairEditor({
'pb-2 grid overflow-auto max-h-full',
// Move over the width of the drag handle
'-ml-3',
+ // Pad to make room for the drag divider
+ 'pt-0.5',
)}
>
{pairs.map((p, i) => {
@@ -171,8 +173,8 @@ export const PairEditor = memo(function PairEditor({
forceUpdateKey={forceUpdateKey}
nameAutocomplete={nameAutocomplete}
valueAutocomplete={valueAutocomplete}
- namePlaceholder={namePlaceholder}
- valuePlaceholder={valuePlaceholder}
+ namePlaceholder={isLast ? namePlaceholder : ''}
+ valuePlaceholder={isLast ? valuePlaceholder : ''}
nameValidate={nameValidate}
valueValidate={valueValidate}
showDelete={!isLast}
diff --git a/src-web/components/core/Tabs/Tabs.tsx b/src-web/components/core/Tabs/Tabs.tsx
index bd460555..4c88193e 100644
--- a/src-web/components/core/Tabs/Tabs.tsx
+++ b/src-web/components/core/Tabs/Tabs.tsx
@@ -102,14 +102,16 @@ export function Tabs({
size="sm"
onClick={isActive ? undefined : () => handleTabChange(t.value)}
className={btnClassName}
+ rightSlot={
+
+ }
>
{option && 'shortLabel' in option
? option.shortLabel
: option?.label ?? 'Unknown'}
-
);
diff --git a/src-web/hooks/Prompt.tsx b/src-web/hooks/Prompt.tsx
index e0759546..74e6cf54 100644
--- a/src-web/hooks/Prompt.tsx
+++ b/src-web/hooks/Prompt.tsx
@@ -3,7 +3,7 @@ import { useCallback, useState } from 'react';
import { Button } from '../components/core/Button';
import type { InputProps } from '../components/core/Input';
import { Input } from '../components/core/Input';
-import { HStack, VStack } from '../components/core/Stacks';
+import { HStack } from '../components/core/Stacks';
export interface PromptProps {
onHide: () => void;
@@ -25,26 +25,27 @@ export function Prompt({ onHide, label, name, defaultValue, onResult }: PromptPr
);
return (
-
);
}