Skip to content

Commit

Permalink
Loading state for Preact renderer
Browse files Browse the repository at this point in the history
Fixes #23
  • Loading branch information
jonathonherbert committed Jan 5, 2025
1 parent f1d7099 commit 748aece
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 12 deletions.
17 changes: 11 additions & 6 deletions client/src/cqlInput/CqlInput.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { EditorView } from "prosemirror-view";
import { CqlServiceInterface } from "../services/CqlService";
import { QueryChangeEventDetail } from "../types/dom";
import { createEditorView } from "./editor/editor";
import { createCqlPlugin, CLASS_VISIBLE } from "./editor/plugin";
import { CLASS_PENDING } from "./popover/TypeaheadPopover";
import { CqlSuggestionService } from "../services/CqlService";

const baseFontSize = 28;
const baseBorderRadius = 5;
Expand Down Expand Up @@ -98,6 +98,7 @@ template.innerHTML = `
.Cql__Option {
padding: 5px;
transition: color 0.1s background 0.1s;
}
.Cql__OptionLabel {
Expand All @@ -113,6 +114,12 @@ template.innerHTML = `
background-color: rgba(255,255,255,0.1);
}
.Cql__Option--is-disabled {
color: #bbb;
pointer-events: none;
cursor: not-allowed;
}
.Cql__Option:hover {
background-color: rgba(255,255,255,0.2);
cursor: pointer;
Expand Down Expand Up @@ -204,8 +211,6 @@ template.innerHTML = `
}
.${CLASS_PENDING} {
height: 2em;
padding: 5px;
position: relative;
color: #bbb;
animation-duration: 1.25s;
Expand Down Expand Up @@ -236,7 +241,7 @@ export type CqlConfig = {
};

export const createCqlInput = (
cqlService: CqlServiceInterface,
cqlSuggestionService: CqlSuggestionService,
config: CqlConfig = { syntaxHighlighting: true }
) => {
class CqlInput extends HTMLElement {
Expand Down Expand Up @@ -275,7 +280,7 @@ export const createCqlInput = (
};

const plugin = createCqlPlugin({
cqlSuggestionsService: cqlService,
cqlSuggestionsService: cqlSuggestionService,
typeaheadEl,
errorEl,
errorMsgEl,
Expand All @@ -290,7 +295,7 @@ export const createCqlInput = (
});

editorView.dom.setAttribute("data-testid", contentEditableTestId);
editorView.dom.classList.add("Cql__ContentEditable")
editorView.dom.classList.add("Cql__ContentEditable");
}

disconnectedCallback() {
Expand Down
11 changes: 8 additions & 3 deletions client/src/cqlInput/popover/TypeaheadPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export class TypeaheadPopover extends Popover {

public setIsPending = () => {
this.isPending = true;
this.updateRenderer();
};

public hide = () => {
Expand All @@ -139,14 +140,18 @@ export class TypeaheadPopover extends Popover {
});
};

private applyValueToInput = (value: string, hide = true) => {
private applyValueToInput = (value: string) => {
if (!this.currentSuggestion) {
return;
}

const { from, to } = this.currentSuggestion;
const { from, to, position } = this.currentSuggestion;
// We will get a new position and suggestions after applying the value, but
// this state will not be updated until suggestions are returned, so we
// clear this state pre-emptively to avoid showing stale suggestions.
this.currentSuggestion = undefined;

if (hide) {
if (position === "chipValue") {
this.hide();
}

Expand Down
12 changes: 11 additions & 1 deletion client/src/cqlInput/popover/components/PopoverContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DateSuggestionContent } from "./DateSuggestionContent";
import { TextSuggestionContent } from "./TextSuggestionContent";
import { useEffect, useState } from "preact/hooks";
import { TypeaheadSuggestion } from "../../../lang/types";
import { CLASS_PENDING } from "../TypeaheadPopover";

export type PopoverRendererState = {
suggestion: TypeaheadSuggestion | undefined;
Expand Down Expand Up @@ -45,7 +46,15 @@ export const PopoverContainer: FunctionComponent<PopoverProps> = ({
return;
}

if (!state?.suggestion) {
if (state.isPending && !state.suggestion) {
return (
<div class={`Cql__Option ${CLASS_PENDING}`}>
<div class="Cql__OptionLabel">Loading</div>
</div>
);
}

if (!state.suggestion) {
return <div>No results</div>;
}

Expand All @@ -54,6 +63,7 @@ export const PopoverContainer: FunctionComponent<PopoverProps> = ({
return (
<TextSuggestionContent
suggestion={state.suggestion}
isPending={state.isPending}
onSelect={onSelect}
subscribeToAction={subscribeToAction}
></TextSuggestionContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import { useEffect, useRef, useState } from "preact/hooks";
import { TextSuggestion } from "../../../lang/types";
import { ActionSubscriber } from "./PopoverContainer";
import { wrapSelection } from "./utils";
import { CLASS_PENDING } from "../TypeaheadPopover";

const numberFormat = new Intl.NumberFormat();

export const TextSuggestionContent = ({
suggestion,
isPending,
onSelect,
subscribeToAction,
}: {
suggestion: TextSuggestion;
isPending: boolean;
onSelect: (value: string) => void;
subscribeToAction: ActionSubscriber;
}) => {
Expand Down Expand Up @@ -54,7 +57,7 @@ export const TextSuggestionContent = ({
}
}, [currentOptionIndex]);

// Reset the option if the suggestions change
// Reset the current option if the suggestions change
useEffect(() => setCurrentOptionIndex(0), [suggestion]);

if (!suggestion.suggestions.length) {
Expand All @@ -65,13 +68,15 @@ export const TextSuggestionContent = ({
);
}

const disabledClass = isPending ? `Cql__Option--is-disabled ${CLASS_PENDING}` : "";

return suggestion.suggestions.map(
({ label, description, value, count }, index) => {
const isSelected = index === currentOptionIndex;
const selectedClass = isSelected ? "Cql__Option--is-selected" : "";
return (
<div
class={`Cql__Option ${selectedClass}`}
class={`Cql__Option ${selectedClass} ${disabledClass}`}
data-index={index}
ref={isSelected ? currentItemRef : null}
onClick={() => onSelect(value)}
Expand Down

0 comments on commit 748aece

Please sign in to comment.