Skip to content

Commit 6b87ea5

Browse files
Add intent property to CodeAutocompleteField
1 parent 47cdaef commit 6b87ea5

3 files changed

Lines changed: 43 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- `<CodeAutocompleteField />`
12+
- Add `intent` property.
13+
914
### Fixed
1015

1116
- `<Pagination />`

src/components/AutoSuggestion/AutoSuggestion.tsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Classes as BlueprintClassNames } from "@blueprintjs/core";
44
import { EditorView, Rect } from "@codemirror/view";
55
import { debounce } from "lodash";
66

7+
import { IntentTypes } from "../../common/Intent";
78
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
89
import { SupportedCodeEditorModes } from "../../extensions/codemirror/hooks/useCodemirrorModeExtension.hooks";
910

@@ -154,6 +155,8 @@ export interface CodeAutocompleteFieldProps {
154155
readOnly?: boolean;
155156
/** Properties that should be added to the outer div container. */
156157
outerDivAttributes?: Omit<React.HTMLAttributes<HTMLDivElement>, "id" | "data-test-id">;
158+
/** Intent state of the input field. Validation errors override this. */
159+
intent?: IntentTypes;
157160
}
158161

159162
// Meta data regarding a request
@@ -192,6 +195,7 @@ export const CodeAutocompleteField = ({
192195
height,
193196
readOnly,
194197
outerDivAttributes,
198+
intent,
195199
}: CodeAutocompleteFieldProps) => {
196200
const value = React.useRef<string>(initialValue);
197201
const cursorPosition = React.useRef(0);
@@ -630,6 +634,14 @@ export const CodeAutocompleteField = ({
630634
[]
631635
);
632636

637+
const hasError = !!value.current && !pathIsValid && !pathValidationPending;
638+
const effectiveIntent = hasError ? "danger" : intent;
639+
const blueprintIntent =
640+
effectiveIntent && !["info", "accent", "neutral"].includes(effectiveIntent)
641+
? effectiveIntent
642+
: undefined;
643+
const inputIntentClass = effectiveIntent ? ` ${eccgui}-intent--${effectiveIntent}` : "";
644+
633645
const codeEditor = React.useMemo(() => {
634646
return (
635647
<ExtendedCodeEditor
@@ -648,6 +660,9 @@ export const CodeAutocompleteField = ({
648660
onMouseDown={handleInputMouseDown}
649661
height={height}
650662
readOnly={readOnly}
663+
codeEditorProps={{
664+
intent: effectiveIntent,
665+
}}
651666
/>
652667
);
653668
}, [
@@ -661,9 +676,8 @@ export const CodeAutocompleteField = ({
661676
multiline,
662677
handleInputMouseDown,
663678
readOnly,
679+
effectiveIntent,
664680
]);
665-
666-
const hasError = !!value.current && !pathIsValid && !pathValidationPending;
667681
const autoSuggestionInput = (
668682
<div
669683
id={id}
@@ -674,7 +688,7 @@ export const CodeAutocompleteField = ({
674688
<div
675689
className={` ${eccgui}-autosuggestion__inputfield ${BlueprintClassNames.INPUT_GROUP} ${
676690
BlueprintClassNames.FILL
677-
} ${hasError ? BlueprintClassNames.INTENT_DANGER : ""}`}
691+
} ${blueprintIntent ? BlueprintClassNames.intentClass(blueprintIntent as any) : ""}${inputIntentClass}`}
678692
>
679693
<ContextOverlay
680694
minimal
@@ -740,7 +754,7 @@ export const CodeAutocompleteField = ({
740754
</>
741755
),
742756
}}
743-
intent={hasError ? "danger" : undefined}
757+
intent={effectiveIntent}
744758
messageText={hasError ? validationErrorText : undefined}
745759
>
746760
{withRightElement}

src/extensions/codemirror/CodeMirror.tsx

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,20 @@ export const CodeEditor = ({
326326
];
327327
}
328328

329+
const syncIntentClass = React.useCallback((editorView: EditorView | undefined, nextIntent?: CodeEditorProps["intent"]) => {
330+
if (!editorView?.dom) {
331+
return;
332+
}
333+
334+
Array.from(editorView.dom.classList)
335+
.filter((className) => className.startsWith(`${eccgui}-intent--`))
336+
.forEach((className) => editorView.dom.classList.remove(className));
337+
338+
if (nextIntent) {
339+
editorView.dom.classList.add(`${eccgui}-intent--${nextIntent}`);
340+
}
341+
}, []);
342+
329343
React.useEffect(() => {
330344
const domEventHandlers = {
331345
...addHandlersFor(!!onScroll, "scroll", onScroll),
@@ -360,7 +374,7 @@ export const CodeEditor = ({
360374
onSelection(v.state.selection.ranges.filter((r) => !r.empty).map(({ from, to }) => ({ from, to })));
361375

362376
if (onFocusChange && currentIntent.current && !v.view.dom.classList?.contains(`${eccgui}-intent--${currentIntent.current}`)) {
363-
v.view.dom.classList.add(`${eccgui}-intent--${currentIntent.current}`);
377+
syncIntentClass(v.view, currentIntent.current);
364378
}
365379

366380
if (onCursorChange) {
@@ -410,9 +424,7 @@ export const CodeEditor = ({
410424
view.dom.classList.add(`${eccgui}-disabled`);
411425
}
412426

413-
if (currentIntent.current) {
414-
view.dom.className += ` ${eccgui}-intent--${currentIntent.current}`;
415-
}
427+
syncIntentClass(view, currentIntent.current);
416428

417429
if (autoFocus) {
418430
view.focus();
@@ -472,6 +484,10 @@ export const CodeEditor = ({
472484
}
473485
}, [disabled])
474486

487+
React.useEffect(() => {
488+
syncIntentClass(view, intent);
489+
}, [intent, view, syncIntentClass]);
490+
475491
React.useEffect(() => {
476492
setEditorAppearance({
477493
...editorAppearance,

0 commit comments

Comments
 (0)