@vuu-ui/vuu-data-editing 5.0.0-alpha.2 → 5.0.0-alpha.3

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.
Files changed (57) hide show
  1. package/README.md +36 -0
  2. package/package.json +7 -6
  3. package/src/DirectEditSession.js +8 -1
  4. package/src/EditButtons.js +6 -5
  5. package/src/EditModeProvider.js +14 -5
  6. package/src/EditSession.js +37 -6
  7. package/src/edit-control/EditControlCheckbox.js +25 -0
  8. package/src/edit-control/EditControlDropdown.js +34 -0
  9. package/src/edit-control/EditControlLookupDropdown.js +31 -0
  10. package/src/edit-control/get-data-item-edit-control.js +139 -0
  11. package/src/edit-control/index.js +4 -0
  12. package/src/edit-errors.js +7 -0
  13. package/src/edit-field/EditField.js +101 -19
  14. package/src/edit-field/useEditField.js +1 -0
  15. package/src/edit-form/CreateRowForm.js +37 -0
  16. package/src/edit-form/EditForm.css.js +32 -0
  17. package/src/edit-form/EditForm.js +85 -0
  18. package/src/edit-form/EditFormButtons.js +48 -0
  19. package/src/edit-form/EditFormContext.js +4 -0
  20. package/src/edit-form/index.js +4 -0
  21. package/src/form-fields.js +40 -0
  22. package/src/index.js +9 -0
  23. package/src/lookup-values/useLookupOptions.js +106 -0
  24. package/src/useConfirmDiscard.js +34 -0
  25. package/src/useCustomEditField.js +76 -0
  26. package/src/useEditForm.js +306 -0
  27. package/src/useEditSessionState.js +72 -0
  28. package/src/useEditable.js +26 -9
  29. package/src/useEditableColumns.js +105 -0
  30. package/src/useEditableTable.js +21 -8
  31. package/types/DirectEditSession.d.ts +6 -1
  32. package/types/EditButtons.d.ts +20 -3
  33. package/types/EditModeProvider.d.ts +10 -2
  34. package/types/EditSession.d.ts +15 -0
  35. package/types/edit-control/EditControlCheckbox.d.ts +8 -0
  36. package/types/edit-control/EditControlDropdown.d.ts +14 -0
  37. package/types/edit-control/EditControlLookupDropdown.d.ts +13 -0
  38. package/types/edit-control/get-data-item-edit-control.d.ts +40 -0
  39. package/types/edit-control/index.d.ts +4 -0
  40. package/types/edit-errors.d.ts +9 -0
  41. package/types/edit-field/EditField.d.ts +37 -3
  42. package/types/edit-field/useEditField.d.ts +1 -0
  43. package/types/edit-form/CreateRowForm.d.ts +29 -0
  44. package/types/edit-form/EditForm.d.ts +36 -0
  45. package/types/edit-form/EditFormButtons.d.ts +18 -0
  46. package/types/edit-form/EditFormContext.d.ts +59 -0
  47. package/types/edit-form/index.d.ts +4 -0
  48. package/types/form-fields.d.ts +32 -0
  49. package/types/index.d.ts +12 -2
  50. package/types/lookup-values/useLookupOptions.d.ts +35 -0
  51. package/types/useConfirmDiscard.d.ts +23 -0
  52. package/types/useCustomEditField.d.ts +51 -0
  53. package/types/useEditForm.d.ts +127 -0
  54. package/types/useEditSessionState.d.ts +27 -0
  55. package/types/useEditable.d.ts +30 -3
  56. package/types/useEditableColumns.d.ts +79 -0
  57. package/types/useEditableTable.d.ts +18 -3
package/README.md CHANGED
@@ -4,6 +4,41 @@ Shared data editing APIs, state management, and React components for VUU UI.
4
4
 
5
5
  This package coordinates edit-session state with editable data sources (both in-memory and remote Vuu session tables) and provides React hooks and UI controls for table editing.
6
6
 
