@vuu-ui/vuu-table 2.1.12 → 2.1.15

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 (102) hide show
  1. package/cjs/Table.js +6 -4
  2. package/cjs/Table.js.map +1 -1
  3. package/cjs/bulk-edit/BulkEditPanel.js +3 -46
  4. package/cjs/bulk-edit/BulkEditPanel.js.map +1 -1
  5. package/cjs/bulk-edit/{InsertNewRowEditor.css.js → BulkEditRow.css.js} +1 -1
  6. package/cjs/bulk-edit/BulkEditRow.css.js.map +1 -0
  7. package/cjs/bulk-edit/{InsertNewRowEditor.js → BulkEditRow.js} +7 -7
  8. package/cjs/bulk-edit/BulkEditRow.js.map +1 -0
  9. package/cjs/bulk-edit/useBulkEditPanel.js.map +1 -1
  10. package/cjs/bulk-edit/{useColumnCascadingEditor.js → useBulkEditRow.js} +1 -1
  11. package/cjs/bulk-edit/useBulkEditRow.js.map +1 -0
  12. package/cjs/cell-renderers/input-cell/InputCell.css.js +1 -1
  13. package/cjs/cell-renderers/input-cell/InputCell.js +4 -13
  14. package/cjs/cell-renderers/input-cell/InputCell.js.map +1 -1
  15. package/cjs/data-row/DataRow.js +2 -11
  16. package/cjs/data-row/DataRow.js.map +1 -1
  17. package/cjs/index.js +4 -0
  18. package/cjs/index.js.map +1 -1
  19. package/cjs/table-cell/TableCell.css.js +1 -1
  20. package/cjs/table-cell/TableCell.js +29 -13
  21. package/cjs/table-cell/TableCell.js.map +1 -1
  22. package/cjs/table-data-source/DataRowMovingWindow.js +3 -3
  23. package/cjs/table-data-source/DataRowMovingWindow.js.map +1 -1
  24. package/cjs/table-data-source/useDataSource.js +1 -1
  25. package/cjs/table-data-source/useDataSource.js.map +1 -1
  26. package/cjs/table-dom-utils.js +2 -26
  27. package/cjs/table-dom-utils.js.map +1 -1
  28. package/cjs/useCell.js +4 -3
  29. package/cjs/useCell.js.map +1 -1
  30. package/cjs/useCellEditing.js +30 -3
  31. package/cjs/useCellEditing.js.map +1 -1
  32. package/cjs/useCellFocus.js.map +1 -1
  33. package/cjs/useKeyboardNavigation.js +0 -10
  34. package/cjs/useKeyboardNavigation.js.map +1 -1
  35. package/cjs/useTable.js +32 -4
  36. package/cjs/useTable.js.map +1 -1
  37. package/esm/Table.js +6 -4
  38. package/esm/Table.js.map +1 -1
  39. package/esm/bulk-edit/BulkEditPanel.js +3 -46
  40. package/esm/bulk-edit/BulkEditPanel.js.map +1 -1
  41. package/esm/bulk-edit/{InsertNewRowEditor.css.js → BulkEditRow.css.js} +1 -1
  42. package/esm/bulk-edit/BulkEditRow.css.js.map +1 -0
  43. package/esm/bulk-edit/{InsertNewRowEditor.js → BulkEditRow.js} +5 -5
  44. package/esm/bulk-edit/BulkEditRow.js.map +1 -0
  45. package/esm/bulk-edit/useBulkEditPanel.js.map +1 -1
  46. package/esm/bulk-edit/{useColumnCascadingEditor.js → useBulkEditRow.js} +1 -1
  47. package/esm/bulk-edit/useBulkEditRow.js.map +1 -0
  48. package/esm/cell-renderers/input-cell/InputCell.css.js +1 -1
  49. package/esm/cell-renderers/input-cell/InputCell.js +5 -14
  50. package/esm/cell-renderers/input-cell/InputCell.js.map +1 -1
  51. package/esm/data-row/DataRow.js +2 -11
  52. package/esm/data-row/DataRow.js.map +1 -1
  53. package/esm/index.js +2 -0
  54. package/esm/index.js.map +1 -1
  55. package/esm/table-cell/TableCell.css.js +1 -1
  56. package/esm/table-cell/TableCell.js +30 -14
  57. package/esm/table-cell/TableCell.js.map +1 -1
  58. package/esm/table-data-source/DataRowMovingWindow.js +3 -3
  59. package/esm/table-data-source/DataRowMovingWindow.js.map +1 -1
  60. package/esm/table-data-source/useDataSource.js +2 -2
  61. package/esm/table-data-source/useDataSource.js.map +1 -1
  62. package/esm/table-dom-utils.js +3 -25
  63. package/esm/table-dom-utils.js.map +1 -1
  64. package/esm/useCell.js +4 -3
  65. package/esm/useCell.js.map +1 -1
  66. package/esm/useCellEditing.js +32 -5
  67. package/esm/useCellEditing.js.map +1 -1
  68. package/esm/useCellFocus.js.map +1 -1
  69. package/esm/useKeyboardNavigation.js +1 -11
  70. package/esm/useKeyboardNavigation.js.map +1 -1
  71. package/esm/useTable.js +33 -5
  72. package/esm/useTable.js.map +1 -1
  73. package/package.json +10 -10
  74. package/types/Table.d.ts +2 -14
  75. package/types/bulk-edit/BulkEditPanel.d.ts +1 -3
  76. package/types/bulk-edit/{InsertNewRowEditor.d.ts → BulkEditRow.d.ts} +1 -1
  77. package/types/bulk-edit/index.d.ts +3 -0
  78. package/types/bulk-edit/useBulkEditPanel.d.ts +1 -1
  79. package/types/index.d.ts +1 -1
  80. package/types/table-cell/TableCell.d.ts +1 -1
  81. package/types/table-data-source/DataRowMovingWindow.d.ts +1 -1
  82. package/types/table-dom-utils.d.ts +1 -3
  83. package/types/useCell.d.ts +1 -1
  84. package/types/useCellEditing.d.ts +3 -1
  85. package/types/useKeyboardNavigation.d.ts +1 -2
  86. package/types/useTable.d.ts +5 -4
  87. package/cjs/bulk-edit/ColumnCascadingUpdateEditor.css.js +0 -6
  88. package/cjs/bulk-edit/ColumnCascadingUpdateEditor.css.js.map +0 -1
  89. package/cjs/bulk-edit/ColumnCascadingUpdateEditor.js +0 -80
  90. package/cjs/bulk-edit/ColumnCascadingUpdateEditor.js.map +0 -1
  91. package/cjs/bulk-edit/InsertNewRowEditor.css.js.map +0 -1
  92. package/cjs/bulk-edit/InsertNewRowEditor.js.map +0 -1
  93. package/cjs/bulk-edit/useColumnCascadingEditor.js.map +0 -1
  94. package/esm/bulk-edit/ColumnCascadingUpdateEditor.css.js +0 -4
  95. package/esm/bulk-edit/ColumnCascadingUpdateEditor.css.js.map +0 -1
  96. package/esm/bulk-edit/ColumnCascadingUpdateEditor.js +0 -78
  97. package/esm/bulk-edit/ColumnCascadingUpdateEditor.js.map +0 -1
  98. package/esm/bulk-edit/InsertNewRowEditor.css.js.map +0 -1
  99. package/esm/bulk-edit/InsertNewRowEditor.js.map +0 -1
  100. package/esm/bulk-edit/useColumnCascadingEditor.js.map +0 -1
  101. package/types/bulk-edit/ColumnCascadingUpdateEditor.d.ts +0 -9
  102. /package/types/bulk-edit/{useColumnCascadingEditor.d.ts → useBulkEditRow.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"DataRow.js","sources":["../../../../packages/vuu-table/src/data-row/DataRow.ts"],"sourcesContent":["import { DataSourceRow, SchemaColumn } from \"@vuu-ui/vuu-data-types\";\nimport {\n StringNumericType,\n VuuColumnDataType,\n VuuDataRow,\n VuuRowDataItemType,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n DataRow,\n DataRowIntrinsicAttribute,\n DataRowOperation,\n DataRowOperations,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n getCalculatedColumnDetails,\n getServerDataType,\n isCalculatedColumn,\n isVuuColumnDataType,\n} from \"@vuu-ui/vuu-utils\";\n\ntype ColumnMapEntry = {\n index: number;\n type: VuuColumnDataType;\n};\n\nconst dataRowSymbol = Symbol(\"DataRow\");\n\n/**\n * We allow undefined to allow us to null out rather than delete entries, for\n * performance reasons.\n */\ntype DataRowColumnMap = Record<string, ColumnMapEntry | undefined>;\n\nconst dataRowIntrinsicAttributes: Record<DataRowIntrinsicAttribute, true> = {\n childCount: true,\n depth: true,\n index: true,\n isExpanded: true,\n isSelected: true,\n isLeaf: true,\n key: true,\n renderIndex: true,\n};\n\nconst dataRowOperations: Record<DataRowOperation, true> = {\n hasColumn: true,\n};\n\nconst isDataRowIntrinsicAttribute = (\n attrName: string,\n): attrName is DataRowIntrinsicAttribute =>\n dataRowIntrinsicAttributes[attrName as DataRowIntrinsicAttribute] === true;\n\nconst isDataRowOperation = (attrName: string): attrName is DataRowOperation =>\n dataRowOperations[attrName as DataRowOperation] === true;\n\nconst stringNumericTypes: Record<StringNumericType, true> = {\n long: true,\n scaleddecimal2: true,\n scaleddecimal4: true,\n scaleddecimal6: true,\n scaleddecimal8: true,\n};\n\nconst isStringNumericType = (\n type: VuuColumnDataType,\n): type is StringNumericType =>\n stringNumericTypes[type as StringNumericType] === true;\n\nconst MAX_DECIMALS = \"0000000\";\n\nconst injectDecimalPoint = (value: string, decimal: 2 | 4 | 6 | 8) => {\n if (value === \"0\" || value === \"-0\" || value === \"\") {\n return value;\n } else {\n if (value[0] === \"-\") {\n const digits = value.slice(1);\n if (digits.length < decimal) {\n return `-0.${(MAX_DECIMALS + digits).slice(-decimal)}`;\n } else if (digits.length === decimal) {\n return `-0.${value}`;\n } else {\n return `-${digits.slice(0, -decimal)}.${digits.slice(-decimal)}`;\n }\n } else {\n if (value.length < decimal) {\n return `0.${(MAX_DECIMALS + value).slice(-decimal)}`;\n } else if (value.length === decimal) {\n return `0.${value}`;\n } else {\n return `${value.slice(0, -decimal)}.${value.slice(-decimal)}`;\n }\n }\n }\n};\n\nconst formatStringNumeric = (value: string, type: StringNumericType) => {\n switch (type) {\n case \"long\":\n return value;\n case \"scaleddecimal2\":\n return injectDecimalPoint(value, 2);\n case \"scaleddecimal4\":\n return injectDecimalPoint(value, 4);\n case \"scaleddecimal6\":\n return injectDecimalPoint(value, 6);\n case \"scaleddecimal8\":\n return injectDecimalPoint(value, 8);\n }\n};\n/**\n * DataRow wraps a vuu DataSourceRow and a columnMap to provide a more convenient\n * API for manipulating rows from server. It is now used internally by Table. This\n * removes the need to always provide a columnMap to any component that must work with\n * data rows. It also removes a category of timing bugs which cause the columnMap\n * to get out of sync with data.\n * Because properties are provided via a proxy, and the DataRow has the Schema, there is\n * flexibility to enhance handling for specific properties. This is used now to insert\n * decimal point in scaleddecimal values.\n * @param data\n * @param columnMap\n * @returns\n */\nfunction DataRowImpl(data: VuuDataRow, columnMap: DataRowColumnMap): DataRow {\n const target: Record<string, VuuRowDataItemType> = {};\n\n const getPropertyNames = () => {\n return Object.keys(columnMap);\n };\n\n const jsonSerializer = () => {\n return Object.entries(columnMap).reduce<Record<string, VuuRowDataItemType>>(\n (json, [name, mapEntry]) => {\n if (mapEntry) {\n json[name] = data[mapEntry.index];\n }\n return json;\n },\n {},\n );\n };\n\n const DataRowOperations: DataRowOperations = {\n hasColumn: (name: string) => columnMap[name] !== undefined,\n };\n\n return new Proxy(target, {\n get(_obj, prop: string | symbol) {\n if (typeof prop === \"symbol\") {\n if (prop === dataRowSymbol) return true;\n // TODO what does React use this for\n return undefined;\n } else if (prop === \"toJSON\") {\n return jsonSerializer;\n } else if (prop === \"toString\") {\n return \"DataRow\";\n } else if (prop === \"$$typeof\") {\n // some react internal weirdness\n return undefined;\n } else if (isDataRowOperation(prop)) {\n return DataRowOperations[prop];\n } else if (prop === \"getPropertyNames\") {\n return getPropertyNames;\n }\n const columnMapEntry = columnMap[prop];\n\n if (columnMapEntry === undefined) {\n if (prop !== \"\") {\n // System columns like the selection checkbox column\n console.warn(`[DataRow:Proxy] unknown column ${prop}`);\n }\n return undefined;\n }\n\n if (isDataRowIntrinsicAttribute(prop)) {\n return data[columnMapEntry.index];\n }\n\n if (isStringNumericType(columnMapEntry.type)) {\n return formatStringNumeric(\n data[columnMapEntry.index] as string,\n columnMapEntry.type,\n );\n }\n\n return data[columnMapEntry.index];\n\n // throw new Error(`Unknown column: ${prop}`);\n },\n set() {\n throw new TypeError(\"DataRow is readonly\");\n },\n }) as DataRow;\n}\n\nexport type DataRowFunc = (data: DataSourceRow) => DataRow;\n\nconst ColumnMapIntrinsicColumns: DataRowColumnMap = {\n index: { index: 0, type: \"int\" },\n renderIndex: { index: 1, type: \"int\" },\n isLeaf: { index: 2, type: \"boolean\" },\n isExpanded: { index: 3, type: \"boolean\" },\n depth: { index: 4, type: \"int\" },\n childCount: { index: 5, type: \"int\" },\n key: { index: 6, type: \"string\" },\n isSelected: { index: 7, type: \"boolean\" },\n};\n\nfunction createColumnMap(\n columns: string[],\n schemaColumns: readonly SchemaColumn[],\n) {\n const columnMap: DataRowColumnMap = {\n ...ColumnMapIntrinsicColumns,\n };\n\n columns.forEach((name, i, cols) => {\n const schemaColumn = schemaColumns.find((col) => col.name === name);\n if (schemaColumn) {\n const serverDataType = getServerDataType(schemaColumn, true);\n columnMap[name] = { index: i + 10, type: serverDataType };\n } else if (isCalculatedColumn(name)) {\n const { serverDataType } = getCalculatedColumnDetails(name);\n if (isVuuColumnDataType(serverDataType)) {\n columnMap[name] = { index: i + 10, type: serverDataType };\n } else {\n throw Error(\n `[DataRow] calculated column with invalid serverDataType ${name}`,\n );\n }\n } else if (name === \"vuuMsg\" && i === cols.length - 1) {\n // Mag column on a session table, always in last place\n columnMap[name] = { index: i + 10, type: \"string\" };\n } else {\n throw Error(`[DataRow] dataRowFactory column not in schema ${name}`);\n }\n });\n\n if (columnMap.vuuMsg === undefined) {\n // We will always check for vuuMsg, even if it isn't explicitly included in the subscribed columns\n return {\n ...columnMap,\n vuuMsg: { index: columns.length + 10, type: \"string\" },\n } as DataRowColumnMap;\n } else {\n return columnMap;\n }\n}\n\n/**\n *\n * @param columns the names of columns included in subscription\n * @param schemaColumns full schema definitions for all available columns,\n * the serverDataTypes are used.\n * @returns a tuple containing:\n * - factory function that will create a DataRow instance from a DataSourceRow\n * array.\n * - a function that can be used to reset the columns, which will be used for all\n * subsequently created DataRows. Used by Table when user adds or removes columns\n * at runtime.\n */\nexport const dataRowFactory = (\n columns: string[],\n schemaColumns: readonly SchemaColumn[],\n): [DataRowFunc, (columns: string[]) => void] => {\n let columnMap = createColumnMap(columns, schemaColumns);\n\n const setColumns = (columns: string[]) => {\n // new columnMap will be used for all subsequently created DataRows\n columnMap = createColumnMap(columns, schemaColumns);\n };\n\n const DataRow = function (data: DataSourceRow) {\n return DataRowImpl(data, columnMap);\n };\n\n return [DataRow, setColumns];\n};\n\nif (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n //@ts-ignore\n window.devtoolsFormatters = [\n {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n header: function (obj: any) {\n if (obj[dataRowSymbol]) {\n return [\n \"div\",\n {\n style: \"display: flex; gap: 4px; justify-content: space-between\",\n },\n [\"span\", {}, \"Vuu DataRow\"],\n [\"span\", { style: \"font-weight: bold;\" }, `[${obj.index}]`],\n [\n \"span\",\n { style: \"font-weight: bold; color: blue;\" },\n `#${obj.key}`,\n ],\n ];\n }\n return null;\n },\n hasBody: function () {\n return true;\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n body: function (obj: any) {\n return [\n \"div\",\n {},\n [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, \"index\"],\n [\"span\", {}, obj.index],\n ],\n [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, \"key\"],\n [\"span\", {}, obj.key],\n ],\n [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, \"renderIndex\"],\n [\"span\", {}, obj.renderIndex],\n ],\n [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, \"isSelected\"],\n [\"span\", {}, obj.isSelected],\n ],\n ...obj.getPropertyNames().map((name: string) => {\n return [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, name],\n [\"span\", {}, obj[name]],\n ];\n }),\n ];\n },\n },\n ];\n}\n"],"names":["DataRowOperations","getServerDataType","isCalculatedColumn","getCalculatedColumnDetails","isVuuColumnDataType","columns","DataRow"],"mappings":"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"}
