From e7b1e0a81f19a976d0cdbf3d04b5c02480cd8e6c Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 21 Feb 2026 11:01:57 +0200 Subject: [PATCH] fix(promoted_attributes): typing sometimes affects the value --- apps/client/src/widgets/PromotedAttributes.tsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/client/src/widgets/PromotedAttributes.tsx b/apps/client/src/widgets/PromotedAttributes.tsx index cbe5737256..6b6543b9d0 100644 --- a/apps/client/src/widgets/PromotedAttributes.tsx +++ b/apps/client/src/widgets/PromotedAttributes.tsx @@ -10,7 +10,6 @@ import FAttribute from "../entities/fattribute"; import FNote from "../entities/fnote"; import { Attribute } from "../services/attribute_parser"; import attributes from "../services/attributes"; -import debounce from "../services/debounce"; import { t } from "../services/i18n"; import { DefinitionObject, extractAttributeDefinitionTypeAndName, LabelType } from "../services/promoted_attribute_definition_parser"; import server from "../services/server"; @@ -185,9 +184,11 @@ const LABEL_MAPPINGS: Record = { function LabelInput({ inputId, ...props }: CellProps & { inputId: string }) { const { valueName, valueAttr, definition, definitionAttr } = props.cell; + const [ valueDraft, setDraft ] = useState(valueAttr.value); const onChangeListener = buildPromotedAttributeLabelChangedListener({...props}); const extraInputProps: InputHTMLAttributes = {}; + // Setup autocomplete. useEffect(() => { if (definition.labelType === "text") { const el = document.getElementById(inputId); @@ -197,6 +198,11 @@ function LabelInput({ inputId, ...props }: CellProps & { inputId: string }) { } }, [ inputId, valueAttr, onChangeListener ]); + // React to model changes. + useEffect(() => { + setDraft(valueAttr.value); + }, [ valueAttr.value ]); + switch (definition.labelType) { case "number": { let step = 1; @@ -217,13 +223,13 @@ function LabelInput({ inputId, ...props }: CellProps & { inputId: string }) { tabIndex={200 + definitionAttr.position} id={inputId} type={LABEL_MAPPINGS[definition.labelType ?? "text"]} - value={valueAttr.value} + value={valueDraft} checked={definition.labelType === "boolean" ? valueAttr.value === "true" : undefined} placeholder={t("promoted_attributes.unset-field-placeholder")} data-attribute-id={valueAttr.attributeId} data-attribute-type={valueAttr.type} data-attribute-name={valueAttr.name} - onChange={onChangeListener} + onBlur={onChangeListener} {...extraInputProps} />; @@ -438,7 +444,7 @@ function setupTextLabelAutocomplete(el: HTMLInputElement, valueAttr: Attribute, } function buildPromotedAttributeLabelChangedListener({ note, cell, componentId, setCells }: CellProps): OnChangeListener { - async function onChange(e: OnChangeEventData) { + return async function(e: OnChangeEventData) { const inputEl = e.target as HTMLInputElement; let value: string; @@ -449,9 +455,7 @@ function buildPromotedAttributeLabelChangedListener({ note, cell, componentId, s } await updateAttribute(note, cell, componentId, value, setCells); - } - - return debounce(onChange, 250); + }; } async function updateAttribute(note: FNote, cell: Cell, componentId: string, value: string | undefined, setCells: Dispatch>) {