7
+ ## Quick start
8
+
9
+ Most applications don't need to assemble the pieces in this package by hand.
10
+ `@vuu-ui/vuu-table-extras` provides ready-made patterns built on it:
11
+
12
+ ```tsx
13
+ import { EditableTable } from "@vuu-ui/vuu-table-extras";
14
+
15
+ // Edit options live on the column descriptors, e.g. { name: "ric", editable: false }
16
+ <EditableTable
17
+ allowDelete
18
+ config={{ columns }}
19
+ dataSource={dataSource}
20
+ showInlineAddRow
21
+ />
22
+
23
+ // The selected row in a generated form beside the table
24
+ <EditableTable config={{ columns }} dataSource={dataSource} editStrategy="form" />
25
+ ```
26
+
27
+ See the Data Editing guides in the showcase (_Docs / DataEditing_, source in
28
+ [`showcase/src/examples/Docs/DataEditing`](../../showcase/src/examples/Docs/DataEditing/)), starting
29
+ with [Getting started](../../showcase/src/examples/Docs/DataEditing/01-GettingStarted.mdx), and the
30
+ _DataEditing_ examples in the showcase.
31
+
32
+ ## Layers
33
+
34
+ | Layer | Use it when | APIs |
35
+ | ----- | ----------- | ---- |
36
+ | Pattern components (`@vuu-ui/vuu-table-extras`) | A standard editing UI fits. | `EditableTable` (inline or form editing), `useBulkEditDialog` |
37
+ | Composable hooks and components (this package) | You need your own layout or behaviour. | `useEditableTable`, `useEditableColumns`, `useEditForm`, `EditForm`, `CreateRowForm`, `EditButtons`, `useConfirmDiscard`, `useEditSessionState`, `useLookupOptions` |
38
+ | Primitives (this package) | You are building a new pattern. | `EditSession`, `DirectEditSession`, `DataEditingProvider`, `EditModeProvider` |
39
+
40
+ The rest of this document describes the primitives and how they work.
41
+
7
42
  ---
8
43
 
9
44
  ## Table of Contents
@@ -155,6 +190,7 @@ A cell is considered edited only when `originalValue !== editedValue && isValid
155
190
  - On success, extracts the row key directly from the response map (`response.data.key`) and records it in `#addedRowKeys`.
156
191
  - Increments `addCount`.
157
192
  - Resets new-row form draft and increments `draftRevision`.
193
+ 5. **Rejection**: if the server rejects the row, the draft is kept and the message is stored in `errors` under `rowErrorColumn` (the final column, where an inline add row shows it). Forms show it in their error banner. The next change to the draft clears it.
158
194
 
159
195
  ### Row Deletions (`deleteSelectedRows`)
160
196
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.0.0-alpha.2",
2
+ "version": "5.0.0-alpha.3",
3
3
  "description": "Shared data editing APIs and React components for VUU UI",
4
4
  "main": "./src/index.js",
5
5
  "author": "heswell",
@@ -12,13 +12,14 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@salt-ds/core": "1.74.0",
15
- "@vuu-ui/vuu-ui-controls": "5.0.0-alpha.2",
16
- "@vuu-ui/vuu-utils": "5.0.0-alpha.2"
15
+ "@vuu-ui/core": "5.0.0-alpha.3",
16
+ "@vuu-ui/vuu-ui-controls": "5.0.0-alpha.3",
17
+ "@vuu-ui/vuu-utils": "5.0.0-alpha.3"
17
18
  },
18
19
  "devDependencies": {
19
- "@vuu-ui/vuu-data-types": "5.0.0-alpha.2",
20
- "@vuu-ui/vuu-protocol-types": "5.0.0-alpha.2",
21
- "@vuu-ui/vuu-table-types": "5.0.0-alpha.2"
20
+ "@vuu-ui/vuu-data-types": "5.0.0-alpha.3",
21
+ "@vuu-ui/vuu-protocol-types": "5.0.0-alpha.3",
22
+ "@vuu-ui/vuu-table-types": "5.0.0-alpha.3"
22
23
  },
