@vuu-ui/vuu-table 0.13.106 → 0.13.108

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 (67) hide show
  1. package/cjs/Row.js +2 -2
  2. package/cjs/Row.js.map +1 -1
  3. package/cjs/Table.css.js +1 -1
  4. package/cjs/bulk-edit/BulkEditPanel.css.js +1 -1
  5. package/cjs/bulk-edit/BulkEditPanel.js +2 -1
  6. package/cjs/bulk-edit/BulkEditPanel.js.map +1 -1
  7. package/cjs/bulk-edit/useBulkEditPanel.js +15 -12
  8. package/cjs/bulk-edit/useBulkEditPanel.js.map +1 -1
  9. package/cjs/cell-block/useCellBlockSelection.js +3 -0
  10. package/cjs/cell-block/useCellBlockSelection.js.map +1 -1
  11. package/cjs/cell-renderers/checkbox-cell/CheckboxCell.js +2 -2
  12. package/cjs/cell-renderers/checkbox-cell/CheckboxCell.js.map +1 -1
  13. package/cjs/cell-renderers/input-cell/InputCell.css.js +1 -1
  14. package/cjs/cell-renderers/input-cell/InputCell.js +3 -2
  15. package/cjs/cell-renderers/input-cell/InputCell.js.map +1 -1
  16. package/cjs/cell-renderers/toggle-cell/ToggleCell.js +1 -1
  17. package/cjs/cell-renderers/toggle-cell/ToggleCell.js.map +1 -1
  18. package/cjs/header-cell/GroupHeaderCell.css.js +1 -1
  19. package/cjs/table-cell/TableCell.css.js +1 -1
  20. package/cjs/table-cell/TableCell.js +19 -19
  21. package/cjs/table-cell/TableCell.js.map +1 -1
  22. package/cjs/table-data-source/useDataSource.js +1 -1
  23. package/cjs/table-data-source/useDataSource.js.map +1 -1
  24. package/cjs/useCellEditing.js +28 -3
  25. package/cjs/useCellEditing.js.map +1 -1
  26. package/cjs/useCellFocus.js +8 -4
  27. package/cjs/useCellFocus.js.map +1 -1
  28. package/cjs/useKeyboardNavigation.js +11 -25
  29. package/cjs/useKeyboardNavigation.js.map +1 -1
  30. package/cjs/useTable.js +23 -14
  31. package/cjs/useTable.js.map +1 -1
  32. package/esm/Row.js +2 -2
  33. package/esm/Row.js.map +1 -1
  34. package/esm/Table.css.js +1 -1
  35. package/esm/bulk-edit/BulkEditPanel.css.js +1 -1
  36. package/esm/bulk-edit/BulkEditPanel.js +2 -1
  37. package/esm/bulk-edit/BulkEditPanel.js.map +1 -1
  38. package/esm/bulk-edit/useBulkEditPanel.js +15 -12
  39. package/esm/bulk-edit/useBulkEditPanel.js.map +1 -1
  40. package/esm/cell-block/useCellBlockSelection.js +3 -0
  41. package/esm/cell-block/useCellBlockSelection.js.map +1 -1
  42. package/esm/cell-renderers/checkbox-cell/CheckboxCell.js +3 -3
  43. package/esm/cell-renderers/checkbox-cell/CheckboxCell.js.map +1 -1
  44. package/esm/cell-renderers/input-cell/InputCell.css.js +1 -1
  45. package/esm/cell-renderers/input-cell/InputCell.js +3 -2
  46. package/esm/cell-renderers/input-cell/InputCell.js.map +1 -1
  47. package/esm/cell-renderers/toggle-cell/ToggleCell.js +2 -2
  48. package/esm/cell-renderers/toggle-cell/ToggleCell.js.map +1 -1
  49. package/esm/header-cell/GroupHeaderCell.css.js +1 -1
  50. package/esm/table-cell/TableCell.css.js +1 -1
  51. package/esm/table-cell/TableCell.js +19 -19
  52. package/esm/table-cell/TableCell.js.map +1 -1
  53. package/esm/table-data-source/useDataSource.js +1 -1
  54. package/esm/table-data-source/useDataSource.js.map +1 -1
  55. package/esm/useCellEditing.js +30 -5
  56. package/esm/useCellEditing.js.map +1 -1
  57. package/esm/useCellFocus.js +8 -4
  58. package/esm/useCellFocus.js.map +1 -1
  59. package/esm/useKeyboardNavigation.js +11 -25
  60. package/esm/useKeyboardNavigation.js.map +1 -1
  61. package/esm/useTable.js +23 -14
  62. package/esm/useTable.js.map +1 -1
  63. package/package.json +11 -11
  64. package/types/bulk-edit/BulkEditPanel.d.ts +3 -2
  65. package/types/useCellEditing.d.ts +3 -1
  66. package/types/useKeyboardNavigation.d.ts +2 -2
  67. package/types/useTable.d.ts +2 -2
@@ -1,7 +1,7 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { memo, useCallback } from 'react';
3
3
  import { Checkbox } from '@salt-ds/core';
4
- import { dispatchCustomEvent, dataColumnAndKeyUnchanged, registerComponent } from '@vuu-ui/vuu-utils';
4
+ import { isRpcSuccess, dispatchCustomEvent, dataColumnAndKeyUnchanged, registerComponent } from '@vuu-ui/vuu-utils';
5
5
  import { useComponentCssInjection } from '@salt-ds/styles';
6
6
  import { useWindow } from '@salt-ds/window';
7
7
  import checkboxCellCss from './CheckboxCell.css.js';
@@ -23,7 +23,7 @@ const CheckboxCell = memo(
23
23
  { previousValue: isChecked, value },
24
24
  "commit"
25
25
  );
26
- if (res === true) {
26
+ if (isRpcSuccess(res)) {
27
27
  dispatchCustomEvent(evt.target, "vuu-commit");
28
28
  }
29
29
  return res;
@@ -37,7 +37,7 @@ const CheckboxCell = memo(
37
37
  { previousValue: isChecked, value: !isChecked },
38
38
  "commit"
39
39
  );
40
- if (res === true) {
40
+ if (isRpcSuccess(res)) {
41
41
  dispatchCustomEvent(evt.target, "vuu-commit");
42
42
  }
43
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CheckboxCell.js","sources":["../../../../../packages/vuu-table/src/cell-renderers/checkbox-cell/CheckboxCell.tsx"],"sourcesContent":["import { MouseEvent, KeyboardEventHandler, memo, useCallback } from \"react\";\nimport { TableCellRendererProps } from \"@vuu-ui/vuu-table-types\";\nimport { Checkbox } from \"@salt-ds/core\";\nimport {\n dataColumnAndKeyUnchanged,\n dispatchCustomEvent,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport checkboxCellCss from \"./CheckboxCell.css\";\n\nconst classBase = \"vuuCheckboxCell\";\n\nexport const CheckboxCell = memo(\n ({ column, columnMap, onEdit, row }: TableCellRendererProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-checkbox-cell\",\n css: checkboxCellCss,\n window: targetWindow,\n });\n\n const dataIdx = columnMap[column.name];\n const isChecked = !!row[dataIdx];\n\n const handleCommit = useCallback(\n (value: boolean) => async (evt: MouseEvent) => {\n const res = await onEdit?.(\n { previousValue: isChecked, value },\n \"commit\",\n );\n if (res === true) {\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-commit\");\n }\n return res;\n },\n [isChecked, onEdit],\n );\n\n const handleKeyDown = useCallback<KeyboardEventHandler>(\n async (evt) => {\n if (evt.key === \"Enter\") {\n const res = await onEdit?.(\n { previousValue: isChecked, value: !isChecked },\n \"commit\",\n );\n if (res === true) {\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-commit\");\n }\n }\n },\n [isChecked, onEdit],\n );\n\n const className = `${classBase}-checkbox`;\n\n return column.editable ? (\n <Checkbox\n checked={isChecked}\n className={className}\n onClick={handleCommit(!isChecked)}\n onKeyDown={handleKeyDown}\n />\n ) : (\n <Checkbox checked={isChecked} className={className} disabled={true} />\n );\n },\n dataColumnAndKeyUnchanged,\n);\nCheckboxCell.displayName = \"CheckboxCell\";\n\nregisterComponent(\"checkbox-cell\", CheckboxCell, \"cell-renderer\", {\n serverDataType: \"boolean\",\n});\n"],"names":[],"mappings":";;;;;;;;AAaA,MAAM,SAAY,GAAA,iBAAA;AAEX,MAAM,YAAe,GAAA,IAAA;AAAA,EAC1B,CAAC,EAAE,MAAA,EAAQ,SAAW,EAAA,MAAA,EAAQ,KAAkC,KAAA;AAC9D,IAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,IAAyB,wBAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,mBAAA;AAAA,MACR,GAAK,EAAA,eAAA;AAAA,MACL,MAAQ,EAAA;AAAA,KACT,CAAA;AAED,IAAM,MAAA,OAAA,GAAU,SAAU,CAAA,MAAA,CAAO,IAAI,CAAA;AACrC,IAAA,MAAM,SAAY,GAAA,CAAC,CAAC,GAAA,CAAI,OAAO,CAAA;AAE/B,IAAA,MAAM,YAAe,GAAA,WAAA;AAAA,MACnB,CAAC,KAAmB,KAAA,OAAO,GAAoB,KAAA;AAC7C,QAAA,MAAM,MAAM,MAAM,MAAA;AAAA,UAChB,EAAE,aAAe,EAAA,SAAA,EAAW,KAAM,EAAA;AAAA,UAClC;AAAA,SACF;AACA,QAAA,IAAI,QAAQ,IAAM,EAAA;AAChB,UAAoB,mBAAA,CAAA,GAAA,CAAI,QAAuB,YAAY,CAAA;AAAA;AAE7D,QAAO,OAAA,GAAA;AAAA,OACT;AAAA,MACA,CAAC,WAAW,MAAM;AAAA,KACpB;AAEA,IAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,MACpB,OAAO,GAAQ,KAAA;AACb,QAAI,IAAA,GAAA,CAAI,QAAQ,OAAS,EAAA;AACvB,UAAA,MAAM,MAAM,MAAM,MAAA;AAAA,YAChB,EAAE,aAAA,EAAe,SAAW,EAAA,KAAA,EAAO,CAAC,SAAU,EAAA;AAAA,YAC9C;AAAA,WACF;AACA,UAAA,IAAI,QAAQ,IAAM,EAAA;AAChB,YAAoB,mBAAA,CAAA,GAAA,CAAI,QAAuB,YAAY,CAAA;AAAA;AAC7D;AACF,OACF;AAAA,MACA,CAAC,WAAW,MAAM;AAAA,KACpB;AAEA,IAAM,MAAA,SAAA,GAAY,GAAG,SAAS,CAAA,SAAA,CAAA;AAE9B,IAAA,OAAO,OAAO,QACZ,mBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,OAAS,EAAA,SAAA;AAAA,QACT,SAAA;AAAA,QACA,OAAA,EAAS,YAAa,CAAA,CAAC,SAAS,CAAA;AAAA,QAChC,SAAW,EAAA;AAAA;AAAA,wBAGZ,GAAA,CAAA,QAAA,EAAA,EAAS,SAAS,SAAW,EAAA,SAAA,EAAsB,UAAU,IAAM,EAAA,CAAA;AAAA,GAExE;AAAA,EACA;AACF;AACA,YAAA,CAAa,WAAc,GAAA,cAAA;AAE3B,iBAAkB,CAAA,eAAA,EAAiB,cAAc,eAAiB,EAAA;AAAA,EAChE,cAAgB,EAAA;AAClB,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"CheckboxCell.js","sources":["../../../../../packages/vuu-table/src/cell-renderers/checkbox-cell/CheckboxCell.tsx"],"sourcesContent":["import { MouseEvent, KeyboardEventHandler, memo, useCallback } from \"react\";\nimport { TableCellRendererProps } from \"@vuu-ui/vuu-table-types\";\nimport { Checkbox } from \"@salt-ds/core\";\nimport {\n dataColumnAndKeyUnchanged,\n dispatchCustomEvent,\n isRpcSuccess,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport checkboxCellCss from \"./CheckboxCell.css\";\n\nconst classBase = \"vuuCheckboxCell\";\n\nexport const CheckboxCell = memo(\n ({ column, columnMap, onEdit, row }: TableCellRendererProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-checkbox-cell\",\n css: checkboxCellCss,\n window: targetWindow,\n });\n\n const dataIdx = columnMap[column.name];\n const isChecked = !!row[dataIdx];\n\n const handleCommit = useCallback(\n (value: boolean) => async (evt: MouseEvent) => {\n const res = await onEdit?.(\n { previousValue: isChecked, value },\n \"commit\",\n );\n if (isRpcSuccess(res)) {\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-commit\");\n }\n return res;\n },\n [isChecked, onEdit],\n );\n\n const handleKeyDown = useCallback<KeyboardEventHandler>(\n async (evt) => {\n if (evt.key === \"Enter\") {\n const res = await onEdit?.(\n { previousValue: isChecked, value: !isChecked },\n \"commit\",\n );\n if (isRpcSuccess(res)) {\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-commit\");\n }\n }\n },\n [isChecked, onEdit],\n );\n\n const className = `${classBase}-checkbox`;\n\n return column.editable ? (\n <Checkbox\n checked={isChecked}\n className={className}\n onClick={handleCommit(!isChecked)}\n onKeyDown={handleKeyDown}\n />\n ) : (\n <Checkbox checked={isChecked} className={className} disabled={true} />\n );\n },\n dataColumnAndKeyUnchanged,\n);\nCheckboxCell.displayName = \"CheckboxCell\";\n\nregisterComponent(\"checkbox-cell\", CheckboxCell, \"cell-renderer\", {\n serverDataType: \"boolean\",\n});\n"],"names":[],"mappings":";;;;;;;;AAcA,MAAM,SAAY,GAAA,iBAAA;AAEX,MAAM,YAAe,GAAA,IAAA;AAAA,EAC1B,CAAC,EAAE,MAAA,EAAQ,SAAW,EAAA,MAAA,EAAQ,KAAkC,KAAA;AAC9D,IAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,IAAyB,wBAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,mBAAA;AAAA,MACR,GAAK,EAAA,eAAA;AAAA,MACL,MAAQ,EAAA;AAAA,KACT,CAAA;AAED,IAAM,MAAA,OAAA,GAAU,SAAU,CAAA,MAAA,CAAO,IAAI,CAAA;AACrC,IAAA,MAAM,SAAY,GAAA,CAAC,CAAC,GAAA,CAAI,OAAO,CAAA;AAE/B,IAAA,MAAM,YAAe,GAAA,WAAA;AAAA,MACnB,CAAC,KAAmB,KAAA,OAAO,GAAoB,KAAA;AAC7C,QAAA,MAAM,MAAM,MAAM,MAAA;AAAA,UAChB,EAAE,aAAe,EAAA,SAAA,EAAW,KAAM,EAAA;AAAA,UAClC;AAAA,SACF;AACA,QAAI,IAAA,YAAA,CAAa,GAAG,CAAG,EAAA;AACrB,UAAoB,mBAAA,CAAA,GAAA,CAAI,QAAuB,YAAY,CAAA;AAAA;AAE7D,QAAO,OAAA,GAAA;AAAA,OACT;AAAA,MACA,CAAC,WAAW,MAAM;AAAA,KACpB;AAEA,IAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,MACpB,OAAO,GAAQ,KAAA;AACb,QAAI,IAAA,GAAA,CAAI,QAAQ,OAAS,EAAA;AACvB,UAAA,MAAM,MAAM,MAAM,MAAA;AAAA,YAChB,EAAE,aAAA,EAAe,SAAW,EAAA,KAAA,EAAO,CAAC,SAAU,EAAA;AAAA,YAC9C;AAAA,WACF;AACA,UAAI,IAAA,YAAA,CAAa,GAAG,CAAG,EAAA;AACrB,YAAoB,mBAAA,CAAA,GAAA,CAAI,QAAuB,YAAY,CAAA;AAAA;AAC7D;AACF,OACF;AAAA,MACA,CAAC,WAAW,MAAM;AAAA,KACpB;AAEA,IAAM,MAAA,SAAA,GAAY,GAAG,SAAS,CAAA,SAAA,CAAA;AAE9B,IAAA,OAAO,OAAO,QACZ,mBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,OAAS,EAAA,SAAA;AAAA,QACT,SAAA;AAAA,QACA,OAAA,EAAS,YAAa,CAAA,CAAC,SAAS,CAAA;AAAA,QAChC,SAAW,EAAA;AAAA;AAAA,wBAGZ,GAAA,CAAA,QAAA,EAAA,EAAS,SAAS,SAAW,EAAA,SAAA,EAAsB,UAAU,IAAM,EAAA,CAAA;AAAA,GAExE;AAAA,EACA;AACF;AACA,YAAA,CAAa,WAAc,GAAA,cAAA;AAE3B,iBAAkB,CAAA,eAAA,EAAiB,cAAc,eAAiB,EAAA;AAAA,EAChE,cAAgB,EAAA;AAClB,CAAC,CAAA;;;;"}
@@ -1,4 +1,4 @@
1
- var inputCellCss = ".vuuTableCell.vuuTableCell-editable {\n .vuuTableInputCell.saltInput-primary {\n --salt-focused-outlineStyle: none;\n --saltInput-height: var(--vuu-table-embedded-control-height);\n --saltInput-minHeight: var(--saltInput-height);\n border-radius: 2px;\n font-weight: 500;\n }\n}\n\n.vuuTableCell:focus .vuuTableInputCell.saltInput-primary,\n.vuuTableInputCell.saltInput-primary.saltInput-focused {\n border: solid 2px var(--salt-focused-outlineColor);\n padding: 0 3px;\n}\n\n.vuuTableCell-editable:focus-within\n .vuuTableInputCell.saltInput-primary:focus-within,\n.vuuTableInputCell.saltInput-primary.saltInput-focused {\n border: dotted 2px var(--salt-focused-outlineColor);\n padding: 0 3px;\n}\n\n.vuuTableInputCell-icon {\n --vuu-icon-height: 13px;\n --vuu-icon-left: 0;\n --vuu-icon-size: 15px;\n --vuu-icon-width: 12px;\n border-radius: 10px;\n}\n\n.vuuTableInputCell-error {\n .saltInput-startAdornmentContainer {\n .vuuTableInputCell-icon {\n --vuu-icon-color: red;\n }\n }\n .saltInput-endAdornmentContainer {\n .vuuTableInputCell-icon {\n --vuu-icon-color: red;\n }\n }\n}\n\n.vuuTableCell-right {\n .saltInput-input {\n text-align: right;\n }\n}\n\n.vuuTableCell-error {\n .vuuTableInputCell {\n outline: var(--vuuTableCell-outline, solid red 2px);\n outline-offset: -2px;\n }\n}\n";
1
+ var inputCellCss = ".vuuTableCell.vuuTableCell-editable {\n .vuuTableInputCell.saltInput-primary {\n --salt-focused-outlineStyle: none;\n --saltInput-height: var(--vuu-table-embedded-control-height);\n --saltInput-minHeight: var(--saltInput-height);\n border-radius: 2px;\n font-weight: 500;\n }\n}\n\n.vuuTableInputCell-icon {\n --vuu-icon-height: 13px;\n --vuu-icon-left: 0;\n --vuu-icon-size: 15px;\n --vuu-icon-width: 12px;\n border-radius: 10px;\n}\n\n.vuuTableInputCell-error {\n .saltInput-startAdornmentContainer {\n .vuuTableInputCell-icon {\n --vuu-icon-color: red;\n }\n }\n .saltInput-endAdornmentContainer {\n .vuuTableInputCell-icon {\n --vuu-icon-color: red;\n }\n }\n}\n\n.vuuTableCell-right {\n .saltInput-input {\n text-align: right;\n }\n}\n\n.vuuTableCell-error {\n .vuuTableInputCell {\n outline: var(--vuuTableCell-outline, solid red 2px);\n outline-offset: -2px;\n }\n}\n";
2
2
 