1
+ {"version":3,"file":"DataRow.js","sources":["../../../../packages/vuu-table/src/data-row/DataRow.ts"],"sourcesContent":["import { DataSourceRow, SchemaColumn } from \"@vuu-ui/vuu-data-types\";\nimport {\n StringNumericType,\n VuuColumnDataType,\n VuuDataRow,\n VuuRowDataItemType,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n DataRow,\n DataRowIntrinsicAttribute,\n DataRowOperation,\n DataRowOperations,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n getCalculatedColumnDetails,\n getServerDataType,\n isCalculatedColumn,\n isVuuColumnDataType,\n} from \"@vuu-ui/vuu-utils\";\n\ntype ColumnMapEntry = {\n index: number;\n type: VuuColumnDataType;\n};\n\nconst dataRowSymbol = Symbol(\"DataRow\");\n\n/**\n * We allow undefined to allow us to null out rather than delete entries, for\n * performance reasons.\n */\ntype DataRowColumnMap = Record<string, ColumnMapEntry | undefined>;\n\nconst dataRowIntrinsicAttributes: Record<DataRowIntrinsicAttribute, true> = {\n childCount: true,\n depth: true,\n index: true,\n isExpanded: true,\n isSelected: true,\n isLeaf: true,\n key: true,\n renderIndex: true,\n};\n\nconst dataRowOperations: Record<DataRowOperation, true> = {\n hasColumn: true,\n};\n\nconst isDataRowIntrinsicAttribute = (\n attrName: string,\n): attrName is DataRowIntrinsicAttribute =>\n dataRowIntrinsicAttributes[attrName as DataRowIntrinsicAttribute] === true;\n\nconst isDataRowOperation = (attrName: string): attrName is DataRowOperation =>\n dataRowOperations[attrName as DataRowOperation] === true;\n\nconst stringNumericTypes: Record<StringNumericType, true> = {\n long: true,\n scaleddecimal2: true,\n scaleddecimal4: true,\n scaleddecimal6: true,\n scaleddecimal8: true,\n};\n\nconst isStringNumericType = (\n type: VuuColumnDataType,\n): type is StringNumericType =>\n stringNumericTypes[type as StringNumericType] === true;\n\nconst MAX_DECIMALS = \"0000000\";\n\nconst injectDecimalPoint = (value: string, decimal: 2 | 4 | 6 | 8) => {\n if (value === \"0\" || value === \"-0\" || value === \"\") {\n return value;\n } else {\n if (value[0] === \"-\") {\n const digits = value.slice(1);\n if (digits.length < decimal) {\n return `-0.${(MAX_DECIMALS + digits).slice(-decimal)}`;\n } else if (digits.length === decimal) {\n return `-0.${value}`;\n } else {\n return `-${digits.slice(0, -decimal)}.${digits.slice(-decimal)}`;\n }\n } else {\n if (value.length < decimal) {\n return `0.${(MAX_DECIMALS + value).slice(-decimal)}`;\n } else if (value.length === decimal) {\n return `0.${value}`;\n } else {\n return `${value.slice(0, -decimal)}.${value.slice(-decimal)}`;\n }\n }\n }\n};\n\nconst formatStringNumeric = (value: string, type: StringNumericType) => {\n switch (type) {\n case \"long\":\n return value;\n case \"scaleddecimal2\":\n return injectDecimalPoint(value, 2);\n case \"scaleddecimal4\":\n return injectDecimalPoint(value, 4);\n case \"scaleddecimal6\":\n return injectDecimalPoint(value, 6);\n case \"scaleddecimal8\":\n return injectDecimalPoint(value, 8);\n }\n};\n/**\n * DataRow wraps a vuu DataSourceRow and a columnMap to provide a more convenient\n * API for manipulating rows from server. It is now used internally by Table. This\n * removes the need to always provide a columnMap to any componnet that must work with\n * data rows. It also removes a category of timing bugs which cause the columnMap\n * to get out of sync with data.\n * Because properties are provided via a proxy, and the DataRow has the Schema, there is\n * flexibility to enhance handling for specific properties. This is used now to insert\n * decimal point in scaleddecimal values.\n * @param data\n * @param columnMap\n * @returns\n */\nfunction DataRowImpl(data: VuuDataRow, columnMap: DataRowColumnMap): DataRow {\n const target: Record<string, VuuRowDataItemType> = {};\n\n const getPropertyNames = () => {\n return Object.keys(columnMap);\n };\n\n const jsonSerializer = () => {\n return Object.entries(columnMap).reduce<Record<string, VuuRowDataItemType>>(\n (json, [name, mapEntry]) => {\n if (mapEntry) {\n json[name] = data[mapEntry.index];\n }\n return json;\n },\n {},\n );\n };\n\n const DataRowOperations: DataRowOperations = {\n hasColumn: (name: string) => columnMap[name] !== undefined,\n };\n\n return new Proxy(target, {\n get(_obj, prop: string | symbol) {\n if (typeof prop === \"symbol\") {\n if (prop === dataRowSymbol) return true;\n // TODO what does React use this for\n return undefined;\n } else if (prop === \"toJSON\") {\n return jsonSerializer;\n } else if (prop === \"toString\") {\n return \"DataRow\";\n } else if (prop === \"$$typeof\") {\n // some react internal weirdness\n return undefined;\n } else if (isDataRowOperation(prop)) {\n return DataRowOperations[prop];\n } else if (prop === \"getPropertyNames\") {\n return getPropertyNames;\n }\n const columnMapEntry = columnMap[prop];\n\n if (columnMapEntry === undefined) {\n if (prop !== \"\") {\n // System columns like the selection checkbox column\n console.warn(`[DataRow:Proxy] unknown column ${prop}`);\n }\n return undefined;\n }\n\n if (isDataRowIntrinsicAttribute(prop)) {\n return data[columnMapEntry.index];\n }\n\n if (isStringNumericType(columnMapEntry.type)) {\n return formatStringNumeric(\n data[columnMapEntry.index] as string,\n columnMapEntry.type,\n );\n }\n\n return data[columnMapEntry.index];\n\n // throw new Error(`Unknown column: ${prop}`);\n },\n set() {\n throw new TypeError(\"DataRow is readonly\");\n },\n }) as DataRow;\n}\n\nexport type DataRowFunc = (data: DataSourceRow) => DataRow;\n\nconst ColumnMapIntrinsicColumns: DataRowColumnMap = {\n index: { index: 0, type: \"int\" },\n renderIndex: { index: 1, type: \"int\" },\n isLeaf: { index: 2, type: \"boolean\" },\n isExpanded: { index: 3, type: \"boolean\" },\n depth: { index: 4, type: \"int\" },\n childCount: { index: 5, type: \"int\" },\n key: { index: 6, type: \"string\" },\n isSelected: { index: 7, type: \"boolean\" },\n};\n\nfunction createColumnMap(\n columns: string[],\n schemaColumns: readonly SchemaColumn[],\n) {\n const columnMap: DataRowColumnMap = {\n ...ColumnMapIntrinsicColumns,\n };\n\n columns.forEach((name, i) => {\n const schemaColumn = schemaColumns.find((col) => col.name === name);\n if (schemaColumn) {\n const serverDataType = getServerDataType(schemaColumn, true);\n columnMap[name] = { index: i + 10, type: serverDataType };\n } else if (isCalculatedColumn(name)) {\n const { serverDataType } = getCalculatedColumnDetails(name);\n if (isVuuColumnDataType(serverDataType)) {\n columnMap[name] = { index: i + 10, type: serverDataType };\n } else {\n throw Error(\n `[DataRow] calculated column with invalid serverDataType ${name}`,\n );\n }\n } else {\n throw Error(`[DataRow] dataRowFactory column not in schema ${name}`);\n }\n });\n return columnMap;\n}\n\n/**\n *\n * @param columns the names of columns included in subscription\n * @param schemaColumns full schema definitions for all available columns,\n * the serverDataTypes are used.\n * @returns a tuple containing:\n * - factory function that will create a DataRow instance from a DataSourceRow\n * array.\n * - a function that can be used to reset the columns, which will be used for all\n * subsequently created DataRows. Used by Table when user adds or removes columns\n * at runtime.\n */\nexport const dataRowFactory = (\n columns: string[],\n schemaColumns: readonly SchemaColumn[],\n): [DataRowFunc, (columns: string[]) => void] => {\n let columnMap = createColumnMap(columns, schemaColumns);\n\n const setColumns = (columns: string[]) => {\n // new columnMap will be used for all subsequently created DataRows\n columnMap = createColumnMap(columns, schemaColumns);\n };\n\n const DataRow = function (data: DataSourceRow) {\n return DataRowImpl(data, columnMap);\n };\n\n return [DataRow, setColumns];\n};\n\nif (process.env.NODE_ENV !== \"production\") {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n //@ts-ignore\n window.devtoolsFormatters = [\n {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n header: function (obj: any) {\n if (obj[dataRowSymbol]) {\n return [\n \"div\",\n {\n style: \"display: flex; gap: 4px; justify-content: space-between\",\n },\n [\"span\", {}, \"Vuu DataRow\"],\n [\"span\", { style: \"font-weight: bold;\" }, `[${obj.index}]`],\n [\n \"span\",\n { style: \"font-weight: bold; color: blue;\" },\n `#${obj.key}`,\n ],\n ];\n }\n return null;\n },\n hasBody: function () {\n return true;\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n body: function (obj: any) {\n return [\n \"div\",\n {},\n [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, \"index\"],\n [\"span\", {}, obj.index],\n ],\n [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, \"key\"],\n [\"span\", {}, obj.key],\n ],\n [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, \"renderIndex\"],\n [\"span\", {}, obj.renderIndex],\n ],\n [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, \"isSelected\"],\n [\"span\", {}, obj.isSelected],\n ],\n ...obj.getPropertyNames().map((name: string) => {\n return [\n \"div\",\n {\n style: \"display: flex; gap: 4px;\",\n },\n [\"span\", {}, name],\n [\"span\", {}, obj[name]],\n ];\n }),\n ];\n },\n },\n ];\n}\n"],"names":["DataRowOperations","getServerDataType","isCalculatedColumn","getCalculatedColumnDetails","isVuuColumnDataType","columns","DataRow"],"mappings":"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"}
package/cjs/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var BulkEditPanel = require('./bulk-edit/BulkEditPanel.js');
4
+ var useBulkEditPanel = require('./bulk-edit/useBulkEditPanel.js');
5
+ var useBulkEditRow = require('./bulk-edit/useBulkEditRow.js');
4
6
  var CheckboxCell = require('./cell-renderers/checkbox-cell/CheckboxCell.js');
