mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-03-08 01:53:30 +01:00
Finished prototype local backends and expression editor
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
border-radius: 4px;
|
||||
padding: 4px 8px;
|
||||
flex: 1;
|
||||
min-width: 0; // Allow flex item to shrink below content size
|
||||
overflow: hidden; // Prevent content overflow
|
||||
transition: all 0.15s ease;
|
||||
|
||||
&:focus-within {
|
||||
@@ -62,3 +64,29 @@
|
||||
color: var(--theme-color-error, #ef4444);
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.ExpandButton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--theme-color-fg-default-shy, rgba(255, 255, 255, 0.5));
|
||||
cursor: pointer;
|
||||
border-radius: 2px;
|
||||
transition: all 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--theme-color-bg-1, rgba(255, 255, 255, 0.1));
|
||||
color: var(--theme-color-primary, #6366f1);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
background-color: var(--theme-color-bg-1, rgba(255, 255, 255, 0.1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,9 @@ export interface ExpressionInputProps extends UnsafeStyleProps {
|
||||
|
||||
/** Debounce delay in milliseconds */
|
||||
debounceMs?: number;
|
||||
|
||||
/** Callback when expand button is clicked - opens expression in full editor */
|
||||
onExpand?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,6 +59,7 @@ export function ExpressionInput({
|
||||
placeholder = 'Enter expression...',
|
||||
testId,
|
||||
debounceMs = 300,
|
||||
onExpand,
|
||||
UNSAFE_className,
|
||||
UNSAFE_style
|
||||
}: ExpressionInputProps) {
|
||||
@@ -143,6 +147,13 @@ export function ExpressionInput({
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
{onExpand && (
|
||||
<Tooltip content="Edit in code editor">
|
||||
<button type="button" className={css['ExpandButton']} onClick={onExpand} aria-label="Edit in code editor">
|
||||
<Icon icon={IconName.Code} size={IconSize.Tiny} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,3 +26,42 @@
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.FxButton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Courier New', monospace;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
color: var(--theme-color-fg-default-shy, rgba(255, 255, 255, 0.5));
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
transition: all 0.15s ease;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--theme-color-bg-1, rgba(255, 255, 255, 0.1));
|
||||
color: var(--theme-color-primary, #6366f1);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
background-color: var(--theme-color-bg-1, rgba(255, 255, 255, 0.1));
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
|
||||
&:hover {
|
||||
background: transparent;
|
||||
color: var(--theme-color-fg-default-shy, rgba(255, 255, 255, 0.5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,23 +62,39 @@ export function ExpressionToggle({
|
||||
|
||||
const tooltipContent = isExpressionMode ? 'Switch to fixed value' : 'Switch to expression';
|
||||
|
||||
const icon = isExpressionMode ? IconName.Code : IconName.MagicWand;
|
||||
|
||||
const variant = isExpressionMode ? IconButtonVariant.Default : IconButtonVariant.OpaqueOnHover;
|
||||
// When in expression mode, show TextInBox icon (switch to fixed value)
|
||||
// When in fixed mode, show "fx" text button (switch to expression)
|
||||
if (isExpressionMode) {
|
||||
return (
|
||||
<Tooltip content={tooltipContent}>
|
||||
<div className={css['Root']} style={UNSAFE_style}>
|
||||
<IconButton
|
||||
icon={IconName.TextInBox}
|
||||
size={IconSize.Tiny}
|
||||
variant={IconButtonVariant.Default}
|
||||
onClick={onToggle}
|
||||
isDisabled={isDisabled}
|
||||
testId={testId}
|
||||
UNSAFE_className={css['ExpressionActive']}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
// Fixed mode - show "fx" text button
|
||||
return (
|
||||
<Tooltip content={tooltipContent}>
|
||||
<div className={css['Root']} style={UNSAFE_style}>
|
||||
<IconButton
|
||||
icon={icon}
|
||||
size={IconSize.Tiny}
|
||||
variant={variant}
|
||||
onClick={onToggle}
|
||||
isDisabled={isDisabled}
|
||||
testId={testId}
|
||||
UNSAFE_className={isExpressionMode ? css['ExpressionActive'] : UNSAFE_className}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className={`${css['FxButton']} ${isDisabled ? css['is-disabled'] : ''} ${UNSAFE_className || ''}`}
|
||||
style={UNSAFE_style}
|
||||
onClick={isDisabled ? undefined : onToggle}
|
||||
disabled={isDisabled}
|
||||
data-test={testId}
|
||||
>
|
||||
fx
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -24,4 +24,6 @@
|
||||
|
||||
.InputContainer {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0; // Allow flex item to shrink below content size
|
||||
overflow: hidden; // Prevent content overflow
|
||||
}
|
||||
|
||||
@@ -74,6 +74,8 @@ export interface PropertyPanelInputProps extends Omit<PropertyPanelBaseInputProp
|
||||
onExpressionChange?: (expression: string) => void;
|
||||
/** Whether the expression has an error */
|
||||
expressionError?: string;
|
||||
/** Callback when expand button is clicked (opens expression in full editor) */
|
||||
onExpressionExpand?: () => void;
|
||||
}
|
||||
|
||||
export function PropertyPanelInput({
|
||||
@@ -90,7 +92,8 @@ export function PropertyPanelInput({
|
||||
expression = '',
|
||||
onExpressionModeChange,
|
||||
onExpressionChange,
|
||||
expressionError
|
||||
expressionError,
|
||||
onExpressionExpand
|
||||
}: PropertyPanelInputProps) {
|
||||
const Input = useMemo(() => {
|
||||
switch (inputType) {
|
||||
@@ -136,6 +139,7 @@ export function PropertyPanelInput({
|
||||
onChange={onExpressionChange}
|
||||
hasError={!!expressionError}
|
||||
errorMessage={expressionError}
|
||||
onExpand={onExpressionExpand}
|
||||
UNSAFE_style={{ flex: 1 }}
|
||||
/>
|
||||
);
|
||||
@@ -165,7 +169,7 @@ export function PropertyPanelInput({
|
||||
<div className={css['Root']}>
|
||||
<div className={classNames(css['Label'], isChanged && css['is-changed'])}>{label}</div>
|
||||
<div className={css['InputContainer']}>
|
||||
<div style={{ display: 'flex', gap: '4px', alignItems: 'center', width: '100%' }}>
|
||||
<div style={{ display: 'flex', gap: '4px', alignItems: 'center', minWidth: 0 }}>
|
||||
{renderInput()}
|
||||
{showExpressionToggle && (
|
||||
<ExpressionToggle mode={expressionMode} isConnected={isConnected} onToggle={handleToggleMode} />
|
||||
|
||||
Reference in New Issue
Block a user