3
3
  export { inputCellCss as default };
4
4
  //# sourceMappingURL=InputCell.css.js.map
@@ -1,9 +1,9 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { registerComponent } from '@vuu-ui/vuu-utils';
3
2
  import { Input } from '@salt-ds/core';
4
- import { useEditableText } from '@vuu-ui/vuu-ui-controls';
5
3
  import { useComponentCssInjection } from '@salt-ds/styles';
6
4
  import { useWindow } from '@salt-ds/window';
5
+ import { useEditableText } from '@vuu-ui/vuu-ui-controls';
6
+ import { registerComponent } from '@vuu-ui/vuu-utils';
7
7
  import cx from 'clsx';
8
8
  import inputCellCss from './InputCell.css.js';
9
9
 
@@ -34,6 +34,7 @@ const InputCell = ({
34
34
  Input,
35
35
  {
36
36
  ...editProps,
37
+ bordered: true,
37
38
  className: cx(classBase, {
38
39
  [`${classBase}-error`]: warningMessage !== void 0
39
40
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"InputCell.js","sources":["../../../../../packages/vuu-table/src/cell-renderers/input-cell/InputCell.tsx"],"sourcesContent":["import { TableCellRendererProps } from \"@vuu-ui/vuu-table-types\";\nimport { registerComponent } from \"@vuu-ui/vuu-utils\";\nimport { Input } from \"@salt-ds/core\";\nimport { useEditableText } from \"@vuu-ui/vuu-ui-controls\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\n\nimport inputCellCss from \"./InputCell.css\";\n\nconst classBase = \"vuuTableInputCell\";\n\nexport const InputCell = ({\n column,\n columnMap,\n onEdit,\n row,\n}: TableCellRendererProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-input-cell\",\n css: inputCellCss,\n window: targetWindow,\n });\n\n const dataIdx = columnMap[column.name];\n const dataValue = row[dataIdx] as number | string;\n const { align = \"left\", clientSideEditValidationCheck } = column;\n\n const { warningMessage, ...editProps } = useEditableText({\n value: dataValue,\n onEdit,\n clientSideEditValidationCheck,\n });\n\n const endAdornment =\n warningMessage && align === \"left\" ? (\n <span className={`${classBase}-icon`} data-icon=\"error\" />\n ) : undefined;\n\n const startAdornment =\n warningMessage && align === \"right\" ? (\n <span className={`${classBase}-icon`} data-icon=\"error\" />\n ) : undefined;\n\n return (\n <Input\n {...editProps}\n className={cx(classBase, {\n [`${classBase}-error`]: warningMessage !== undefined,\n })}\n endAdornment={endAdornment}\n startAdornment={startAdornment}\n />\n );\n};\n\nregisterComponent(\"input-cell\", InputCell, \"cell-renderer\", {\n userCanAssign: false,\n});\n"],"names":[],"mappings":";;;;;;;;;AAUA,MAAM,SAAY,GAAA,mBAAA;AAEX,MAAM,YAAY,CAAC;AAAA,EACxB,MAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAA8B,KAAA;AAC5B,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAA,YAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,OAAA,GAAU,SAAU,CAAA,MAAA,CAAO,IAAI,CAAA;AACrC,EAAM,MAAA,SAAA,GAAY,IAAI,OAAO,CAAA;AAC7B,EAAA,MAAM,EAAE,KAAA,GAAQ,MAAQ,EAAA,6BAAA,EAAkC,GAAA,MAAA;AAE1D,EAAA,MAAM,EAAE,cAAA,EAAgB,GAAG,SAAA,KAAc,eAAgB,CAAA;AAAA,IACvD,KAAO,EAAA,SAAA;AAAA,IACP,MAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,YACJ,GAAA,cAAA,IAAkB,KAAU,KAAA,MAAA,mBACzB,GAAA,CAAA,MAAA,EAAA,EAAK,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,KAAA,CAAA,EAAS,WAAU,EAAA,OAAA,EAAQ,CACtD,GAAA,KAAA,CAAA;AAEN,EAAA,MAAM,cACJ,GAAA,cAAA,IAAkB,KAAU,KAAA,OAAA,mBACzB,GAAA,CAAA,MAAA,EAAA,EAAK,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,KAAA,CAAA,EAAS,WAAU,EAAA,OAAA,EAAQ,CACtD,GAAA,KAAA,CAAA;AAEN,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,MACJ,SAAA,EAAW,GAAG,SAAW,EAAA;AAAA,QACvB,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,cAAmB,KAAA,KAAA;AAAA,OAC5C,CAAA;AAAA,MACD,YAAA;AAAA,MACA;AAAA;AAAA,GACF;AAEJ;AAEA,iBAAkB,CAAA,YAAA,EAAc,WAAW,eAAiB,EAAA;AAAA,EAC1D,aAAe,EAAA;AACjB,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"InputCell.js","sources":["../../../../../packages/vuu-table/src/cell-renderers/input-cell/InputCell.tsx"],"sourcesContent":["import { Input } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { TableCellRendererProps } from \"@vuu-ui/vuu-table-types\";\nimport { useEditableText } from \"@vuu-ui/vuu-ui-controls\";\nimport { registerComponent } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\n\nimport inputCellCss from \"./InputCell.css\";\n\nconst classBase = \"vuuTableInputCell\";\n\nexport const InputCell = ({\n column,\n columnMap,\n onEdit,\n row,\n}: TableCellRendererProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-input-cell\",\n css: inputCellCss,\n window: targetWindow,\n });\n\n const dataIdx = columnMap[column.name];\n const dataValue = row[dataIdx] as number | string;\n const { align = \"left\", clientSideEditValidationCheck } = column;\n\n const { warningMessage, ...editProps } = useEditableText({\n value: dataValue,\n onEdit,\n clientSideEditValidationCheck,\n });\n\n const endAdornment =\n warningMessage && align === \"left\" ? (\n <span className={`${classBase}-icon`} data-icon=\"error\" />\n ) : undefined;\n\n const startAdornment =\n warningMessage && align === \"right\" ? (\n <span className={`${classBase}-icon`} data-icon=\"error\" />\n ) : undefined;\n\n return (\n <Input\n {...editProps}\n bordered\n className={cx(classBase, {\n [`${classBase}-error`]: warningMessage !== undefined,\n })}\n endAdornment={endAdornment}\n startAdornment={startAdornment}\n />\n );\n};\n\nregisterComponent(\"input-cell\", InputCell, \"cell-renderer\", {\n userCanAssign: false,\n});\n"],"names":[],"mappings":";;;;;;;;;AAUA,MAAM,SAAY,GAAA,mBAAA;AAEX,MAAM,YAAY,CAAC;AAAA,EACxB,MAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAA8B,KAAA;AAC5B,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAA,YAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,OAAA,GAAU,SAAU,CAAA,MAAA,CAAO,IAAI,CAAA;AACrC,EAAM,MAAA,SAAA,GAAY,IAAI,OAAO,CAAA;AAC7B,EAAA,MAAM,EAAE,KAAA,GAAQ,MAAQ,EAAA,6BAAA,EAAkC,GAAA,MAAA;AAE1D,EAAA,MAAM,EAAE,cAAA,EAAgB,GAAG,SAAA,KAAc,eAAgB,CAAA;AAAA,IACvD,KAAO,EAAA,SAAA;AAAA,IACP,MAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,YACJ,GAAA,cAAA,IAAkB,KAAU,KAAA,MAAA,mBACzB,GAAA,CAAA,MAAA,EAAA,EAAK,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,KAAA,CAAA,EAAS,WAAU,EAAA,OAAA,EAAQ,CACtD,GAAA,KAAA,CAAA;AAEN,EAAA,MAAM,cACJ,GAAA,cAAA,IAAkB,KAAU,KAAA,OAAA,mBACzB,GAAA,CAAA,MAAA,EAAA,EAAK,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,KAAA,CAAA,EAAS,WAAU,EAAA,OAAA,EAAQ,CACtD,GAAA,KAAA,CAAA;AAEN,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,MACJ,QAAQ,EAAA,IAAA;AAAA,MACR,SAAA,EAAW,GAAG,SAAW,EAAA;AAAA,QACvB,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG,cAAmB,KAAA,KAAA;AAAA,OAC5C,CAAA;AAAA,MACD,YAAA;AAAA,MACA;AAAA;AAAA,GACF;AAEJ;AAEA,iBAAkB,CAAA,YAAA,EAAc,WAAW,eAAiB,EAAA;AAAA,EAC1D,aAAe,EAAA;AACjB,CAAC,CAAA;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { dispatchCustomEvent, dataColumnAndKeyUnchanged, registerComponent, isTypeDescriptor, isValueListRenderer } from '@vuu-ui/vuu-utils';
2
+ import { isRpcSuccess, dispatchCustomEvent, dataColumnAndKeyUnchanged, registerComponent, isTypeDescriptor, isValueListRenderer } from '@vuu-ui/vuu-utils';
3
3
  import { useComponentCssInjection } from '@salt-ds/styles';
4
4
  import { useWindow } from '@salt-ds/window';
5
5
  import cx from 'clsx';
@@ -38,7 +38,7 @@ const ToggleCell = memo(function ToggleCell2({
38
38
  { previousValue: value, value: newValue },
39
39
  "commit"
40
40
  );
41
- if (res === true) {
41
+ if (isRpcSuccess(res)) {
42
42
  dispatchCustomEvent(evt.target, "vuu-commit");
43
43
  }
44
44
  return res;
@@ -1 +1 @@
1
- {"version":3,"file":"ToggleCell.js","sources":["../../../../../packages/vuu-table/src/cell-renderers/toggle-cell/ToggleCell.tsx"],"sourcesContent":["import {\n ColumnDescriptor,\n TableCellRendererProps,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n CommitHandler,\n dataColumnAndKeyUnchanged,\n dispatchCustomEvent,\n isTypeDescriptor,\n isValueListRenderer,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\n\nimport { memo, useCallback } from \"react\";\nimport { CycleStateButton } from \"@vuu-ui/vuu-ui-controls\";\n\nimport toggleCellCss from \"./ToggleCell.css\";\n\nconst classBase = \"vuuTableToggleCell\";\n\nconst getValueList = ({ name, type }: ColumnDescriptor) => {\n if (isTypeDescriptor(type) && isValueListRenderer(type.renderer)) {\n return type.renderer.values;\n } else {\n throw Error(\n `useLookupValues column ${name} has not been configured with a values list`,\n );\n }\n};\n\nexport const ToggleCell = memo(function ToggleCell({\n column,\n columnMap,\n onEdit,\n row,\n}: TableCellRendererProps) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toggle-cell\",\n css: toggleCellCss,\n window: targetWindow,\n });\n\n const values = getValueList(column);\n const dataIdx = columnMap[column.name];\n const value = row[dataIdx] as string;\n\n const handleCommit = useCallback<CommitHandler<HTMLButtonElement>>(\n async (evt, newValue) => {\n const res = await onEdit?.(\n { previousValue: value, value: newValue },\n \"commit\",\n );\n if (res === true) {\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-commit\");\n }\n return res;\n },\n [onEdit, value],\n );\n\n return (\n <CycleStateButton\n className={cx(classBase, `${classBase}-${column.name}`)}\n onCommit={handleCommit}\n value={value}\n values={values}\n variant=\"cta\"\n >\n {value}\n </CycleStateButton>\n );\n}, dataColumnAndKeyUnchanged);\n\nregisterComponent(\"toggle-cell\", ToggleCell, \"cell-renderer\", {\n userCanAssign: false,\n});\n"],"names":["ToggleCell"],"mappings":";;;;;;;;;AAqBA,MAAM,SAAY,GAAA,oBAAA;AAElB,MAAM,YAAe,GAAA,CAAC,EAAE,IAAA,EAAM,MAA6B,KAAA;AACzD,EAAA,IAAI,iBAAiB,IAAI,CAAA,IAAK,mBAAoB,CAAA,IAAA,CAAK,QAAQ,CAAG,EAAA;AAChE,IAAA,OAAO,KAAK,QAAS,CAAA,MAAA;AAAA,GAChB,MAAA;AACL,IAAM,MAAA,KAAA;AAAA,MACJ,0BAA0B,IAAI,CAAA,2CAAA;AAAA,KAChC;AAAA;AAEJ,CAAA;AAEa,MAAA,UAAA,GAAa,IAAK,CAAA,SAASA,WAAW,CAAA;AAAA,EACjD,MAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAA2B,EAAA;AACzB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,iBAAA;AAAA,IACR,GAAK,EAAA,aAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,MAAA,GAAS,aAAa,MAAM,CAAA;AAClC,EAAM,MAAA,OAAA,GAAU,SAAU,CAAA,MAAA,CAAO,IAAI,CAAA;AACrC,EAAM,MAAA,KAAA,GAAQ,IAAI,OAAO,CAAA;AAEzB,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,OAAO,KAAK,QAAa,KAAA;AACvB,MAAA,MAAM,MAAM,MAAM,MAAA;AAAA,QAChB,EAAE,aAAA,EAAe,KAAO,EAAA,KAAA,EAAO,QAAS,EAAA;AAAA,QACxC;AAAA,OACF;AACA,MAAA,IAAI,QAAQ,IAAM,EAAA;AAChB,QAAoB,mBAAA,CAAA,GAAA,CAAI,QAAuB,YAAY,CAAA;AAAA;AAE7D,MAAO,OAAA,GAAA;AAAA,KACT;AAAA,IACA,CAAC,QAAQ,KAAK;AAAA,GAChB;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,gBAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,GAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAI,CAAA,EAAA,MAAA,CAAO,IAAI,CAAE,CAAA,CAAA;AAAA,MACtD,QAAU,EAAA,YAAA;AAAA,MACV,KAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAQ,EAAA,KAAA;AAAA,MAEP,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ,CAAA,EAAG,yBAAyB;AAE5B,iBAAkB,CAAA,aAAA,EAAe,YAAY,eAAiB,EAAA;AAAA,EAC5D,aAAe,EAAA;AACjB,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"ToggleCell.js","sources":["../../../../../packages/vuu-table/src/cell-renderers/toggle-cell/ToggleCell.tsx"],"sourcesContent":["import {\n ColumnDescriptor,\n TableCellRendererProps,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n CommitHandler,\n dataColumnAndKeyUnchanged,\n dispatchCustomEvent,\n isRpcSuccess,\n isTypeDescriptor,\n isValueListRenderer,\n registerComponent,\n} from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\n\nimport { memo, useCallback } from \"react\";\nimport { CycleStateButton } from \"@vuu-ui/vuu-ui-controls\";\n\nimport toggleCellCss from \"./ToggleCell.css\";\n\nconst classBase = \"vuuTableToggleCell\";\n\nconst getValueList = ({ name, type }: ColumnDescriptor) => {\n if (isTypeDescriptor(type) && isValueListRenderer(type.renderer)) {\n return type.renderer.values;\n } else {\n throw Error(\n `useLookupValues column ${name} has not been configured with a values list`,\n );\n }\n};\n\nexport const ToggleCell = memo(function ToggleCell({\n column,\n columnMap,\n onEdit,\n row,\n}: TableCellRendererProps) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toggle-cell\",\n css: toggleCellCss,\n window: targetWindow,\n });\n\n const values = getValueList(column);\n const dataIdx = columnMap[column.name];\n const value = row[dataIdx] as string;\n\n const handleCommit = useCallback<CommitHandler<HTMLButtonElement>>(\n async (evt, newValue) => {\n const res = await onEdit?.(\n { previousValue: value, value: newValue },\n \"commit\",\n );\n if (isRpcSuccess(res)) {\n dispatchCustomEvent(evt.target as HTMLElement, \"vuu-commit\");\n }\n return res;\n },\n [onEdit, value],\n );\n\n return (\n <CycleStateButton\n className={cx(classBase, `${classBase}-${column.name}`)}\n onCommit={handleCommit}\n value={value}\n values={values}\n variant=\"cta\"\n >\n {value}\n </CycleStateButton>\n );\n}, dataColumnAndKeyUnchanged);\n\nregisterComponent(\"toggle-cell\", ToggleCell, \"cell-renderer\", {\n userCanAssign: false,\n});\n"],"names":["ToggleCell"],"mappings":";;;;;;;;;AAsBA,MAAM,SAAY,GAAA,oBAAA;AAElB,MAAM,YAAe,GAAA,CAAC,EAAE,IAAA,EAAM,MAA6B,KAAA;AACzD,EAAA,IAAI,iBAAiB,IAAI,CAAA,IAAK,mBAAoB,CAAA,IAAA,CAAK,QAAQ,CAAG,EAAA;AAChE,IAAA,OAAO,KAAK,QAAS,CAAA,MAAA;AAAA,GAChB,MAAA;AACL,IAAM,MAAA,KAAA;AAAA,MACJ,0BAA0B,IAAI,CAAA,2CAAA;AAAA,KAChC;AAAA;AAEJ,CAAA;AAEa,MAAA,UAAA,GAAa,IAAK,CAAA,SAASA,WAAW,CAAA;AAAA,EACjD,MAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAA2B,EAAA;AACzB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,iBAAA;AAAA,IACR,GAAK,EAAA,aAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,MAAA,GAAS,aAAa,MAAM,CAAA;AAClC,EAAM,MAAA,OAAA,GAAU,SAAU,CAAA,MAAA,CAAO,IAAI,CAAA;AACrC,EAAM,MAAA,KAAA,GAAQ,IAAI,OAAO,CAAA;AAEzB,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,OAAO,KAAK,QAAa,KAAA;AACvB,MAAA,MAAM,MAAM,MAAM,MAAA;AAAA,QAChB,EAAE,aAAA,EAAe,KAAO,EAAA,KAAA,EAAO,QAAS,EAAA;AAAA,QACxC;AAAA,OACF;AACA,MAAI,IAAA,YAAA,CAAa,GAAG,CAAG,EAAA;AACrB,QAAoB,mBAAA,CAAA,GAAA,CAAI,QAAuB,YAAY,CAAA;AAAA;AAE7D,MAAO,OAAA,GAAA;AAAA,KACT;AAAA,IACA,CAAC,QAAQ,KAAK;AAAA,GAChB;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,gBAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,GAAG,SAAW,EAAA,CAAA,EAAG,SAAS,CAAI,CAAA,EAAA,MAAA,CAAO,IAAI,CAAE,CAAA,CAAA;AAAA,MACtD,QAAU,EAAA,YAAA;AAAA,MACV,KAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAQ,EAAA,KAAA;AAAA,MAEP,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ,CAAA,EAAG,yBAAyB;AAE5B,iBAAkB,CAAA,aAAA,EAAe,YAAY,eAAiB,EAAA;AAAA,EAC5D,aAAe,EAAA;AACjB,CAAC,CAAA;;;;"}
@@ -1,4 +1,4 @@
1
- var headerCellCss = ".vuu-theme {\n --svg-spinner: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\"><path fill=\"rgb(38, 112, 169)\" d=\"M73,50c0-12.7-10.3-23-23-23S27,37.3,27,50 M30.9,50c0-10.5,8.5-19.1,19.1-19.1S69.1,39.5,69.1,50\"><animateTransform attributeName=\"transform\" attributeType=\"XML\" type=\"rotate\" dur=\"1s\" from=\"0 50 50\" to=\"360 50 50\" repeatCount=\"indefinite\" /></path></svg>');\n}\n\n.vuuTableGroupHeaderCell {\n --vuuColumnHeaderPill-margin: 0;\n --cell-align: \"flex-start\";\n text-align: left;\n cursor: default;\n /* ensure header row sits atop everything else when scrolling down */\n\n --vuuColumnHeaderPill-margin: 0;\n --vuuColumnHeaderPill-flex: 0 0 24px;\n\n align-items: center;\n background-color: var(\n --vuuTableHeaderCell-background,\n var(--table-background)\n );\n border-bottom: none;\n border-right-color: var(--cell-borderColor);\n border-right-style: solid;\n border-right-width: 1px;\n box-sizing: border-box;\n display: inline-flex;\n gap: 4px;\n height: 100%;\n padding: 0 12px 0 4px;\n position: relative;\n vertical-align: top;\n\n &.vuuPinLeft,\n &.vuuPinRight {\n background-color: var(\n --vuuTableHeaderCell-background,\n var(--table-background)\n );\n }\n}\n\n.vuuTableGroupHeaderCell-inner {\n align-items: center;\n display: flex;\n gap: 4px;\n height: 100%;\n padding-left: 1px;\n}\n\n.vuuTableGroupHeaderCell-col {\n align-items: center;\n background-color: inherit;\n display: inline-flex;\n flex: 0 1 auto;\n height: calc(var(--vuuTableHeaderHeight) - 2px);\n justify-content: space-between;\n padding-right: 8px;\n position: relative;\n}\n\n.vuuTableGroupHeaderCell-label {\n align-items: center;\n display: flex;\n flex: 0 0 auto;\n}\n\n.vuuTableGroupHeaderCell-close {\n --vuu-icon-height: 18px;\n --vuu-icon-width: 18px;\n cursor: pointer;\n left: 3px;\n}\n\n.vuuTableGroupHeaderCell-resizing {\n --columnResizer-color: var(--salt-color-blue-500);\n --columnResizer-height: var(--table-height);\n --columnResizer-width: 2px;\n}\n.vuuTableGroupHeaderCell-pending {\n --pending-content: \"\";\n}\n\n.vuuTableGroupHeaderCell-col:has(+ .vuuColumnResizer):after {\n content: var(--pending-content);\n width: 24px;\n height: 24px;\n background-image: var(--svg-spinner);\n background-repeat: no-repeat;\n background-size: cover;\n}\n\n.vuuTableGroupHeaderCell:focus {\n outline: var(\n --vuuTableCell-outline,\n solid var(--salt-focused-outlineColor) 2px\n );\n outline-offset: -2px;\n /** This is to achieve a white background to outline dashes */\n box-shadow: inset 0 0 0 var(--cell-outline-width) white;\n border-bottom: none;\n}\n";
1
+ var headerCellCss = ".vuu-theme-deprecated {\n --svg-spinner: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\"><path fill=\"rgb(38, 112, 169)\" d=\"M73,50c0-12.7-10.3-23-23-23S27,37.3,27,50 M30.9,50c0-10.5,8.5-19.1,19.1-19.1S69.1,39.5,69.1,50\"><animateTransform attributeName=\"transform\" attributeType=\"XML\" type=\"rotate\" dur=\"1s\" from=\"0 50 50\" to=\"360 50 50\" repeatCount=\"indefinite\" /></path></svg>');\n}\n\n.vuuTableGroupHeaderCell {\n --vuuColumnHeaderPill-margin: 0;\n --cell-align: \"flex-start\";\n text-align: left;\n cursor: default;\n /* ensure header row sits atop everything else when scrolling down */\n\n --vuuColumnHeaderPill-margin: 0;\n --vuuColumnHeaderPill-flex: 0 0 24px;\n\n align-items: center;\n background-color: var(\n --vuuTableHeaderCell-background,\n var(--table-background)\n );\n border-bottom: none;\n border-right-color: var(--cell-borderColor);\n border-right-style: solid;\n border-right-width: 1px;\n box-sizing: border-box;\n display: inline-flex;\n gap: 4px;\n height: 100%;\n padding: 0 12px 0 4px;\n position: relative;\n vertical-align: top;\n\n &.vuuPinLeft,\n &.vuuPinRight {\n background-color: var(\n --vuuTableHeaderCell-background,\n var(--table-background)\n );\n }\n}\n\n.vuuTableGroupHeaderCell-inner {\n align-items: center;\n display: flex;\n gap: 4px;\n height: 100%;\n padding-left: 1px;\n}\n\n.vuuTableGroupHeaderCell-col {\n align-items: center;\n background-color: inherit;\n display: inline-flex;\n flex: 0 1 auto;\n height: calc(var(--vuuTableHeaderHeight) - 2px);\n justify-content: space-between;\n padding-right: 8px;\n position: relative;\n}\n\n.vuuTableGroupHeaderCell-label {\n align-items: center;\n display: flex;\n flex: 0 0 auto;\n}\n\n.vuuTableGroupHeaderCell-close {\n --vuu-icon-height: 18px;\n --vuu-icon-width: 18px;\n cursor: pointer;\n left: 3px;\n}\n\n.vuuTableGroupHeaderCell-resizing {\n --columnResizer-color: var(--salt-color-blue-500);\n --columnResizer-height: var(--table-height);\n --columnResizer-width: 2px;\n}\n.vuuTableGroupHeaderCell-pending {\n --pending-content: \"\";\n}\n\n.vuuTableGroupHeaderCell-col:has(+ .vuuColumnResizer):after {\n content: var(--pending-content);\n width: 24px;\n height: 24px;\n background-image: var(--svg-spinner);\n background-repeat: no-repeat;\n background-size: cover;\n}\n\n.vuuTableGroupHeaderCell:focus {\n outline: var(\n --vuuTableCell-outline,\n solid var(--salt-focused-outlineColor) 2px\n );\n outline-offset: -2px;\n /** This is to achieve a white background to outline dashes */\n box-shadow: inset 0 0 0 var(--cell-outline-width) white;\n border-bottom: none;\n}\n";
2
2
 
3
3
  export { headerCellCss as default };
4
4
  //# sourceMappingURL=GroupHeaderCell.css.js.map
@@ -1,4 +1,4 @@
1
- var tableCellCss = ".vuuTableCell {\n border-right-color: var(--cell-borderColor);\n border-right-style: solid;\n border-right-width: 1px;\n /* unfortunately inline-flex doesn't play nice with text-overflow ellipsis */\n display: inline-block;\n white-space: nowrap;\n height: 100%;\n outline-offset: -2px;\n overflow: hidden;\n padding: var(--vuuTableCell-padding, 0 11px 0 8px);\n text-overflow: ellipsis;\n vertical-align: top;\n}\n\n.vuuTableCell-right {\n text-align: right;\n}\n\n.vuuTableCell-editable {\n align-items: center;\n display: inline-flex;\n text-overflow: unset;\n}\n\n.vuuTableCell:focus {\n outline: var(\n --vuuTableCell-outline,\n solid var(--salt-focused-outlineColor) 2px\n );\n /** This is to achieve a white background to outline dashes */\n box-shadow: inset 0 0 0 var(--cell-outline-width) white;\n border-bottom: none;\n}\n\n.vuuTableRow-selected .vuuTableCell:not(.vuuTableCell-editable):focus {\n outline: var(\n --vuuTableCell-outline,\n solid var(--salt-focused-outlineColor) 2px\n );\n\n &:has(.vuuCheckboxRowSelector) {\n outline: none;\n }\n}\n.vuuTableCell-editable:focus {\n outline: none;\n}\n\n.vuuTableCell.ContextOpen {\n outline: var(\n --vuuTableCell-outline,\n solid var(--vuuTableCell-contextOpen-outlineColor, var(--salt-focused-outlineColor)) 2px\n );\n}\n";
1
+ var tableCellCss = ".vuuTableCell {\n border-right-color: var(--cell-borderColor);\n border-right-style: solid;\n border-right-width: 1px;\n /* unfortunately inline-flex doesn't play nice with text-overflow ellipsis */\n display: inline-block;\n white-space: nowrap;\n height: 100%;\n outline-offset: -2px;\n overflow: hidden;\n padding: var(--vuuTableCell-padding, 0 11px 0 8px);\n text-overflow: ellipsis;\n vertical-align: top;\n}\n\n.vuuTableCell-right {\n text-align: right;\n}\n\n.vuuTableCell-editable {\n align-items: center;\n display: inline-flex;\n padding: 0px 1px 0 2px;\n}\n\n.vuuTableCell-editable:focus-within,\n.vuuTableCell:focus {\n outline: var(\n --vuuTableCell-outline,\n solid var(--salt-focused-outlineColor) 2px\n );\n /** This is to achieve a white background to outline dashes */\n box-shadow: inset 0 0 0 var(--cell-outline-width) white;\n border-bottom: none;\n}\n\n.vuuTableCell-editable.vuuEditing {\n outline: var(\n --vuuTableCell-outline,\n dotted var(--salt-focused-outlineColor) 2px\n );\n\n}\n\n.vuuTableRow-selected .vuuTableCell:not(.vuuTableCell-editable):focus {\n outline: var(\n --vuuTableCell-outline,\n solid var(--salt-focused-outlineColor) 2px\n );\n\n &:has(.vuuCheckboxRowSelector) {\n outline: none;\n }\n}\n.vuuTableCell-editable:focus {\n outline: none;\n}\n\n.vuuTableCell.ContextOpen {\n outline: var(\n --vuuTableCell-outline,\n solid var(--vuuTableCell-contextOpen-outlineColor, var(--salt-focused-outlineColor)) 2px\n );\n}\n";
2
2
 
3
3
  export { tableCellCss as default };
4
4
  //# sourceMappingURL=TableCell.css.js.map
@@ -1,7 +1,7 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { getTypedValue } from '@vuu-ui/vuu-utils';
3
2
  import { useComponentCssInjection } from '@salt-ds/styles';
4
3
  import { useWindow } from '@salt-ds/window';
4
+ import { getTypedValue } from '@vuu-ui/vuu-utils';
5
5
  import { useState, useCallback } from 'react';
6
6
  import { useCell } from '../useCell.js';
7
7
  import { useHighlighting } from '../useHighlighting.js';
@@ -30,30 +30,30 @@ const TableCell = ({
30
30
  (editState, editPhase) => {
31
31
  if (editPhase === "commit") {
32
32
  const { serverDataType = "string" } = column;
33
- if (onDataEdited) {
34
- const typedValue = getTypedValue(
35
- String(editState.value),
36
- serverDataType,
37
- true
38
- );
39
- return onDataEdited({
33
+ const typedValue = getTypedValue(
34
+ String(editState.value),
35
+ serverDataType,
36
+ true
37
+ );
38
+ return onDataEdited?.(
39
+ {
40
40
  ...editState,
41
41
  row,
42
42
  columnName: column.name,
43
43
  value: typedValue
44
- });
45
- } else {
46
- throw Error(
47
- "TableCell onDataEdited prop not supplied for an editable cell"
48
- );
49
- }
44
+ },
45
+ editPhase
46
+ );
50
47
  } else {
51
48
  setHasError(editState.isValid === false);
52
- onDataEdited({
53
- ...editState,
54
- row,
55
- columnName: column.name
56
- });
49
+ onDataEdited?.(
50
+ {
51
+ ...editState,
52
+ row,
53
+ columnName: column.name
54
+ },
55
+ editPhase
56
+ );
57
57
  return void 0;
58
58
  }
59
59
  },
@@ -1 +1 @@
1
- {"version":3,"file":"TableCell.js","sources":["../../../../packages/vuu-table/src/table-cell/TableCell.tsx"],"sourcesContent":["import type {\n DataItemEditHandler,\n TableCellProps,\n} from \"@vuu-ui/vuu-table-types\";\nimport { getTypedValue } from \"@vuu-ui/vuu-utils\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { MouseEventHandler, useCallback, useState } from \"react\";\nimport { useCell } from \"../useCell\";\nimport { useHighlighting } from \"../useHighlighting\";\n\nimport tableCellCss from \"./TableCell.css\";\n\nconst classBase = \"vuuTableCell\";\n\nexport const TableCell = ({\n column,\n columnMap,\n onClick,\n onDataEdited,\n row,\n searchPattern = \"\",\n}: TableCellProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-table-cell\",\n css: tableCellCss,\n window: targetWindow,\n });\n\n const [hasError, setHasError] = useState(false);\n\n const { className, style } = useCell(column, classBase, false, hasError);\n const { ariaColIndex, CellRenderer, valueFormatter } = column;\n const dataIdx = columnMap[column.name];\n\n const handleDataItemEdited = useCallback<DataItemEditHandler>(\n (editState, editPhase) => {\n if (editPhase === \"commit\") {\n const { serverDataType = \"string\" } = column;\n if (onDataEdited) {\n const typedValue = getTypedValue(\n String(editState.value),\n serverDataType,\n true,\n );\n return onDataEdited({\n ...editState,\n row,\n columnName: column.name,\n value: typedValue,\n });\n } else {\n throw Error(\n \"TableCell onDataEdited prop not supplied for an editable cell\",\n );\n }\n } else {\n setHasError(editState.isValid === false);\n onDataEdited({\n ...editState,\n row,\n columnName: column.name,\n });\n return undefined;\n }\n },\n [column, onDataEdited, row],\n );\n\n const handleClick = useCallback<MouseEventHandler>(\n (evt) => {\n onClick?.(evt, column);\n },\n [column, onClick],\n );\n\n const value = valueFormatter(row[dataIdx]);\n const valueWithHighlighting = useHighlighting(value, searchPattern);\n\n return (\n <div\n aria-colindex={ariaColIndex}\n className={className}\n onClick={onClick ? handleClick : undefined}\n role=\"cell\"\n style={style}\n >\n {CellRenderer ? (\n <CellRenderer\n column={column}\n columnMap={columnMap}\n onEdit={handleDataItemEdited}\n row={row}\n searchPattern={searchPattern}\n />\n ) : (\n valueWithHighlighting\n )}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAaA,MAAM,SAAY,GAAA,cAAA;AAEX,MAAM,YAAY,CAAC;AAAA,EACxB,MAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,GAAA;AAAA,EACA,aAAgB,GAAA;AAClB,CAAsB,KAAA;AACpB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAA,YAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAE9C,EAAM,MAAA,EAAE,WAAW,KAAM,EAAA,GAAI,QAAQ,MAAQ,EAAA,SAAA,EAAW,OAAO,QAAQ,CAAA;AACvE,EAAA,MAAM,EAAE,YAAA,EAAc,YAAc,EAAA,cAAA,EAAmB,GAAA,MAAA;AACvD,EAAM,MAAA,OAAA,GAAU,SAAU,CAAA,MAAA,CAAO,IAAI,CAAA;AAErC,EAAA,MAAM,oBAAuB,GAAA,WAAA;AAAA,IAC3B,CAAC,WAAW,SAAc,KAAA;AACxB,MAAA,IAAI,cAAc,QAAU,EAAA;AAC1B,QAAM,MAAA,EAAE,cAAiB,GAAA,QAAA,EAAa,GAAA,MAAA;AACtC,QAAA,IAAI,YAAc,EAAA;AAChB,UAAA,MAAM,UAAa,GAAA,aAAA;AAAA,YACjB,MAAA,CAAO,UAAU,KAAK,CAAA;AAAA,YACtB,cAAA;AAAA,YACA;AAAA,WACF;AACA,UAAA,OAAO,YAAa,CAAA;AAAA,YAClB,GAAG,SAAA;AAAA,YACH,GAAA;AAAA,YACA,YAAY,MAAO,CAAA,IAAA;AAAA,YACnB,KAAO,EAAA;AAAA,WACR,CAAA;AAAA,SACI,MAAA;AACL,UAAM,MAAA,KAAA;AAAA,YACJ;AAAA,WACF;AAAA;AACF,OACK,MAAA;AACL,QAAY,WAAA,CAAA,SAAA,CAAU,YAAY,KAAK,CAAA;AACvC,QAAa,YAAA,CAAA;AAAA,UACX,GAAG,SAAA;AAAA,UACH,GAAA;AAAA,UACA,YAAY,MAAO,CAAA;AAAA,SACpB,CAAA;AACD,QAAO,OAAA,KAAA,CAAA;AAAA;AACT,KACF;AAAA,IACA,CAAC,MAAQ,EAAA,YAAA,EAAc,GAAG;AAAA,GAC5B;AAEA,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,CAAC,GAAQ,KAAA;AACP,MAAA,OAAA,GAAU,KAAK,MAAM,CAAA;AAAA,KACvB;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,GAClB;AAEA,EAAA,MAAM,KAAQ,GAAA,cAAA,CAAe,GAAI,CAAA,OAAO,CAAC,CAAA;AACzC,EAAM,MAAA,qBAAA,GAAwB,eAAgB,CAAA,KAAA,EAAO,aAAa,CAAA;AAElE,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,eAAe,EAAA,YAAA;AAAA,MACf,SAAA;AAAA,MACA,OAAA,EAAS,UAAU,WAAc,GAAA,KAAA,CAAA;AAAA,MACjC,IAAK,EAAA,MAAA;AAAA,MACL,KAAA;AAAA,MAEC,QACC,EAAA,YAAA,mBAAA,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,SAAA;AAAA,UACA,MAAQ,EAAA,oBAAA;AAAA,UACR,GAAA;AAAA,UACA;AAAA;AAAA,OAGF,GAAA;AAAA;AAAA,GAEJ;AAEJ;;;;"}
1
+ {"version":3,"file":"TableCell.js","sources":["../../../../packages/vuu-table/src/table-cell/TableCell.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport type {\n TableCellEditHandler,\n TableCellProps,\n} from \"@vuu-ui/vuu-table-types\";\nimport { getTypedValue } from \"@vuu-ui/vuu-utils\";\nimport { MouseEventHandler, useCallback, useState } from \"react\";\nimport { useCell } from \"../useCell\";\nimport { useHighlighting } from \"../useHighlighting\";\n\nimport tableCellCss from \"./TableCell.css\";\n\nconst classBase = \"vuuTableCell\";\n\nexport const TableCell = ({\n column,\n columnMap,\n onClick,\n onDataEdited,\n row,\n searchPattern = \"\",\n}: TableCellProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-table-cell\",\n css: tableCellCss,\n window: targetWindow,\n });\n\n const [hasError, setHasError] = useState(false);\n\n const { className, style } = useCell(column, classBase, false, hasError);\n const { ariaColIndex, CellRenderer, valueFormatter } = column;\n const dataIdx = columnMap[column.name];\n\n const handleDataItemEdited = useCallback<TableCellEditHandler>(\n (editState, editPhase) => {\n if (editPhase === \"commit\") {\n const { serverDataType = \"string\" } = column;\n const typedValue = getTypedValue(\n String(editState.value),\n serverDataType,\n true,\n );\n return onDataEdited?.(\n {\n ...editState,\n row,\n columnName: column.name,\n value: typedValue,\n },\n editPhase,\n );\n } else {\n setHasError(editState.isValid === false);\n onDataEdited?.(\n {\n ...editState,\n row,\n columnName: column.name,\n },\n editPhase,\n );\n return undefined;\n }\n },\n [column, onDataEdited, row],\n );\n\n const handleClick = useCallback<MouseEventHandler>(\n (evt) => {\n onClick?.(evt, column);\n },\n [column, onClick],\n );\n\n const value = valueFormatter(row[dataIdx]);\n const valueWithHighlighting = useHighlighting(value, searchPattern);\n\n return (\n <div\n aria-colindex={ariaColIndex}\n className={className}\n onClick={onClick ? handleClick : undefined}\n role=\"cell\"\n style={style}\n >\n {CellRenderer ? (\n <CellRenderer\n column={column}\n columnMap={columnMap}\n onEdit={handleDataItemEdited}\n row={row}\n searchPattern={searchPattern}\n />\n ) : (\n valueWithHighlighting\n )}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAaA,MAAM,SAAY,GAAA,cAAA;AAEX,MAAM,YAAY,CAAC;AAAA,EACxB,MAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,GAAA;AAAA,EACA,aAAgB,GAAA;AAClB,CAAsB,KAAA;AACpB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAA,YAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAE9C,EAAM,MAAA,EAAE,WAAW,KAAM,EAAA,GAAI,QAAQ,MAAQ,EAAA,SAAA,EAAW,OAAO,QAAQ,CAAA;AACvE,EAAA,MAAM,EAAE,YAAA,EAAc,YAAc,EAAA,cAAA,EAAmB,GAAA,MAAA;AACvD,EAAM,MAAA,OAAA,GAAU,SAAU,CAAA,MAAA,CAAO,IAAI,CAAA;AAErC,EAAA,MAAM,oBAAuB,GAAA,WAAA;AAAA,IAC3B,CAAC,WAAW,SAAc,KAAA;AACxB,MAAA,IAAI,cAAc,QAAU,EAAA;AAC1B,QAAM,MAAA,EAAE,cAAiB,GAAA,QAAA,EAAa,GAAA,MAAA;AACtC,QAAA,MAAM,UAAa,GAAA,aAAA;AAAA,UACjB,MAAA,CAAO,UAAU,KAAK,CAAA;AAAA,UACtB,cAAA;AAAA,UACA;AAAA,SACF;AACA,QAAO,OAAA,YAAA;AAAA,UACL;AAAA,YACE,GAAG,SAAA;AAAA,YACH,GAAA;AAAA,YACA,YAAY,MAAO,CAAA,IAAA;AAAA,YACnB,KAAO,EAAA;AAAA,WACT;AAAA,UACA;AAAA,SACF;AAAA,OACK,MAAA;AACL,QAAY,WAAA,CAAA,SAAA,CAAU,YAAY,KAAK,CAAA;AACvC,QAAA,YAAA;AAAA,UACE;AAAA,YACE,GAAG,SAAA;AAAA,YACH,GAAA;AAAA,YACA,YAAY,MAAO,CAAA;AAAA,WACrB;AAAA,UACA;AAAA,SACF;AACA,QAAO,OAAA,KAAA,CAAA;AAAA;AACT,KACF;AAAA,IACA,CAAC,MAAQ,EAAA,YAAA,EAAc,GAAG;AAAA,GAC5B;AAEA,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,CAAC,GAAQ,KAAA;AACP,MAAA,OAAA,GAAU,KAAK,MAAM,CAAA;AAAA,KACvB;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,GAClB;AAEA,EAAA,MAAM,KAAQ,GAAA,cAAA,CAAe,GAAI,CAAA,OAAO,CAAC,CAAA;AACzC,EAAM,MAAA,qBAAA,GAAwB,eAAgB,CAAA,KAAA,EAAO,aAAa,CAAA;AAElE,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,eAAe,EAAA,YAAA;AAAA,MACf,SAAA;AAAA,MACA,OAAA,EAAS,UAAU,WAAc,GAAA,KAAA,CAAA;AAAA,MACjC,IAAK,EAAA,MAAA;AAAA,MACL,KAAA;AAAA,MAEC,QACC,EAAA,YAAA,mBAAA,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,SAAA;AAAA,UACA,MAAQ,EAAA,oBAAA;AAAA,UACR,GAAA;AAAA,UACA;AAAA;AAAA,OAGF,GAAA;AAAA;AAAA,GAEJ;AAEJ;;;;"}
@@ -104,7 +104,7 @@ const useDataSource = ({
104
104
  `[useDataSource] autoSelect row key ${autoSelect} not in viewport`
105
105
  );
106
106
  }
107
- } else if (message.rows.length > 0) {
107
+ } else {
108
108
  selectRow(message.rows[0]);
109
109
  }
110
110
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useDataSource.js","sources":["../../../../packages/vuu-table/src/table-data-source/useDataSource.ts"],"sourcesContent":["import type {\n DataSourceConfigChangeHandler,\n DataSourceRow,\n DataSourceSubscribeCallback,\n DataSourceSubscribedMessage,\n DataSourceSuspenseProps,\n} from \"@vuu-ui/vuu-data-types\";\nimport { SelectRowRequest, VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { NULL_RANGE, Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { TableProps } from \"../Table\";\nimport { metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { TableRowSelectHandlerInternal } from \"@vuu-ui/vuu-table-types\";\nimport { MovingWindow } from \"./moving-window\";\n\nconst { KEY } = metadataKeys;\n\nexport interface DataSourceHookProps\n extends Pick<\n TableProps,\n | \"autoSelectFirstRow\"\n | \"autoSelectRowKey\"\n | \"dataSource\"\n | \"renderBufferSize\"\n | \"revealSelected\"\n | \"selectionModel\"\n > {\n suspenseProps?: DataSourceSuspenseProps;\n onSelect: TableRowSelectHandlerInternal;\n onSizeChange: (size: number) => void;\n onSubscribed: (subscription: DataSourceSubscribedMessage) => void;\n}\n\nexport const useDataSource = ({\n autoSelectFirstRow,\n autoSelectRowKey,\n dataSource,\n onSizeChange,\n onSubscribed,\n renderBufferSize = 0,\n revealSelected,\n onSelect,\n selectionModel,\n suspenseProps,\n}: DataSourceHookProps) => {\n const [, forceUpdate] = useState<unknown>(null);\n const data = useRef<DataSourceRow[]>([]);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<Range>(NULL_RANGE);\n const totalRowCountRef = useRef(0);\n const rowAutoSelected = useRef(false);\n\n const autoSelect =\n autoSelectRowKey ??\n (autoSelectFirstRow || selectionModel === \"single-no-deselect\");\n\n const handleConfigChange = useCallback<DataSourceConfigChangeHandler>(\n (_config, _range, _confirmed, configChanges) => {\n if (configChanges?.filterChanged) {\n rowAutoSelected.current = false;\n }\n },\n [],\n );\n\n useEffect(() => {\n if (autoSelect) {\n dataSource.on(\"config\", handleConfigChange);\n }\n return () => {\n if (autoSelect) {\n dataSource.removeListener(\"config\", handleConfigChange);\n }\n };\n }, [autoSelect, dataSource, handleConfigChange]);\n\n const dataWindow = useMemo(() => new MovingWindow(NULL_RANGE), []);\n\n useMemo(() => {\n dataSource.on(\"resumed\", () => {\n // When we resume a dataSource (after switching tabs etc)\n // client will receive rows. We may not have received any\n // setRange calls at this point so dataWindow range will\n //not yet be set. If the dataWindow range is already set,\n // this is a no-op.\n const { range } = dataSource;\n if (range.to !== 0) {\n dataWindow.setRange(dataSource.range.withBuffer);\n }\n });\n }, [dataSource, dataWindow]);\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n for (const row of updates) {\n dataWindow.add(row);\n }\n data.current = dataWindow.data;\n if (isMounted.current) {\n // TODO do we ever need to worry about missing updates here ?\n forceUpdate({});\n }\n },\n [dataWindow],\n );\n\n const selectRow = useCallback(\n (row: DataSourceRow) => {\n const rowKey = row[KEY];\n dataSource.select?.({\n preserveExistingSelection: false,\n rowKey,\n type: \"SELECT_ROW\",\n } as SelectRowRequest);\n onSelect?.(row);\n },\n [dataSource, onSelect],\n );\n\n const datasourceMessageHandler: DataSourceSubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n const size = dataWindow.data.length;\n dataWindow.setRowCount(message.size);\n totalRowCountRef.current = message.size;\n\n if (dataWindow.data.length < size) {\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n }\n }\n if (message.rows) {\n setData(message.rows);\n if (autoSelect && rowAutoSelected.current === false) {\n // OR if no selected row in message.rows, e.g after a filter\n rowAutoSelected.current = true;\n if (typeof autoSelect === \"string\") {\n const row = message.rows.find((row) => row[KEY] === autoSelect);\n if (row) {\n selectRow(row);\n } else {\n console.warn(\n `[useDataSource] autoSelect row key ${autoSelect} not in viewport`,\n );\n }\n } else if (message.rows.length > 0) {\n selectRow(message.rows[0]);\n }\n }\n } else if (message.size === 0) {\n setData([]);\n } else if (typeof message.size === \"number\") {\n data.current = dataWindow.data;\n hasUpdated.current = true;\n }\n } else if (message.type === \"viewport-clear\") {\n onSizeChange?.(0);\n dataWindow.setRowCount(0);\n setData([]);\n\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [autoSelect, dataWindow, onSizeChange, onSubscribed, selectRow, setData],\n );\n\n const getSelectedRows = useCallback(() => {\n return dataWindow.getSelectedRows();\n }, [dataWindow]);\n\n useEffect(() => {\n isMounted.current = true;\n if (dataSource.status !== \"initialising\") {\n dataSource.resume?.(datasourceMessageHandler);\n }\n return () => {\n isMounted.current = false;\n dataSource.suspend?.(\n suspenseProps?.escalateToDisable,\n suspenseProps?.escalateDelay,\n );\n };\n }, [dataSource, datasourceMessageHandler, suspenseProps]);\n\n useEffect(() => {\n if (dataSource.status === \"disabled\") {\n dataSource.enable?.(datasourceMessageHandler);\n }\n }, [dataSource, datasourceMessageHandler]);\n\n const setRange = useCallback(\n (viewportRange: VuuRange) => {\n if (!rangeRef.current.equals(viewportRange)) {\n const range = Range(\n viewportRange.from,\n viewportRange.to,\n renderBufferSize,\n );\n\n dataWindow.setRange(range.withBuffer);\n\n if (\n dataSource.status !== \"subscribed\" &&\n dataSource.status !== \"subscribing\"\n ) {\n dataSource?.subscribe(\n {\n range,\n revealSelected,\n selectedKeyValues: autoSelectRowKey\n ? [autoSelectRowKey]\n : undefined,\n },\n datasourceMessageHandler,\n );\n } else {\n dataSource.range = rangeRef.current = range;\n }\n }\n },\n [\n autoSelectRowKey,\n dataSource,\n dataWindow,\n datasourceMessageHandler,\n renderBufferSize,\n revealSelected,\n ],\n );\n\n const removeColumnDataFromCache = useCallback(\n (indexOfRemovedColumn: number) => {\n dataWindow.spliceDataAtIndex(indexOfRemovedColumn);\n data.current = dataWindow.data;\n },\n [dataWindow],\n );\n\n return {\n data: data.current,\n dataRef: data,\n getSelectedRows,\n range: rangeRef.current,\n removeColumnDataFromCache,\n setRange,\n };\n};\n"],"names":["row"],"mappings":"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"}
1
+ {"version":3,"file":"useDataSource.js","sources":["../../../../packages/vuu-table/src/table-data-source/useDataSource.ts"],"sourcesContent":["import type {\n DataSourceConfigChangeHandler,\n DataSourceRow,\n DataSourceSubscribeCallback,\n DataSourceSubscribedMessage,\n DataSourceSuspenseProps,\n} from \"@vuu-ui/vuu-data-types\";\nimport { SelectRowRequest, VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { NULL_RANGE, Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { TableProps } from \"../Table\";\nimport { metadataKeys } from \"@vuu-ui/vuu-utils\";\nimport { TableRowSelectHandlerInternal } from \"@vuu-ui/vuu-table-types\";\nimport { MovingWindow } from \"./moving-window\";\n\nconst { KEY } = metadataKeys;\n\nexport interface DataSourceHookProps\n extends Pick<\n TableProps,\n | \"autoSelectFirstRow\"\n | \"autoSelectRowKey\"\n | \"dataSource\"\n | \"renderBufferSize\"\n | \"revealSelected\"\n | \"selectionModel\"\n > {\n suspenseProps?: DataSourceSuspenseProps;\n onSelect: TableRowSelectHandlerInternal;\n onSizeChange: (size: number) => void;\n onSubscribed: (subscription: DataSourceSubscribedMessage) => void;\n}\n\nexport const useDataSource = ({\n autoSelectFirstRow,\n autoSelectRowKey,\n dataSource,\n onSizeChange,\n onSubscribed,\n renderBufferSize = 0,\n revealSelected,\n onSelect,\n selectionModel,\n suspenseProps,\n}: DataSourceHookProps) => {\n const [, forceUpdate] = useState<unknown>(null);\n const data = useRef<DataSourceRow[]>([]);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<Range>(NULL_RANGE);\n const totalRowCountRef = useRef(0);\n const rowAutoSelected = useRef(false);\n\n const autoSelect =\n autoSelectRowKey ??\n (autoSelectFirstRow || selectionModel === \"single-no-deselect\");\n\n const handleConfigChange = useCallback<DataSourceConfigChangeHandler>(\n (_config, _range, _confirmed, configChanges) => {\n if (configChanges?.filterChanged) {\n rowAutoSelected.current = false;\n }\n },\n [],\n );\n\n useEffect(() => {\n if (autoSelect) {\n dataSource.on(\"config\", handleConfigChange);\n }\n return () => {\n if (autoSelect) {\n dataSource.removeListener(\"config\", handleConfigChange);\n }\n };\n }, [autoSelect, dataSource, handleConfigChange]);\n\n const dataWindow = useMemo(() => new MovingWindow(NULL_RANGE), []);\n\n useMemo(() => {\n dataSource.on(\"resumed\", () => {\n // When we resume a dataSource (after switching tabs etc)\n // client will receive rows. We may not have received any\n // setRange calls at this point so dataWindow range will\n //not yet be set. If the dataWindow range is already set,\n // this is a no-op.\n const { range } = dataSource;\n if (range.to !== 0) {\n dataWindow.setRange(dataSource.range.withBuffer);\n }\n });\n }, [dataSource, dataWindow]);\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n for (const row of updates) {\n dataWindow.add(row);\n }\n data.current = dataWindow.data;\n if (isMounted.current) {\n // TODO do we ever need to worry about missing updates here ?\n forceUpdate({});\n }\n },\n [dataWindow],\n );\n\n const selectRow = useCallback(\n (row: DataSourceRow) => {\n const rowKey = row[KEY];\n dataSource.select?.({\n preserveExistingSelection: false,\n rowKey,\n type: \"SELECT_ROW\",\n } as SelectRowRequest);\n onSelect?.(row);\n },\n [dataSource, onSelect],\n );\n\n const datasourceMessageHandler: DataSourceSubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n const size = dataWindow.data.length;\n dataWindow.setRowCount(message.size);\n totalRowCountRef.current = message.size;\n\n if (dataWindow.data.length < size) {\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n }\n }\n if (message.rows) {\n setData(message.rows);\n if (autoSelect && rowAutoSelected.current === false) {\n // OR if no selected row in message.rows, e.g after a filter\n rowAutoSelected.current = true;\n if (typeof autoSelect === \"string\") {\n const row = message.rows.find((row) => row[KEY] === autoSelect);\n if (row) {\n selectRow(row);\n } else {\n console.warn(\n `[useDataSource] autoSelect row key ${autoSelect} not in viewport`,\n );\n }\n } else {\n selectRow(message.rows[0]);\n }\n }\n } else if (message.size === 0) {\n setData([]);\n } else if (typeof message.size === \"number\") {\n data.current = dataWindow.data;\n hasUpdated.current = true;\n }\n } else if (message.type === \"viewport-clear\") {\n onSizeChange?.(0);\n dataWindow.setRowCount(0);\n setData([]);\n\n if (isMounted.current === false) {\n console.log(\"setting state whilst unmounted\");\n }\n\n forceUpdate({});\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [autoSelect, dataWindow, onSizeChange, onSubscribed, selectRow, setData],\n );\n\n const getSelectedRows = useCallback(() => {\n return dataWindow.getSelectedRows();\n }, [dataWindow]);\n\n useEffect(() => {\n isMounted.current = true;\n if (dataSource.status !== \"initialising\") {\n dataSource.resume?.(datasourceMessageHandler);\n }\n return () => {\n isMounted.current = false;\n dataSource.suspend?.(\n suspenseProps?.escalateToDisable,\n suspenseProps?.escalateDelay,\n );\n };\n }, [dataSource, datasourceMessageHandler, suspenseProps]);\n\n useEffect(() => {\n if (dataSource.status === \"disabled\") {\n dataSource.enable?.(datasourceMessageHandler);\n }\n }, [dataSource, datasourceMessageHandler]);\n\n const setRange = useCallback(\n (viewportRange: VuuRange) => {\n if (!rangeRef.current.equals(viewportRange)) {\n const range = Range(\n viewportRange.from,\n viewportRange.to,\n renderBufferSize,\n );\n\n dataWindow.setRange(range.withBuffer);\n\n if (\n dataSource.status !== \"subscribed\" &&\n dataSource.status !== \"subscribing\"\n ) {\n dataSource?.subscribe(\n {\n range,\n revealSelected,\n selectedKeyValues: autoSelectRowKey\n ? [autoSelectRowKey]\n : undefined,\n },\n datasourceMessageHandler,\n );\n } else {\n dataSource.range = rangeRef.current = range;\n }\n }\n },\n [\n autoSelectRowKey,\n dataSource,\n dataWindow,\n datasourceMessageHandler,\n renderBufferSize,\n revealSelected,\n ],\n );\n\n const removeColumnDataFromCache = useCallback(\n (indexOfRemovedColumn: number) => {\n dataWindow.spliceDataAtIndex(indexOfRemovedColumn);\n data.current = dataWindow.data;\n },\n [dataWindow],\n );\n\n return {\n data: data.current,\n dataRef: data,\n getSelectedRows,\n range: rangeRef.current,\n removeColumnDataFromCache,\n setRange,\n };\n};\n"],"names":["row"],"mappings":"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"}
@@ -1,11 +1,31 @@
1
- import { isCharacterKey } from '@vuu-ui/vuu-utils';
1
+ import { queryClosest, dispatchCustomEvent, isCharacterKey } from '@vuu-ui/vuu-utils';
2
2
  import { useCallback } from 'react';
3
- import { cellIsTextInput } from './table-dom-utils.js';
3
+ import { getAriaCellPos, cellIsTextInput } from './table-dom-utils.js';
4
4
 
5
- const useCellEditing = ({ navigate }) => {
5
+ const useCellEditing = ({
6
+ focusCell,
7
+ navigate
8
+ }) => {
6
9
  const commitHandler = useCallback(() => {
7
10
  navigate();
8
11
  }, [navigate]);
12
+ const editModeHandler = useCallback(
13
+ (e) => {
14
+ const tableCell = queryClosest(
15
+ e.target,
16
+ ".vuuTableCell",
17
+ true
18
+ );
19
+ if (e.type === "vuu-exit-edit-mode") {
20
+ tableCell.classList.remove("vuuEditing");
21
+ const cellPos = getAriaCellPos(tableCell);
22
+ focusCell(cellPos, true);
23
+ } else {
24
+ tableCell.classList.add("vuuEditing");
25
+ }
26
+ },
27
+ [focusCell]
28
+ );
9
29
  const editInput = useCallback(
10
30
  (evt) => {
11
31
  const cellEl = evt.target;
@@ -24,6 +44,7 @@ const useCellEditing = ({ navigate }) => {
24
44
  if (input) {
25
45
  input.focus();
26
46
  input.select();
47
+ dispatchCustomEvent(input, "vuu-begin-edit");
27
48
  }
28
49
  },
29
50
  []
@@ -55,15 +76,19 @@ const useCellEditing = ({ navigate }) => {
55
76
  (e) => {
56
77
  const el = e.target;
57
78
  el.removeEventListener("vuu-commit", commitHandler, true);
79
+ el.removeEventListener("vuu-enter-edit-mode", editModeHandler, true);
80
+ el.removeEventListener("vuu-exit-edit-mode", editModeHandler, true);
58
81
  },
59
- [commitHandler]
82
+ [commitHandler, editModeHandler]
60
83
  );
61
84
  const handleFocus = useCallback(
62
85
  (e) => {
63
86
  const el = e.target;
64
87
  el.addEventListener("vuu-commit", commitHandler, true);
88
+ el.addEventListener("vuu-enter-edit-mode", editModeHandler, true);
89
+ el.addEventListener("vuu-exit-edit-mode", editModeHandler, true);
65
90
  },
66
- [commitHandler]
91
+ [commitHandler, editModeHandler]
67
92
  );
68
93
  return {
69
94
  onBlur: handleBlur,
@@ -1 +1 @@
1
- {"version":3,"file":"useCellEditing.js","sources":["../../../packages/vuu-table/src/useCellEditing.ts"],"sourcesContent":["import { isCharacterKey } from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n KeyboardEvent as ReactKeyboardEvent,\n MouseEvent,\n useCallback,\n} from \"react\";\nimport { cellIsTextInput } from \"./table-dom-utils\";\n\nexport interface CellEditingHookProps {\n navigate: () => void;\n}\n\nexport const useCellEditing = ({ navigate }: CellEditingHookProps) => {\n const commitHandler = useCallback(() => {\n navigate();\n }, [navigate]);\n\n const editInput = useCallback(\n (evt: MouseEvent<HTMLElement> | ReactKeyboardEvent<HTMLElement>) => {\n const cellEl = evt.target as HTMLDivElement;\n const input = cellEl.matches(\"input\")\n ? (cellEl as HTMLInputElement)\n : cellEl.querySelector(\"input\");\n\n if (input) {\n input.focus();\n input.select();\n }\n },\n [],\n );\n\n const focusInput = useCallback(\n (evt: MouseEvent<HTMLElement> | ReactKeyboardEvent<HTMLElement>) => {\n const cellEl = evt.target as HTMLDivElement;\n const input = cellEl.querySelector(\"input\");\n if (input) {\n input.focus();\n input.select();\n }\n },\n [],\n );\n\n const handleKeyDown = useCallback(\n (e: ReactKeyboardEvent<HTMLElement>) => {\n const el = e.target as HTMLElement;\n if (cellIsTextInput(el)) {\n if (isCharacterKey(e.key)) {\n editInput(e);\n } else if (e.key === \"Enter\") {\n focusInput(e);\n }\n }\n },\n [editInput, focusInput],\n );\n\n const handleDoubleClick = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n const el = e.target as HTMLElement;\n if (el.matches(\"input\") || el.querySelector(\"input\")) {\n editInput(e);\n e.stopPropagation();\n }\n },\n [editInput],\n );\n\n const handleBlur = useCallback<FocusEventHandler>(\n (e) => {\n const el = e.target as HTMLElement;\n el.removeEventListener(\"vuu-commit\", commitHandler, true);\n },\n [commitHandler],\n );\n\n const handleFocus = useCallback<FocusEventHandler>(\n (e) => {\n const el = e.target as HTMLElement;\n el.addEventListener(\"vuu-commit\", commitHandler, true);\n },\n [commitHandler],\n );\n\n return {\n onBlur: handleBlur,\n onDoubleClick: handleDoubleClick,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n };\n};\n"],"names":[],"mappings":";;;;AAaO,MAAM,cAAiB,GAAA,CAAC,EAAE,QAAA,EAAqC,KAAA;AACpE,EAAM,MAAA,aAAA,GAAgB,YAAY,MAAM;AACtC,IAAS,QAAA,EAAA;AAAA,GACX,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,MAAM,SAAY,GAAA,WAAA;AAAA,IAChB,CAAC,GAAmE,KAAA;AAClE,MAAA,MAAM,SAAS,GAAI,CAAA,MAAA;AACnB,MAAM,MAAA,KAAA,GAAQ,OAAO,OAAQ,CAAA,OAAO,IAC/B,MACD,GAAA,MAAA,CAAO,cAAc,OAAO,CAAA;AAEhC,MAAA,IAAI,KAAO,EAAA;AACT,QAAA,KAAA,CAAM,KAAM,EAAA;AACZ,QAAA,KAAA,CAAM,MAAO,EAAA;AAAA;AACf,KACF;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,UAAa,GAAA,WAAA;AAAA,IACjB,CAAC,GAAmE,KAAA;AAClE,MAAA,MAAM,SAAS,GAAI,CAAA,MAAA;AACnB,MAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,aAAA,CAAc,OAAO,CAAA;AAC1C,MAAA,IAAI,KAAO,EAAA;AACT,QAAA,KAAA,CAAM,KAAM,EAAA;AACZ,QAAA,KAAA,CAAM,MAAO,EAAA;AAAA;AACf,KACF;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,IACpB,CAAC,CAAuC,KAAA;AACtC,MAAA,MAAM,KAAK,CAAE,CAAA,MAAA;AACb,MAAI,IAAA,eAAA,CAAgB,EAAE,CAAG,EAAA;AACvB,QAAI,IAAA,cAAA,CAAe,CAAE,CAAA,GAAG,CAAG,EAAA;AACzB,UAAA,SAAA,CAAU,CAAC,CAAA;AAAA,SACb,MAAA,IAAW,CAAE,CAAA,GAAA,KAAQ,OAAS,EAAA;AAC5B,UAAA,UAAA,CAAW,CAAC,CAAA;AAAA;AACd;AACF,KACF;AAAA,IACA,CAAC,WAAW,UAAU;AAAA,GACxB;AAEA,EAAA,MAAM,iBAAoB,GAAA,WAAA;AAAA,IACxB,CAAC,CAA+B,KAAA;AAC9B,MAAA,MAAM,KAAK,CAAE,CAAA,MAAA;AACb,MAAA,IAAI,GAAG,OAAQ,CAAA,OAAO,KAAK,EAAG,CAAA,aAAA,CAAc,OAAO,CAAG,EAAA;AACpD,QAAA,SAAA,CAAU,CAAC,CAAA;AACX,QAAA,CAAA,CAAE,eAAgB,EAAA;AAAA;AACpB,KACF;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAEA,EAAA,MAAM,UAAa,GAAA,WAAA;AAAA,IACjB,CAAC,CAAM,KAAA;AACL,MAAA,MAAM,KAAK,CAAE,CAAA,MAAA;AACb,MAAG,EAAA,CAAA,mBAAA,CAAoB,YAAc,EAAA,aAAA,EAAe,IAAI,CAAA;AAAA,KAC1D;AAAA,IACA,CAAC,aAAa;AAAA,GAChB;AAEA,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAClB,CAAC,CAAM,KAAA;AACL,MAAA,MAAM,KAAK,CAAE,CAAA,MAAA;AACb,MAAG,EAAA,CAAA,gBAAA,CAAiB,YAAc,EAAA,aAAA,EAAe,IAAI,CAAA;AAAA,KACvD;AAAA,IACA,CAAC,aAAa;AAAA,GAChB;AAEA,EAAO,OAAA;AAAA,IACL,MAAQ,EAAA,UAAA;AAAA,IACR,aAAe,EAAA,iBAAA;AAAA,IACf,OAAS,EAAA,WAAA;AAAA,IACT,SAAW,EAAA;AAAA,GACb;AACF;;;;"}
1
+ {"version":3,"file":"useCellEditing.js","sources":["../../../packages/vuu-table/src/useCellEditing.ts"],"sourcesContent":["import {\n dispatchCustomEvent,\n isCharacterKey,\n queryClosest,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n KeyboardEvent as ReactKeyboardEvent,\n MouseEvent,\n useCallback,\n} from \"react\";\nimport { cellIsTextInput, getAriaCellPos } from \"./table-dom-utils\";\nimport { FocusCell } from \"./useCellFocus\";\n\nexport interface CellEditingHookProps {\n focusCell: FocusCell;\n navigate: () => void;\n}\n\nexport const useCellEditing = ({\n focusCell,\n navigate,\n}: CellEditingHookProps) => {\n const commitHandler = useCallback(() => {\n navigate();\n }, [navigate]);\n\n const editModeHandler = useCallback(\n (e: Event) => {\n // console.log(`[useCellEditing] editModeHandler ${e.type}`);\n const tableCell = queryClosest<HTMLDivElement>(\n e.target,\n \".vuuTableCell\",\n true,\n );\n if (e.type === \"vuu-exit-edit-mode\") {\n tableCell.classList.remove(\"vuuEditing\");\n // console.log(\"shift focus back to cell\");\n const cellPos = getAriaCellPos(tableCell);\n focusCell(cellPos, true);\n // console.log({ tableCell });\n } else {\n // console.log(\"what do we do in edit mode ?\");\n tableCell.classList.add(\"vuuEditing\");\n }\n },\n [focusCell],\n );\n\n const editInput = useCallback(\n (evt: MouseEvent<HTMLElement> | ReactKeyboardEvent<HTMLElement>) => {\n const cellEl = evt.target as HTMLDivElement;\n const input = cellEl.matches(\"input\")\n ? (cellEl as HTMLInputElement)\n : cellEl.querySelector(\"input\");\n\n if (input) {\n input.focus();\n input.select();\n }\n },\n [],\n );\n\n const focusInput = useCallback(\n (evt: MouseEvent<HTMLElement> | ReactKeyboardEvent<HTMLElement>) => {\n const cellEl = evt.target as HTMLDivElement;\n const input = cellEl.querySelector(\"input\");\n if (input) {\n input.focus();\n input.select();\n // need to put the input into edit mode\n dispatchCustomEvent(input, \"vuu-begin-edit\");\n }\n },\n [],\n );\n\n const handleKeyDown = useCallback(\n (e: ReactKeyboardEvent<HTMLElement>) => {\n // console.log(`[useCellEditing] handleKeyDown `);\n\n const el = e.target as HTMLElement;\n if (cellIsTextInput(el)) {\n if (isCharacterKey(e.key)) {\n editInput(e);\n } else if (e.key === \"Enter\") {\n focusInput(e);\n }\n }\n },\n [editInput, focusInput],\n );\n\n const handleDoubleClick = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n const el = e.target as HTMLElement;\n if (el.matches(\"input\") || el.querySelector(\"input\")) {\n editInput(e);\n e.stopPropagation();\n }\n },\n [editInput],\n );\n\n const handleBlur = useCallback<FocusEventHandler>(\n (e) => {\n // console.log(\n // `[useCellEditing] handleBlur, unregisters the vuu-commit handler `,\n // );\n const el = e.target as HTMLElement;\n el.removeEventListener(\"vuu-commit\", commitHandler, true);\n el.removeEventListener(\"vuu-enter-edit-mode\", editModeHandler, true);\n el.removeEventListener(\"vuu-exit-edit-mode\", editModeHandler, true);\n },\n [commitHandler, editModeHandler],\n );\n\n const handleFocus = useCallback<FocusEventHandler>(\n (e) => {\n // console.log(\n // `[useCellEditing] handleFocus, registers the vuu-commit handler `,\n // );\n const el = e.target as HTMLElement;\n el.addEventListener(\"vuu-commit\", commitHandler, true);\n el.addEventListener(\"vuu-enter-edit-mode\", editModeHandler, true);\n el.addEventListener(\"vuu-exit-edit-mode\", editModeHandler, true);\n },\n [commitHandler, editModeHandler],\n );\n\n return {\n onBlur: handleBlur,\n onDoubleClick: handleDoubleClick,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -6,6 +6,12 @@ const getCellPosition = (el) => {
6
6
  const top = parseInt(el.parentElement?.style.top ?? "-1");
7
7
  return { top };
8
8
  };
9
+ const isDifferentCellPosition = (currentPos, newPos) => {
10
+ if (currentPos === void 0) {
11
+ return true;
12
+ }
13
+ return currentPos[0] !== newPos[0] || currentPos[1] !== newPos[1];
14
+ };
9
15
  const useCellFocus = ({
10
16
  cellFocusStateRef,
11
17
  containerRef,
@@ -19,12 +25,10 @@ const useCellFocus = ({
19
25
  [cellFocusStateRef]
20
26
  );
21
27
  const focusCell = useCallback(
22
- (cellPos, fromKeyboard = false) => {
28
+ (cellPos) => {
23
29
  if (containerRef.current) {
24
30
  const { current: state } = cellFocusStateRef;
25
- if (fromKeyboard && state.outsideViewport) {
26
- state.cellPos = cellPos;
27
- } else {
31
+ if (isDifferentCellPosition(state.cellPos, cellPos)) {
28
32
  const activeCell = getTableCell(containerRef, cellPos);
29
33
  if (activeCell) {
30
34
  if (activeCell !== state.el) {
@@ -1 +1 @@
1
- {"version":3,"file":"useCellFocus.js","sources":["../../../packages/vuu-table/src/useCellFocus.ts"],"sourcesContent":["import {\n KeyboardEventHandler,\n RefCallback,\n RefObject,\n useCallback,\n} from \"react\";\nimport {\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { isArrowKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { CellPos } from \"@vuu-ui/vuu-table-types\";\nimport type { ICellFocusState } from \"./CellFocusState\";\n\nexport interface CellFocusHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n containerRef: RefObject<HTMLElement | null>;\n disableFocus?: boolean;\n requestScroll?: ScrollRequestHandler;\n}\n\nconst getCellPosition = (el: HTMLElement) => {\n const top = parseInt(el.parentElement?.style.top ?? \"-1\");\n return { top };\n};\n\nexport type FocusCell = (cellPos: CellPos, fromKeyboard?: boolean) => void;\n\nexport const useCellFocus = ({\n cellFocusStateRef,\n containerRef,\n disableFocus = false,\n requestScroll,\n}: CellFocusHookProps) => {\n const focusCellPlaceholderRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n cellFocusStateRef.current.placeholderEl = el;\n },\n [cellFocusStateRef],\n );\n\n const focusCell = useCallback<FocusCell>(\n (cellPos, fromKeyboard = false) => {\n if (containerRef.current) {\n const { current: state } = cellFocusStateRef;\n\n if (fromKeyboard && state.outsideViewport) {\n state.cellPos = cellPos;\n } else {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== state.el) {\n state.el?.removeAttribute(\"tabindex\");\n activeCell.setAttribute(\"tabindex\", \"0\");\n\n // TODO no need to measure if we're navigating horizontally\n // state.cellPos = cellPos;\n state.el = activeCell;\n state.pos = getCellPosition(activeCell);\n state.outsideViewport = false;\n\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `${state.pos.top}px`;\n }\n }\n state.cellPos = cellPos;\n\n // TODO needs to be scroll cell to accommodate horizontal virtualization\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n }\n },\n [cellFocusStateRef, containerRef, requestScroll],\n );\n\n const setTableBodyRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n const { current: state } = cellFocusStateRef;\n const table = queryClosest<HTMLDivElement>(el, \".vuuTable\");\n if (table) {\n if (state.el === null && !disableFocus) {\n const headerCell = table.querySelector<HTMLDivElement>(\n headerCellQuery(1),\n );\n if (headerCell) {\n headerCell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = headerCell;\n state.pos = { top: -20 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `-20px`;\n }\n } else {\n const cell = table.querySelector<HTMLDivElement>(\n dataCellQuery(0, 0),\n );\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = cell;\n state.pos = { top: 0 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `0px`;\n }\n }\n }\n }\n }\n }\n },\n [cellFocusStateRef, disableFocus],\n );\n\n const focusCellPlaceholderKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n const { outsideViewport, pos } = cellFocusStateRef.current;\n if (pos && isArrowKey(evt.key)) {\n // TODO depends on whether we're scrolling up or down\n if (outsideViewport === \"above\") {\n requestScroll?.({ type: \"scroll-top\", scrollPos: pos.top });\n } else if (outsideViewport === \"below\") {\n requestScroll?.({ type: \"scroll-bottom\", scrollPos: pos.top });\n } else {\n throw Error(\n `cellFocusPlaceholder should not have focus if inside viewport`,\n );\n }\n }\n },\n [cellFocusStateRef, requestScroll],\n );\n\n return {\n focusCell,\n focusCellPlaceholderKeyDown,\n focusCellPlaceholderRef,\n setTableBodyRef,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useCellFocus.js","sources":["../../../packages/vuu-table/src/useCellFocus.ts"],"sourcesContent":["import {\n KeyboardEventHandler,\n RefCallback,\n RefObject,\n useCallback,\n} from \"react\";\nimport {\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { isArrowKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { CellPos } from \"@vuu-ui/vuu-table-types\";\nimport type { ICellFocusState } from \"./CellFocusState\";\n\nexport interface CellFocusHookProps {\n cellFocusStateRef: RefObject<ICellFocusState>;\n containerRef: RefObject<HTMLElement | null>;\n disableFocus?: boolean;\n requestScroll?: ScrollRequestHandler;\n}\n\nconst getCellPosition = (el: HTMLElement) => {\n const top = parseInt(el.parentElement?.style.top ?? \"-1\");\n return { top };\n};\n\nconst isDifferentCellPosition = (\n currentPos: CellPos | undefined,\n newPos: CellPos,\n) => {\n if (currentPos === undefined) {\n return true;\n }\n return currentPos[0] !== newPos[0] || currentPos[1] !== newPos[1];\n};\n\nexport type FocusCell = (cellPos: CellPos, fromKeyboard?: boolean) => void;\n\nexport const useCellFocus = ({\n cellFocusStateRef,\n containerRef,\n disableFocus = false,\n requestScroll,\n}: CellFocusHookProps) => {\n const focusCellPlaceholderRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n cellFocusStateRef.current.placeholderEl = el;\n },\n [cellFocusStateRef],\n );\n\n const focusCell = useCallback<FocusCell>(\n (cellPos) => {\n if (containerRef.current) {\n const { current: state } = cellFocusStateRef;\n if (isDifferentCellPosition(state.cellPos, cellPos)) {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== state.el) {\n state.el?.removeAttribute(\"tabindex\");\n activeCell.setAttribute(\"tabindex\", \"0\");\n\n // TODO no need to measure if we're navigating horizontally\n // state.cellPos = cellPos;\n state.el = activeCell;\n state.pos = getCellPosition(activeCell);\n state.outsideViewport = false;\n\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `${state.pos.top}px`;\n }\n }\n state.cellPos = cellPos;\n\n // TODO needs to be scroll cell to accommodate horizontal virtualization\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n }\n },\n [cellFocusStateRef, containerRef, requestScroll],\n );\n\n const setTableBodyRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n const { current: state } = cellFocusStateRef;\n const table = queryClosest<HTMLDivElement>(el, \".vuuTable\");\n if (table) {\n if (state.el === null && !disableFocus) {\n const headerCell = table.querySelector<HTMLDivElement>(\n headerCellQuery(1),\n );\n if (headerCell) {\n headerCell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = headerCell;\n state.pos = { top: -20 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `-20px`;\n }\n } else {\n const cell = table.querySelector<HTMLDivElement>(\n dataCellQuery(0, 0),\n );\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = cell;\n state.pos = { top: 0 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `0px`;\n }\n }\n }\n }\n }\n }\n },\n [cellFocusStateRef, disableFocus],\n );\n\n const focusCellPlaceholderKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n const { outsideViewport, pos } = cellFocusStateRef.current;\n if (pos && isArrowKey(evt.key)) {\n // TODO depends on whether we're scrolling up or down\n if (outsideViewport === \"above\") {\n requestScroll?.({ type: \"scroll-top\", scrollPos: pos.top });\n } else if (outsideViewport === \"below\") {\n requestScroll?.({ type: \"scroll-bottom\", scrollPos: pos.top });\n } else {\n throw Error(\n `cellFocusPlaceholder should not have focus if inside viewport`,\n );\n }\n }\n },\n [cellFocusStateRef, requestScroll],\n );\n\n return {\n focusCell,\n focusCellPlaceholderKeyDown,\n focusCellPlaceholderRef,\n setTableBodyRef,\n };\n};\n"],"names":[],"mappings":"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"}
@@ -27,13 +27,6 @@ const isNavigationKey = (key, navigationStyle) => {
27
27
  return false;
28
28
  }
29
29
  };
30
- const editCellWithEditInProgress = (el) => {
31
- if (el) {
32
- const input = el.querySelector("input");
33
- return input && document.activeElement === input;
34
- }
35
- return false;
36
- };
37
30
  const focusControlWithinCell = (e, el) => {
38
31
  if (e.shiftKey && e.key.match(/Arrow(Left|Right)/)) {
39
32
  if (el?.classList.contains("vuuTableHeaderCell")) {
@@ -105,12 +98,12 @@ const useKeyboardNavigation = ({
105
98
  [onHighlight, setHighlightedIdx]
106
99
  );
107
100
  const setActiveCell = useCallback(
108
- (rowIdx, colIdx, fromKeyboard = false) => {
101
+ (rowIdx, colIdx) => {
109
102
  const pos = [rowIdx, colIdx];
110
103
  if (navigationStyle === "row") {
111
104
  setHighlightedIdx(rowIdx);
112
105
  } else {
113
- focusCell(pos, fromKeyboard);
106
+ focusCell(pos);
114
107
  }
115
108
  },
116
109
  [focusCell, navigationStyle, setHighlightedIdx]
@@ -118,12 +111,10 @@ const useKeyboardNavigation = ({
118
111
  const nextPageItemIdx = useCallback(
119
112
  (key, [rowIdx, colIdx]) => new Promise((resolve) => {
120
113
  let newRowIdx = rowIdx;
121
- const { current: focusState } = cellFocusStateRef;
122
114
  switch (key) {
123
115
  case "PageDown": {
124
116
  newRowIdx = Math.min(rowCount - 1, rowIdx + viewportRowCount);
125
117
  if (newRowIdx !== rowIdx) {
126
- focusState.cellPos = [newRowIdx, colIdx];
127
118
  requestScroll?.({ type: "scroll-page", direction: "down" });
128
119
  }
129
120
  break;
@@ -131,7 +122,6 @@ const useKeyboardNavigation = ({
131
122
  case "PageUp": {
132
123
  newRowIdx = Math.max(0, rowIdx - viewportRowCount);
133
124
  if (newRowIdx !== rowIdx) {
134
- focusState.cellPos = [newRowIdx, colIdx];
135
125
  requestScroll?.({ type: "scroll-page", direction: "up" });
136
126
  }
137
127
  break;
@@ -139,7 +129,6 @@ const useKeyboardNavigation = ({
139
129
  case "Home": {
140
130
  newRowIdx = headerCount + 1;
141
131
  if (newRowIdx !== rowIdx) {
142
- focusState.cellPos = [newRowIdx, colIdx];
143
132
  requestScroll?.({ type: "scroll-end", direction: "home" });
144
133
  }
145
134
  break;
@@ -147,7 +136,6 @@ const useKeyboardNavigation = ({
147
136
  case "End": {
148
137
  newRowIdx = rowCount + headerCount;
149
138
  if (newRowIdx !== rowIdx) {
150
- focusState.cellPos = [newRowIdx, colIdx];
151
139
  requestScroll?.({ type: "scroll-end", direction: "end" });
152
140
  }
153
141
  break;
@@ -157,7 +145,7 @@ const useKeyboardNavigation = ({
157
145
  resolve([newRowIdx, colIdx]);
158
146
  }, 35);
159
147
  }),
160
- [cellFocusStateRef, headerCount, requestScroll, rowCount, viewportRowCount]
148
+ [headerCount, requestScroll, rowCount, viewportRowCount]
161
149
  );
162
150
  const handleFocus = useCallback(() => {
163
151
  if (disableHighlightOnFocus !== true) {
@@ -210,7 +198,7 @@ const useKeyboardNavigation = ({
210
198
  }
211
199
  }
212
200
  if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {
213
- setActiveCell(nextRowIdx, nextColIdx, true);
201
+ setActiveCell(nextRowIdx, nextColIdx);
214
202
  setHighlightedIndex(nextRowIdx);
215
203
  }
216
204
  },
@@ -266,15 +254,13 @@ const useKeyboardNavigation = ({
266
254
  return;
267
255
  }
268
256
  if (rowCount > 0 && isNavigationKey(e.key, navigationStyle)) {
269
- if (e.key === "ArrowDown" && editCellWithEditInProgress(cell)) ; else {
270
- e.preventDefault();
271
- e.stopPropagation();
272
- if (navigationStyle === "row") {
273
- moveHighlightedRow(e.key);
274
- } else if (navigationStyle !== "none") {
275
- if (!focusControlWithinCell(e, cell)) {
276
- navigateChildItems(navigationStyle, e.key, e.shiftKey);
277
- }
257
+ e.preventDefault();
258
+ e.stopPropagation();
259
+ if (navigationStyle === "row") {
260
+ moveHighlightedRow(e.key);
261
+ } else if (navigationStyle !== "none") {
262
+ if (!focusControlWithinCell(e, cell)) {
263
+ navigateChildItems(navigationStyle, e.key, e.shiftKey);
278
264
  }
279
265
  }
280
266
  }