5
7
  var CheckboxRowSelectorCell = require('./cell-renderers/checkbox-row-selector/CheckboxRowSelectorCell.js');
6
8
  var InputCell = require('./cell-renderers/input-cell/InputCell.js');
@@ -30,6 +32,8 @@ var VirtualColSpan = require('./VirtualColSpan.js');
30
32
 
31
33
 
32
34
  exports.BulkEditPanel = BulkEditPanel.BulkEditPanel;
35
+ exports.useBulkEditPanel = useBulkEditPanel.useBulkEditPanel;
36
+ exports.useBulkEditRow = useBulkEditRow.useBulkEditRow;
33
37
  exports.CheckboxCell = CheckboxCell.CheckboxCell;
34
38
  exports.CheckboxRowSelectorCell = CheckboxRowSelectorCell.CheckboxRowSelectorCell;
35
39
  exports.InputCell = InputCell.InputCell;
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- 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 &:has(.vuuCheckboxRowSelector) {\n text-overflow: unset;\n }\n\n}\n\n.vuuTableCell-right {\n text-align: right;\n}\n\n.vuuTableCell-editable {\n align-items: center;\n display: inline-flex;\n padding: var(--vuuTableCell-padding-editable, 0px 1px 0 2px);\n}\n\n.vuuTableCell:focus-visible {\n outline: none;\n}\n\n.vuuTableCell-editable:focus-within,\n.vuuTableCell:focus {\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 .saltInput-bordered {\n border-color: transparent;\n outline: solid var(--salt-editable-borderColor-active) 2px;\n outline-offset: -1px;\n }\n\n .saltInput-bordered.vuuEditing{\n outline: dashed var(--salt-editable-borderColor-active) 2px;\n outline-offset: -1px;\n }\n\n .vuuTableInputCell-error.saltInput-bordered {\n outline: dashed var(--salt-status-error-borderColor) 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";
3
+ 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 &:has(.vuuCheckboxRowSelector) {\n text-overflow: unset;\n }\n\n}\n\n.vuuTableCell-right {\n text-align: right;\n}\n\n.vuuTableCell-editable {\n align-items: center;\n display: inline-flex;\n padding: var(--vuuTableCell-padding-editable, 0px 1px 0 2px);\n}\n\n.vuuTableCell:focus-visible {\n outline: none;\n}\n\n.vuuTableCell-editable:focus-within,\n.vuuTableCell:focus {\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 .saltInput-bordered {\n border-color: transparent;\n outline: solid var(--salt-editable-borderColor-active) 2px;\n outline-offset: -1px;\n }\n\n &.vuuEditing {\n .saltInput-bordered {\n outline: dashed var(--salt-editable-borderColor-active) 2px;\n outline-offset: -1px;\n }\n\n .vuuTableInputCell-error.saltInput-bordered {\n outline: dashed var(--salt-status-error-borderColor) 2px;\n }\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";
4
4
 
5
5
  module.exports = tableCellCss;
6
6
  //# sourceMappingURL=TableCell.css.js.map
@@ -3,17 +3,18 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var styles = require('@salt-ds/styles');
5
5
  var window = require('@salt-ds/window');
6
+ var vuuUtils = require('@vuu-ui/vuu-utils');
6
7
  var react = require('react');
7
8
  var useCell = require('../useCell.js');
8
9
  var useHighlighting = require('../useHighlighting.js');
9
10
  var TableCell$1 = require('./TableCell.css.js');
10
- var vuuUtils = require('@vuu-ui/vuu-utils');
11
11
 
12
12
  const classBase = "vuuTableCell";
13
13
  const TableCell = ({
14
14
  column,
15
15
  dataRow,
16
16
  onClick,
17
+ onDataEdited,
17
18
  searchPattern = ""
18
19
  }) => {
19
20
  const targetWindow = window.useWindow();
@@ -22,26 +23,41 @@ const TableCell = ({
22
23
  css: TableCell$1,
23
24
  window: targetWindow
24
25
  });
25
- const editSession = vuuUtils.useEditSession();
26
- const { className, style } = useCell.useCell(column, classBase, false);
27
- const { ariaColIndex, CellRenderer, name, valueFormatter } = column;
26
+ const [hasError, setHasError] = react.useState(false);
27
+ const { className, style } = useCell.useCell(column, classBase, false, hasError);
28
+ const { ariaColIndex, CellRenderer, valueFormatter } = column;
28
29
  const handleDataItemEdited = react.useCallback(
29
30
  (editState, editPhase) => {
30
- const { isValid = true, previousValue = "", value: value2 } = editState;
31
31
  if (editPhase === "commit") {
32
- return editSession?.commit(
33
- dataRow.key,
34
- name,
35
- previousValue,
36
- value2,
37
- isValid
32
+ const { serverDataType = "string" } = column;
33
+ const typedValue = vuuUtils.getTypedValue(
34
+ String(editState.value),
35
+ serverDataType,
36
+ true
37
+ );
38
+ return onDataEdited?.(
39
+ {
40
+ ...editState,
41
+ dataRow,
42
+ columnName: column.name,
43
+ value: typedValue
44
+ },
45
+ editPhase
38
46
  );
39
47
  } else {
40
- editSession?.edit(dataRow.key, name, previousValue, value2);
48
+ setHasError(editState.isValid === false);
49
+ onDataEdited?.(
50
+ {
51
+ ...editState,
52
+ dataRow,
53
+ columnName: column.name
54
+ },
55
+ editPhase
56
+ );
41
57
  return void 0;
42
58
  }
43
59
  },
44
- [dataRow.key, editSession, name]
60
+ [column, dataRow, onDataEdited]
45
61
  );
46
62
  const handleClick = react.useCallback(
47
63
  (evt) => {
@@ -1 +1 @@
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 { MouseEventHandler, useCallback } from \"react\";\nimport { useCell } from \"../useCell\";\nimport { useHighlighting } from \"../useHighlighting\";\n\nimport tableCellCss from \"./TableCell.css\";\nimport { useEditSession } from \"@vuu-ui/vuu-utils\";\n\nconst classBase = \"vuuTableCell\";\n\nexport const TableCell = ({\n column,\n dataRow,\n onClick,\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 editSession = useEditSession();\n\n const { className, style } = useCell(column, classBase, false);\n const { ariaColIndex, CellRenderer, name, valueFormatter } = column;\n\n const handleDataItemEdited = useCallback<TableCellEditHandler>(\n (editState, editPhase) => {\n const { isValid = true, previousValue = \"\", value } = editState;\n if (editPhase === \"commit\") {\n return editSession?.commit(\n dataRow.key,\n name,\n previousValue,\n value,\n isValid,\n );\n } else {\n editSession?.edit(dataRow.key, name, previousValue, value);\n return undefined;\n }\n },\n [dataRow.key, editSession, name],\n );\n\n const handleClick = useCallback<MouseEventHandler>(\n (evt) => {\n onClick?.(evt, column);\n },\n [column, onClick],\n );\n\n const value = valueFormatter(dataRow[column.name]);\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 dataRow={dataRow}\n onEdit={handleDataItemEdited}\n searchPattern={searchPattern}\n />\n ) : (\n valueWithHighlighting\n )}\n </div>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","tableCellCss","useEditSession","useCell","useCallback","value","useHighlighting","jsx"],"mappings":";;;;;;;;;;;AAaA,MAAM,SAAY,GAAA,cAAA;AAEX,MAAM,YAAY,CAAC;AAAA,EACxB,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAgB,GAAA;AAClB,CAAsB,KAAA;AACpB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAAC,WAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,cAAcC,uBAAe,EAAA;AAEnC,EAAA,MAAM,EAAE,SAAW,EAAA,KAAA,KAAUC,eAAQ,CAAA,MAAA,EAAQ,WAAW,KAAK,CAAA;AAC7D,EAAA,MAAM,EAAE,YAAA,EAAc,YAAc,EAAA,IAAA,EAAM,gBAAmB,GAAA,MAAA;AAE7D,EAAA,MAAM,oBAAuB,GAAAC,iBAAA;AAAA,IAC3B,CAAC,WAAW,SAAc,KAAA;AACxB,MAAA,MAAM,EAAE,OAAU,GAAA,IAAA,EAAM,gBAAgB,EAAI,EAAA,KAAA,EAAAC,QAAU,GAAA,SAAA;AACtD,MAAA,IAAI,cAAc,QAAU,EAAA;AAC1B,QAAA,OAAO,WAAa,EAAA,MAAA;AAAA,UAClB,OAAQ,CAAA,GAAA;AAAA,UACR,IAAA;AAAA,UACA,aAAA;AAAA,UACAA,MAAAA;AAAA,UACA;AAAA,SACF;AAAA,OACK,MAAA;AACL,QAAA,WAAA,EAAa,IAAK,CAAA,OAAA,CAAQ,GAAK,EAAA,IAAA,EAAM,eAAeA,MAAK,CAAA;AACzD,QAAO,OAAA,KAAA,CAAA;AAAA;AACT,KACF;AAAA,IACA,CAAC,OAAA,CAAQ,GAAK,EAAA,WAAA,EAAa,IAAI;AAAA,GACjC;AAEA,EAAA,MAAM,WAAc,GAAAD,iBAAA;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,OAAQ,CAAA,MAAA,CAAO,IAAI,CAAC,CAAA;AACjD,EAAM,MAAA,qBAAA,GAAwBE,+BAAgB,CAAA,KAAA,EAAO,aAAa,CAAA;AAElE,EACE,uBAAAC,cAAA;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,mBAAAA,cAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,OAAA;AAAA,UACA,MAAQ,EAAA,oBAAA;AAAA,UACR;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 dataRow,\n onClick,\n onDataEdited,\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 dataRow,\n columnName: column.name,\n value: typedValue,\n },\n editPhase,\n );\n } else {\n setHasError(editState.isValid === false);\n onDataEdited?.(\n {\n ...editState,\n dataRow,\n columnName: column.name,\n },\n editPhase,\n );\n return undefined;\n }\n },\n [column, dataRow, onDataEdited],\n );\n\n const handleClick = useCallback<MouseEventHandler>(\n (evt) => {\n onClick?.(evt, column);\n },\n [column, onClick],\n );\n\n const value = valueFormatter(dataRow[column.name]);\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 dataRow={dataRow}\n onEdit={handleDataItemEdited}\n searchPattern={searchPattern}\n />\n ) : (\n valueWithHighlighting\n )}\n </div>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","tableCellCss","useState","useCell","useCallback","getTypedValue","useHighlighting","jsx"],"mappings":";;;;;;;;;;;AAaA,MAAM,SAAY,GAAA,cAAA;AAEX,MAAM,YAAY,CAAC;AAAA,EACxB,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAgB,GAAA;AAClB,CAAsB,KAAA;AACpB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAAC,WAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIC,eAAS,KAAK,CAAA;AAE9C,EAAM,MAAA,EAAE,WAAW,KAAM,EAAA,GAAIC,gBAAQ,MAAQ,EAAA,SAAA,EAAW,OAAO,QAAQ,CAAA;AACvE,EAAA,MAAM,EAAE,YAAA,EAAc,YAAc,EAAA,cAAA,EAAmB,GAAA,MAAA;AAGvD,EAAA,MAAM,oBAAuB,GAAAC,iBAAA;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,GAAAC,sBAAA;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,OAAA;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,OAAA;AAAA,YACA,YAAY,MAAO,CAAA;AAAA,WACrB;AAAA,UACA;AAAA,SACF;AACA,QAAO,OAAA,KAAA,CAAA;AAAA;AACT,KACF;AAAA,IACA,CAAC,MAAQ,EAAA,OAAA,EAAS,YAAY;AAAA,GAChC;AAEA,EAAA,MAAM,WAAc,GAAAD,iBAAA;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,OAAQ,CAAA,MAAA,CAAO,IAAI,CAAC,CAAA;AACjD,EAAM,MAAA,qBAAA,GAAwBE,+BAAgB,CAAA,KAAA,EAAO,aAAa,CAAA;AAElE,EACE,uBAAAC,cAAA;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,mBAAAA,cAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,OAAA;AAAA,UACA,MAAQ,EAAA,oBAAA;AAAA,UACR;AAAA;AAAA,OAGF,GAAA;AAAA;AAAA,GAEJ;AAEJ;;;;"}
@@ -13,7 +13,7 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
13
13
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
14
14
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
15
15
  var _range;
16
- class MovingDataRowWindow {
16
+ class DataRowMovingWindow {
17
17
  constructor({ from, to }) {
18
18
  __publicField(this, "data");
19
19
  __publicField(this, "rowCount", 0);
@@ -42,7 +42,7 @@ class MovingDataRowWindow {
42
42
  return this.data.find((row) => row.key === key);
43
43
  }
44
44
  isWithinRange(index) {
45
- return __privateGet(this, _range).isWithin(index);
45
+ return index < this.rowCount && __privateGet(this, _range).isWithin(index);
46
46
  }
47
47
  setRange({ from, to }) {
48
48
  if (from !== __privateGet(this, _range).from || to !== __privateGet(this, _range).to) {
@@ -95,5 +95,5 @@ class MovingDataRowWindow {
95
95
  }
96
96
  _range = new WeakMap();
97
97
 
98
- exports.MovingDataRowWindow = MovingDataRowWindow;
98
+ exports.DataRowMovingWindow = DataRowMovingWindow;
99
99
  //# sourceMappingURL=DataRowMovingWindow.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataRowMovingWindow.js","sources":["../../../../packages/vuu-table/src/table-data-source/DataRowMovingWindow.ts"],"sourcesContent":["import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { DataRow } from \"@vuu-ui/vuu-table-types\";\nimport { WindowRange } from \"@vuu-ui/vuu-utils\";\n\nexport class MovingDataRowWindow {\n public data: DataRow[];\n public rowCount = 0;\n #range: WindowRange;\n\n constructor({ from, to }: VuuRange) {\n this.#range = new WindowRange(from, to);\n //internal data is always 0 based, we add range.from to determine an offset\n this.data = new Array(Math.max(0, to - from));\n this.rowCount = 0;\n }\n\n setRowCount = (rowCount: number) => {\n if (rowCount < this.data.length) {\n this.data.length = rowCount;\n }\n\n this.rowCount = rowCount;\n };\n\n add(data: DataRow) {\n const { index } = data;\n if (this.isWithinRange(index)) {\n const internalIndex = index - this.#range.from;\n this.data[internalIndex] = data;\n }\n }\n\n getAtIndex(index: number) {\n return this.#range.isWithin(index) &&\n this.data[index - this.#range.from] != null\n ? this.data[index - this.#range.from]\n : undefined;\n }\n\n getByKey(key: string) {\n return this.data.find((row) => row.key === key);\n }\n\n isWithinRange(index: number) {\n return this.#range.isWithin(index);\n }\n\n setRange({ from, to }: VuuRange) {\n if (from !== this.#range.from || to !== this.#range.to) {\n const [overlapFrom, overlapTo] = this.#range.overlap(from, to);\n const newData = new Array(Math.max(0, to - from));\n for (let i = overlapFrom; i < overlapTo; i++) {\n const data = this.getAtIndex(i);\n if (data) {\n const index = i - from;\n newData[index] = data;\n }\n }\n this.data = newData;\n this.#range.from = from;\n this.#range.to = to;\n }\n }\n\n getSelectedRows() {\n return this.data.filter((dataRow) => dataRow.isSelected);\n }\n\n get hasData() {\n return this.data.some((d) => d !== undefined);\n }\n\n /**\n * This will throw if there is no data. Check `hasData` first\n * to guard against this, if not certain.\n */\n get firstRow() {\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i]) {\n return this.data[i];\n }\n }\n throw Error(`[DataRowMovingWinddow] firstRow, no data`);\n }\n\n get range() {\n return this.#range;\n }\n\n // TODO make this more performant, see implementation in\n // array-backed-moving-window - use same implementation\n get hasAllRowsWithinRange(): boolean {\n const { from, to } = this.#range;\n\n for (let i = from; i < to; i++) {\n if (this.getAtIndex(i) === undefined) {\n return false;\n }\n }\n return true;\n }\n}\n"],"names":["WindowRange"],"mappings":"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"}
1
+ {"version":3,"file":"DataRowMovingWindow.js","sources":["../../../../packages/vuu-table/src/table-data-source/DataRowMovingWindow.ts"],"sourcesContent":["import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { DataRow } from \"@vuu-ui/vuu-table-types\";\nimport { WindowRange } from \"@vuu-ui/vuu-utils\";\n\nexport class DataRowMovingWindow {\n public data: DataRow[];\n public rowCount = 0;\n #range: WindowRange;\n\n constructor({ from, to }: VuuRange) {\n this.#range = new WindowRange(from, to);\n //internal data is always 0 based, we add range.from to determine an offset\n this.data = new Array(Math.max(0, to - from));\n this.rowCount = 0;\n }\n\n setRowCount = (rowCount: number) => {\n if (rowCount < this.data.length) {\n this.data.length = rowCount;\n }\n\n this.rowCount = rowCount;\n };\n\n add(data: DataRow) {\n const { index } = data;\n if (this.isWithinRange(index)) {\n const internalIndex = index - this.#range.from;\n this.data[internalIndex] = data;\n }\n }\n\n getAtIndex(index: number) {\n return this.#range.isWithin(index) &&\n this.data[index - this.#range.from] != null\n ? this.data[index - this.#range.from]\n : undefined;\n }\n\n getByKey(key: string) {\n return this.data.find((row) => row.key === key);\n }\n\n isWithinRange(index: number) {\n return index < this.rowCount && this.#range.isWithin(index);\n }\n\n setRange({ from, to }: VuuRange) {\n if (from !== this.#range.from || to !== this.#range.to) {\n const [overlapFrom, overlapTo] = this.#range.overlap(from, to);\n const newData = new Array(Math.max(0, to - from));\n for (let i = overlapFrom; i < overlapTo; i++) {\n const data = this.getAtIndex(i);\n if (data) {\n const index = i - from;\n newData[index] = data;\n }\n }\n this.data = newData;\n this.#range.from = from;\n this.#range.to = to;\n }\n }\n\n getSelectedRows() {\n return this.data.filter((dataRow) => dataRow.isSelected);\n }\n\n get hasData() {\n return this.data.some((d) => d !== undefined);\n }\n\n /**\n * This will throw if there is no data. Check `hasData` first\n * to guard against this, if not certain.\n */\n get firstRow() {\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i]) {\n return this.data[i];\n }\n }\n throw Error(`[DataRowMovingWinddow] firstRow, no data`);\n }\n\n get range() {\n return this.#range;\n }\n\n // TODO make this more performant, see implementation in\n // array-backed-moving-window - use same implementation\n get hasAllRowsWithinRange(): boolean {\n const { from, to } = this.#range;\n\n for (let i = from; i < to; i++) {\n if (this.getAtIndex(i) === undefined) {\n return false;\n }\n }\n return true;\n }\n}\n"],"names":["WindowRange"],"mappings":"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"}
@@ -49,7 +49,7 @@ const useDataSource = ({
49
49
  };
50
50
  }, [autoSelect, dataSource, handleConfigChange]);
51
51
  const dataRowWindow = react.useMemo(
52
- () => new DataRowMovingWindow.MovingDataRowWindow(rangeRef.current.withBuffer),
52
+ () => new DataRowMovingWindow.DataRowMovingWindow(rangeRef.current.withBuffer),
53
53
  []
54
54
  );
55
55
  const handleResume = react.useCallback(() => {
@@ -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 SchemaColumn,\n} from \"@vuu-ui/vuu-data-types\";\nimport { SelectRowRequest, VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { TableProps } from \"../Table\";\nimport {\n DataRow,\n TableRowSelectHandlerInternal,\n} from \"@vuu-ui/vuu-table-types\";\nimport { MovingDataRowWindow } from \"./DataRowMovingWindow\";\nimport { dataRowFactory, DataRowFunc } from \"../data-row/DataRow\";\n\nconst NullDataRow = () => ({}) as DataRow;\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 dataRows = useRef<DataRow[]>([]);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<Range>(dataSource.range);\n const dataRowRef = useRef<DataRowFunc>(NullDataRow);\n const setColumnsRef = useRef<undefined | ((columns: string[]) => void)>(\n undefined,\n );\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 dataRowWindow = useMemo(\n () => new MovingDataRowWindow(rangeRef.current.withBuffer),\n [],\n );\n\n const handleResume = useCallback(() => {\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 dataRowWindow.setRange(dataSource.range.withBuffer);\n }\n }, [dataRowWindow, dataSource]);\n\n useEffect(() => {\n return () => {\n dataSource.removeListener(\"resumed\", handleResume);\n };\n }, [dataSource, handleResume]);\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n const { current: DataRow } = dataRowRef;\n for (const row of updates) {\n // for now, we create a new DataRow each time\n dataRowWindow.add(DataRow(row));\n }\n dataRows.current = dataRowWindow.data;\n if (isMounted.current) {\n // TODO do we ever need to worry about missing updates here ?\n forceUpdate({});\n }\n },\n [dataRowWindow],\n );\n\n const selectRow = useCallback(\n (dataRow: DataRow) => {\n const rowKey = dataRow.key;\n dataSource.select?.({\n preserveExistingSelection: false,\n rowKey,\n type: \"SELECT_ROW\",\n } as SelectRowRequest);\n onSelect?.(dataRow);\n },\n [dataSource, onSelect],\n );\n\n const createDataRow = useCallback(\n (columns: string[], schemaColumns: readonly SchemaColumn[]) => {\n const [DataRow, setColumns] = dataRowFactory(columns, schemaColumns);\n dataRowRef.current = DataRow;\n setColumnsRef.current = setColumns;\n },\n [],\n );\n\n const datasourceMessageHandler: DataSourceSubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n createDataRow(message.columns, message.tableSchema.columns);\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n // const size = dataRowWindow.data.length;\n dataRowWindow.setRowCount(message.size);\n totalRowCountRef.current = message.size;\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 dataRow = dataRowWindow.getByKey(autoSelect);\n if (dataRow) {\n selectRow(dataRow);\n } else {\n console.warn(\n `[useDataSource] autoSelect row key ${autoSelect} not in viewport`,\n );\n }\n } else if (dataRowWindow.hasData) {\n selectRow(dataRowWindow.firstRow);\n }\n }\n } else if (message.size === 0) {\n setData([]);\n } else if (typeof message.size === \"number\") {\n dataRows.current = dataRowWindow.data;\n hasUpdated.current = true;\n }\n } else if (message.type === \"viewport-clear\") {\n onSizeChange?.(0);\n dataRowWindow.setRowCount(0);\n setData([]);\n forceUpdate({});\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [\n autoSelect,\n createDataRow,\n dataRowWindow,\n onSizeChange,\n onSubscribed,\n selectRow,\n setData,\n ],\n );\n\n const getSelectedRows = useCallback(() => {\n return dataRowWindow.getSelectedRows();\n }, [dataRowWindow]);\n\n useEffect(() => {\n if (dataSource.status === \"disabled\") {\n dataSource.enable?.(datasourceMessageHandler);\n }\n }, [dataSource, datasourceMessageHandler]);\n\n useMemo(() => {\n setColumnsRef.current?.(dataSource.columns);\n }, [dataSource.columns]);\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 dataRowWindow.setRange(range.withBuffer);\n\n if (\n dataSource.status !== \"subscribed\" &&\n dataSource.status !== \"subscribing\" &&\n dataSource.status !== \"enabling\"\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 dataRowWindow,\n dataSource,\n datasourceMessageHandler,\n renderBufferSize,\n revealSelected,\n ],\n );\n\n useEffect(() => {\n if (dataSource.status !== \"initialising\") {\n const { columns, tableSchema } = dataSource;\n if (tableSchema) {\n createDataRow(columns, tableSchema.columns);\n } else {\n throw Error(\n `[useDataSource] a resumed dataSource must have a tableSchema`,\n );\n }\n dataSource.resume?.(datasourceMessageHandler);\n\n if (dataSource.range.from > 0) {\n // UI does not currently restore scroll position, so always reset to top of dataset\n const { from, to } = rangeRef.current.reset;\n setRange({ from, to });\n }\n }\n return () => {\n dataSource.suspend?.(\n suspenseProps?.escalateToDisable,\n suspenseProps?.escalateDelay,\n );\n };\n }, [\n createDataRow,\n dataSource,\n datasourceMessageHandler,\n setRange,\n suspenseProps,\n ]);\n\n return {\n dataRows: dataRows.current,\n dataRowsRef: dataRows,\n getSelectedRows,\n range: rangeRef.current,\n setRange,\n };\n};\n"],"names":["useState","useRef","useCallback","useEffect","useMemo","MovingDataRowWindow","DataRow","dataRowFactory","Range"],"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 SchemaColumn,\n} from \"@vuu-ui/vuu-data-types\";\nimport { SelectRowRequest, VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { TableProps } from \"../Table\";\nimport {\n DataRow,\n TableRowSelectHandlerInternal,\n} from \"@vuu-ui/vuu-table-types\";\nimport { DataRowMovingWindow } from \"./DataRowMovingWindow\";\nimport { dataRowFactory, DataRowFunc } from \"../data-row/DataRow\";\n\nconst NullDataRow = () => ({}) as DataRow;\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 dataRows = useRef<DataRow[]>([]);\n const isMounted = useRef(true);\n const hasUpdated = useRef(false);\n const rangeRef = useRef<Range>(dataSource.range);\n const dataRowRef = useRef<DataRowFunc>(NullDataRow);\n const setColumnsRef = useRef<undefined | ((columns: string[]) => void)>(\n undefined,\n );\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 dataRowWindow = useMemo(\n () => new DataRowMovingWindow(rangeRef.current.withBuffer),\n [],\n );\n\n const handleResume = useCallback(() => {\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 dataRowWindow.setRange(dataSource.range.withBuffer);\n }\n }, [dataRowWindow, dataSource]);\n\n useEffect(() => {\n return () => {\n dataSource.removeListener(\"resumed\", handleResume);\n };\n }, [dataSource, handleResume]);\n\n const setData = useCallback(\n (updates: DataSourceRow[]) => {\n const { current: DataRow } = dataRowRef;\n for (const row of updates) {\n // for now, we create a new DataRow each time\n dataRowWindow.add(DataRow(row));\n }\n dataRows.current = dataRowWindow.data;\n if (isMounted.current) {\n // TODO do we ever need to worry about missing updates here ?\n forceUpdate({});\n }\n },\n [dataRowWindow],\n );\n\n const selectRow = useCallback(\n (dataRow: DataRow) => {\n const rowKey = dataRow.key;\n dataSource.select?.({\n preserveExistingSelection: false,\n rowKey,\n type: \"SELECT_ROW\",\n } as SelectRowRequest);\n onSelect?.(dataRow);\n },\n [dataSource, onSelect],\n );\n\n const createDataRow = useCallback(\n (columns: string[], schemaColumns: readonly SchemaColumn[]) => {\n const [DataRow, setColumns] = dataRowFactory(columns, schemaColumns);\n dataRowRef.current = DataRow;\n setColumnsRef.current = setColumns;\n },\n [],\n );\n\n const datasourceMessageHandler: DataSourceSubscribeCallback = useCallback(\n (message) => {\n if (message.type === \"subscribed\") {\n createDataRow(message.columns, message.tableSchema.columns);\n onSubscribed?.(message);\n } else if (message.type === \"viewport-update\") {\n if (typeof message.size === \"number\") {\n onSizeChange?.(message.size);\n // const size = dataRowWindow.data.length;\n dataRowWindow.setRowCount(message.size);\n totalRowCountRef.current = message.size;\n\n // if (dataRowWindow.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 dataRow = dataRowWindow.getByKey(autoSelect);\n if (dataRow) {\n selectRow(dataRow);\n } else {\n console.warn(\n `[useDataSource] autoSelect row key ${autoSelect} not in viewport`,\n );\n }\n } else if (dataRowWindow.hasData) {\n selectRow(dataRowWindow.firstRow);\n }\n }\n } else if (message.size === 0) {\n setData([]);\n } else if (typeof message.size === \"number\") {\n dataRows.current = dataRowWindow.data;\n hasUpdated.current = true;\n }\n } else if (message.type === \"viewport-clear\") {\n onSizeChange?.(0);\n dataRowWindow.setRowCount(0);\n setData([]);\n forceUpdate({});\n } else {\n console.log(`useDataSource unexpected message ${message.type}`);\n }\n },\n [\n autoSelect,\n createDataRow,\n dataRowWindow,\n onSizeChange,\n onSubscribed,\n selectRow,\n setData,\n ],\n );\n\n const getSelectedRows = useCallback(() => {\n return dataRowWindow.getSelectedRows();\n }, [dataRowWindow]);\n\n useEffect(() => {\n if (dataSource.status === \"disabled\") {\n dataSource.enable?.(datasourceMessageHandler);\n }\n }, [dataSource, datasourceMessageHandler]);\n\n useMemo(() => {\n setColumnsRef.current?.(dataSource.columns);\n }, [dataSource.columns]);\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 dataRowWindow.setRange(range.withBuffer);\n\n if (\n dataSource.status !== \"subscribed\" &&\n dataSource.status !== \"subscribing\" &&\n dataSource.status !== \"enabling\"\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 dataRowWindow,\n dataSource,\n datasourceMessageHandler,\n renderBufferSize,\n revealSelected,\n ],\n );\n\n useEffect(() => {\n if (dataSource.status !== \"initialising\") {\n const { columns, tableSchema } = dataSource;\n if (tableSchema) {\n createDataRow(columns, tableSchema.columns);\n } else {\n throw Error(\n `[useDataSource] a resumed dataSource must have a tableSchema`,\n );\n }\n dataSource.resume?.(datasourceMessageHandler);\n\n if (dataSource.range.from > 0) {\n // UI does not currently restore scroll position, so always reset to top of dataset\n const { from, to } = rangeRef.current.reset;\n setRange({ from, to });\n }\n }\n return () => {\n dataSource.suspend?.(\n suspenseProps?.escalateToDisable,\n suspenseProps?.escalateDelay,\n );\n };\n }, [\n createDataRow,\n dataSource,\n datasourceMessageHandler,\n setRange,\n suspenseProps,\n ]);\n\n return {\n dataRows: dataRows.current,\n dataRowsRef: dataRows,\n getSelectedRows,\n range: rangeRef.current,\n setRange,\n };\n};\n"],"names":["useState","useRef","useCallback","useEffect","useMemo","DataRowMovingWindow","DataRow","dataRowFactory","Range"],"mappings":"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"}
@@ -22,12 +22,9 @@ const getLevelUp = (containerRef, cellPos) => {
22
22
  }
23
23
  return cellPos;
24
24
  };
25
- const getTableCellElement = (containerRef, [rowIdx, colIdx]) => {
25
+ const getTableCell = (containerRef, [rowIdx, colIdx]) => {
26
26
  const cssQuery = dataCellQuery(rowIdx, colIdx);
27
- return containerRef.current?.querySelector(cssQuery);
28
- };
29
- const getTableCell = (containerRef, cellPos) => {
30
- const cell = getTableCellElement(containerRef, cellPos);
27
+ const cell = containerRef.current?.querySelector(cssQuery);
31
28
  if (cellIsEditable(cell)) {
32
29
  const focusableContent = cell.querySelector(
33
30
  `button,input[type="checkbox"]`
@@ -120,25 +117,6 @@ function getNextCellPos(key, [rowIdx, colIdx], columnCount, maxRowIndex) {
120
117
  }
121
118
  return [rowIdx, colIdx];
122
119
  }
123
- const getNextEditableCellPos = (containerRef, key, cellPos, columnCount, maxRowIndex) => {
124
- let [lastRowIdx, lastColIdx] = cellPos;
125
- do {
126
- const [nextRowIdx, nextColIdx] = getNextCellPos(
127
- key,
128
- [lastRowIdx, lastColIdx],
129
- columnCount,
130
- maxRowIndex
131
- );
132
- if (nextRowIdx === lastRowIdx && nextColIdx === lastColIdx) {
133
- return cellPos;
134
- }
135
- const cell = getTableCellElement(containerRef, [nextRowIdx, nextColIdx]);
136
- if (cellIsEditable(cell)) {
137
- return [nextRowIdx, nextColIdx];
138
- }
139
- [lastRowIdx, lastColIdx] = [nextRowIdx, nextColIdx];
140
- } while (true);
141
- };
142
120
  const getTreeNodeOperation = (containerRef, navigationStyle, cellPos, key, shiftKey) => {
143
121
  const cell = getTableCell(containerRef, cellPos);
144
122
  if (navigationStyle === "cell" && !cellIsGroupCell(cell)) {
@@ -196,10 +174,8 @@ exports.getFocusedCell = getFocusedCell;
196
174
  exports.getHeaderCell = getHeaderCell;
197
175
  exports.getLevelUp = getLevelUp;
198
176
  exports.getNextCellPos = getNextCellPos;
199
- exports.getNextEditableCellPos = getNextEditableCellPos;
200
177
  exports.getRowElementByAriaIndex = getRowElementByAriaIndex;
201
178
  exports.getTableCell = getTableCell;
202
- exports.getTableCellElement = getTableCellElement;
203
179
  exports.getTreeNodeOperation = getTreeNodeOperation;
204
180
  exports.headerCellQuery = headerCellQuery;
205
181
  exports.howFarIsRowOutsideViewport = howFarIsRowOutsideViewport;
@@ -1 +1 @@
1
- {"version":3,"file":"table-dom-utils.js","sources":["../../../packages/vuu-table/src/table-dom-utils.ts"],"sourcesContent":["import { RefObject } from \"react\";\nimport { ScrollDirection } from \"./useTableScroll\";\nimport {\n getAriaColIndex,\n getAriaRowIndex,\n type ArrowKey,\n type PageKey,\n} from \"@vuu-ui/vuu-utils\";\nimport type { CellPos } from \"@vuu-ui/vuu-table-types\";\n\nexport type NavigationKey = PageKey | ArrowKey;\n\nexport const headerCellQuery = (colIdx: number) =>\n `.vuuTable-col-headers .vuuTableHeaderCell[aria-colindex='${colIdx}']`;\n\nexport const dataCellQuery = (ariaRowIdx: number, ariaColIdx: number) =>\n `.vuuTable-table [aria-rowindex='${ariaRowIdx}'] > [aria-colindex='${ariaColIdx}']`;\n\nexport const getLevelUp = (\n containerRef: RefObject<HTMLElement | null>,\n cellPos: CellPos,\n): CellPos => {\n const cell = getTableCell(containerRef, cellPos);\n let row = cell?.parentElement;\n const level = parseInt(row?.ariaLevel ?? \"1\");\n if (level > 1) {\n const targetLevel = `${level - 1}`;\n while (row !== null && row.ariaLevel !== targetLevel) {\n row = row.previousElementSibling as HTMLElement;\n }\n if (row) {\n const nextRowIndex = parseInt(row.ariaRowIndex ?? \"- 1\");\n if (nextRowIndex !== -1) {\n return [nextRowIndex, 1];\n }\n }\n }\n return cellPos;\n};\n\nexport const getTableCellElement = (\n containerRef: RefObject<HTMLElement | null>,\n [rowIdx, colIdx]: CellPos,\n) => {\n const cssQuery = dataCellQuery(rowIdx, colIdx);\n return containerRef.current?.querySelector(cssQuery) as HTMLDivElement;\n};\n\nexport const getTableCell = (\n containerRef: RefObject<HTMLElement | null>,\n cellPos: CellPos,\n) => {\n const cell = getTableCellElement(containerRef, cellPos);\n\n if (cellIsEditable(cell)) {\n // Dropdown gets focus, Input does not\n const focusableContent = cell.querySelector(\n `button,input[type=\"checkbox\"]`,\n ) as HTMLElement;\n return focusableContent || cell;\n } else {\n return cell;\n }\n};\n\nexport const getHeaderCell = (\n containerRef: RefObject<HTMLElement | null>,\n columnName: string,\n) =>\n containerRef.current?.querySelector(\n `.vuuTableHeaderCell[data-column-name=\"${columnName}\"]`,\n ) as HTMLDivElement | null;\n\nexport const getFocusedCell = (el: HTMLElement | Element | null) => {\n if (el?.role == \"cell\" || el?.role === \"columnheader\") {\n return el as HTMLDivElement;\n } else {\n return el?.closest(\n \"[role='columnHeader'],[role='cell']\",\n ) as HTMLDivElement | null;\n }\n};\n\nexport const cellIsEditable = (cell: HTMLDivElement | null) =>\n cell?.classList.contains(\"vuuTableCell-editable\");\n\nexport const cellDropdownShowing = (cell: HTMLDivElement | null) => {\n if (cellIsEditable(cell)) {\n return cell?.querySelector('.saltDropdown[aria-expanded=\"true\"]') !== null;\n }\n return false;\n};\n\nconst cellIsGroupCell = (cell: HTMLElement | null) =>\n cell?.classList.contains(\"vuuTableGroupCell\");\n\nconst rowIsExpanded = (cell: HTMLElement) => {\n switch (cell.parentElement?.ariaExpanded) {\n case \"true\":\n return true;\n case \"false\":\n return false;\n default:\n return undefined;\n }\n};\n\nexport const cellIsTextInput = (cell: HTMLElement) =>\n cell.querySelector(\".vuuTableInputCell\") !== null;\n\nexport const getRowElementByAriaIndex = (\n container: HTMLDivElement | EventTarget,\n rowIndex: number,\n) => {\n if (rowIndex === -1) {\n return null;\n } else {\n const activeRow = (container as HTMLElement).querySelector(\n `[aria-rowindex=\"${rowIndex}\"]`,\n ) as HTMLElement;\n\n if (activeRow) {\n return activeRow;\n } else {\n throw Error(\n `getRowElementAtIndex no row found for index index ${rowIndex}`,\n );\n }\n }\n};\n\nexport const getIndexFromCellElement = (cellElement: HTMLElement | null) =>\n getAriaColIndex(cellElement);\n\nexport const getAriaCellPos = (tableCell: HTMLDivElement): CellPos => {\n const focusedRow = tableCell.closest(\"[role='row']\") as HTMLElement;\n return [getAriaRowIndex(focusedRow), getAriaColIndex(tableCell)];\n};\n\nconst closestRow = (el: HTMLElement) =>\n el.closest('[role=\"row\"]') as HTMLElement;\n\nexport const closestRowIndex = (el: HTMLElement) =>\n getAriaRowIndex(closestRow(el));\n\nexport function getNextCellPos(\n key: ArrowKey,\n [rowIdx, colIdx]: CellPos,\n columnCount: number,\n maxRowIndex: number,\n): CellPos {\n if (key === \"ArrowUp\") {\n if (rowIdx > -1) {\n return [rowIdx - 1, colIdx];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowDown\") {\n if (rowIdx === -1) {\n return [1, colIdx];\n } else if (rowIdx === maxRowIndex) {\n return [rowIdx, colIdx];\n } else {\n return [rowIdx + 1, colIdx];\n }\n } else if (key === \"ArrowRight\") {\n if (colIdx < columnCount) {\n return [rowIdx, colIdx + 1];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowLeft\") {\n if (colIdx > 1) {\n return [rowIdx, colIdx - 1];\n } else {\n return [rowIdx, colIdx];\n }\n }\n return [rowIdx, colIdx];\n}\n\nexport const getNextEditableCellPos = (\n containerRef: RefObject<HTMLElement | null>,\n key: ArrowKey,\n cellPos: CellPos,\n columnCount: number,\n maxRowIndex: number,\n) => {\n let [lastRowIdx, lastColIdx] = cellPos;\n do {\n const [nextRowIdx, nextColIdx] = getNextCellPos(\n key,\n [lastRowIdx, lastColIdx],\n columnCount,\n maxRowIndex,\n );\n if (nextRowIdx === lastRowIdx && nextColIdx === lastColIdx) {\n // we have not moved, we never found a new editable cell, bail\n return cellPos;\n }\n\n const cell = getTableCellElement(containerRef, [nextRowIdx, nextColIdx]);\n if (cellIsEditable(cell)) {\n return [nextRowIdx, nextColIdx];\n }\n // keep going\n [lastRowIdx, lastColIdx] = [nextRowIdx, nextColIdx];\n // eslint-disable-next-line no-constant-condition\n } while (true);\n};\n\nexport type TreeNodeOperation = \"expand\" | \"collapse\" | \"level-up\";\n\nexport const getTreeNodeOperation = (\n containerRef: RefObject<HTMLElement | null>,\n navigationStyle: \"cell\" | \"tree\",\n cellPos: CellPos,\n key: NavigationKey,\n shiftKey: boolean,\n): TreeNodeOperation | undefined => {\n const cell = getTableCell(containerRef, cellPos);\n if (navigationStyle === \"cell\" && !cellIsGroupCell(cell)) {\n return undefined;\n }\n if (navigationStyle == \"cell\" && !shiftKey) {\n return undefined;\n }\n if (cellIsGroupCell(cell)) {\n const isExpanded = rowIsExpanded(cell);\n if (isExpanded === true) {\n if (key === \"ArrowLeft\") {\n return \"collapse\";\n }\n } else if (isExpanded === false) {\n if (key === \"ArrowRight\") {\n return \"expand\";\n } else if (key === \"ArrowLeft\") {\n return \"level-up\";\n }\n } else if (key === \"ArrowLeft\") {\n return \"level-up\";\n }\n }\n};\n\nconst NO_SCROLL_NECESSARY = [undefined, undefined] as const;\n\nexport const howFarIsRowOutsideViewport = (\n rowEl: HTMLElement,\n totalHeaderHeight: number,\n contentContainer = rowEl.closest(\".vuuTable-contentContainer\"),\n): readonly [ScrollDirection | undefined, number | undefined] => {\n //TODO lots of scope for optimisation here\n if (contentContainer) {\n // TODO take totalHeaderHeight into consideration\n const viewport = contentContainer?.getBoundingClientRect();\n const upperBoundary = viewport.top + totalHeaderHeight;\n const row = rowEl.getBoundingClientRect();\n if (row) {\n if (row.bottom > viewport.bottom) {\n return [\"down\", row.bottom - viewport.bottom];\n } else if (row.top < upperBoundary) {\n return [\"up\", row.top - upperBoundary];\n } else {\n return NO_SCROLL_NECESSARY;\n }\n } else {\n throw Error(\"Whats going on, row not found\");\n }\n } else {\n throw Error(\"Whats going on, scrollbar container not found\");\n }\n};\n"],"names":["getAriaRowIndex","getAriaColIndex"],"mappings":";;;;AAYO,MAAM,eAAkB,GAAA,CAAC,MAC9B,KAAA,CAAA,yDAAA,EAA4D,MAAM,CAAA,EAAA;AAE7D,MAAM,gBAAgB,CAAC,UAAA,EAAoB,eAChD,CAAmC,gCAAA,EAAA,UAAU,wBAAwB,UAAU,CAAA,EAAA;AAEpE,MAAA,UAAA,GAAa,CACxB,YAAA,EACA,OACY,KAAA;AACZ,EAAM,MAAA,IAAA,GAAO,YAAa,CAAA,YAAA,EAAc,OAAO,CAAA;AAC/C,EAAA,IAAI,MAAM,IAAM,EAAA,aAAA;AAChB,EAAA,MAAM,KAAQ,GAAA,QAAA,CAAS,GAAK,EAAA,SAAA,IAAa,GAAG,CAAA;AAC5C,EAAA,IAAI,QAAQ,CAAG,EAAA;AACb,IAAM,MAAA,WAAA,GAAc,CAAG,EAAA,KAAA,GAAQ,CAAC,CAAA,CAAA;AAChC,IAAA,OAAO,GAAQ,KAAA,IAAA,IAAQ,GAAI,CAAA,SAAA,KAAc,WAAa,EAAA;AACpD,MAAA,GAAA,GAAM,GAAI,CAAA,sBAAA;AAAA;AAEZ,IAAA,IAAI,GAAK,EAAA;AACP,MAAA,MAAM,YAAe,GAAA,QAAA,CAAS,GAAI,CAAA,YAAA,IAAgB,KAAK,CAAA;AACvD,MAAA,IAAI,iBAAiB,CAAI,CAAA,EAAA;AACvB,QAAO,OAAA,CAAC,cAAc,CAAC,CAAA;AAAA;AACzB;AACF;AAEF,EAAO,OAAA,OAAA;AACT;AAEO,MAAM,sBAAsB,CACjC,YAAA,EACA,CAAC,MAAA,EAAQ,MAAM,CACZ,KAAA;AACH,EAAM,MAAA,QAAA,GAAW,aAAc,CAAA,MAAA,EAAQ,MAAM,CAAA;AAC7C,EAAO,OAAA,YAAA,CAAa,OAAS,EAAA,aAAA,CAAc,QAAQ,CAAA;AACrD;AAEa,MAAA,YAAA,GAAe,CAC1B,YAAA,EACA,OACG,KAAA;AACH,EAAM,MAAA,IAAA,GAAO,mBAAoB,CAAA,YAAA,EAAc,OAAO,CAAA;AAEtD,EAAI,IAAA,cAAA,CAAe,IAAI,CAAG,EAAA;AAExB,IAAA,MAAM,mBAAmB,IAAK,CAAA,aAAA;AAAA,MAC5B,CAAA,6BAAA;AAAA,KACF;AACA,IAAA,OAAO,gBAAoB,IAAA,IAAA;AAAA,GACtB,MAAA;AACL,IAAO,OAAA,IAAA;AAAA;AAEX;AAEO,MAAM,aAAgB,GAAA,CAC3B,YACA,EAAA,UAAA,KAEA,aAAa,OAAS,EAAA,aAAA;AAAA,EACpB,yCAAyC,UAAU,CAAA,EAAA;AACrD;AAEW,MAAA,cAAA,GAAiB,CAAC,EAAqC,KAAA;AAClE,EAAA,IAAI,EAAI,EAAA,IAAA,IAAQ,MAAU,IAAA,EAAA,EAAI,SAAS,cAAgB,EAAA;AACrD,IAAO,OAAA,EAAA;AAAA,GACF,MAAA;AACL,IAAA,OAAO,EAAI,EAAA,OAAA;AAAA,MACT;AAAA,KACF;AAAA;AAEJ;AAEO,MAAM,iBAAiB,CAAC,IAAA,KAC7B,IAAM,EAAA,SAAA,CAAU,SAAS,uBAAuB;AAErC,MAAA,mBAAA,GAAsB,CAAC,IAAgC,KAAA;AAClE,EAAI,IAAA,cAAA,CAAe,IAAI,CAAG,EAAA;AACxB,IAAO,OAAA,IAAA,EAAM,aAAc,CAAA,qCAAqC,CAAM,KAAA,IAAA;AAAA;AAExE,EAAO,OAAA,KAAA;AACT;AAEA,MAAM,kBAAkB,CAAC,IAAA,KACvB,IAAM,EAAA,SAAA,CAAU,SAAS,mBAAmB,CAAA;AAE9C,MAAM,aAAA,GAAgB,CAAC,IAAsB,KAAA;AAC3C,EAAQ,QAAA,IAAA,CAAK,eAAe,YAAc;AAAA,IACxC,KAAK,MAAA;AACH,MAAO,OAAA,IAAA;AAAA,IACT,KAAK,OAAA;AACH,MAAO,OAAA,KAAA;AAAA,IACT;AACE,MAAO,OAAA,KAAA,CAAA;AAAA;AAEb,CAAA;AAEO,MAAM,kBAAkB,CAAC,IAAA,KAC9B,IAAK,CAAA,aAAA,CAAc,oBAAoB,CAAM,KAAA;AAElC,MAAA,wBAAA,GAA2B,CACtC,SAAA,EACA,QACG,KAAA;AACH,EAAA,IAAI,aAAa,CAAI,CAAA,EAAA;AACnB,IAAO,OAAA,IAAA;AAAA,GACF,MAAA;AACL,IAAA,MAAM,YAAa,SAA0B,CAAA,aAAA;AAAA,MAC3C,mBAAmB,QAAQ,CAAA,EAAA;AAAA,KAC7B;AAEA,IAAA,IAAI,SAAW,EAAA;AACb,MAAO,OAAA,SAAA;AAAA,KACF,MAAA;AACL,MAAM,MAAA,KAAA;AAAA,QACJ,qDAAqD,QAAQ,CAAA;AAAA,OAC/D;AAAA;AACF;AAEJ;AAKa,MAAA,cAAA,GAAiB,CAAC,SAAuC,KAAA;AACpE,EAAM,MAAA,UAAA,GAAa,SAAU,CAAA,OAAA,CAAQ,cAAc,CAAA;AACnD,EAAA,OAAO,CAACA,wBAAgB,CAAA,UAAU,CAAG,EAAAC,wBAAA,CAAgB,SAAS,CAAC,CAAA;AACjE;AAEA,MAAM,UAAa,GAAA,CAAC,EAClB,KAAA,EAAA,CAAG,QAAQ,cAAc,CAAA;AAEpB,MAAM,kBAAkB,CAAC,EAAA,KAC9BD,wBAAgB,CAAA,UAAA,CAAW,EAAE,CAAC;AAEzB,SAAS,eACd,GACA,EAAA,CAAC,QAAQ,MAAM,CAAA,EACf,aACA,WACS,EAAA;AACT,EAAA,IAAI,QAAQ,SAAW,EAAA;AACrB,IAAA,IAAI,SAAS,CAAI,CAAA,EAAA;AACf,MAAO,OAAA,CAAC,MAAS,GAAA,CAAA,EAAG,MAAM,CAAA;AAAA,KACrB,MAAA;AACL,MAAO,OAAA,CAAC,QAAQ,MAAM,CAAA;AAAA;AACxB,GACF,MAAA,IAAW,QAAQ,WAAa,EAAA;AAC9B,IAAA,IAAI,WAAW,CAAI,CAAA,EAAA;AACjB,MAAO,OAAA,CAAC,GAAG,MAAM,CAAA;AAAA,KACnB,MAAA,IAAW,WAAW,WAAa,EAAA;AACjC,MAAO,OAAA,CAAC,QAAQ,MAAM,CAAA;AAAA,KACjB,MAAA;AACL,MAAO,OAAA,CAAC,MAAS,GAAA,CAAA,EAAG,MAAM,CAAA;AAAA;AAC5B,GACF,MAAA,IAAW,QAAQ,YAAc,EAAA;AAC/B,IAAA,IAAI,SAAS,WAAa,EAAA;AACxB,MAAO,OAAA,CAAC,MAAQ,EAAA,MAAA,GAAS,CAAC,CAAA;AAAA,KACrB,MAAA;AACL,MAAO,OAAA,CAAC,QAAQ,MAAM,CAAA;AAAA;AACxB,GACF,MAAA,IAAW,QAAQ,WAAa,EAAA;AAC9B,IAAA,IAAI,SAAS,CAAG,EAAA;AACd,MAAO,OAAA,CAAC,MAAQ,EAAA,MAAA,GAAS,CAAC,CAAA;AAAA,KACrB,MAAA;AACL,MAAO,OAAA,CAAC,QAAQ,MAAM,CAAA;AAAA;AACxB;AAEF,EAAO,OAAA,CAAC,QAAQ,MAAM,CAAA;AACxB;AAEO,MAAM,yBAAyB,CACpC,YAAA,EACA,GACA,EAAA,OAAA,EACA,aACA,WACG,KAAA;AACH,EAAI,IAAA,CAAC,UAAY,EAAA,UAAU,CAAI,GAAA,OAAA;AAC/B,EAAG,GAAA;AACD,IAAM,MAAA,CAAC,UAAY,EAAA,UAAU,CAAI,GAAA,cAAA;AAAA,MAC/B,GAAA;AAAA,MACA,CAAC,YAAY,UAAU,CAAA;AAAA,MACvB,WAAA;AAAA,MACA;AAAA,KACF;AACA,IAAI,IAAA,UAAA,KAAe,UAAc,IAAA,UAAA,KAAe,UAAY,EAAA;AAE1D,MAAO,OAAA,OAAA;AAAA;AAGT,IAAA,MAAM,OAAO,mBAAoB,CAAA,YAAA,EAAc,CAAC,UAAA,EAAY,UAAU,CAAC,CAAA;AACvE,IAAI,IAAA,cAAA,CAAe,IAAI,CAAG,EAAA;AACxB,MAAO,OAAA,CAAC,YAAY,UAAU,CAAA;AAAA;AAGhC,IAAA,CAAC,UAAY,EAAA,UAAU,CAAI,GAAA,CAAC,YAAY,UAAU,CAAA;AAAA,GAE3C,QAAA,IAAA;AACX;AAIO,MAAM,uBAAuB,CAClC,YAAA,EACA,eACA,EAAA,OAAA,EACA,KACA,QACkC,KAAA;AAClC,EAAM,MAAA,IAAA,GAAO,YAAa,CAAA,YAAA,EAAc,OAAO,CAAA;AAC/C,EAAA,IAAI,eAAoB,KAAA,MAAA,IAAU,CAAC,eAAA,CAAgB,IAAI,CAAG,EAAA;AACxD,IAAO,OAAA,KAAA,CAAA;AAAA;AAET,EAAI,IAAA,eAAA,IAAmB,MAAU,IAAA,CAAC,QAAU,EAAA;AAC1C,IAAO,OAAA,KAAA,CAAA;AAAA;AAET,EAAI,IAAA,eAAA,CAAgB,IAAI,CAAG,EAAA;AACzB,IAAM,MAAA,UAAA,GAAa,cAAc,IAAI,CAAA;AACrC,IAAA,IAAI,eAAe,IAAM,EAAA;AACvB,MAAA,IAAI,QAAQ,WAAa,EAAA;AACvB,QAAO,OAAA,UAAA;AAAA;AACT,KACF,MAAA,IAAW,eAAe,KAAO,EAAA;AAC/B,MAAA,IAAI,QAAQ,YAAc,EAAA;AACxB,QAAO,OAAA,QAAA;AAAA,OACT,MAAA,IAAW,QAAQ,WAAa,EAAA;AAC9B,QAAO,OAAA,UAAA;AAAA;AACT,KACF,MAAA,IAAW,QAAQ,WAAa,EAAA;AAC9B,MAAO,OAAA,UAAA;AAAA;AACT;AAEJ;AAEA,MAAM,mBAAA,GAAsB,CAAC,KAAA,CAAA,EAAW,KAAS,CAAA,CAAA;AAEpC,MAAA,0BAAA,GAA6B,CACxC,KACA,EAAA,iBAAA,EACA,mBAAmB,KAAM,CAAA,OAAA,CAAQ,4BAA4B,CACE,KAAA;AAE/D,EAAA,IAAI,gBAAkB,EAAA;AAEpB,IAAM,MAAA,QAAA,GAAW,kBAAkB,qBAAsB,EAAA;AACzD,IAAM,MAAA,aAAA,GAAgB,SAAS,GAAM,GAAA,iBAAA;AACrC,IAAM,MAAA,GAAA,GAAM,MAAM,qBAAsB,EAAA;AACxC,IAAA,IAAI,GAAK,EAAA;AACP,MAAI,IAAA,GAAA,CAAI,MAAS,GAAA,QAAA,CAAS,MAAQ,EAAA;AAChC,QAAA,OAAO,CAAC,MAAA,EAAQ,GAAI,CAAA,MAAA,GAAS,SAAS,MAAM,CAAA;AAAA,OAC9C,MAAA,IAAW,GAAI,CAAA,GAAA,GAAM,aAAe,EAAA;AAClC,QAAA,OAAO,CAAC,IAAA,EAAM,GAAI,CAAA,GAAA,GAAM,aAAa,CAAA;AAAA,OAChC,MAAA;AACL,QAAO,OAAA,mBAAA;AAAA;AACT,KACK,MAAA;AACL,MAAA,MAAM,MAAM,+BAA+B,CAAA;AAAA;AAC7C,GACK,MAAA;AACL,IAAA,MAAM,MAAM,+CAA+C,CAAA;AAAA;AAE/D;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"table-dom-utils.js","sources":["../../../packages/vuu-table/src/table-dom-utils.ts"],"sourcesContent":["import { RefObject } from \"react\";\nimport { ScrollDirection } from \"./useTableScroll\";\nimport {\n getAriaColIndex,\n getAriaRowIndex,\n type ArrowKey,\n type PageKey,\n} from \"@vuu-ui/vuu-utils\";\nimport type { CellPos } from \"@vuu-ui/vuu-table-types\";\n\nexport type NavigationKey = PageKey | ArrowKey;\n\nexport const headerCellQuery = (colIdx: number) =>\n `.vuuTable-col-headers .vuuTableHeaderCell[aria-colindex='${colIdx}']`;\n\nexport const dataCellQuery = (ariaRowIdx: number, ariaColIdx: number) =>\n `.vuuTable-table [aria-rowindex='${ariaRowIdx}'] > [aria-colindex='${ariaColIdx}']`;\n\nexport const getLevelUp = (\n containerRef: RefObject<HTMLElement | null>,\n cellPos: CellPos,\n): CellPos => {\n const cell = getTableCell(containerRef, cellPos);\n let row = cell?.parentElement;\n const level = parseInt(row?.ariaLevel ?? \"1\");\n if (level > 1) {\n const targetLevel = `${level - 1}`;\n while (row !== null && row.ariaLevel !== targetLevel) {\n row = row.previousElementSibling as HTMLElement;\n }\n if (row) {\n const nextRowIndex = parseInt(row.ariaRowIndex ?? \"- 1\");\n if (nextRowIndex !== -1) {\n return [nextRowIndex, 1];\n }\n }\n }\n return cellPos;\n};\nexport const getTableCell = (\n containerRef: RefObject<HTMLElement | null>,\n [rowIdx, colIdx]: CellPos,\n) => {\n const cssQuery = dataCellQuery(rowIdx, colIdx);\n const cell = containerRef.current?.querySelector(cssQuery) as HTMLDivElement;\n\n if (cellIsEditable(cell)) {\n // Dropdown gets focus, Input does not\n const focusableContent = cell.querySelector(\n `button,input[type=\"checkbox\"]`,\n ) as HTMLElement;\n return focusableContent || cell;\n } else {\n return cell;\n }\n};\n\nexport const getHeaderCell = (\n containerRef: RefObject<HTMLElement | null>,\n columnName: string,\n) =>\n containerRef.current?.querySelector(\n `.vuuTableHeaderCell[data-column-name=\"${columnName}\"]`,\n ) as HTMLDivElement | null;\n\nexport const getFocusedCell = (el: HTMLElement | Element | null) => {\n if (el?.role == \"cell\" || el?.role === \"columnheader\") {\n return el as HTMLDivElement;\n } else {\n return el?.closest(\n \"[role='columnHeader'],[role='cell']\",\n ) as HTMLDivElement | null;\n }\n};\n\nexport const cellIsEditable = (cell: HTMLDivElement | null) =>\n cell?.classList.contains(\"vuuTableCell-editable\");\n\nexport const cellDropdownShowing = (cell: HTMLDivElement | null) => {\n if (cellIsEditable(cell)) {\n return cell?.querySelector('.saltDropdown[aria-expanded=\"true\"]') !== null;\n }\n return false;\n};\n\nconst cellIsGroupCell = (cell: HTMLElement | null) =>\n cell?.classList.contains(\"vuuTableGroupCell\");\n\nconst rowIsExpanded = (cell: HTMLElement) => {\n switch (cell.parentElement?.ariaExpanded) {\n case \"true\":\n return true;\n case \"false\":\n return false;\n default:\n return undefined;\n }\n};\n\nexport const cellIsTextInput = (cell: HTMLElement) =>\n cell.querySelector(\".vuuTableInputCell\") !== null;\n\nexport const getRowElementByAriaIndex = (\n container: HTMLDivElement | EventTarget,\n rowIndex: number,\n) => {\n if (rowIndex === -1) {\n return null;\n } else {\n const activeRow = (container as HTMLElement).querySelector(\n `[aria-rowindex=\"${rowIndex}\"]`,\n ) as HTMLElement;\n\n if (activeRow) {\n return activeRow;\n } else {\n throw Error(\n `getRowElementAtIndex no row found for index index ${rowIndex}`,\n );\n }\n }\n};\n\nexport const getIndexFromCellElement = (cellElement: HTMLElement | null) =>\n getAriaColIndex(cellElement);\n\nexport const getAriaCellPos = (tableCell: HTMLDivElement): CellPos => {\n const focusedRow = tableCell.closest(\"[role='row']\") as HTMLElement;\n return [getAriaRowIndex(focusedRow), getAriaColIndex(tableCell)];\n};\n\nconst closestRow = (el: HTMLElement) =>\n el.closest('[role=\"row\"]') as HTMLElement;\n\nexport const closestRowIndex = (el: HTMLElement) =>\n getAriaRowIndex(closestRow(el));\n\nexport function getNextCellPos(\n key: ArrowKey,\n [rowIdx, colIdx]: CellPos,\n columnCount: number,\n maxRowIndex: number,\n): CellPos {\n if (key === \"ArrowUp\") {\n if (rowIdx > -1) {\n return [rowIdx - 1, colIdx];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowDown\") {\n if (rowIdx === -1) {\n return [1, colIdx];\n } else if (rowIdx === maxRowIndex) {\n return [rowIdx, colIdx];\n } else {\n return [rowIdx + 1, colIdx];\n }\n } else if (key === \"ArrowRight\") {\n if (colIdx < columnCount) {\n return [rowIdx, colIdx + 1];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowLeft\") {\n if (colIdx > 1) {\n return [rowIdx, colIdx - 1];\n } else {\n return [rowIdx, colIdx];\n }\n }\n return [rowIdx, colIdx];\n}\n\nexport type TreeNodeOperation = \"expand\" | \"collapse\" | \"level-up\";\n\nexport const getTreeNodeOperation = (\n containerRef: RefObject<HTMLElement | null>,\n navigationStyle: \"cell\" | \"tree\",\n cellPos: CellPos,\n key: NavigationKey,\n shiftKey: boolean,\n): TreeNodeOperation | undefined => {\n const cell = getTableCell(containerRef, cellPos);\n if (navigationStyle === \"cell\" && !cellIsGroupCell(cell)) {\n return undefined;\n }\n if (navigationStyle == \"cell\" && !shiftKey) {\n return undefined;\n }\n if (cellIsGroupCell(cell)) {\n const isExpanded = rowIsExpanded(cell);\n if (isExpanded === true) {\n if (key === \"ArrowLeft\") {\n return \"collapse\";\n }\n } else if (isExpanded === false) {\n if (key === \"ArrowRight\") {\n return \"expand\";\n } else if (key === \"ArrowLeft\") {\n return \"level-up\";\n }\n } else if (key === \"ArrowLeft\") {\n return \"level-up\";\n }\n }\n};\n\nconst NO_SCROLL_NECESSARY = [undefined, undefined] as const;\n\nexport const howFarIsRowOutsideViewport = (\n rowEl: HTMLElement,\n totalHeaderHeight: number,\n contentContainer = rowEl.closest(\".vuuTable-contentContainer\"),\n): readonly [ScrollDirection | undefined, number | undefined] => {\n //TODO lots of scope for optimisation here\n if (contentContainer) {\n // TODO take totalHeaderHeight into consideration\n const viewport = contentContainer?.getBoundingClientRect();\n const upperBoundary = viewport.top + totalHeaderHeight;\n const row = rowEl.getBoundingClientRect();\n if (row) {\n if (row.bottom > viewport.bottom) {\n return [\"down\", row.bottom - viewport.bottom];\n } else if (row.top < upperBoundary) {\n return [\"up\", row.top - upperBoundary];\n } else {\n return NO_SCROLL_NECESSARY;\n }\n } else {\n throw Error(\"Whats going on, row not found\");\n }\n } else {\n throw Error(\"Whats going on, scrollbar container not found\");\n }\n};\n"],"names":["getAriaRowIndex","getAriaColIndex"],"mappings":"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"}
package/cjs/useCell.js CHANGED
@@ -4,7 +4,7 @@ var vuuUtils = require('@vuu-ui/vuu-utils');
4
4
  var cx = require('clsx');
5
5
  var react = require('react');
6
6
 
7
- const useCell = (column, classBase, isHeader) => (
7
+ const useCell = (column, classBase, isHeader, hasError) => (
8
8
  // TODO measure perf without the memo, might not be worth the cost
9
9
  react.useMemo(() => {
10
10
  const className = cx(classBase, column.className, {
@@ -12,14 +12,15 @@ const useCell = (column, classBase, isHeader) => (
12
12
  vuuPinRight: column.pin === "right",
13
13
  vuuEndPin: isHeader && column.pinnedWidth,
14
14
  [`${classBase}-editable`]: column.editable,
15
- [`${classBase}-right`]: column.align === "right"
15
+ [`${classBase}-right`]: column.align === "right",
16
+ [`${classBase}-error`]: hasError
16
17
  });
17
18
  const style = vuuUtils.getColumnStyle(column);
18
19
  return {
19
20
  className,
20
21
  style
21
22
  };
22
- }, [classBase, column, isHeader])
23
+ }, [classBase, column, isHeader, hasError])
23
24
  );
24
25
 
25
26
  exports.useCell = useCell;
@@ -1 +1 @@
1
- {"version":3,"file":"useCell.js","sources":["../../../packages/vuu-table/src/useCell.ts"],"sourcesContent":["import { RuntimeColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { getColumnStyle } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { useMemo } from \"react\";\n\nexport const useCell = (\n column: RuntimeColumnDescriptor,\n classBase: string,\n isHeader?: boolean,\n) =>\n // TODO measure perf without the memo, might not be worth the cost\n useMemo(() => {\n const className = cx(classBase, column.className, {\n vuuPinLeft: column.pin === \"left\",\n vuuPinRight: column.pin === \"right\",\n vuuEndPin: isHeader && column.pinnedWidth,\n [`${classBase}-editable`]: column.editable,\n [`${classBase}-right`]: column.align === \"right\",\n });\n\n const style = getColumnStyle(column);\n return {\n className,\n style,\n };\n }, [classBase, column, isHeader]);\n"],"names":["useMemo","getColumnStyle"],"mappings":";;;;;;AAKa,MAAA,OAAA,GAAU,CACrB,MAAA,EACA,SACA,EAAA,QAAA;AAAA;AAAA,EAGAA,cAAQ,MAAM;AACZ,IAAA,MAAM,SAAY,GAAA,EAAA,CAAG,SAAW,EAAA,MAAA,CAAO,SAAW,EAAA;AAAA,MAChD,UAAA,EAAY,OAAO,GAAQ,KAAA,MAAA;AAAA,MAC3B,WAAA,EAAa,OAAO,GAAQ,KAAA,OAAA;AAAA,MAC5B,SAAA,EAAW,YAAY,MAAO,CAAA,WAAA;AAAA,MAC9B,CAAC,CAAA,EAAG,SAAS,CAAA,SAAA,CAAW,GAAG,MAAO,CAAA,QAAA;AAAA,MAClC,CAAC,CAAG,EAAA,SAAS,CAAQ,MAAA,CAAA,GAAG,OAAO,KAAU,KAAA;AAAA,KAC1C,CAAA;AAED,IAAM,MAAA,KAAA,GAAQC,wBAAe,MAAM,CAAA;AACnC,IAAO,OAAA;AAAA,MACL,SAAA;AAAA,MACA;AAAA,KACF;AAAA,GACC,EAAA,CAAC,SAAW,EAAA,MAAA,EAAQ,QAAQ,CAAC;AAAA;;;;"}
1
+ {"version":3,"file":"useCell.js","sources":["../../../packages/vuu-table/src/useCell.ts"],"sourcesContent":["import { RuntimeColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { getColumnStyle } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { useMemo } from \"react\";\n\nexport const useCell = (\n column: RuntimeColumnDescriptor,\n classBase: string,\n isHeader?: boolean,\n hasError?: boolean,\n) =>\n // TODO measure perf without the memo, might not be worth the cost\n useMemo(() => {\n const className = cx(classBase, column.className, {\n vuuPinLeft: column.pin === \"left\",\n vuuPinRight: column.pin === \"right\",\n vuuEndPin: isHeader && column.pinnedWidth,\n [`${classBase}-editable`]: column.editable,\n [`${classBase}-right`]: column.align === \"right\",\n [`${classBase}-error`]: hasError,\n });\n\n const style = getColumnStyle(column);\n return {\n className,\n style,\n };\n }, [classBase, column, isHeader, hasError]);\n"],"names":["useMemo","getColumnStyle"],"mappings":";;;;;;AAKO,MAAM,OAAU,GAAA,CACrB,MACA,EAAA,SAAA,EACA,QACA,EAAA,QAAA;AAAA;AAAA,EAGAA,cAAQ,MAAM;AACZ,IAAA,MAAM,SAAY,GAAA,EAAA,CAAG,SAAW,EAAA,MAAA,CAAO,SAAW,EAAA;AAAA,MAChD,UAAA,EAAY,OAAO,GAAQ,KAAA,MAAA;AAAA,MAC3B,WAAA,EAAa,OAAO,GAAQ,KAAA,OAAA;AAAA,MAC5B,SAAA,EAAW,YAAY,MAAO,CAAA,WAAA;AAAA,MAC9B,CAAC,CAAA,EAAG,SAAS,CAAA,SAAA,CAAW,GAAG,MAAO,CAAA,QAAA;AAAA,MAClC,CAAC,CAAG,EAAA,SAAS,CAAQ,MAAA,CAAA,GAAG,OAAO,KAAU,KAAA,OAAA;AAAA,MACzC,CAAC,CAAA,EAAG,SAAS,CAAA,MAAA,CAAQ,GAAG;AAAA,KACzB,CAAA;AAED,IAAM,MAAA,KAAA,GAAQC,wBAAe,MAAM,CAAA;AACnC,IAAO,OAAA;AAAA,MACL,SAAA;AAAA,MACA;AAAA,KACF;AAAA,KACC,CAAC,SAAA,EAAW,MAAQ,EAAA,QAAA,EAAU,QAAQ,CAAC;AAAA;;;;"}
@@ -4,16 +4,37 @@ var vuuUtils = require('@vuu-ui/vuu-utils');
4
4
  var react = require('react');
5
5
  var tableDomUtils = require('./table-dom-utils.js');
6
6
 
7
- const useCellEditing = ({ navigate }) => {
7
+ const useCellEditing = ({
8
+ focusCell,
9
+ navigate
10
+ }) => {
8
11
  const commitHandler = react.useCallback(() => {
9
12
  navigate();
10
13
  }, [navigate]);
14
+ const editModeHandler = react.useCallback(
15
+ (e) => {
16
+ const tableCell = vuuUtils.queryClosest(
17
+ e.target,
18
+ ".vuuTableCell",
19
+ true
20
+ );
21
+ if (e.type === "vuu-exit-edit-mode") {
22
+ tableCell.classList.remove("vuuEditing");
23
+ const cellPos = tableDomUtils.getAriaCellPos(tableCell);
24
+ focusCell(cellPos, true);
25
+ } else {
26
+ tableCell.classList.add("vuuEditing");
27
+ }
28
+ },
29
+ [focusCell]
30
+ );
11
31
  const editInput = react.useCallback(
12
32
  (evt) => {
13
33
  const cellEl = evt.target;
14
34
  const input = cellEl.matches("input") ? cellEl : cellEl.querySelector("input");
15
35
  if (input) {
16
36
  input.focus();
37
+ input.select();
17
38
  }
18
39
  },
19
40
  []
@@ -24,6 +45,8 @@ const useCellEditing = ({ navigate }) => {
24
45
  const input = cellEl.querySelector("input");
25
46
  if (input) {
26
47
  input.focus();
48
+ input.select();
49
+ vuuUtils.dispatchCustomEvent(input, "vuu-begin-edit");
27
50
  }
28
51
  },
29
52
  []
@@ -55,15 +78,19 @@ const useCellEditing = ({ navigate }) => {
55
78
  (e) => {
56
79
  const el = e.target;
57
80
  el.removeEventListener("vuu-commit", commitHandler, true);
81
+ el.removeEventListener("vuu-enter-edit-mode", editModeHandler, true);
82
+ el.removeEventListener("vuu-exit-edit-mode", editModeHandler, true);
58
83
  },
59
- [commitHandler]
84
+ [commitHandler, editModeHandler]
60
85
  );
61
86
  const handleFocus = react.useCallback(
62
87
  (e) => {
63
88
  const el = e.target;
64
89
  el.addEventListener("vuu-commit", commitHandler, true);
90
+ el.addEventListener("vuu-enter-edit-mode", editModeHandler, true);
91
+ el.addEventListener("vuu-exit-edit-mode", editModeHandler, true);
65
92
  },
66
- [commitHandler]
93
+ [commitHandler, editModeHandler]
67
94
  );
68
95
  return {
69
96
  onBlur: handleBlur,