@vuu-ui/vuu-ui-controls 2.1.9 → 2.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,19 +11,15 @@ const useEditableText = ({
11
11
  type = "string"
12
12
  }) => {
13
13
  const [editState, setEditState] = React.useState({
14
- editing: false,
15
14
  value: stringValueOf(value)
16
15
  });
17
16
  const initialValueRef = React.useRef(value?.toString() ?? "");
18
17
  const isDirtyRef = React.useRef(false);
18
+ const isEditingRef = React.useRef(false);
19
19
  React.useMemo(() => {
20
20
  if (initialValueRef.current !== value?.toString()) {
21
21
  initialValueRef.current = stringValueOf(value);
22
- setEditState((editState2) => ({
23
- ...editState2,
24
- message: void 0,
25
- value: stringValueOf(value)
26
- }));
22
+ setEditState({ message: void 0, value: stringValueOf(value) });
27
23
  }
28
24
  }, [value]);
29
25
  const commit = React.useCallback(async () => {
@@ -37,9 +33,10 @@ const useEditableText = ({
37
33
  return false;
38
34
  } else {
39
35
  const { current: initialValue } = initialValueRef;
40
- const previousValue = vuuUtils.getTypedValue(initialValue, type);
41
36
  try {
42
37
  const typedValue = vuuUtils.getTypedValue(value2, type, true);
38
+ console.log(`[useEditableText] typedValue = ${typedValue}`);
39
+ const previousValue = vuuUtils.getTypedValue(initialValue, type);
43
40
  const response = await onEdit?.(
44
41
  {
45
42
  editType: "commit",
@@ -52,14 +49,12 @@ const useEditableText = ({
52
49
  if (vuuUtils.isRpcSuccess(response)) {
53
50
  isDirtyRef.current = false;
54
51
  setEditState(({ previousValue: previousValue2, value: value3 }) => ({
55
- editing: false,
56
52
  previousValue: previousValue2 === value3 ? void 0 : previousValue2 === void 0 ? initialValue : previousValue2,
57
53
  value: value3
58
54
  }));
59
55
  } else if (vuuUtils.isRpcError(response)) {
60
56
  if (response.errorMessage === "CHANGE_REVERTED") {
61
57
  setEditState(({ value: value3 }) => ({
62
- editing: true,
63
58
  previousValue: void 0,
64
59
  value: value3
65
60
  }));
@@ -84,15 +79,6 @@ const useEditableText = ({
84
79
  ...state,
85
80
  message: message2
86
81
  }));
87
- onEdit?.(
88
- {
89
- editType: "commit",
90
- isValid: false,
91
- previousValue,
92
- value: value2
93
- },
94
- "commit"
95
- );
96
82
  } else {
97
83
  setEditState((state) => ({
98
84
  ...state,
@@ -104,15 +90,38 @@ const useEditableText = ({
104
90
  }
105
91
  return false;
106
92
  }, [column, editState, onEdit, type]);
107
- const toggleActivation = React.useCallback(
108
- async (input, cancel = false) => {
109
- if (editState.editing) {
110
- if (isDirtyRef.current) {
111
- if (cancel) {
93
+ const handleKeyDown = React.useCallback(
94
+ async (evt) => {
95
+ const { key, target } = evt;
96
+ const input = target;
97
+ if (key === "Enter") {
98
+ if (isEditingRef.current) {
99
+ if (isDirtyRef.current) {
100
+ const commitSuccessful = await commit();
101
+ if (commitSuccessful) {
102
+ isEditingRef.current = false;
103
+ vuuUtils.dispatchCustomEvent(input, "vuu-exit-edit-mode");
104
+ vuuUtils.dispatchCustomEvent(input, "vuu-commit");
105
+ }
106
+ } else {
107
+ isEditingRef.current = false;
108
+ vuuUtils.dispatchCustomEvent(input, "vuu-exit-edit-mode");
109
+ }
110
+ } else {
111
+ isEditingRef.current = true;
112
+ vuuUtils.dispatchCustomEvent(input, "vuu-enter-edit-mode");
113
+ input.select();
114
+ }
115
+ } else if (key === "ArrowRight" || key === "ArrowLeft" || key === "ArrowUp" || key === "ArrowDown") {
116
+ if (isEditingRef.current) {
117
+ evt.stopPropagation();
118
+ }
119
+ } else if (evt.key === "Escape") {
120
+ if (isEditingRef.current) {
121
+ if (isDirtyRef.current) {
112
122
  const { value: previousValue } = editState;
113
123
  isDirtyRef.current = false;
114
124
  setEditState({
115
- editing: false,
116
125
  value: initialValueRef.current,
117
126
  message: void 0
118
127
  });
@@ -125,64 +134,44 @@ const useEditableText = ({
125
134
  },
126
135
  "cancel"
127
136
  );
128
- } else {
129
- const commitSuccessful = await commit();
130
- if (commitSuccessful) {
131
- setEditState((editState2) => ({ ...editState2, editing: false }));
132
- vuuUtils.dispatchCustomEvent(input, "vuu-commit");
133
- }
134
137
  }
135
- } else {
136
- setEditState((editState2) => ({ ...editState2, editing: false }));
138
+ isEditingRef.current = false;
139
+ vuuUtils.dispatchCustomEvent(input, "vuu-exit-edit-mode");
137
140
  }
138
- } else if (!cancel) {
139
- setEditState((editState2) => ({ ...editState2, editing: true }));
140
- input.select();
141
141
  }
142
142
  },
143
143
  [commit, editState, onEdit]
144
144
  );
145
- const handleKeyDown = React.useCallback(
146
- async (evt) => {
147
- const { key, target } = evt;
148
- const input = target;
149
- if (key === "Enter") {
150
- toggleActivation(input);
151
- } else if (key === "ArrowRight" || key === "ArrowLeft" || key === "ArrowUp" || key === "ArrowDown") {
152
- if (editState.editing) {
153
- evt.stopPropagation();
154
- }
155
- } else if (evt.key === "Escape") {
156
- toggleActivation(input, true);
157
- }
158
- },
159
- [editState, toggleActivation]
160
- );
145
+ const beginEditHandler = React.useCallback((evt) => {
146
+ isEditingRef.current = true;
147
+ vuuUtils.dispatchCustomEvent(evt.target, "vuu-enter-edit-mode");
148
+ }, []);
161
149
  const handleFocus = React.useCallback(
162
150
  (e) => {
163
- const input = e.target;
164
- const source = e.relatedTarget;
165
- if (source?.classList.contains("vuuTableCell") && source.contains(input)) {
166
- toggleActivation(input);
167
- }
151
+ e.target.addEventListener("vuu-begin-edit", beginEditHandler, true);
168
152
  },
169
- [toggleActivation]
153
+ [beginEditHandler]
170
154
  );
171
- const handleBlur = React.useCallback(async () => {
172
- if (editState.editing) {
173
- if (isDirtyRef.current) {
174
- const commitSuccessful = await commit();
175
- console.log({ commitSuccessful });
155
+ const handleBlur = React.useCallback(
156
+ async (evt) => {
157
+ evt.target.removeEventListener("vuu-begin-edit", beginEditHandler, true);
158
+ if (isEditingRef.current) {
159
+ if (isDirtyRef.current) {
160
+ const commitSuccessful = await commit();
161
+ console.log({ commitSuccessful });
162
+ }
163
+ isEditingRef.current = false;
164
+ vuuUtils.dispatchCustomEvent(evt.target, "vuu-exit-edit-mode");
176
165
  }
177
- setEditState((editState2) => ({ ...editState2, editing: false }));
178
- }
179
- }, [commit, editState]);
166
+ },
167
+ [beginEditHandler, commit]
168
+ );
180
169
  const handleChange = React.useCallback(
181
170
  (evt) => {
182
171
  const { value: value2 } = evt.target;
183
172
  isDirtyRef.current = value2 !== initialValueRef.current;
184
173
  const result = column.clientSideEditValidationCheck?.(value2, "change");
185
- setEditState({ editing: true, value: value2 });
174
+ setEditState({ value: value2 });
186
175
  onEdit?.(
187
176
  {
188
177
  editType: "change",
@@ -193,11 +182,11 @@ const useEditableText = ({
193
182
  "change"
194
183
  );
195
184
  if (result?.ok === false) {
196
- setEditState({
197
- editing: true,
198
- value: value2,
199
- message: result.messages?.join(",")
200
- });
185
+ setEditState({ value: value2, message: result.messages?.join(",") });
186
+ }
187
+ if (!isEditingRef.current) {
188
+ isEditingRef.current = true;
189
+ vuuUtils.dispatchCustomEvent(evt.target, "vuu-enter-edit-mode");
201
190
  }
202
191
  },
203
192
  [column, onEdit]
@@ -207,14 +196,13 @@ const useEditableText = ({
207
196
  * has the value been edited during this edit session
208
197
  */
209
198
  edited: editState.previousValue !== void 0 && editState.previousValue !== editState.value,
210
- editing: editState.editing,
199
+ //TODO why are we detecting commit here, why not use VuuInput ?
211
200
  inputProps: {
212
201
  onBlur: handleBlur,
213
202
  onFocus: handleFocus,
214
203
  onKeyDown: handleKeyDown
215
204
  },
216
205
  onChange: handleChange,
217
- previousValue: editState.previousValue,
218
206
  value: editState.value,
219
207
  warningMessage: editState.message
220
208
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useEditableText.js","sources":["../../../../packages/vuu-ui-controls/src/editable/useEditableText.ts"],"sourcesContent":["import { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport type {\n RuntimeColumnDescriptor,\n TableCellEditHandler,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n DataValidationError,\n dispatchCustomEvent,\n getTypedValue,\n isRpcError,\n isRpcSuccess,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n column: Pick<\n RuntimeColumnDescriptor,\n \"clientSideEditValidationCheck\" | \"label\" | \"name\"\n >;\n value?: T;\n onEdit?: TableCellEditHandler;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\ntype EditState = {\n editing: boolean;\n message?: string;\n // Set once we commit an edit, cleared when edit session is ended.\n previousValue?: string;\n value: string;\n};\n\nconst stringValueOf = (value?: VuuRowDataItemType) => value?.toString() ?? \"\";\n\nexport const useEditableText = <T extends string | number | boolean = string>({\n column,\n value,\n onEdit,\n type = \"string\",\n}: EditableTextHookProps<T>) => {\n const [editState, setEditState] = useState<EditState>({\n editing: false,\n value: stringValueOf(value),\n });\n const initialValueRef = useRef<string>(value?.toString() ?? \"\");\n const isDirtyRef = useRef(false);\n\n useMemo(() => {\n if (initialValueRef.current !== value?.toString()) {\n initialValueRef.current = stringValueOf(value);\n setEditState((editState) => ({\n ...editState,\n message: undefined,\n value: stringValueOf(value),\n }));\n }\n }, [value]);\n\n const commit = useCallback(async () => {\n const { value } = editState;\n const result = column.clientSideEditValidationCheck?.(value, \"*\");\n if (result?.ok === false) {\n setEditState((state) => ({\n ...state,\n message: result?.messages?.join(\",\"),\n }));\n return false;\n } else {\n //save initial value,it could be reset by time async operation completes\n const { current: initialValue } = initialValueRef;\n const previousValue = getTypedValue(initialValue, type);\n try {\n const typedValue = getTypedValue(value, type, true);\n const response = await onEdit?.(\n {\n editType: \"commit\",\n isValid: true,\n previousValue,\n value: typedValue,\n },\n \"commit\",\n );\n if (isRpcSuccess(response)) {\n isDirtyRef.current = false;\n setEditState(({ previousValue, value }) => ({\n editing: false,\n previousValue:\n previousValue === value\n ? undefined\n : previousValue === undefined\n ? initialValue\n : previousValue,\n value,\n }));\n } else if (isRpcError(response)) {\n if (response.errorMessage === \"CHANGE_REVERTED\") {\n setEditState(({ value }) => ({\n editing: true,\n previousValue: undefined,\n value,\n }));\n initialValueRef.current = value;\n return true;\n } else {\n setEditState((state) => ({\n ...state,\n message: response.errorMessage,\n }));\n }\n }\n initialValueRef.current = value;\n return true;\n } catch (e) {\n if (e instanceof DataValidationError) {\n const { actualType, expectedType, message } = e;\n if (column) {\n const { name, label = name } = column;\n const message = `${label} is a ${expectedType} value, data entered is ${actualType} `;\n setEditState((state) => ({\n ...state,\n message,\n }));\n onEdit?.(\n {\n editType: \"commit\",\n isValid: false,\n previousValue,\n value,\n },\n \"commit\",\n );\n } else {\n setEditState((state) => ({\n ...state,\n message,\n }));\n }\n }\n }\n }\n return false;\n }, [column, editState, onEdit, type]);\n\n const toggleActivation = useCallback(\n async (input: HTMLInputElement, cancel = false) => {\n if (editState.editing) {\n if (isDirtyRef.current) {\n if (cancel) {\n const { value: previousValue } = editState;\n isDirtyRef.current = false;\n setEditState({\n editing: false,\n value: initialValueRef.current,\n message: undefined,\n });\n // this assumes the original value was valid, is that safe ?\n onEdit?.(\n {\n editType: \"cancel\",\n isValid: true,\n previousValue,\n value: initialValueRef.current,\n },\n \"cancel\",\n );\n } else {\n const commitSuccessful = await commit();\n if (commitSuccessful) {\n setEditState((editState) => ({ ...editState, editing: false }));\n dispatchCustomEvent(input, \"vuu-commit\");\n }\n }\n } else {\n setEditState((editState) => ({ ...editState, editing: false }));\n }\n } else if (!cancel) {\n setEditState((editState) => ({ ...editState, editing: true }));\n input.select();\n }\n },\n [commit, editState, onEdit],\n );\n\n const handleKeyDown = useCallback(\n async (evt: KeyboardEvent<HTMLElement>) => {\n const { key, target } = evt;\n const input = target as HTMLInputElement;\n if (key === \"Enter\") {\n toggleActivation(input);\n } else if (\n key === \"ArrowRight\" ||\n key === \"ArrowLeft\" ||\n key === \"ArrowUp\" ||\n key === \"ArrowDown\"\n ) {\n if (editState.editing) {\n evt.stopPropagation();\n } else {\n // console.log(\n // `[useEditableText] handleKeydown, arrowkey, not editing so let it bubble`,\n // );\n // evt.preventDefault();\n }\n } else if (evt.key === \"Escape\") {\n toggleActivation(input, true);\n }\n },\n [editState, toggleActivation],\n );\n\n const handleFocus = useCallback<FocusEventHandler<HTMLElement>>(\n (e) => {\n // If focus is transferred from enclosing cell element, we are explicitl entering edit mode\n const input = e.target as HTMLInputElement;\n const source = e.relatedTarget as HTMLElement;\n if (\n source?.classList.contains(\"vuuTableCell\") &&\n source.contains(input)\n ) {\n toggleActivation(input);\n }\n },\n [toggleActivation],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(async () => {\n if (editState.editing) {\n if (isDirtyRef.current) {\n const commitSuccessful = await commit();\n console.log({ commitSuccessful });\n }\n setEditState((editState) => ({ ...editState, editing: false }));\n }\n }, [commit, editState]);\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n isDirtyRef.current = value !== initialValueRef.current;\n const result = column.clientSideEditValidationCheck?.(value, \"change\");\n setEditState({ editing: true, value });\n\n onEdit?.(\n {\n editType: \"change\",\n isValid: result?.ok !== false,\n previousValue: initialValueRef.current,\n value,\n },\n \"change\",\n );\n if (result?.ok === false) {\n setEditState({\n editing: true,\n value,\n message: result.messages?.join(\",\"),\n });\n }\n },\n [column, onEdit],\n );\n\n // console.log(\n // `[useEditableText] edited = ${\n // editState.previousValue !== undefined &&\n // editState.previousValue !== editState.value\n // }\n // editState.previousValue ${editState.previousValue}\n // editState.value ${editState.value}\n // `,\n // );\n\n return {\n /**\n * has the value been edited during this edit session\n */\n edited:\n editState.previousValue !== undefined &&\n editState.previousValue !== editState.value,\n editing: editState.editing,\n inputProps: {\n onBlur: handleBlur,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n previousValue: editState.previousValue,\n value: editState.value,\n warningMessage: editState.message,\n };\n};\n"],"names":["useState","useRef","useMemo","editState","useCallback","value","getTypedValue","isRpcSuccess","previousValue","isRpcError","DataValidationError","message","dispatchCustomEvent"],"mappings":"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"}
1
+ {"version":3,"file":"useEditableText.js","sources":["../../../../packages/vuu-ui-controls/src/editable/useEditableText.ts"],"sourcesContent":["import { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport type {\n RuntimeColumnDescriptor,\n TableCellEditHandler,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n DataValidationError,\n dispatchCustomEvent,\n getTypedValue,\n isRpcError,\n isRpcSuccess,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n column: Pick<\n RuntimeColumnDescriptor,\n \"clientSideEditValidationCheck\" | \"label\" | \"name\"\n >;\n value?: T;\n onEdit?: TableCellEditHandler;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\ntype EditState = {\n message?: string;\n // Set once we commit an edit, cleared when edit session is ended.\n previousValue?: string;\n value: string;\n};\n\nconst stringValueOf = (value?: VuuRowDataItemType) => value?.toString() ?? \"\";\n\nexport const useEditableText = <T extends string | number | boolean = string>({\n column,\n value,\n onEdit,\n type = \"string\",\n}: EditableTextHookProps<T>) => {\n const [editState, setEditState] = useState<EditState>({\n value: stringValueOf(value),\n });\n const initialValueRef = useRef<string>(value?.toString() ?? \"\");\n const isDirtyRef = useRef(false);\n const isEditingRef = useRef(false);\n\n useMemo(() => {\n if (initialValueRef.current !== value?.toString()) {\n initialValueRef.current = stringValueOf(value);\n setEditState({ message: undefined, value: stringValueOf(value) });\n }\n }, [value]);\n\n const commit = useCallback(async () => {\n const { value } = editState;\n const result = column.clientSideEditValidationCheck?.(value, \"*\");\n if (result?.ok === false) {\n setEditState((state) => ({\n ...state,\n message: result?.messages?.join(\",\"),\n }));\n return false;\n } else {\n //save initial value,it could be reset by time async operation completes\n const { current: initialValue } = initialValueRef;\n try {\n const typedValue = getTypedValue(value, type, true);\n console.log(`[useEditableText] typedValue = ${typedValue}`);\n const previousValue = getTypedValue(initialValue, type);\n const response = await onEdit?.(\n {\n editType: \"commit\",\n isValid: true,\n previousValue,\n value: typedValue,\n },\n \"commit\",\n );\n if (isRpcSuccess(response)) {\n isDirtyRef.current = false;\n setEditState(({ previousValue, value }) => ({\n previousValue:\n previousValue === value\n ? undefined\n : previousValue === undefined\n ? initialValue\n : previousValue,\n value,\n }));\n } else if (isRpcError(response)) {\n if (response.errorMessage === \"CHANGE_REVERTED\") {\n setEditState(({ value }) => ({\n previousValue: undefined,\n value,\n }));\n initialValueRef.current = value;\n return true;\n } else {\n setEditState((state) => ({\n ...state,\n message: response.errorMessage,\n }));\n }\n }\n initialValueRef.current = value;\n return true;\n } catch (e) {\n if (e instanceof DataValidationError) {\n const { actualType, expectedType, message } = e;\n if (column) {\n const { name, label = name } = column;\n const message = `${label} is a ${expectedType} value, data entered is ${actualType} `;\n setEditState((state) => ({\n ...state,\n message,\n }));\n } else {\n setEditState((state) => ({\n ...state,\n message,\n }));\n }\n }\n }\n }\n return false;\n }, [column, editState, onEdit, type]);\n\n const handleKeyDown = useCallback(\n async (evt: KeyboardEvent<HTMLElement>) => {\n const { key, target } = evt;\n const input = target as HTMLInputElement;\n if (key === \"Enter\") {\n if (isEditingRef.current) {\n if (isDirtyRef.current) {\n const commitSuccessful = await commit();\n if (commitSuccessful) {\n isEditingRef.current = false;\n dispatchCustomEvent(input, \"vuu-exit-edit-mode\");\n dispatchCustomEvent(input, \"vuu-commit\");\n }\n } else {\n isEditingRef.current = false;\n dispatchCustomEvent(input, \"vuu-exit-edit-mode\");\n }\n } else {\n isEditingRef.current = true;\n dispatchCustomEvent(input, \"vuu-enter-edit-mode\");\n input.select();\n }\n } else if (\n key === \"ArrowRight\" ||\n key === \"ArrowLeft\" ||\n key === \"ArrowUp\" ||\n key === \"ArrowDown\"\n ) {\n if (isEditingRef.current) {\n evt.stopPropagation();\n } else {\n // console.log(\n // `[useEditableText] handleKeydown, arrowkey, not editing so let it bubble`,\n // );\n // evt.preventDefault();\n }\n } else if (evt.key === \"Escape\") {\n if (isEditingRef.current) {\n if (isDirtyRef.current) {\n const { value: previousValue } = editState;\n isDirtyRef.current = false;\n setEditState({\n value: initialValueRef.current,\n message: undefined,\n });\n // this assumes the original value was valid, is that safe ?\n onEdit?.(\n {\n editType: \"cancel\",\n isValid: true,\n previousValue,\n value: initialValueRef.current,\n },\n \"cancel\",\n );\n }\n isEditingRef.current = false;\n dispatchCustomEvent(input, \"vuu-exit-edit-mode\");\n }\n }\n },\n [commit, editState, onEdit],\n );\n\n const beginEditHandler = useCallback((evt: Event) => {\n isEditingRef.current = true;\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-enter-edit-mode\");\n }, []);\n\n const handleFocus = useCallback<FocusEventHandler<HTMLElement>>(\n (e) => {\n e.target.addEventListener(\"vuu-begin-edit\", beginEditHandler, true);\n },\n [beginEditHandler],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n async (evt) => {\n evt.target.removeEventListener(\"vuu-begin-edit\", beginEditHandler, true);\n if (isEditingRef.current) {\n if (isDirtyRef.current) {\n const commitSuccessful = await commit();\n console.log({ commitSuccessful });\n }\n isEditingRef.current = false;\n dispatchCustomEvent(evt.target, \"vuu-exit-edit-mode\");\n }\n },\n [beginEditHandler, commit],\n );\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n isDirtyRef.current = value !== initialValueRef.current;\n const result = column.clientSideEditValidationCheck?.(value, \"change\");\n setEditState({ value });\n\n onEdit?.(\n {\n editType: \"change\",\n isValid: result?.ok !== false,\n previousValue: initialValueRef.current,\n value,\n },\n \"change\",\n );\n if (result?.ok === false) {\n setEditState({ value, message: result.messages?.join(\",\") });\n }\n\n if (!isEditingRef.current) {\n isEditingRef.current = true;\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-enter-edit-mode\");\n }\n },\n [column, onEdit],\n );\n\n return {\n /**\n * has the value been edited during this edit session\n */\n edited:\n editState.previousValue !== undefined &&\n editState.previousValue !== editState.value,\n //TODO why are we detecting commit here, why not use VuuInput ?\n inputProps: {\n onBlur: handleBlur,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n value: editState.value,\n warningMessage: editState.message,\n };\n};\n"],"names":["useState","useRef","useMemo","useCallback","value","getTypedValue","isRpcSuccess","previousValue","isRpcError","DataValidationError","message","dispatchCustomEvent"],"mappings":"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"}
@@ -9,19 +9,15 @@ const useEditableText = ({
9
9
  type = "string"
10
10
  }) => {
11
11
  const [editState, setEditState] = useState({
12
- editing: false,
13
12
  value: stringValueOf(value)
14
13
  });
15
14
  const initialValueRef = useRef(value?.toString() ?? "");
16
15
  const isDirtyRef = useRef(false);
16
+ const isEditingRef = useRef(false);
17
17
  useMemo(() => {
18
18
  if (initialValueRef.current !== value?.toString()) {
19
19
  initialValueRef.current = stringValueOf(value);
20
- setEditState((editState2) => ({
21
- ...editState2,
22
- message: void 0,
23
- value: stringValueOf(value)
24
- }));
20
+ setEditState({ message: void 0, value: stringValueOf(value) });
25
21
  }
26
22
  }, [value]);
27
23
  const commit = useCallback(async () => {
@@ -35,9 +31,10 @@ const useEditableText = ({
35
31
  return false;
36
32
  } else {
37
33
  const { current: initialValue } = initialValueRef;
38
- const previousValue = getTypedValue(initialValue, type);
39
34
  try {
40
35
  const typedValue = getTypedValue(value2, type, true);
36
+ console.log(`[useEditableText] typedValue = ${typedValue}`);
37
+ const previousValue = getTypedValue(initialValue, type);
41
38
  const response = await onEdit?.(
42
39
  {
43
40
  editType: "commit",
@@ -50,14 +47,12 @@ const useEditableText = ({
50
47
  if (isRpcSuccess(response)) {
51
48
  isDirtyRef.current = false;
52
49
  setEditState(({ previousValue: previousValue2, value: value3 }) => ({
53
- editing: false,
54
50
  previousValue: previousValue2 === value3 ? void 0 : previousValue2 === void 0 ? initialValue : previousValue2,
55
51
  value: value3
56
52
  }));
57
53
  } else if (isRpcError(response)) {
58
54
  if (response.errorMessage === "CHANGE_REVERTED") {
59
55
  setEditState(({ value: value3 }) => ({
60
- editing: true,
61
56
  previousValue: void 0,
62
57
  value: value3
63
58
  }));
@@ -82,15 +77,6 @@ const useEditableText = ({
82
77
  ...state,
83
78
  message: message2
84
79
  }));
85
- onEdit?.(
86
- {
87
- editType: "commit",
88
- isValid: false,
89
- previousValue,
90
- value: value2
91
- },
92
- "commit"
93
- );
94
80
  } else {
95
81
  setEditState((state) => ({
96
82
  ...state,
@@ -102,15 +88,38 @@ const useEditableText = ({
102
88
  }
103
89
  return false;
104
90
  }, [column, editState, onEdit, type]);
105
- const toggleActivation = useCallback(
106
- async (input, cancel = false) => {
107
- if (editState.editing) {
108
- if (isDirtyRef.current) {
109
- if (cancel) {
91
+ const handleKeyDown = useCallback(
92
+ async (evt) => {
93
+ const { key, target } = evt;
94
+ const input = target;
95
+ if (key === "Enter") {
96
+ if (isEditingRef.current) {
97
+ if (isDirtyRef.current) {
98
+ const commitSuccessful = await commit();
99
+ if (commitSuccessful) {
100
+ isEditingRef.current = false;
101
+ dispatchCustomEvent(input, "vuu-exit-edit-mode");
102
+ dispatchCustomEvent(input, "vuu-commit");
103
+ }
104
+ } else {
105
+ isEditingRef.current = false;
106
+ dispatchCustomEvent(input, "vuu-exit-edit-mode");
107
+ }
108
+ } else {
109
+ isEditingRef.current = true;
110
+ dispatchCustomEvent(input, "vuu-enter-edit-mode");
111
+ input.select();
112
+ }
113
+ } else if (key === "ArrowRight" || key === "ArrowLeft" || key === "ArrowUp" || key === "ArrowDown") {
114
+ if (isEditingRef.current) {
115
+ evt.stopPropagation();
116
+ }
117
+ } else if (evt.key === "Escape") {
118
+ if (isEditingRef.current) {
119
+ if (isDirtyRef.current) {
110
120
  const { value: previousValue } = editState;
111
121
  isDirtyRef.current = false;
112
122
  setEditState({
113
- editing: false,
114
123
  value: initialValueRef.current,
115
124
  message: void 0
116
125
  });
@@ -123,64 +132,44 @@ const useEditableText = ({
123
132
  },
124
133
  "cancel"
125
134
  );
126
- } else {
127
- const commitSuccessful = await commit();
128
- if (commitSuccessful) {
129
- setEditState((editState2) => ({ ...editState2, editing: false }));
130
- dispatchCustomEvent(input, "vuu-commit");
131
- }
132
135
  }
133
- } else {
134
- setEditState((editState2) => ({ ...editState2, editing: false }));
136
+ isEditingRef.current = false;
137
+ dispatchCustomEvent(input, "vuu-exit-edit-mode");
135
138
  }
136
- } else if (!cancel) {
137
- setEditState((editState2) => ({ ...editState2, editing: true }));
138
- input.select();
139
139
  }
140
140
  },
141
141
  [commit, editState, onEdit]
142
142
  );
143
- const handleKeyDown = useCallback(
144
- async (evt) => {
145
- const { key, target } = evt;
146
- const input = target;
147
- if (key === "Enter") {
148
- toggleActivation(input);
149
- } else if (key === "ArrowRight" || key === "ArrowLeft" || key === "ArrowUp" || key === "ArrowDown") {
150
- if (editState.editing) {
151
- evt.stopPropagation();
152
- }
153
- } else if (evt.key === "Escape") {
154
- toggleActivation(input, true);
155
- }
156
- },
157
- [editState, toggleActivation]
158
- );
143
+ const beginEditHandler = useCallback((evt) => {
144
+ isEditingRef.current = true;
145
+ dispatchCustomEvent(evt.target, "vuu-enter-edit-mode");
146
+ }, []);
159
147
  const handleFocus = useCallback(
160
148
  (e) => {
161
- const input = e.target;
162
- const source = e.relatedTarget;
163
- if (source?.classList.contains("vuuTableCell") && source.contains(input)) {
164
- toggleActivation(input);
165
- }
149
+ e.target.addEventListener("vuu-begin-edit", beginEditHandler, true);
166
150
  },
167
- [toggleActivation]
151
+ [beginEditHandler]
168
152
  );
169
- const handleBlur = useCallback(async () => {
170
- if (editState.editing) {
171
- if (isDirtyRef.current) {
172
- const commitSuccessful = await commit();
173
- console.log({ commitSuccessful });
153
+ const handleBlur = useCallback(
154
+ async (evt) => {
155
+ evt.target.removeEventListener("vuu-begin-edit", beginEditHandler, true);
156
+ if (isEditingRef.current) {
157
+ if (isDirtyRef.current) {
158
+ const commitSuccessful = await commit();
159
+ console.log({ commitSuccessful });
160
+ }
161
+ isEditingRef.current = false;
162
+ dispatchCustomEvent(evt.target, "vuu-exit-edit-mode");
174
163
  }
175
- setEditState((editState2) => ({ ...editState2, editing: false }));
176
- }
177
- }, [commit, editState]);
164
+ },
165
+ [beginEditHandler, commit]
166
+ );
178
167
  const handleChange = useCallback(
179
168
  (evt) => {
180
169
  const { value: value2 } = evt.target;
181
170
  isDirtyRef.current = value2 !== initialValueRef.current;
182
171
  const result = column.clientSideEditValidationCheck?.(value2, "change");
183
- setEditState({ editing: true, value: value2 });
172
+ setEditState({ value: value2 });
184
173
  onEdit?.(
185
174
  {
186
175
  editType: "change",
@@ -191,11 +180,11 @@ const useEditableText = ({
191
180
  "change"
192
181
  );
193
182
  if (result?.ok === false) {
194
- setEditState({
195
- editing: true,
196
- value: value2,
197
- message: result.messages?.join(",")
198
- });
183
+ setEditState({ value: value2, message: result.messages?.join(",") });
184
+ }
185
+ if (!isEditingRef.current) {
186
+ isEditingRef.current = true;
187
+ dispatchCustomEvent(evt.target, "vuu-enter-edit-mode");
199
188
  }
200
189
  },
201
190
  [column, onEdit]
@@ -205,14 +194,13 @@ const useEditableText = ({
205
194
  * has the value been edited during this edit session
206
195
  */
207
196
  edited: editState.previousValue !== void 0 && editState.previousValue !== editState.value,
208
- editing: editState.editing,
197
+ //TODO why are we detecting commit here, why not use VuuInput ?
209
198
  inputProps: {
210
199
  onBlur: handleBlur,
211
200
  onFocus: handleFocus,
212
201
  onKeyDown: handleKeyDown
213
202
  },
214
203
  onChange: handleChange,
215
- previousValue: editState.previousValue,
216
204
  value: editState.value,
217
205
  warningMessage: editState.message
218
206
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useEditableText.js","sources":["../../../../packages/vuu-ui-controls/src/editable/useEditableText.ts"],"sourcesContent":["import { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport type {\n RuntimeColumnDescriptor,\n TableCellEditHandler,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n DataValidationError,\n dispatchCustomEvent,\n getTypedValue,\n isRpcError,\n isRpcSuccess,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n column: Pick<\n RuntimeColumnDescriptor,\n \"clientSideEditValidationCheck\" | \"label\" | \"name\"\n >;\n value?: T;\n onEdit?: TableCellEditHandler;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\ntype EditState = {\n editing: boolean;\n message?: string;\n // Set once we commit an edit, cleared when edit session is ended.\n previousValue?: string;\n value: string;\n};\n\nconst stringValueOf = (value?: VuuRowDataItemType) => value?.toString() ?? \"\";\n\nexport const useEditableText = <T extends string | number | boolean = string>({\n column,\n value,\n onEdit,\n type = \"string\",\n}: EditableTextHookProps<T>) => {\n const [editState, setEditState] = useState<EditState>({\n editing: false,\n value: stringValueOf(value),\n });\n const initialValueRef = useRef<string>(value?.toString() ?? \"\");\n const isDirtyRef = useRef(false);\n\n useMemo(() => {\n if (initialValueRef.current !== value?.toString()) {\n initialValueRef.current = stringValueOf(value);\n setEditState((editState) => ({\n ...editState,\n message: undefined,\n value: stringValueOf(value),\n }));\n }\n }, [value]);\n\n const commit = useCallback(async () => {\n const { value } = editState;\n const result = column.clientSideEditValidationCheck?.(value, \"*\");\n if (result?.ok === false) {\n setEditState((state) => ({\n ...state,\n message: result?.messages?.join(\",\"),\n }));\n return false;\n } else {\n //save initial value,it could be reset by time async operation completes\n const { current: initialValue } = initialValueRef;\n const previousValue = getTypedValue(initialValue, type);\n try {\n const typedValue = getTypedValue(value, type, true);\n const response = await onEdit?.(\n {\n editType: \"commit\",\n isValid: true,\n previousValue,\n value: typedValue,\n },\n \"commit\",\n );\n if (isRpcSuccess(response)) {\n isDirtyRef.current = false;\n setEditState(({ previousValue, value }) => ({\n editing: false,\n previousValue:\n previousValue === value\n ? undefined\n : previousValue === undefined\n ? initialValue\n : previousValue,\n value,\n }));\n } else if (isRpcError(response)) {\n if (response.errorMessage === \"CHANGE_REVERTED\") {\n setEditState(({ value }) => ({\n editing: true,\n previousValue: undefined,\n value,\n }));\n initialValueRef.current = value;\n return true;\n } else {\n setEditState((state) => ({\n ...state,\n message: response.errorMessage,\n }));\n }\n }\n initialValueRef.current = value;\n return true;\n } catch (e) {\n if (e instanceof DataValidationError) {\n const { actualType, expectedType, message } = e;\n if (column) {\n const { name, label = name } = column;\n const message = `${label} is a ${expectedType} value, data entered is ${actualType} `;\n setEditState((state) => ({\n ...state,\n message,\n }));\n onEdit?.(\n {\n editType: \"commit\",\n isValid: false,\n previousValue,\n value,\n },\n \"commit\",\n );\n } else {\n setEditState((state) => ({\n ...state,\n message,\n }));\n }\n }\n }\n }\n return false;\n }, [column, editState, onEdit, type]);\n\n const toggleActivation = useCallback(\n async (input: HTMLInputElement, cancel = false) => {\n if (editState.editing) {\n if (isDirtyRef.current) {\n if (cancel) {\n const { value: previousValue } = editState;\n isDirtyRef.current = false;\n setEditState({\n editing: false,\n value: initialValueRef.current,\n message: undefined,\n });\n // this assumes the original value was valid, is that safe ?\n onEdit?.(\n {\n editType: \"cancel\",\n isValid: true,\n previousValue,\n value: initialValueRef.current,\n },\n \"cancel\",\n );\n } else {\n const commitSuccessful = await commit();\n if (commitSuccessful) {\n setEditState((editState) => ({ ...editState, editing: false }));\n dispatchCustomEvent(input, \"vuu-commit\");\n }\n }\n } else {\n setEditState((editState) => ({ ...editState, editing: false }));\n }\n } else if (!cancel) {\n setEditState((editState) => ({ ...editState, editing: true }));\n input.select();\n }\n },\n [commit, editState, onEdit],\n );\n\n const handleKeyDown = useCallback(\n async (evt: KeyboardEvent<HTMLElement>) => {\n const { key, target } = evt;\n const input = target as HTMLInputElement;\n if (key === \"Enter\") {\n toggleActivation(input);\n } else if (\n key === \"ArrowRight\" ||\n key === \"ArrowLeft\" ||\n key === \"ArrowUp\" ||\n key === \"ArrowDown\"\n ) {\n if (editState.editing) {\n evt.stopPropagation();\n } else {\n // console.log(\n // `[useEditableText] handleKeydown, arrowkey, not editing so let it bubble`,\n // );\n // evt.preventDefault();\n }\n } else if (evt.key === \"Escape\") {\n toggleActivation(input, true);\n }\n },\n [editState, toggleActivation],\n );\n\n const handleFocus = useCallback<FocusEventHandler<HTMLElement>>(\n (e) => {\n // If focus is transferred from enclosing cell element, we are explicitl entering edit mode\n const input = e.target as HTMLInputElement;\n const source = e.relatedTarget as HTMLElement;\n if (\n source?.classList.contains(\"vuuTableCell\") &&\n source.contains(input)\n ) {\n toggleActivation(input);\n }\n },\n [toggleActivation],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(async () => {\n if (editState.editing) {\n if (isDirtyRef.current) {\n const commitSuccessful = await commit();\n console.log({ commitSuccessful });\n }\n setEditState((editState) => ({ ...editState, editing: false }));\n }\n }, [commit, editState]);\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n isDirtyRef.current = value !== initialValueRef.current;\n const result = column.clientSideEditValidationCheck?.(value, \"change\");\n setEditState({ editing: true, value });\n\n onEdit?.(\n {\n editType: \"change\",\n isValid: result?.ok !== false,\n previousValue: initialValueRef.current,\n value,\n },\n \"change\",\n );\n if (result?.ok === false) {\n setEditState({\n editing: true,\n value,\n message: result.messages?.join(\",\"),\n });\n }\n },\n [column, onEdit],\n );\n\n // console.log(\n // `[useEditableText] edited = ${\n // editState.previousValue !== undefined &&\n // editState.previousValue !== editState.value\n // }\n // editState.previousValue ${editState.previousValue}\n // editState.value ${editState.value}\n // `,\n // );\n\n return {\n /**\n * has the value been edited during this edit session\n */\n edited:\n editState.previousValue !== undefined &&\n editState.previousValue !== editState.value,\n editing: editState.editing,\n inputProps: {\n onBlur: handleBlur,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n previousValue: editState.previousValue,\n value: editState.value,\n warningMessage: editState.message,\n };\n};\n"],"names":["editState","value","previousValue","message"],"mappings":"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"}
1
+ {"version":3,"file":"useEditableText.js","sources":["../../../../packages/vuu-ui-controls/src/editable/useEditableText.ts"],"sourcesContent":["import { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport type {\n RuntimeColumnDescriptor,\n TableCellEditHandler,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n DataValidationError,\n dispatchCustomEvent,\n getTypedValue,\n isRpcError,\n isRpcSuccess,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n column: Pick<\n RuntimeColumnDescriptor,\n \"clientSideEditValidationCheck\" | \"label\" | \"name\"\n >;\n value?: T;\n onEdit?: TableCellEditHandler;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\ntype EditState = {\n message?: string;\n // Set once we commit an edit, cleared when edit session is ended.\n previousValue?: string;\n value: string;\n};\n\nconst stringValueOf = (value?: VuuRowDataItemType) => value?.toString() ?? \"\";\n\nexport const useEditableText = <T extends string | number | boolean = string>({\n column,\n value,\n onEdit,\n type = \"string\",\n}: EditableTextHookProps<T>) => {\n const [editState, setEditState] = useState<EditState>({\n value: stringValueOf(value),\n });\n const initialValueRef = useRef<string>(value?.toString() ?? \"\");\n const isDirtyRef = useRef(false);\n const isEditingRef = useRef(false);\n\n useMemo(() => {\n if (initialValueRef.current !== value?.toString()) {\n initialValueRef.current = stringValueOf(value);\n setEditState({ message: undefined, value: stringValueOf(value) });\n }\n }, [value]);\n\n const commit = useCallback(async () => {\n const { value } = editState;\n const result = column.clientSideEditValidationCheck?.(value, \"*\");\n if (result?.ok === false) {\n setEditState((state) => ({\n ...state,\n message: result?.messages?.join(\",\"),\n }));\n return false;\n } else {\n //save initial value,it could be reset by time async operation completes\n const { current: initialValue } = initialValueRef;\n try {\n const typedValue = getTypedValue(value, type, true);\n console.log(`[useEditableText] typedValue = ${typedValue}`);\n const previousValue = getTypedValue(initialValue, type);\n const response = await onEdit?.(\n {\n editType: \"commit\",\n isValid: true,\n previousValue,\n value: typedValue,\n },\n \"commit\",\n );\n if (isRpcSuccess(response)) {\n isDirtyRef.current = false;\n setEditState(({ previousValue, value }) => ({\n previousValue:\n previousValue === value\n ? undefined\n : previousValue === undefined\n ? initialValue\n : previousValue,\n value,\n }));\n } else if (isRpcError(response)) {\n if (response.errorMessage === \"CHANGE_REVERTED\") {\n setEditState(({ value }) => ({\n previousValue: undefined,\n value,\n }));\n initialValueRef.current = value;\n return true;\n } else {\n setEditState((state) => ({\n ...state,\n message: response.errorMessage,\n }));\n }\n }\n initialValueRef.current = value;\n return true;\n } catch (e) {\n if (e instanceof DataValidationError) {\n const { actualType, expectedType, message } = e;\n if (column) {\n const { name, label = name } = column;\n const message = `${label} is a ${expectedType} value, data entered is ${actualType} `;\n setEditState((state) => ({\n ...state,\n message,\n }));\n } else {\n setEditState((state) => ({\n ...state,\n message,\n }));\n }\n }\n }\n }\n return false;\n }, [column, editState, onEdit, type]);\n\n const handleKeyDown = useCallback(\n async (evt: KeyboardEvent<HTMLElement>) => {\n const { key, target } = evt;\n const input = target as HTMLInputElement;\n if (key === \"Enter\") {\n if (isEditingRef.current) {\n if (isDirtyRef.current) {\n const commitSuccessful = await commit();\n if (commitSuccessful) {\n isEditingRef.current = false;\n dispatchCustomEvent(input, \"vuu-exit-edit-mode\");\n dispatchCustomEvent(input, \"vuu-commit\");\n }\n } else {\n isEditingRef.current = false;\n dispatchCustomEvent(input, \"vuu-exit-edit-mode\");\n }\n } else {\n isEditingRef.current = true;\n dispatchCustomEvent(input, \"vuu-enter-edit-mode\");\n input.select();\n }\n } else if (\n key === \"ArrowRight\" ||\n key === \"ArrowLeft\" ||\n key === \"ArrowUp\" ||\n key === \"ArrowDown\"\n ) {\n if (isEditingRef.current) {\n evt.stopPropagation();\n } else {\n // console.log(\n // `[useEditableText] handleKeydown, arrowkey, not editing so let it bubble`,\n // );\n // evt.preventDefault();\n }\n } else if (evt.key === \"Escape\") {\n if (isEditingRef.current) {\n if (isDirtyRef.current) {\n const { value: previousValue } = editState;\n isDirtyRef.current = false;\n setEditState({\n value: initialValueRef.current,\n message: undefined,\n });\n // this assumes the original value was valid, is that safe ?\n onEdit?.(\n {\n editType: \"cancel\",\n isValid: true,\n previousValue,\n value: initialValueRef.current,\n },\n \"cancel\",\n );\n }\n isEditingRef.current = false;\n dispatchCustomEvent(input, \"vuu-exit-edit-mode\");\n }\n }\n },\n [commit, editState, onEdit],\n );\n\n const beginEditHandler = useCallback((evt: Event) => {\n isEditingRef.current = true;\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-enter-edit-mode\");\n }, []);\n\n const handleFocus = useCallback<FocusEventHandler<HTMLElement>>(\n (e) => {\n e.target.addEventListener(\"vuu-begin-edit\", beginEditHandler, true);\n },\n [beginEditHandler],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n async (evt) => {\n evt.target.removeEventListener(\"vuu-begin-edit\", beginEditHandler, true);\n if (isEditingRef.current) {\n if (isDirtyRef.current) {\n const commitSuccessful = await commit();\n console.log({ commitSuccessful });\n }\n isEditingRef.current = false;\n dispatchCustomEvent(evt.target, \"vuu-exit-edit-mode\");\n }\n },\n [beginEditHandler, commit],\n );\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n isDirtyRef.current = value !== initialValueRef.current;\n const result = column.clientSideEditValidationCheck?.(value, \"change\");\n setEditState({ value });\n\n onEdit?.(\n {\n editType: \"change\",\n isValid: result?.ok !== false,\n previousValue: initialValueRef.current,\n value,\n },\n \"change\",\n );\n if (result?.ok === false) {\n setEditState({ value, message: result.messages?.join(\",\") });\n }\n\n if (!isEditingRef.current) {\n isEditingRef.current = true;\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-enter-edit-mode\");\n }\n },\n [column, onEdit],\n );\n\n return {\n /**\n * has the value been edited during this edit session\n */\n edited:\n editState.previousValue !== undefined &&\n editState.previousValue !== editState.value,\n //TODO why are we detecting commit here, why not use VuuInput ?\n inputProps: {\n onBlur: handleBlur,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n value: editState.value,\n warningMessage: editState.message,\n };\n};\n"],"names":["value","previousValue","message"],"mappings":"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"}
package/package.json CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
- "version": "2.1.9",
2
+ "version": "2.1.10",
3
3
  "description": "VUU UI Controls",
4
4
  "author": "heswell",
5
5
  "license": "Apache-2.0",
6
6
  "devDependencies": {
7
- "@vuu-ui/vuu-data-types": "2.1.9",
8
- "@vuu-ui/vuu-protocol-types": "2.1.9",
9
- "@vuu-ui/vuu-table-types": "2.1.9"
7
+ "@vuu-ui/vuu-data-types": "2.1.10",
8
+ "@vuu-ui/vuu-protocol-types": "2.1.10",
9
+ "@vuu-ui/vuu-table-types": "2.1.10"
10
10
  },
11
11
  "dependencies": {
12
- "@vuu-ui/vuu-context-menu": "2.1.9",
13
- "@vuu-ui/vuu-data-react": "2.1.9",
14
- "@vuu-ui/vuu-layout": "2.1.9",
15
- "@vuu-ui/vuu-popups": "2.1.9",
16
- "@vuu-ui/vuu-table": "2.1.9",
17
- "@vuu-ui/vuu-utils": "2.1.9",
12
+ "@vuu-ui/vuu-context-menu": "2.1.10",
13
+ "@vuu-ui/vuu-data-react": "2.1.10",
14
+ "@vuu-ui/vuu-layout": "2.1.10",
15
+ "@vuu-ui/vuu-popups": "2.1.10",
16
+ "@vuu-ui/vuu-table": "2.1.10",
17
+ "@vuu-ui/vuu-utils": "2.1.10",
18
18
  "@salt-ds/core": "1.54.1",
19
19
  "@salt-ds/icons": "1.16.0",
20
20
  "@salt-ds/styles": "0.2.1",
@@ -12,14 +12,12 @@ export declare const useEditableText: <T extends string | number | boolean = str
12
12
  * has the value been edited during this edit session
13
13
  */
14
14
  edited: boolean;
15
- editing: boolean;
16
15
  inputProps: {
17
16
  onBlur: FocusEventHandler<HTMLElement>;
18
17
  onFocus: FocusEventHandler<HTMLElement>;
19
18
  onKeyDown: (evt: KeyboardEvent<HTMLElement>) => Promise<void>;
20
19
  };
21
20
  onChange: FormEventHandler;
22
- previousValue: string | undefined;
23
21
  value: string;
24
22
  warningMessage: string | undefined;
25
23
  };