23
24
  "peerDependencies": {
24
25
  "react": "^19.2.3"
@@ -1,9 +1,11 @@
1
1
  import { EventEmitter } from "@vuu-ui/vuu-utils";
2
2
  class DirectEditSession extends EventEmitter {
3
3
  #dataSource;
4
- constructor({ dataSource }){
4
+ #validate;
5
+ constructor({ dataSource, validate }){
5
6
  super();
6
7
  this.#dataSource = dataSource;
8
+ this.#validate = validate;
7
9
  }
8
10
  get dataSource() {
9
11
  return this.#dataSource;
@@ -25,6 +27,11 @@ class DirectEditSession extends EventEmitter {
25
27
  errorMessage: "Invalid value",
26
28
  type: "ERROR_RESULT"
27
29
  };
30
+ const errorMessage = this.#validate?.(key, columnName, typedValue);
31
+ if (errorMessage) return {
32
+ errorMessage,
33
+ type: "ERROR_RESULT"
34
+ };
28
35
  const editCell = this.#dataSource.editCell;
29
36
  if (void 0 === editCell) throw Error("[DirectEditSession] datasource does not support editCell");
30
37
  const response = await editCell.call(this.#dataSource, key, columnName, typedValue);
@@ -1,10 +1,11 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Button } from "@salt-ds/core";
3
3
  import { useCallback } from "react";
4
- import { useEditState } from "./useEditState.js";
5
- const EditButtons = ({ canCancel, canSave: _canSave, confirmCancel, confirmSave, editSession, hasSelection = false, onCancel, onDelete, onSave, saveLabel = "Save" })=>{
6
- const editState = useEditState(editSession);
7
- const isDirty = editSession?.isDirty ?? false;
4
+ import { useEditSessionState } from "./useEditSessionState.js";
5
+ const EditButtons = ({ canCancel: canCancelProp, canSave: canSaveProp, confirmCancel, confirmSave, editSession, hasSelection = false, onCancel, onDelete, onSave, saveLabel = "Save" })=>{
6
+ const { canCancel: sessionCanCancel, canSave: sessionCanSave, editState, isDirty } = useEditSessionState(editSession);
7
+ const canSave = false !== canSaveProp && sessionCanSave;
8
+ const canCancel = canCancelProp ?? sessionCanCancel;
8
9
  const handleSave = useCallback(async ()=>{
9
10
  if (confirmSave) {
10
11
  const confirmed = await confirmSave();
@@ -36,7 +37,7 @@ const EditButtons = ({ canCancel, canSave: _canSave, confirmCancel, confirmSave,
36
37
  children: "Delete"
37
38
  }),
38
39
  /*#__PURE__*/ jsx(Button, {
39
- disabled: !editSession?.canSave,
40
+ disabled: !canSave,
40
41
  onClick: handleSave,
41
42
  sentiment: "accented",
42
43
  children: "stale" === editState ? `${saveLabel} (force)` : saveLabel
@@ -1,8 +1,14 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { createContext, useContext, useEffect, useState } from "react";
2
+ import { createContext, useContext, useEffect, useMemo, useState } from "react";
3
+ let warnedMissingProvider = false;
3
4
  const EditModeContext = /*#__PURE__*/ createContext({
4
5
  isEditMode: false,
5
- setEditMode: ()=>"EditModeProvider in place"
6
+ setEditMode: ()=>{
7
+ if ("production" !== process.env.NODE_ENV && !warnedMissingProvider) {
8
+ warnedMissingProvider = true;
9
+ console.warn("[useEditMode] setEditMode called with no EditModeProvider in scope, edit mode will not change");
10
+ }
11
+ }
6
12
  });
7
13
  const EditModeProvider = ({ children, isEditMode: isEditModeProp = false })=>{
8
14
  const [isEditMode, setEditMode] = useState(isEditModeProp);
@@ -11,11 +17,14 @@ const EditModeProvider = ({ children, isEditMode: isEditModeProp = false })=>{
11
17
  }, [
12
18
  isEditModeProp
13
19
  ]);
14
- return /*#__PURE__*/ jsx(EditModeContext.Provider, {
15
- value: {
20
+ const value = useMemo(()=>({
16
21
  isEditMode,
17
22
  setEditMode
18
- },
23
+ }), [
24
+ isEditMode
25
+ ]);
26
+ return /*#__PURE__*/ jsx(EditModeContext.Provider, {
27
+ value: value,
19
28
  children: children
20
29
  });
21
30
  };
@@ -145,19 +145,31 @@ class EditSession extends EventEmitter {
145
145
  });
146
146
  }
147
147
  setNewRowValue(column, value) {
148
+ const { rowErrorColumn, ...newRowState } = this.#newRowState;
148
149
  const errors = {
149
- ...this.#newRowState.errors
150
+ ...newRowState.errors
150
151
  };
151
152
  delete errors[column];
153
+ if (void 0 !== rowErrorColumn) delete errors[rowErrorColumn];
152
154
  this.#setNewRowState({
153
- ...this.#newRowState,
155
+ ...newRowState,
154
156
  errors,
155
157
  values: {
156
- ...this.#newRowState.values,
158
+ ...newRowState.values,
157
159
  [column]: value
158
160
  }
159
161
  });
160
162
  }
163
+ clearNewRow() {
164
+ this.#setNewRowState({
165
+ columns: this.#newRowState.columns,
166
+ draftRevision: this.#newRowState.draftRevision + 1,
167
+ errors: {},
168
+ requiredColumns: this.#newRowState.requiredColumns,
169
+ submitting: false,
170
+ values: {}
171
+ });
172
+ }
161
173
  async addNewRow() {
162
174
  const requiredColumns = this.#newRowState.requiredColumns ?? this.#newRowState.columns;
163
175
  const missingErrors = Object.fromEntries(requiredColumns.filter((column)=>{
@@ -167,8 +179,13 @@ class EditSession extends EventEmitter {
167
179
  column,
168
180
  "Value required"
169
181
  ]));
170
- const errors = {
171
- ...this.#newRowState.errors,
182
+ const { rowErrorColumn, ...newRowState } = this.#newRowState;
183
+ const { [rowErrorColumn ?? ""]: _serverError, ...fieldErrors } = newRowState.errors;
184
+ const errors = void 0 === rowErrorColumn ? {
185
+ ...newRowState.errors,
186
+ ...missingErrors
187
+ } : {
188
+ ...fieldErrors,
172
189
  ...missingErrors
173
190
  };
174
191
  if (Object.keys(errors).length > 0) {
@@ -186,7 +203,8 @@ class EditSession extends EventEmitter {
186
203
  type: "SUCCESS_RESULT"
187
204
  };
188
205
  this.#setNewRowState({
189
- ...this.#newRowState,
206
+ ...newRowState,
207
+ errors,
190
208
  submitting: true
191
209
  });
192
210
  try {
@@ -200,6 +218,7 @@ class EditSession extends EventEmitter {
200
218
  errors: finalColumn ? {
201
219
  [finalColumn]: response.errorMessage
202
220
  } : this.#newRowState.errors,
221
+ rowErrorColumn: finalColumn,
203
222
  submitting: false
204
223
  });
205
224
  return response;
@@ -221,6 +240,7 @@ class EditSession extends EventEmitter {
221
240
  errors: finalColumn ? {
222
241
  [finalColumn]: errorMessage
223
242
  } : this.#newRowState.errors,
243
+ rowErrorColumn: finalColumn,
224
244
  submitting: false
225
245
  });
226
246
  return {
@@ -282,6 +302,14 @@ class EditSession extends EventEmitter {
282
302
  hasRowChanges(key) {
283
303
  return this.#rowEdits.has(key);
284
304
  }
305
+ getEditedValues(key) {
306
+ const cellEdits = this.#rowEdits.get(key)?.cellEdits;
307
+ if (!cellEdits) return {};
308
+ return Object.fromEntries(Array.from(cellEdits, ([column, { editedValue }])=>[
309
+ column,
310
+ editedValue
311
+ ]));
312
+ }
285
313
  isCellEdited(key, columnName) {
286
314
  const cellEdit = this.#rowEdits.get(key)?.cellEdits.get(columnName);
287
315
  return cellEdit?.isValid === true && cellEdit.originalValue !== cellEdit.editedValue;
@@ -424,6 +452,9 @@ class EditSession extends EventEmitter {
424
452
  get dataSource() {
425
453
  return this.#sessionDataSource ?? this.#sourceTableDataSource;
426
454
  }
455
+ get sourceDataSource() {
456
+ return this.#sourceTableDataSource;
457
+ }
427
458
  get sessionDataSource() {
428
459
  return this.#sessionDataSource;
429
460
  }
@@ -0,0 +1,25 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Checkbox } from "@salt-ds/core";
3
+ import { useCallback, useEffect, useState } from "react";
4
+ const isChecked = (value)=>true === value || "true" === value;
5
+ const EditControlCheckbox = ({ className, onCommit, value })=>{
6
+ const [checked, setChecked] = useState(isChecked(value));
7
+ useEffect(()=>{
8
+ setChecked(isChecked(value));
9
+ }, [
10
+ value
11
+ ]);
12
+ const handleChange = useCallback((evt)=>{
13
+ setChecked(evt.target.checked);
14
+ onCommit(evt, evt.target.checked);
15
+ }, [
16
+ onCommit
17
+ ]);
18
+ return /*#__PURE__*/ jsx(Checkbox, {
19
+ checked: checked,
20
+ className: className,
21
+ "data-edit-control": true,
22
+ onChange: handleChange
23
+ });
24
+ };
25
+ export { EditControlCheckbox };
@@ -0,0 +1,34 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Dropdown, Option } from "@salt-ds/core";
3
+ import { useCallback } from "react";
4
+ const toOption = (value)=>"string" == typeof value ? {
5
+ label: value,
6
+ value
7
+ } : value;
8
+ const EditControlDropdown = ({ className, onCommit, value, values })=>{
9
+ const options = values.map(toOption);
10
+ const selectedValue = void 0 === value ? "" : String(value);
11
+ const selected = options.find((option)=>option.value === selectedValue);
12
+ const handleSelectionChange = useCallback((evt, [option])=>{
13
+ if (option) onCommit(evt, option.value);
14
+ }, [
15
+ onCommit
16
+ ]);
17
+ return /*#__PURE__*/ jsx(Dropdown, {
18
+ bordered: true,
19
+ className: className,
20
+ "data-edit-control": true,
21
+ "data-icon": "triangle-down",
22
+ onSelectionChange: handleSelectionChange,
23
+ placeholder: "Please select value",
24
+ selected: selected ? [
25
+ selected
26
+ ] : [],
27
+ value: selected?.label ?? selectedValue,
28
+ children: options.map((option)=>/*#__PURE__*/ jsx(Option, {
29
+ value: option,
30
+ children: option.label
31
+ }, option.value))
32
+ });
33
+ };
34
+ export { EditControlDropdown };
@@ -0,0 +1,31 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { useLookupValues } from "../lookup-values/useLookupValues.js";
4
+ import { EditControlDropdown } from "./EditControlDropdown.js";
5
+ const EditControlLookupDropdown = ({ className, lookup: { labelColumn, table, valueColumn }, onCommit, value })=>{
6
+ const optionMap = useMemo(()=>({
7
+ label: labelColumn,
8
+ value: valueColumn
9
+ }), [
10
+ labelColumn,
11
+ valueColumn
12
+ ]);
13
+ const lookupValues = useLookupValues({
14
+ enabled: true,
15
+ optionMap,
16
+ table
17
+ });
18
+ const values = useMemo(()=>lookupValues.map(({ label, value })=>({
19
+ label,
20
+ value: String(value)
21
+ })), [
22
+ lookupValues
23
+ ]);
24
+ return /*#__PURE__*/ jsx(EditControlDropdown, {
25
+ className: className,
26
+ onCommit: onCommit,
27
+ value: value,
28
+ values: values
29
+ });
30
+ };
31
+ export { EditControlLookupDropdown };
@@ -0,0 +1,139 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { VuuDatePicker, VuuInput, VuuTimePicker, VuuTypeaheadInput } from "@vuu-ui/vuu-ui-controls";
3
+ import { EpochTimestamp, getTemporalInfo, isDataValueEditable, isTimeDataValueWithMilliseconds, isValidTimeString, isValidTimeStringMillis, parseTemporalInput } from "@vuu-ui/vuu-utils";
4
+ import { EditControlCheckbox } from "./EditControlCheckbox.js";
5
+ import { EditControlDropdown } from "./EditControlDropdown.js";
6
+ import { EditControlLookupDropdown } from "./EditControlLookupDropdown.js";
7
+ const VARIANT_MIN_CHARACTER_COUNT = {
8
+ default: void 0,
9
+ pick: 0,
10
+ search: 1
11
+ };
12
+ const isTypeaheadEditor = (editor)=>editor?.name === "typeahead";
13
+ const isValueListEditor = (editor)=>Array.isArray(editor?.values);
14
+ const isLookupEditor = (editor)=>editor?.lookup !== void 0;
15
+ const isCheckboxEditor = (editor)=>editor?.name === "checkbox-cell" || editor?.name === "toggle-cell";
16
+ const timeOfDayPattern = /^\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?$/;
17
+ const toEpochTimestamp = (value, { encoding })=>{
18
+ if (("string" == typeof value || "number" == typeof value) && !timeOfDayPattern.test(`${value}`)) return EpochTimestamp.fromWire(value, encoding);
19
+ };
20
+ const pad = (n)=>`${n}`.padStart(2, "0");
21
+ function toTimeString(value, timestamp, { timeZone }, milliseconds = false) {
22
+ if (timestamp) {
23
+ const { hour, minute, second, millisecond } = timestamp.getFields(timeZone);
24
+ const timeString = `${pad(hour)}:${pad(minute)}:${pad(second)}`;
25
+ return milliseconds ? `${timeString}.${`${millisecond}`.padStart(3, "0")}` : timeString;
26
+ }
27
+ if ("string" == typeof value) if (milliseconds) {
28
+ const timeString = 8 === value.length ? `${value}.000` : value.slice(0, 12);
29
+ if (isValidTimeStringMillis(timeString)) return timeString;
30
+ } else {
31
+ const timeString = value.slice(0, 8);
32
+ if (isValidTimeString(timeString)) return timeString;
33
+ }
34
+ }
35
+ const getDataItemEditControl = ({ InputProps, TypeaheadProps, className, commitOnBlur, commitWhenCleared, dataDescriptor, editOperation = "update", errorMessage, onCommit, purpose = "edit", table, variant })=>{
36
+ const { editor } = dataDescriptor;
37
+ const temporalInfo = getTemporalInfo(dataDescriptor);
38
+ const value = InputProps?.value ?? InputProps?.inputProps?.value;
39
+ if (!isDataValueEditable(dataDescriptor, editOperation, true)) return /*#__PURE__*/ jsx(VuuInput, {
40
+ variant: "secondary",
41
+ ...InputProps,
42
+ onCommit: onCommit,
43
+ readOnly: true,
44
+ "data-edit-control": true
45
+ });
46
+ if (temporalInfo?.kind === "time") {
47
+ const { value, onChange } = InputProps?.inputProps ?? {};
48
+ const baseValue = toEpochTimestamp(value, temporalInfo);
49
+ const handleCommitTime = (evt, timeString)=>{
50
+ if (baseValue) {
51
+ const timestamp = parseTemporalInput(timeString, temporalInfo, baseValue);
52
+ onCommit(evt, timestamp ? `${timestamp.toWire(temporalInfo.encoding)}` : "");
53
+ } else onCommit(evt, timeString);
54
+ };
55
+ return isTimeDataValueWithMilliseconds(dataDescriptor) ? /*#__PURE__*/ jsx(VuuTimePicker, {
56
+ className: className,
57
+ milliseconds: true,
58
+ value: "" === value ? "" : toTimeString(value, baseValue, temporalInfo, true),
59
+ onChange: onChange,
60
+ onCommit: handleCommitTime,
61
+ "data-edit-control": true
62
+ }) : /*#__PURE__*/ jsx(VuuTimePicker, {
63
+ className: className,
64
+ value: "" === value ? "" : toTimeString(value, baseValue, temporalInfo),
65
+ onChange: onChange,
66
+ onCommit: handleCommitTime,
67
+ "data-edit-control": true
68
+ });
69
+ }
70
+ if (temporalInfo) {
71
+ const baseValue = toEpochTimestamp(InputProps?.inputProps?.value, temporalInfo);
72
+ const handleCommitDate = (evt, startOfDayMillis)=>{
73
+ let timestamp = EpochTimestamp.fromMillis(startOfDayMillis);
74
+ if (baseValue && "datetime" === temporalInfo.kind) {
75
+ const { year, month, day } = timestamp.getFields(temporalInfo.timeZone);
76
+ const { hour, minute, second, millisecond } = baseValue.getFields(temporalInfo.timeZone);
77
+ timestamp = EpochTimestamp.fromFields({
78
+ year,
79
+ month,
80
+ day,
81
+ hour,
82
+ minute,
83
+ second,
84
+ millisecond
85
+ }, temporalInfo.timeZone, baseValue.subMilliNanos);
86
+ }
87
+ onCommit(evt, `${timestamp.toWire(temporalInfo.encoding)}`);
88
+ };
89
+ return /*#__PURE__*/ jsx(VuuDatePicker, {
90
+ className: className,
91
+ onCommit: handleCommitDate,
92
+ timeZone: temporalInfo.timeZone,
93
+ value: baseValue,
94
+ "data-edit-control": true
95
+ });
96
+ }
97
+ if ("edit" === purpose && (isCheckboxEditor(editor) || void 0 === editor && "boolean" === dataDescriptor.serverDataType)) return /*#__PURE__*/ jsx(EditControlCheckbox, {
98
+ className: className,
99
+ onCommit: onCommit,
100
+ value: value
101
+ });
102
+ if (isLookupEditor(editor)) return /*#__PURE__*/ jsx(EditControlLookupDropdown, {
103
+ className: className,
104
+ lookup: editor.lookup,
105
+ onCommit: onCommit,
106
+ value: value
107
+ });
108
+ else if (isValueListEditor(editor)) return /*#__PURE__*/ jsx(EditControlDropdown, {
109
+ className: className,
110
+ onCommit: onCommit,
111
+ value: value,
112
+ values: editor.values
113
+ });
114
+ else if (table && (isTypeaheadEditor(editor) || "filter" === purpose && "string" === dataDescriptor.serverDataType)) {
115
+ const minCharacterCountToTriggerSuggestions = TypeaheadProps?.minCharacterCountToTriggerSuggestions ?? (isTypeaheadEditor(editor) ? editor.minCharacterCountToTriggerSuggestions : void 0) ?? VARIANT_MIN_CHARACTER_COUNT[variant ?? "default"];
116
+ return /*#__PURE__*/ jsx(VuuTypeaheadInput, {
117
+ ...InputProps,
118
+ ...TypeaheadProps,
119
+ className: className,
120
+ column: dataDescriptor.name,
121
+ "data-edit-control": true,
122
+ "data-variant": variant,
123
+ minCharacterCountToTriggerSuggestions: minCharacterCountToTriggerSuggestions,
124
+ onCommit: onCommit,
125
+ table: table
126
+ });
127
+ }
128
+ return /*#__PURE__*/ jsx(VuuInput, {
129
+ variant: "secondary",
130
+ ...InputProps,
131
+ className: className,
132
+ commitOnBlur: commitOnBlur,
133
+ commitWhenCleared: commitWhenCleared,
134
+ onCommit: onCommit,
135
+ errorMessage: errorMessage,
136
+ "data-edit-control": true
137
+ });
138
+ };
139
+ export { getDataItemEditControl };
@@ -0,0 +1,4 @@
1
+ export * from "./EditControlCheckbox.js";
2
+ export * from "./EditControlDropdown.js";
3
+ export * from "./EditControlLookupDropdown.js";
4
+ export * from "./get-data-item-edit-control.js";
@@ -0,0 +1,7 @@
1
+ const toError = (cause)=>cause instanceof Error ? cause : new Error(String(cause));
2
+ const reportEditError = (source, onError, cause, operation)=>{
3
+ const error = toError(cause);
4
+ if (onError) onError(error, operation);
5
+ else console.error("[%s] %s edit session failed", source, operation, error);
6
+ };
7
+ export { reportEditError, toError };