@osdk/react-components 0.40.0 → 0.41.0-main-7e4163b0319ea02499200d07dc4969e11a5cb33c

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 (121) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/browser/object-table/ColumnConfigDialog.js +20 -15
  3. package/build/browser/object-table/ColumnConfigDialog.js.map +1 -1
  4. package/build/browser/object-table/EditableCell.js +4 -3
  5. package/build/browser/object-table/EditableCell.js.map +1 -1
  6. package/build/browser/object-table/MultiColumnSortDialog.js +15 -12
  7. package/build/browser/object-table/MultiColumnSortDialog.js.map +1 -1
  8. package/build/browser/object-table/ObjectTable.js +3 -1
  9. package/build/browser/object-table/ObjectTable.js.map +1 -1
  10. package/build/browser/object-table/ObjectTableApi.js.map +1 -1
  11. package/build/browser/object-table/ObjectTableLabels.js +130 -0
  12. package/build/browser/object-table/ObjectTableLabels.js.map +1 -0
  13. package/build/browser/object-table/SelectionCells.js +5 -2
  14. package/build/browser/object-table/SelectionCells.js.map +1 -1
  15. package/build/browser/object-table/Table.js +7 -3
  16. package/build/browser/object-table/Table.js.map +1 -1
  17. package/build/browser/object-table/TableEditContainer.js +8 -6
  18. package/build/browser/object-table/TableEditContainer.js.map +1 -1
  19. package/build/browser/object-table/TableHeaderWithPopover.js +11 -9
  20. package/build/browser/object-table/TableHeaderWithPopover.js.map +1 -1
  21. package/build/browser/object-table/components/AsyncValueCell.js +4 -2
  22. package/build/browser/object-table/components/AsyncValueCell.js.map +1 -1
  23. package/build/browser/public/experimental/object-table.js.map +1 -1
  24. package/build/browser/util/UserAgent.js +1 -1
  25. package/build/browser/util/UserAgent.js.map +1 -1
  26. package/build/cjs/chunk-323YOMG2.cjs +11 -0
  27. package/build/cjs/{chunk-4YFH7US6.cjs.map → chunk-323YOMG2.cjs.map} +1 -1
  28. package/build/cjs/{chunk-AY3WIKRW.cjs → chunk-4SGNGOAP.cjs} +490 -397
  29. package/build/cjs/chunk-4SGNGOAP.cjs.map +1 -0
  30. package/build/cjs/{chunk-5U23QYOL.cjs → chunk-6UIKJ4X4.cjs} +4 -4
  31. package/build/cjs/{chunk-5U23QYOL.cjs.map → chunk-6UIKJ4X4.cjs.map} +1 -1
  32. package/build/cjs/{chunk-PMQT5CIV.cjs → chunk-74V4AJ4A.cjs} +4 -4
  33. package/build/cjs/{chunk-PMQT5CIV.cjs.map → chunk-74V4AJ4A.cjs.map} +1 -1
  34. package/build/cjs/chunk-CWOMGAE4.cjs +11 -0
  35. package/build/cjs/{chunk-GNOUY65C.cjs.map → chunk-CWOMGAE4.cjs.map} +1 -1
  36. package/build/cjs/chunk-EMR3I6AL.cjs +11 -0
  37. package/build/cjs/{chunk-6U4W2HH5.cjs.map → chunk-EMR3I6AL.cjs.map} +1 -1
  38. package/build/cjs/{chunk-CEDJUDDR.cjs → chunk-GIKFNRWU.cjs} +4 -4
  39. package/build/cjs/{chunk-CEDJUDDR.cjs.map → chunk-GIKFNRWU.cjs.map} +1 -1
  40. package/build/cjs/{chunk-UQM4DWUN.cjs → chunk-GNXZZXHI.cjs} +3 -3
  41. package/build/cjs/chunk-GNXZZXHI.cjs.map +1 -0
  42. package/build/cjs/{chunk-ZKLRFU6R.cjs → chunk-JQAAJFKE.cjs} +4 -4
  43. package/build/cjs/{chunk-ZKLRFU6R.cjs.map → chunk-JQAAJFKE.cjs.map} +1 -1
  44. package/build/cjs/{chunk-IA32Z765.cjs → chunk-LIJJHXK6.cjs} +4 -4
  45. package/build/cjs/{chunk-IA32Z765.cjs.map → chunk-LIJJHXK6.cjs.map} +1 -1
  46. package/build/cjs/{chunk-MJC5CXYJ.cjs → chunk-LKDGFSTS.cjs} +4 -4
  47. package/build/cjs/{chunk-MJC5CXYJ.cjs.map → chunk-LKDGFSTS.cjs.map} +1 -1
  48. package/build/cjs/{chunk-PXCVMAUL.cjs → chunk-V2YDHJFF.cjs} +4 -4
  49. package/build/cjs/{chunk-PXCVMAUL.cjs.map → chunk-V2YDHJFF.cjs.map} +1 -1
  50. package/build/cjs/chunk-VOLJ5FDD.cjs +11 -0
  51. package/build/cjs/{chunk-XEDHHJ5U.cjs.map → chunk-VOLJ5FDD.cjs.map} +1 -1
  52. package/build/cjs/chunk-YXCVZKTN.cjs +11 -0
  53. package/build/cjs/{chunk-ACLCVBDB.cjs.map → chunk-YXCVZKTN.cjs.map} +1 -1
  54. package/build/cjs/public/experimental/action-form.cjs +4 -4
  55. package/build/cjs/public/experimental/cbac-picker.cjs +11 -11
  56. package/build/cjs/public/experimental/document-viewer.cjs +4 -4
  57. package/build/cjs/public/experimental/email-viewer.cjs +3 -3
  58. package/build/cjs/public/experimental/excel-viewer.cjs +3 -3
  59. package/build/cjs/public/experimental/filter-list.cjs +15 -15
  60. package/build/cjs/public/experimental/image-viewer.cjs +3 -3
  61. package/build/cjs/public/experimental/markdown-renderer.cjs +3 -3
  62. package/build/cjs/public/experimental/object-table.cjs +21 -21
  63. package/build/cjs/public/experimental/object-table.d.cts +136 -4
  64. package/build/cjs/public/experimental/pdf-viewer.cjs +7 -7
  65. package/build/cjs/public/experimental/tiff-renderer.cjs +3 -3
  66. package/build/cjs/public/experimental/video-viewer.cjs +3 -3
  67. package/build/cjs/public/experimental/xml-viewer.cjs +3 -3
  68. package/build/cjs/public/experimental.cjs +71 -71
  69. package/build/cjs/public/experimental.d.cts +1 -1
  70. package/build/esm/object-table/ColumnConfigDialog.js +20 -15
  71. package/build/esm/object-table/ColumnConfigDialog.js.map +1 -1
  72. package/build/esm/object-table/EditableCell.js +4 -3
  73. package/build/esm/object-table/EditableCell.js.map +1 -1
  74. package/build/esm/object-table/MultiColumnSortDialog.js +15 -12
  75. package/build/esm/object-table/MultiColumnSortDialog.js.map +1 -1
  76. package/build/esm/object-table/ObjectTable.js +3 -1
  77. package/build/esm/object-table/ObjectTable.js.map +1 -1
  78. package/build/esm/object-table/ObjectTableApi.js.map +1 -1
  79. package/build/esm/object-table/ObjectTableLabels.js +130 -0
  80. package/build/esm/object-table/ObjectTableLabels.js.map +1 -0
  81. package/build/esm/object-table/SelectionCells.js +5 -2
  82. package/build/esm/object-table/SelectionCells.js.map +1 -1
  83. package/build/esm/object-table/Table.js +7 -3
  84. package/build/esm/object-table/Table.js.map +1 -1
  85. package/build/esm/object-table/TableEditContainer.js +8 -6
  86. package/build/esm/object-table/TableEditContainer.js.map +1 -1
  87. package/build/esm/object-table/TableHeaderWithPopover.js +11 -9
  88. package/build/esm/object-table/TableHeaderWithPopover.js.map +1 -1
  89. package/build/esm/object-table/components/AsyncValueCell.js +4 -2
  90. package/build/esm/object-table/components/AsyncValueCell.js.map +1 -1
  91. package/build/esm/public/experimental/object-table.js.map +1 -1
  92. package/build/esm/util/UserAgent.js +1 -1
  93. package/build/esm/util/UserAgent.js.map +1 -1
  94. package/build/types/object-table/ColumnConfigDialog.d.ts +10 -1
  95. package/build/types/object-table/ColumnConfigDialog.d.ts.map +1 -1
  96. package/build/types/object-table/EditableCell.d.ts.map +1 -1
  97. package/build/types/object-table/MultiColumnSortDialog.d.ts +10 -1
  98. package/build/types/object-table/MultiColumnSortDialog.d.ts.map +1 -1
  99. package/build/types/object-table/ObjectTable.d.ts +1 -1
  100. package/build/types/object-table/ObjectTable.d.ts.map +1 -1
  101. package/build/types/object-table/ObjectTableApi.d.ts +9 -0
  102. package/build/types/object-table/ObjectTableApi.d.ts.map +1 -1
  103. package/build/types/object-table/ObjectTableLabels.d.ts +135 -0
  104. package/build/types/object-table/ObjectTableLabels.d.ts.map +1 -0
  105. package/build/types/object-table/SelectionCells.d.ts.map +1 -1
  106. package/build/types/object-table/Table.d.ts +7 -0
  107. package/build/types/object-table/Table.d.ts.map +1 -1
  108. package/build/types/object-table/TableEditContainer.d.ts.map +1 -1
  109. package/build/types/object-table/TableHeaderWithPopover.d.ts.map +1 -1
  110. package/build/types/object-table/components/AsyncValueCell.d.ts.map +1 -1
  111. package/build/types/public/experimental/object-table.d.ts +1 -0
  112. package/build/types/public/experimental/object-table.d.ts.map +1 -1
  113. package/docs/ObjectTable.md +1 -0
  114. package/package.json +6 -6
  115. package/build/cjs/chunk-4YFH7US6.cjs +0 -11
  116. package/build/cjs/chunk-6U4W2HH5.cjs +0 -11
  117. package/build/cjs/chunk-ACLCVBDB.cjs +0 -11
  118. package/build/cjs/chunk-AY3WIKRW.cjs.map +0 -1
  119. package/build/cjs/chunk-GNOUY65C.cjs +0 -11
  120. package/build/cjs/chunk-UQM4DWUN.cjs.map +0 -1
  121. package/build/cjs/chunk-XEDHHJ5U.cjs +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @osdk/react-components
2
2
 
3
+ ## 0.41.0-main-7e4163b0319ea02499200d07dc4969e11a5cb33c
4
+
5
+ ### Minor Changes
6
+
7
+ - 3b7e3a5: Add a `labels` prop to `ObjectTable`/`BaseTable` (and the standalone `ColumnConfigDialog`/`MultiColumnSortDialog`) so every user-facing string can be overridden for localization or wording. Any subset can be supplied; unset keys fall back to the built-in English defaults.
8
+ - 7e4163b: Restrict base-ui/react version to <1.4.0
9
+
3
10
  ## 0.40.0
4
11
 
5
12
  ### Minor Changes
@@ -24,8 +24,10 @@ import { Checkbox } from "../base-components/checkbox/Checkbox.js";
24
24
  import { Dialog } from "../base-components/dialog/Dialog.js";
25
25
  import { DraggableList } from "../base-components/draggable-list/DraggableList.js";
26
26
  import { SearchBar } from "../base-components/search-bar/SearchBar.js";
27
+ import { useObjectTableLabels, withObjectTableLabels } from "./ObjectTableLabels.js";
27
28
  import styles from "./ColumnConfigDialog.module.css.js";
28
- export function ColumnConfigDialog({
29
+ export const ColumnConfigDialog = withObjectTableLabels(ColumnConfigDialogInner);
30
+ function ColumnConfigDialogInner({
29
31
  isOpen,
30
32
  onClose,
31
33
  columnOptions,
@@ -34,6 +36,7 @@ export function ColumnConfigDialog({
34
36
  onApply,
35
37
  isValidConfig
36
38
  }) {
39
+ const labels = useObjectTableLabels();
37
40
  const [visibleColumns, setVisibleColumns] = useState([]);
38
41
  const [searchQuery, setSearchQuery] = useState("");
39
42
  const allColumns = useMemo(() => {
@@ -116,15 +119,18 @@ export function ColumnConfigDialog({
116
119
  }, [allColumns, searchQuery]);
117
120
  const footer = useMemo(() => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ActionButton, {
118
121
  onClick: onClose
119
- }, "Cancel"), /*#__PURE__*/React.createElement(ActionButton, {
122
+ }, labels.columnConfigCancel), /*#__PURE__*/React.createElement(ActionButton, {
120
123
  variant: "primary",
121
124
  onClick: handleApply,
122
125
  disabled: isApplyDisabled
123
- }, "Apply")), [onClose, handleApply, isApplyDisabled]);
126
+ }, labels.columnConfigApply)), [onClose, handleApply, isApplyDisabled, labels]);
127
+ const dialogTitle = useMemo(() => /*#__PURE__*/React.createElement("div", {
128
+ className: styles.title
129
+ }, /*#__PURE__*/React.createElement(Cog, null), labels.columnConfigTitle), [labels]);
124
130
  return /*#__PURE__*/React.createElement(Dialog, {
125
131
  isOpen: isOpen,
126
132
  onOpenChange: onClose,
127
- title: DialogTitle,
133
+ title: dialogTitle,
128
134
  footer: footer,
129
135
  className: styles.columnConfigDialog
130
136
  }, /*#__PURE__*/React.createElement("div", {
@@ -142,9 +148,6 @@ export function ColumnConfigDialog({
142
148
  filteredColumns: filteredAvailableColumns
143
149
  })));
144
150
  }
145
- const DialogTitle = /*#__PURE__*/React.createElement("div", {
146
- className: styles.title
147
- }, /*#__PURE__*/React.createElement(Cog, null), "Configure Table Columns");
148
151
  const getColumnConfig = (allColumns, visibleColumns) => {
149
152
  const hiddenColumns = allColumns.filter(col => !visibleColumns.some(v => v.id === col.id));
150
153
  return [...visibleColumns.map(col => ({
@@ -160,22 +163,23 @@ function VisibleColumnsList({
160
163
  onReorder,
161
164
  onRemove
162
165
  }) {
166
+ const labels = useObjectTableLabels();
163
167
  return /*#__PURE__*/React.createElement("div", {
164
168
  className: styles.visibleColumnsContainer
165
169
  }, /*#__PURE__*/React.createElement("div", {
166
170
  className: styles.sectionHeader
167
171
  }, /*#__PURE__*/React.createElement("div", {
168
172
  className: styles.sectionTitle
169
- }, /*#__PURE__*/React.createElement("span", null, "Visible Columns"), /*#__PURE__*/React.createElement("span", {
173
+ }, /*#__PURE__*/React.createElement("span", null, labels.columnConfigVisibleColumns), /*#__PURE__*/React.createElement("span", {
170
174
  className: styles.countTag
171
175
  }, columns.length)), /*#__PURE__*/React.createElement("div", {
172
176
  className: styles.sectionHint
173
- }, "Drag to reorder")), /*#__PURE__*/React.createElement(DraggableList, {
177
+ }, labels.columnConfigDragToReorder)), /*#__PURE__*/React.createElement(DraggableList, {
174
178
  items: columns,
175
179
  onReorder: onReorder,
176
180
  onRemove: onRemove,
177
181
  removeIconVariant: "trash",
178
- emptyMessage: "No visible columns",
182
+ emptyMessage: labels.columnConfigNoVisibleColumns,
179
183
  className: styles.columnList
180
184
  }));
181
185
  }
@@ -191,6 +195,7 @@ function AvailableColumnsList({
191
195
  const totalCount = filteredColumns.length;
192
196
  const allFilteredSelected = filteredColumns.every(col => visibleColumns.some(v => v.id === col.id));
193
197
  const someFilteredSelected = filteredColumns.some(col => visibleColumns.some(v => v.id === col.id));
198
+ const labels = useObjectTableLabels();
194
199
  const handleSelectAllClick = useCallback(() => {
195
200
  onSelectAll(filteredColumns);
196
201
  }, [filteredColumns, onSelectAll]);
@@ -198,11 +203,11 @@ function AvailableColumnsList({
198
203
  className: styles.availableColumnsContainer
199
204
  }, /*#__PURE__*/React.createElement("div", {
200
205
  className: classNames(styles.sectionHeader, styles.sectionTitle)
201
- }, "Add or Remove Columns"), /*#__PURE__*/React.createElement(SearchBar, {
206
+ }, labels.columnConfigAddOrRemoveColumns), /*#__PURE__*/React.createElement(SearchBar, {
202
207
  value: searchQuery,
203
208
  onChange: onSearchChange,
204
- placeholder: "Search...",
205
- "aria-label": "Search available columns",
209
+ placeholder: labels.columnConfigSearchPlaceholder,
210
+ "aria-label": labels.columnConfigSearchAriaLabel,
206
211
  className: styles.searchContainer
207
212
  }), /*#__PURE__*/React.createElement(Collapsible.Root, {
208
213
  defaultOpen: true,
@@ -216,7 +221,7 @@ function AvailableColumnsList({
216
221
  indeterminate: someFilteredSelected && !allFilteredSelected,
217
222
  onCheckedChange: handleSelectAllClick,
218
223
  className: styles.checkbox
219
- }), "All Columns"), /*#__PURE__*/React.createElement(Collapsible.Trigger, {
224
+ }), labels.columnConfigAllColumns), /*#__PURE__*/React.createElement(Collapsible.Trigger, {
220
225
  className: styles.categoryTrigger
221
226
  }, /*#__PURE__*/React.createElement("span", {
222
227
  className: styles.categoryCount
@@ -226,7 +231,7 @@ function AvailableColumnsList({
226
231
  className: styles.propertyList
227
232
  }, filteredColumns.length === 0 ? /*#__PURE__*/React.createElement("div", {
228
233
  className: styles.emptyState
229
- }, "No matching columns found") : filteredColumns.map(column => /*#__PURE__*/React.createElement(PropertyItem, {
234
+ }, labels.columnConfigNoMatchingColumns) : filteredColumns.map(column => /*#__PURE__*/React.createElement(PropertyItem, {
230
235
  key: column.id,
231
236
  column: column,
232
237
  isSelected: visibleColumns.some(v => v.id === column.id),
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnConfigDialog.js","names":["Collapsible","CaretDown","Cog","SmallInfoSign","arrayMove","classNames","React","useCallback","useEffect","useMemo","useState","ActionButton","Checkbox","Dialog","DraggableList","SearchBar","styles","ColumnConfigDialog","isOpen","onClose","columnOptions","currentVisibility","currentColumnOrder","onApply","isValidConfig","visibleColumns","setVisibleColumns","searchQuery","setSearchQuery","allColumns","map","opt","isVisible","id","label","name","visibleCols","filter","col","length","sort","a","b","indexA","indexOf","indexB","orderA","Infinity","orderB","handleApply","getColumnConfig","isValid","isApplyDisabled","handleReorderColumns","fromIndex","toIndex","items","handleRemoveColumn","columnId","prev","handleToggleColumn","column","isCurrentlyVisible","some","handleSearchChange","event","target","value","handleSelectAll","columns","allSelected","every","v","newColumns","filteredAvailableColumns","query","toLowerCase","trim","includes","footer","createElement","Fragment","onClick","variant","disabled","onOpenChange","title","DialogTitle","className","columnConfigDialog","dialogLayout","VisibleColumnsList","onReorder","onRemove","AvailableColumnsList","onSearchChange","onToggleColumn","onSelectAll","filteredColumns","hiddenColumns","visibleColumnsContainer","sectionHeader","sectionTitle","countTag","sectionHint","removeIconVariant","emptyMessage","columnList","selectedCount","totalCount","allFilteredSelected","someFilteredSelected","handleSelectAllClick","availableColumnsContainer","onChange","placeholder","searchContainer","Root","defaultOpen","propertiesList","categoryHeader","selectAllLabel","checked","indeterminate","onCheckedChange","checkbox","Trigger","categoryTrigger","categoryCount","caretIcon","Panel","propertyList","emptyState","PropertyItem","key","isSelected","onToggle","showInfoIcon","handleClick","propertyItem","propertyLabel","propertyName","infoIcon"],"sources":["ColumnConfigDialog.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Collapsible } from \"@base-ui/react/collapsible\";\nimport { CaretDown, Cog, SmallInfoSign } from \"@blueprintjs/icons\";\nimport { arrayMove } from \"@dnd-kit/sortable\";\nimport type { ColumnOrderState, VisibilityState } from \"@tanstack/react-table\";\nimport classNames from \"classnames\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { Checkbox } from \"../base-components/checkbox/Checkbox.js\";\nimport { Dialog } from \"../base-components/dialog/Dialog.js\";\nimport { DraggableList } from \"../base-components/draggable-list/DraggableList.js\";\nimport { SearchBar } from \"../base-components/search-bar/SearchBar.js\";\nimport type { ColumnOption } from \"./utils/types.js\";\n\nimport styles from \"./ColumnConfigDialog.module.css\";\n\nexport interface ColumnConfig {\n columnId: string;\n isVisible: boolean;\n}\n\nexport type ColumnConfigOptions = Array<Pick<ColumnOption, \"id\" | \"name\">>;\n\nexport interface ColumnConfigDialogProps {\n isOpen: boolean;\n onClose: () => void;\n columnOptions: ColumnConfigOptions;\n currentVisibility?: VisibilityState;\n currentColumnOrder?: ColumnOrderState;\n onApply: (columns: ColumnConfig[]) => void;\n isValidConfig?: (columns: ColumnConfig[]) => boolean;\n}\n\ninterface ColumnItem {\n id: string;\n label: string;\n isVisible: boolean;\n}\n\nexport function ColumnConfigDialog({\n isOpen,\n onClose,\n columnOptions,\n currentVisibility,\n currentColumnOrder,\n onApply,\n isValidConfig,\n}: ColumnConfigDialogProps): React.ReactElement | null {\n const [visibleColumns, setVisibleColumns] = useState<ColumnItem[]>([]);\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n const allColumns: ColumnItem[] = useMemo(() => {\n return columnOptions.map((opt) => {\n const isVisible = currentVisibility ? currentVisibility[opt.id] : false;\n\n return {\n id: opt.id,\n label: opt.name,\n isVisible,\n };\n });\n }, [columnOptions, currentVisibility]);\n\n // Sync local state with prop when dialog is opened\n useEffect(() => {\n if (isOpen) {\n const visibleCols = allColumns.filter((col) => col.isVisible);\n\n // Sort by current column order if available\n if (!!currentColumnOrder?.length) {\n visibleCols.sort((a, b) => {\n const indexA = currentColumnOrder.indexOf(a.id);\n const indexB = currentColumnOrder.indexOf(b.id);\n // If not in order array, put at end\n const orderA = indexA === -1 ? Infinity : indexA;\n const orderB = indexB === -1 ? Infinity : indexB;\n return orderA - orderB;\n });\n }\n\n setVisibleColumns(visibleCols);\n setSearchQuery(\"\");\n }\n }, [isOpen, allColumns, currentColumnOrder]);\n\n const handleApply = useCallback(() => {\n onApply(getColumnConfig(allColumns, visibleColumns));\n onClose();\n }, [allColumns, visibleColumns, onApply, onClose]);\n\n // If no condition provided, default to valid\n const isValid = isValidConfig\n ? isValidConfig(getColumnConfig(allColumns, visibleColumns))\n : true;\n\n const isApplyDisabled = visibleColumns.length === 0 || !isValid;\n\n const handleReorderColumns = useCallback(\n (fromIndex: number, toIndex: number) => {\n setVisibleColumns((items) => arrayMove(items, fromIndex, toIndex));\n },\n []\n );\n\n const handleRemoveColumn = useCallback((columnId: string) => {\n setVisibleColumns((prev) => prev.filter((col) => col.id !== columnId));\n }, []);\n\n const handleToggleColumn = useCallback((column: ColumnItem) => {\n setVisibleColumns((prev) => {\n const isCurrentlyVisible = prev.some((col) => col.id === column.id);\n if (isCurrentlyVisible) {\n return prev.filter((col) => col.id !== column.id);\n } else {\n return [...prev, column];\n }\n });\n }, []);\n\n const handleSearchChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchQuery(event.target.value);\n },\n []\n );\n\n const handleSelectAll = useCallback((columns: ColumnItem[]) => {\n setVisibleColumns((prev) => {\n const allSelected = columns.every((col) =>\n prev.some((v) => v.id === col.id)\n );\n if (allSelected) {\n // Deselect all filtered columns\n return prev.filter((v) => !columns.some((col) => col.id === v.id));\n } else {\n // Select all filtered columns that aren't already selected\n const newColumns = columns.filter(\n (col) => !prev.some((v) => v.id === col.id)\n );\n return [...prev, ...newColumns];\n }\n });\n }, []);\n\n const filteredAvailableColumns = useMemo(() => {\n const query = searchQuery.toLowerCase().trim();\n if (!query) {\n return allColumns;\n }\n return allColumns.filter(\n (col) =>\n (col.label?.toLowerCase().includes(query) ?? false) ||\n col.id.toLowerCase().includes(query)\n );\n }, [allColumns, searchQuery]);\n\n const footer = useMemo(\n () => (\n <>\n <ActionButton onClick={onClose}>Cancel</ActionButton>\n <ActionButton\n variant=\"primary\"\n onClick={handleApply}\n disabled={isApplyDisabled}\n >\n Apply\n </ActionButton>\n </>\n ),\n [onClose, handleApply, isApplyDisabled]\n );\n\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onClose}\n title={DialogTitle}\n footer={footer}\n className={styles.columnConfigDialog}\n >\n <div className={styles.dialogLayout}>\n <VisibleColumnsList\n columns={visibleColumns}\n onReorder={handleReorderColumns}\n onRemove={handleRemoveColumn}\n />\n <AvailableColumnsList\n visibleColumns={visibleColumns}\n searchQuery={searchQuery}\n onSearchChange={handleSearchChange}\n onToggleColumn={handleToggleColumn}\n onSelectAll={handleSelectAll}\n filteredColumns={filteredAvailableColumns}\n />\n </div>\n </Dialog>\n );\n}\n\nconst DialogTitle = (\n <div className={styles.title}>\n <Cog />\n Configure Table Columns\n </div>\n);\n\nconst getColumnConfig = (\n allColumns: ColumnItem[],\n visibleColumns: ColumnItem[]\n): ColumnConfig[] => {\n const hiddenColumns = allColumns.filter(\n (col) => !visibleColumns.some((v) => v.id === col.id)\n );\n\n return [\n ...visibleColumns.map((col) => ({ columnId: col.id, isVisible: true })),\n ...hiddenColumns.map((col) => ({ columnId: col.id, isVisible: false })),\n ];\n};\n\ninterface VisibleColumnsListProps {\n columns: ColumnItem[];\n onReorder: (fromIndex: number, toIndex: number) => void;\n onRemove: (columnId: string) => void;\n}\n\nfunction VisibleColumnsList({\n columns,\n onReorder,\n onRemove,\n}: VisibleColumnsListProps): React.ReactElement {\n return (\n <div className={styles.visibleColumnsContainer}>\n <div className={styles.sectionHeader}>\n <div className={styles.sectionTitle}>\n <span>Visible Columns</span>\n <span className={styles.countTag}>{columns.length}</span>\n </div>\n <div className={styles.sectionHint}>Drag to reorder</div>\n </div>\n <DraggableList\n items={columns}\n onReorder={onReorder}\n onRemove={onRemove}\n removeIconVariant=\"trash\"\n emptyMessage=\"No visible columns\"\n className={styles.columnList}\n />\n </div>\n );\n}\n\ninterface AvailableColumnsListProps {\n visibleColumns: ColumnItem[];\n searchQuery: string;\n onSearchChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n onToggleColumn: (column: ColumnItem) => void;\n onSelectAll: (columns: ColumnItem[]) => void;\n filteredColumns: ColumnItem[];\n}\n\nfunction AvailableColumnsList({\n visibleColumns,\n searchQuery,\n onSearchChange,\n onToggleColumn,\n onSelectAll,\n filteredColumns,\n}: AvailableColumnsListProps): React.ReactElement {\n const selectedCount = visibleColumns.length;\n const totalCount = filteredColumns.length;\n const allFilteredSelected = filteredColumns.every((col) =>\n visibleColumns.some((v) => v.id === col.id)\n );\n const someFilteredSelected = filteredColumns.some((col) =>\n visibleColumns.some((v) => v.id === col.id)\n );\n\n const handleSelectAllClick = useCallback(() => {\n onSelectAll(filteredColumns);\n }, [filteredColumns, onSelectAll]);\n\n return (\n <div className={styles.availableColumnsContainer}>\n <div className={classNames(styles.sectionHeader, styles.sectionTitle)}>\n Add or Remove Columns\n </div>\n <SearchBar\n value={searchQuery}\n onChange={onSearchChange}\n placeholder=\"Search...\"\n aria-label=\"Search available columns\"\n className={styles.searchContainer}\n />\n <Collapsible.Root defaultOpen={true} className={styles.propertiesList}>\n <div className={styles.categoryHeader}>\n <label className={styles.selectAllLabel}>\n <Checkbox\n checked={allFilteredSelected}\n indeterminate={someFilteredSelected && !allFilteredSelected}\n onCheckedChange={handleSelectAllClick}\n className={styles.checkbox}\n />\n All Columns\n </label>\n <Collapsible.Trigger className={styles.categoryTrigger}>\n <span className={styles.categoryCount}>\n {selectedCount}/{totalCount}\n </span>\n <CaretDown className={styles.caretIcon} />\n </Collapsible.Trigger>\n </div>\n <Collapsible.Panel className={styles.propertyList}>\n {filteredColumns.length === 0 ? (\n <div className={styles.emptyState}>No matching columns found</div>\n ) : (\n filteredColumns.map((column) => (\n <PropertyItem\n key={column.id}\n column={column}\n isSelected={visibleColumns.some((v) => v.id === column.id)}\n onToggle={onToggleColumn}\n />\n ))\n )}\n </Collapsible.Panel>\n </Collapsible.Root>\n </div>\n );\n}\n\ninterface PropertyItemProps {\n column: ColumnItem;\n isSelected: boolean;\n onToggle: (column: ColumnItem) => void;\n showInfoIcon?: boolean;\n}\n\nfunction PropertyItem({\n column,\n isSelected,\n onToggle,\n showInfoIcon = false,\n}: PropertyItemProps): React.ReactElement {\n const handleClick = useCallback(() => {\n onToggle(column);\n }, [onToggle, column]);\n\n return (\n <div className={styles.propertyItem}>\n <label className={styles.propertyLabel}>\n <Checkbox\n checked={isSelected}\n onCheckedChange={handleClick}\n className={styles.checkbox}\n />\n <span className={styles.propertyName}>{column.label}</span>\n </label>\n {showInfoIcon && <SmallInfoSign className={styles.infoIcon} />}\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"ColumnConfigDialog.js","names":["Collapsible","CaretDown","Cog","SmallInfoSign","arrayMove","classNames","React","useCallback","useEffect","useMemo","useState","ActionButton","Checkbox","Dialog","DraggableList","SearchBar","useObjectTableLabels","withObjectTableLabels","styles","ColumnConfigDialog","ColumnConfigDialogInner","isOpen","onClose","columnOptions","currentVisibility","currentColumnOrder","onApply","isValidConfig","labels","visibleColumns","setVisibleColumns","searchQuery","setSearchQuery","allColumns","map","opt","isVisible","id","label","name","visibleCols","filter","col","length","sort","a","b","indexA","indexOf","indexB","orderA","Infinity","orderB","handleApply","getColumnConfig","isValid","isApplyDisabled","handleReorderColumns","fromIndex","toIndex","items","handleRemoveColumn","columnId","prev","handleToggleColumn","column","isCurrentlyVisible","some","handleSearchChange","event","target","value","handleSelectAll","columns","allSelected","every","v","newColumns","filteredAvailableColumns","query","toLowerCase","trim","includes","footer","createElement","Fragment","onClick","columnConfigCancel","variant","disabled","columnConfigApply","dialogTitle","className","title","columnConfigTitle","onOpenChange","columnConfigDialog","dialogLayout","VisibleColumnsList","onReorder","onRemove","AvailableColumnsList","onSearchChange","onToggleColumn","onSelectAll","filteredColumns","hiddenColumns","visibleColumnsContainer","sectionHeader","sectionTitle","columnConfigVisibleColumns","countTag","sectionHint","columnConfigDragToReorder","removeIconVariant","emptyMessage","columnConfigNoVisibleColumns","columnList","selectedCount","totalCount","allFilteredSelected","someFilteredSelected","handleSelectAllClick","availableColumnsContainer","columnConfigAddOrRemoveColumns","onChange","placeholder","columnConfigSearchPlaceholder","columnConfigSearchAriaLabel","searchContainer","Root","defaultOpen","propertiesList","categoryHeader","selectAllLabel","checked","indeterminate","onCheckedChange","checkbox","columnConfigAllColumns","Trigger","categoryTrigger","categoryCount","caretIcon","Panel","propertyList","emptyState","columnConfigNoMatchingColumns","PropertyItem","key","isSelected","onToggle","showInfoIcon","handleClick","propertyItem","propertyLabel","propertyName","infoIcon"],"sources":["ColumnConfigDialog.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Collapsible } from \"@base-ui/react/collapsible\";\nimport { CaretDown, Cog, SmallInfoSign } from \"@blueprintjs/icons\";\nimport { arrayMove } from \"@dnd-kit/sortable\";\nimport type { ColumnOrderState, VisibilityState } from \"@tanstack/react-table\";\nimport classNames from \"classnames\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { Checkbox } from \"../base-components/checkbox/Checkbox.js\";\nimport { Dialog } from \"../base-components/dialog/Dialog.js\";\nimport { DraggableList } from \"../base-components/draggable-list/DraggableList.js\";\nimport { SearchBar } from \"../base-components/search-bar/SearchBar.js\";\nimport type { ObjectTableLabels } from \"./ObjectTableLabels.js\";\nimport {\n useObjectTableLabels,\n withObjectTableLabels,\n} from \"./ObjectTableLabels.js\";\nimport type { ColumnOption } from \"./utils/types.js\";\n\nimport styles from \"./ColumnConfigDialog.module.css\";\n\nexport interface ColumnConfig {\n columnId: string;\n isVisible: boolean;\n}\n\nexport type ColumnConfigOptions = Array<Pick<ColumnOption, \"id\" | \"name\">>;\n\nexport interface ColumnConfigDialogProps {\n isOpen: boolean;\n onClose: () => void;\n columnOptions: ColumnConfigOptions;\n currentVisibility?: VisibilityState;\n currentColumnOrder?: ColumnOrderState;\n onApply: (columns: ColumnConfig[]) => void;\n isValidConfig?: (columns: ColumnConfig[]) => boolean;\n /**\n * Overrides for the dialog's user-facing strings. Provide any subset; unset\n * keys fall back to the built-in English defaults. When this dialog is\n * rendered inside a `BaseTable`/`ObjectTable`, it inherits that table's\n * `labels` and this prop is only needed to override further. See\n * {@link ObjectTableLabels}.\n */\n labels?: Partial<ObjectTableLabels>;\n}\n\ninterface ColumnItem {\n id: string;\n label: string;\n isVisible: boolean;\n}\n\nexport const ColumnConfigDialog: React.FC<ColumnConfigDialogProps> =\n withObjectTableLabels(ColumnConfigDialogInner);\n\nfunction ColumnConfigDialogInner({\n isOpen,\n onClose,\n columnOptions,\n currentVisibility,\n currentColumnOrder,\n onApply,\n isValidConfig,\n}: Omit<ColumnConfigDialogProps, \"labels\">): React.ReactElement {\n const labels = useObjectTableLabels();\n const [visibleColumns, setVisibleColumns] = useState<ColumnItem[]>([]);\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n const allColumns: ColumnItem[] = useMemo(() => {\n return columnOptions.map((opt) => {\n const isVisible = currentVisibility ? currentVisibility[opt.id] : false;\n\n return {\n id: opt.id,\n label: opt.name,\n isVisible,\n };\n });\n }, [columnOptions, currentVisibility]);\n\n // Sync local state with prop when dialog is opened\n useEffect(() => {\n if (isOpen) {\n const visibleCols = allColumns.filter((col) => col.isVisible);\n\n // Sort by current column order if available\n if (!!currentColumnOrder?.length) {\n visibleCols.sort((a, b) => {\n const indexA = currentColumnOrder.indexOf(a.id);\n const indexB = currentColumnOrder.indexOf(b.id);\n // If not in order array, put at end\n const orderA = indexA === -1 ? Infinity : indexA;\n const orderB = indexB === -1 ? Infinity : indexB;\n return orderA - orderB;\n });\n }\n\n setVisibleColumns(visibleCols);\n setSearchQuery(\"\");\n }\n }, [isOpen, allColumns, currentColumnOrder]);\n\n const handleApply = useCallback(() => {\n onApply(getColumnConfig(allColumns, visibleColumns));\n onClose();\n }, [allColumns, visibleColumns, onApply, onClose]);\n\n // If no condition provided, default to valid\n const isValid = isValidConfig\n ? isValidConfig(getColumnConfig(allColumns, visibleColumns))\n : true;\n\n const isApplyDisabled = visibleColumns.length === 0 || !isValid;\n\n const handleReorderColumns = useCallback(\n (fromIndex: number, toIndex: number) => {\n setVisibleColumns((items) => arrayMove(items, fromIndex, toIndex));\n },\n []\n );\n\n const handleRemoveColumn = useCallback((columnId: string) => {\n setVisibleColumns((prev) => prev.filter((col) => col.id !== columnId));\n }, []);\n\n const handleToggleColumn = useCallback((column: ColumnItem) => {\n setVisibleColumns((prev) => {\n const isCurrentlyVisible = prev.some((col) => col.id === column.id);\n if (isCurrentlyVisible) {\n return prev.filter((col) => col.id !== column.id);\n } else {\n return [...prev, column];\n }\n });\n }, []);\n\n const handleSearchChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchQuery(event.target.value);\n },\n []\n );\n\n const handleSelectAll = useCallback((columns: ColumnItem[]) => {\n setVisibleColumns((prev) => {\n const allSelected = columns.every((col) =>\n prev.some((v) => v.id === col.id)\n );\n if (allSelected) {\n // Deselect all filtered columns\n return prev.filter((v) => !columns.some((col) => col.id === v.id));\n } else {\n // Select all filtered columns that aren't already selected\n const newColumns = columns.filter(\n (col) => !prev.some((v) => v.id === col.id)\n );\n return [...prev, ...newColumns];\n }\n });\n }, []);\n\n const filteredAvailableColumns = useMemo(() => {\n const query = searchQuery.toLowerCase().trim();\n if (!query) {\n return allColumns;\n }\n return allColumns.filter(\n (col) =>\n (col.label?.toLowerCase().includes(query) ?? false) ||\n col.id.toLowerCase().includes(query)\n );\n }, [allColumns, searchQuery]);\n\n const footer = useMemo(\n () => (\n <>\n <ActionButton onClick={onClose}>\n {labels.columnConfigCancel}\n </ActionButton>\n <ActionButton\n variant=\"primary\"\n onClick={handleApply}\n disabled={isApplyDisabled}\n >\n {labels.columnConfigApply}\n </ActionButton>\n </>\n ),\n [onClose, handleApply, isApplyDisabled, labels]\n );\n\n const dialogTitle = useMemo(\n () => (\n <div className={styles.title}>\n <Cog />\n {labels.columnConfigTitle}\n </div>\n ),\n [labels]\n );\n\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onClose}\n title={dialogTitle}\n footer={footer}\n className={styles.columnConfigDialog}\n >\n <div className={styles.dialogLayout}>\n <VisibleColumnsList\n columns={visibleColumns}\n onReorder={handleReorderColumns}\n onRemove={handleRemoveColumn}\n />\n <AvailableColumnsList\n visibleColumns={visibleColumns}\n searchQuery={searchQuery}\n onSearchChange={handleSearchChange}\n onToggleColumn={handleToggleColumn}\n onSelectAll={handleSelectAll}\n filteredColumns={filteredAvailableColumns}\n />\n </div>\n </Dialog>\n );\n}\n\nconst getColumnConfig = (\n allColumns: ColumnItem[],\n visibleColumns: ColumnItem[]\n): ColumnConfig[] => {\n const hiddenColumns = allColumns.filter(\n (col) => !visibleColumns.some((v) => v.id === col.id)\n );\n\n return [\n ...visibleColumns.map((col) => ({ columnId: col.id, isVisible: true })),\n ...hiddenColumns.map((col) => ({ columnId: col.id, isVisible: false })),\n ];\n};\n\ninterface VisibleColumnsListProps {\n columns: ColumnItem[];\n onReorder: (fromIndex: number, toIndex: number) => void;\n onRemove: (columnId: string) => void;\n}\n\nfunction VisibleColumnsList({\n columns,\n onReorder,\n onRemove,\n}: VisibleColumnsListProps): React.ReactElement {\n const labels = useObjectTableLabels();\n return (\n <div className={styles.visibleColumnsContainer}>\n <div className={styles.sectionHeader}>\n <div className={styles.sectionTitle}>\n <span>{labels.columnConfigVisibleColumns}</span>\n <span className={styles.countTag}>{columns.length}</span>\n </div>\n <div className={styles.sectionHint}>\n {labels.columnConfigDragToReorder}\n </div>\n </div>\n <DraggableList\n items={columns}\n onReorder={onReorder}\n onRemove={onRemove}\n removeIconVariant=\"trash\"\n emptyMessage={labels.columnConfigNoVisibleColumns}\n className={styles.columnList}\n />\n </div>\n );\n}\n\ninterface AvailableColumnsListProps {\n visibleColumns: ColumnItem[];\n searchQuery: string;\n onSearchChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n onToggleColumn: (column: ColumnItem) => void;\n onSelectAll: (columns: ColumnItem[]) => void;\n filteredColumns: ColumnItem[];\n}\n\nfunction AvailableColumnsList({\n visibleColumns,\n searchQuery,\n onSearchChange,\n onToggleColumn,\n onSelectAll,\n filteredColumns,\n}: AvailableColumnsListProps): React.ReactElement {\n const selectedCount = visibleColumns.length;\n const totalCount = filteredColumns.length;\n const allFilteredSelected = filteredColumns.every((col) =>\n visibleColumns.some((v) => v.id === col.id)\n );\n const someFilteredSelected = filteredColumns.some((col) =>\n visibleColumns.some((v) => v.id === col.id)\n );\n\n const labels = useObjectTableLabels();\n\n const handleSelectAllClick = useCallback(() => {\n onSelectAll(filteredColumns);\n }, [filteredColumns, onSelectAll]);\n\n return (\n <div className={styles.availableColumnsContainer}>\n <div className={classNames(styles.sectionHeader, styles.sectionTitle)}>\n {labels.columnConfigAddOrRemoveColumns}\n </div>\n <SearchBar\n value={searchQuery}\n onChange={onSearchChange}\n placeholder={labels.columnConfigSearchPlaceholder}\n aria-label={labels.columnConfigSearchAriaLabel}\n className={styles.searchContainer}\n />\n <Collapsible.Root defaultOpen={true} className={styles.propertiesList}>\n <div className={styles.categoryHeader}>\n <label className={styles.selectAllLabel}>\n <Checkbox\n checked={allFilteredSelected}\n indeterminate={someFilteredSelected && !allFilteredSelected}\n onCheckedChange={handleSelectAllClick}\n className={styles.checkbox}\n />\n {labels.columnConfigAllColumns}\n </label>\n <Collapsible.Trigger className={styles.categoryTrigger}>\n <span className={styles.categoryCount}>\n {selectedCount}/{totalCount}\n </span>\n <CaretDown className={styles.caretIcon} />\n </Collapsible.Trigger>\n </div>\n <Collapsible.Panel className={styles.propertyList}>\n {filteredColumns.length === 0 ? (\n <div className={styles.emptyState}>\n {labels.columnConfigNoMatchingColumns}\n </div>\n ) : (\n filteredColumns.map((column) => (\n <PropertyItem\n key={column.id}\n column={column}\n isSelected={visibleColumns.some((v) => v.id === column.id)}\n onToggle={onToggleColumn}\n />\n ))\n )}\n </Collapsible.Panel>\n </Collapsible.Root>\n </div>\n );\n}\n\ninterface PropertyItemProps {\n column: ColumnItem;\n isSelected: boolean;\n onToggle: (column: ColumnItem) => void;\n showInfoIcon?: boolean;\n}\n\nfunction PropertyItem({\n column,\n isSelected,\n onToggle,\n showInfoIcon = false,\n}: PropertyItemProps): React.ReactElement {\n const handleClick = useCallback(() => {\n onToggle(column);\n }, [onToggle, column]);\n\n return (\n <div className={styles.propertyItem}>\n <label className={styles.propertyLabel}>\n <Checkbox\n checked={isSelected}\n onCheckedChange={handleClick}\n className={styles.checkbox}\n />\n <span className={styles.propertyName}>{column.label}</span>\n </label>\n {showInfoIcon && <SmallInfoSign className={styles.infoIcon} />}\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -20,11 +20,11 @@ import { Tooltip } from "../base-components/tooltip/Tooltip.js";
20
20
  import { DatePickerCellField } from "./components/DatePickerCellField.js";
21
21
  import { DropdownCellField } from "./components/DropdownCellField.js";
22
22
  import { TextInputCellField } from "./components/TextInputCellField.js";
23
+ import { useObjectTableLabels } from "./ObjectTableLabels.js";
23
24
  import { cellValuesEqual } from "./utils/editableUtils.js";
24
25
  import styles from "./EditableCell.module.css.js";
25
26
  const NUMBER_TYPES = ["double", "integer", "long", "float", "decimal", "byte", "short"];
26
27
  const DATE_TYPES = ["datetime", "timestamp"];
27
- const VALIDATION_ERROR_MESSAGE = "Validation error";
28
28
  function valueToString(value) {
29
29
  if (value == null) {
30
30
  return "";
@@ -65,6 +65,7 @@ function EditableCellInner({
65
65
  rowCellEdits,
66
66
  isRowFocused = false
67
67
  }) {
68
+ const labels = useObjectTableLabels();
68
69
  const [inputValue, setInputValue] = useState(valueToString(currentValue));
69
70
  const isCancelled = useRef(false);
70
71
  const validationAbortControllerRef = useRef(null);
@@ -108,10 +109,10 @@ function EditableCellInner({
108
109
  }
109
110
  }, error => {
110
111
  if (!controller.signal.aborted && error.name !== "AbortError") {
111
- onCellValidationError?.(cellId, VALIDATION_ERROR_MESSAGE);
112
+ onCellValidationError?.(cellId, labels.cellValidationError);
112
113
  }
113
114
  });
114
- }, [validateEdit, onCellValidationError, clearCellValidationError, cellId]);
115
+ }, [validateEdit, onCellValidationError, clearCellValidationError, cellId, labels]);
115
116
  const commitEdit = useCallback(newValue => {
116
117
  abortValidation();
117
118
  onCellEdit(cellId, {
@@ -1 +1 @@
1
- {"version":3,"file":"EditableCell.js","names":["Error","React","useCallback","useEffect","useMemo","useRef","useState","Tooltip","DatePickerCellField","DropdownCellField","TextInputCellField","cellValuesEqual","styles","NUMBER_TYPES","DATE_TYPES","VALIDATION_ERROR_MESSAGE","valueToString","value","JSON","stringify","String","parseValueByType","dataType","includes","parsedNumber","Number","isNaN","EditableCellInner","initialValue","currentValue","cellId","onCellEdit","onCellValidationError","clearCellValidationError","originalRowData","rowId","columnId","validateEdit","validationError","editFieldConfig","rowCellEdits","isRowFocused","inputValue","setInputValue","isCancelled","validationAbortControllerRef","abortValidation","current","abort","hasValidationError","isEdited","runValidation","parsedValue","controller","AbortController","validationPromise","Promise","race","_","reject","signal","addEventListener","DOMException","then","errorMessage","aborted","error","name","commitEdit","newValue","oldValue","handleBlur","handleInputChange","handleKeyDown","e","key","currentTarget","blur","handleCommit","inputType","dropdownFieldProps","fieldComponent","getFieldComponentProps","undefined","datePickerFieldProps","createElement","Provider","Root","disabled","Trigger","className","osdkEditableCellTrigger","render","osdkTooltipTriggerWrapper","fieldComponentProps","onChange","onValueChange","onBlur","onKeyDown","Portal","Positioner","sideOffset","side","Popup","errorIcon","Arrow","EditableCell","memo"],"sources":["EditableCell.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Error } from \"@blueprintjs/icons\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { Tooltip } from \"../base-components/tooltip/Tooltip.js\";\nimport { DatePickerCellField } from \"./components/DatePickerCellField.js\";\nimport { DropdownCellField } from \"./components/DropdownCellField.js\";\nimport { TextInputCellField } from \"./components/TextInputCellField.js\";\nimport { cellValuesEqual } from \"./utils/editableUtils.js\";\nimport type { CellEditInfo, EditFieldConfig } from \"./utils/types.js\";\n\nimport styles from \"./EditableCell.module.css\";\n\nconst NUMBER_TYPES: readonly string[] = [\n \"double\",\n \"integer\",\n \"long\",\n \"float\",\n \"decimal\",\n \"byte\",\n \"short\",\n];\n\nconst DATE_TYPES: readonly string[] = [\"datetime\", \"timestamp\"];\n\nconst VALIDATION_ERROR_MESSAGE = \"Validation error\";\n\nexport interface EditableCellProps<TData extends RowData, CellValue = unknown> {\n initialValue: CellValue;\n currentValue: CellValue;\n cellId: string;\n dataType?: string;\n onCellEdit: (cellId: string, info: CellEditInfo<TData, CellValue>) => void;\n onCellValidationError?: (cellId: string, error: string) => void;\n clearCellValidationError?: (cellId: string) => void;\n validationError?: string;\n originalRowData: TData;\n rowId: string;\n columnId: string;\n validateEdit?: (value: unknown) => Promise<string | undefined>;\n editFieldConfig?: EditFieldConfig<TData>;\n /**\n * Pending edits for this row, keyed by `columnId`. Forwarded to\n * `EditFieldConfig#getFieldComponentProps`. Filtering happens in\n * `DefaultCellRenderer` so unedited rows receive a stable `undefined`\n * reference and `React.memo` can skip them.\n */\n rowCellEdits?: Record<string, CellEditInfo<TData, unknown>>;\n isRowFocused?: boolean;\n}\n\nfunction valueToString(value: unknown): string {\n if (value == null) {\n return \"\";\n }\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n // At this point, value is a primitive (string, number, boolean, symbol, bigint)\n return String(value as string | number | boolean | symbol | bigint);\n}\n\nfunction parseValueByType(value: string, dataType?: string): unknown {\n if (!dataType || !NUMBER_TYPES.includes(dataType)) {\n return value;\n }\n\n if (value === \"\") {\n return null;\n }\n\n const parsedNumber = Number(value);\n\n if (isNaN(parsedNumber)) {\n return value;\n }\n\n return parsedNumber;\n}\n\nfunction EditableCellInner<TData extends RowData, CellValue = unknown>({\n initialValue,\n currentValue,\n cellId,\n dataType,\n onCellEdit,\n onCellValidationError,\n clearCellValidationError,\n originalRowData,\n rowId,\n columnId,\n validateEdit,\n validationError,\n editFieldConfig,\n rowCellEdits,\n isRowFocused = false,\n}: EditableCellProps<TData, CellValue>): React.ReactElement {\n const [inputValue, setInputValue] = useState<string>(\n valueToString(currentValue)\n );\n const isCancelled = useRef(false);\n const validationAbortControllerRef = useRef<AbortController | null>(null);\n\n const abortValidation = useCallback(() => {\n if (validationAbortControllerRef.current) {\n validationAbortControllerRef.current.abort();\n validationAbortControllerRef.current = null;\n }\n }, []);\n\n const hasValidationError = validationError != null;\n const isEdited = !cellValuesEqual(currentValue, initialValue);\n\n useEffect(() => {\n setInputValue(valueToString(currentValue));\n }, [currentValue]);\n\n useEffect(() => {\n return () => {\n abortValidation();\n };\n }, [abortValidation]);\n\n const runValidation = useCallback(\n (parsedValue: unknown) => {\n if (!validateEdit) {\n return;\n }\n\n const controller = new AbortController();\n validationAbortControllerRef.current = controller;\n\n const validationPromise = validateEdit(parsedValue);\n\n // Race between validation and abort\n Promise.race([\n validationPromise,\n new Promise<string | undefined>((_, reject) => {\n controller.signal.addEventListener(\"abort\", () => {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n });\n }),\n ]).then(\n (errorMessage) => {\n if (controller.signal.aborted) {\n return;\n }\n if (errorMessage) {\n onCellValidationError?.(cellId, errorMessage);\n } else {\n clearCellValidationError?.(cellId);\n }\n },\n (error) => {\n if (!controller.signal.aborted && error.name !== \"AbortError\") {\n onCellValidationError?.(cellId, VALIDATION_ERROR_MESSAGE);\n }\n }\n );\n },\n [validateEdit, onCellValidationError, clearCellValidationError, cellId]\n );\n\n const commitEdit = useCallback(\n (newValue: CellValue) => {\n abortValidation();\n\n onCellEdit(cellId, {\n rowId,\n columnId,\n newValue,\n oldValue: initialValue,\n originalRowData,\n });\n\n runValidation(newValue);\n },\n [\n abortValidation,\n onCellEdit,\n cellId,\n rowId,\n columnId,\n initialValue,\n originalRowData,\n runValidation,\n ]\n );\n\n // Text/number input: commit on blur\n const handleBlur = useCallback(() => {\n if (isCancelled.current) {\n isCancelled.current = false;\n return;\n }\n\n // No-op when the input wasn't actually changed by the user\n if (inputValue === valueToString(currentValue)) {\n return;\n }\n\n const parsedValue = parseValueByType(inputValue, dataType) as CellValue;\n commitEdit(parsedValue);\n }, [inputValue, currentValue, dataType, commitEdit]);\n\n const handleInputChange = useCallback(\n (value: string) => {\n // Cancel any in-flight validation\n abortValidation();\n setInputValue(value);\n },\n [abortValidation]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.currentTarget.blur();\n }\n if (e.key === \"Escape\") {\n isCancelled.current = true;\n setInputValue(valueToString(currentValue));\n e.currentTarget.blur();\n }\n },\n [currentValue]\n );\n\n const handleCommit = useCallback(\n (newValue: unknown) => {\n // No-op if the value hasn't actually moved from what the cell already\n // displays. null and undefined are treated as the same empty state so\n // a dropdown that clears a never-set cell doesn't fire; \"\" stays\n // distinct since an empty string can be meaningful data.\n if (cellValuesEqual(newValue, currentValue)) return;\n commitEdit(newValue as CellValue);\n },\n [commitEdit, currentValue]\n );\n\n const inputType =\n dataType && NUMBER_TYPES.includes(dataType) ? \"number\" : \"text\";\n\n // Compute field-component props once per (editFieldConfig, originalRowData, rowCellEdits).\n // The narrowed return type is preserved in each useMemo\n const dropdownFieldProps = useMemo(\n () =>\n editFieldConfig?.fieldComponent === \"DROPDOWN\"\n ? editFieldConfig.getFieldComponentProps(originalRowData, rowCellEdits)\n : undefined,\n [editFieldConfig, originalRowData, rowCellEdits]\n );\n\n const datePickerFieldProps = useMemo(\n () =>\n editFieldConfig?.fieldComponent === \"DATE_PICKER\"\n ? editFieldConfig.getFieldComponentProps(originalRowData, rowCellEdits)\n : undefined,\n [editFieldConfig, originalRowData, rowCellEdits]\n );\n\n const renderFieldInput = () => {\n switch (editFieldConfig?.fieldComponent) {\n case \"DROPDOWN\":\n return (\n <DropdownCellField\n fieldComponentProps={dropdownFieldProps!}\n isRowFocused={isRowFocused}\n inputValue={inputValue}\n value={currentValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n />\n );\n case \"DATE_PICKER\":\n return (\n <DatePickerCellField\n fieldComponentProps={datePickerFieldProps}\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n />\n );\n default:\n if (dataType != null && DATE_TYPES.includes(dataType)) {\n return (\n <DatePickerCellField\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n dataType={dataType}\n />\n );\n }\n return (\n <TextInputCellField\n inputType={inputType}\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onValueChange={handleInputChange}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n />\n );\n }\n };\n\n return (\n <Tooltip.Provider>\n <Tooltip.Root disabled={!hasValidationError}>\n <Tooltip.Trigger\n className={styles.osdkEditableCellTrigger}\n render={<span className={styles.osdkTooltipTriggerWrapper} />}\n >\n {renderFieldInput()}\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner sideOffset={4} side={\"bottom\"}>\n <Tooltip.Popup>\n <div className={styles.validationError}>\n <Error className={styles.errorIcon} />\n {validationError}\n </div>\n <Tooltip.Arrow />\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n </Tooltip.Provider>\n );\n}\n\nexport const EditableCell = React.memo(\n EditableCellInner\n) as typeof EditableCellInner;\n(\"\");\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"EditableCell.js","names":["Error","React","useCallback","useEffect","useMemo","useRef","useState","Tooltip","DatePickerCellField","DropdownCellField","TextInputCellField","useObjectTableLabels","cellValuesEqual","styles","NUMBER_TYPES","DATE_TYPES","valueToString","value","JSON","stringify","String","parseValueByType","dataType","includes","parsedNumber","Number","isNaN","EditableCellInner","initialValue","currentValue","cellId","onCellEdit","onCellValidationError","clearCellValidationError","originalRowData","rowId","columnId","validateEdit","validationError","editFieldConfig","rowCellEdits","isRowFocused","labels","inputValue","setInputValue","isCancelled","validationAbortControllerRef","abortValidation","current","abort","hasValidationError","isEdited","runValidation","parsedValue","controller","AbortController","validationPromise","Promise","race","_","reject","signal","addEventListener","DOMException","then","errorMessage","aborted","error","name","cellValidationError","commitEdit","newValue","oldValue","handleBlur","handleInputChange","handleKeyDown","e","key","currentTarget","blur","handleCommit","inputType","dropdownFieldProps","fieldComponent","getFieldComponentProps","undefined","datePickerFieldProps","createElement","Provider","Root","disabled","Trigger","className","osdkEditableCellTrigger","render","osdkTooltipTriggerWrapper","fieldComponentProps","onChange","onValueChange","onBlur","onKeyDown","Portal","Positioner","sideOffset","side","Popup","errorIcon","Arrow","EditableCell","memo"],"sources":["EditableCell.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Error } from \"@blueprintjs/icons\";\nimport type { RowData } from \"@tanstack/react-table\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { Tooltip } from \"../base-components/tooltip/Tooltip.js\";\nimport { DatePickerCellField } from \"./components/DatePickerCellField.js\";\nimport { DropdownCellField } from \"./components/DropdownCellField.js\";\nimport { TextInputCellField } from \"./components/TextInputCellField.js\";\nimport { useObjectTableLabels } from \"./ObjectTableLabels.js\";\nimport { cellValuesEqual } from \"./utils/editableUtils.js\";\nimport type { CellEditInfo, EditFieldConfig } from \"./utils/types.js\";\n\nimport styles from \"./EditableCell.module.css\";\n\nconst NUMBER_TYPES: readonly string[] = [\n \"double\",\n \"integer\",\n \"long\",\n \"float\",\n \"decimal\",\n \"byte\",\n \"short\",\n];\n\nconst DATE_TYPES: readonly string[] = [\"datetime\", \"timestamp\"];\n\nexport interface EditableCellProps<TData extends RowData, CellValue = unknown> {\n initialValue: CellValue;\n currentValue: CellValue;\n cellId: string;\n dataType?: string;\n onCellEdit: (cellId: string, info: CellEditInfo<TData, CellValue>) => void;\n onCellValidationError?: (cellId: string, error: string) => void;\n clearCellValidationError?: (cellId: string) => void;\n validationError?: string;\n originalRowData: TData;\n rowId: string;\n columnId: string;\n validateEdit?: (value: unknown) => Promise<string | undefined>;\n editFieldConfig?: EditFieldConfig<TData>;\n /**\n * Pending edits for this row, keyed by `columnId`. Forwarded to\n * `EditFieldConfig#getFieldComponentProps`. Filtering happens in\n * `DefaultCellRenderer` so unedited rows receive a stable `undefined`\n * reference and `React.memo` can skip them.\n */\n rowCellEdits?: Record<string, CellEditInfo<TData, unknown>>;\n isRowFocused?: boolean;\n}\n\nfunction valueToString(value: unknown): string {\n if (value == null) {\n return \"\";\n }\n if (typeof value === \"object\") {\n return JSON.stringify(value);\n }\n // At this point, value is a primitive (string, number, boolean, symbol, bigint)\n return String(value as string | number | boolean | symbol | bigint);\n}\n\nfunction parseValueByType(value: string, dataType?: string): unknown {\n if (!dataType || !NUMBER_TYPES.includes(dataType)) {\n return value;\n }\n\n if (value === \"\") {\n return null;\n }\n\n const parsedNumber = Number(value);\n\n if (isNaN(parsedNumber)) {\n return value;\n }\n\n return parsedNumber;\n}\n\nfunction EditableCellInner<TData extends RowData, CellValue = unknown>({\n initialValue,\n currentValue,\n cellId,\n dataType,\n onCellEdit,\n onCellValidationError,\n clearCellValidationError,\n originalRowData,\n rowId,\n columnId,\n validateEdit,\n validationError,\n editFieldConfig,\n rowCellEdits,\n isRowFocused = false,\n}: EditableCellProps<TData, CellValue>): React.ReactElement {\n const labels = useObjectTableLabels();\n const [inputValue, setInputValue] = useState<string>(\n valueToString(currentValue)\n );\n const isCancelled = useRef(false);\n const validationAbortControllerRef = useRef<AbortController | null>(null);\n\n const abortValidation = useCallback(() => {\n if (validationAbortControllerRef.current) {\n validationAbortControllerRef.current.abort();\n validationAbortControllerRef.current = null;\n }\n }, []);\n\n const hasValidationError = validationError != null;\n const isEdited = !cellValuesEqual(currentValue, initialValue);\n\n useEffect(() => {\n setInputValue(valueToString(currentValue));\n }, [currentValue]);\n\n useEffect(() => {\n return () => {\n abortValidation();\n };\n }, [abortValidation]);\n\n const runValidation = useCallback(\n (parsedValue: unknown) => {\n if (!validateEdit) {\n return;\n }\n\n const controller = new AbortController();\n validationAbortControllerRef.current = controller;\n\n const validationPromise = validateEdit(parsedValue);\n\n // Race between validation and abort\n Promise.race([\n validationPromise,\n new Promise<string | undefined>((_, reject) => {\n controller.signal.addEventListener(\"abort\", () => {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n });\n }),\n ]).then(\n (errorMessage) => {\n if (controller.signal.aborted) {\n return;\n }\n if (errorMessage) {\n onCellValidationError?.(cellId, errorMessage);\n } else {\n clearCellValidationError?.(cellId);\n }\n },\n (error) => {\n if (!controller.signal.aborted && error.name !== \"AbortError\") {\n onCellValidationError?.(cellId, labels.cellValidationError);\n }\n }\n );\n },\n [\n validateEdit,\n onCellValidationError,\n clearCellValidationError,\n cellId,\n labels,\n ]\n );\n\n const commitEdit = useCallback(\n (newValue: CellValue) => {\n abortValidation();\n\n onCellEdit(cellId, {\n rowId,\n columnId,\n newValue,\n oldValue: initialValue,\n originalRowData,\n });\n\n runValidation(newValue);\n },\n [\n abortValidation,\n onCellEdit,\n cellId,\n rowId,\n columnId,\n initialValue,\n originalRowData,\n runValidation,\n ]\n );\n\n // Text/number input: commit on blur\n const handleBlur = useCallback(() => {\n if (isCancelled.current) {\n isCancelled.current = false;\n return;\n }\n\n // No-op when the input wasn't actually changed by the user\n if (inputValue === valueToString(currentValue)) {\n return;\n }\n\n const parsedValue = parseValueByType(inputValue, dataType) as CellValue;\n commitEdit(parsedValue);\n }, [inputValue, currentValue, dataType, commitEdit]);\n\n const handleInputChange = useCallback(\n (value: string) => {\n // Cancel any in-flight validation\n abortValidation();\n setInputValue(value);\n },\n [abortValidation]\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.currentTarget.blur();\n }\n if (e.key === \"Escape\") {\n isCancelled.current = true;\n setInputValue(valueToString(currentValue));\n e.currentTarget.blur();\n }\n },\n [currentValue]\n );\n\n const handleCommit = useCallback(\n (newValue: unknown) => {\n // No-op if the value hasn't actually moved from what the cell already\n // displays. null and undefined are treated as the same empty state so\n // a dropdown that clears a never-set cell doesn't fire; \"\" stays\n // distinct since an empty string can be meaningful data.\n if (cellValuesEqual(newValue, currentValue)) return;\n commitEdit(newValue as CellValue);\n },\n [commitEdit, currentValue]\n );\n\n const inputType =\n dataType && NUMBER_TYPES.includes(dataType) ? \"number\" : \"text\";\n\n // Compute field-component props once per (editFieldConfig, originalRowData, rowCellEdits).\n // The narrowed return type is preserved in each useMemo\n const dropdownFieldProps = useMemo(\n () =>\n editFieldConfig?.fieldComponent === \"DROPDOWN\"\n ? editFieldConfig.getFieldComponentProps(originalRowData, rowCellEdits)\n : undefined,\n [editFieldConfig, originalRowData, rowCellEdits]\n );\n\n const datePickerFieldProps = useMemo(\n () =>\n editFieldConfig?.fieldComponent === \"DATE_PICKER\"\n ? editFieldConfig.getFieldComponentProps(originalRowData, rowCellEdits)\n : undefined,\n [editFieldConfig, originalRowData, rowCellEdits]\n );\n\n const renderFieldInput = () => {\n switch (editFieldConfig?.fieldComponent) {\n case \"DROPDOWN\":\n return (\n <DropdownCellField\n fieldComponentProps={dropdownFieldProps!}\n isRowFocused={isRowFocused}\n inputValue={inputValue}\n value={currentValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n />\n );\n case \"DATE_PICKER\":\n return (\n <DatePickerCellField\n fieldComponentProps={datePickerFieldProps}\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n />\n );\n default:\n if (dataType != null && DATE_TYPES.includes(dataType)) {\n return (\n <DatePickerCellField\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onChange={handleCommit}\n dataType={dataType}\n />\n );\n }\n return (\n <TextInputCellField\n inputType={inputType}\n inputValue={inputValue}\n hasValidationError={hasValidationError}\n isEdited={isEdited}\n onValueChange={handleInputChange}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n />\n );\n }\n };\n\n return (\n <Tooltip.Provider>\n <Tooltip.Root disabled={!hasValidationError}>\n <Tooltip.Trigger\n className={styles.osdkEditableCellTrigger}\n render={<span className={styles.osdkTooltipTriggerWrapper} />}\n >\n {renderFieldInput()}\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner sideOffset={4} side={\"bottom\"}>\n <Tooltip.Popup>\n <div className={styles.validationError}>\n <Error className={styles.errorIcon} />\n {validationError}\n </div>\n <Tooltip.Arrow />\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n </Tooltip.Provider>\n );\n}\n\nexport const EditableCell = React.memo(\n EditableCellInner\n) as typeof EditableCellInner;\n(\"\");\n"],"mappings":"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","ignoreList":[]}
@@ -22,15 +22,18 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
22
22
  import { ActionButton } from "../base-components/action-button/ActionButton.js";
23
23
  import { Dialog } from "../base-components/dialog/Dialog.js";
24
24
  import { SearchableMenu } from "../base-components/searchable-menu/SearchableMenu.js";
25
+ import { useObjectTableLabels, withObjectTableLabels } from "./ObjectTableLabels.js";
25
26
  import { SortableItemsList } from "./SortableItemsList.js";
26
27
  import styles from "./MultiColumnSortDialog.module.css.js";
27
- export function MultiColumnSortDialog({
28
+ export const MultiColumnSortDialog = withObjectTableLabels(MultiColumnSortDialogInner);
29
+ function MultiColumnSortDialogInner({
28
30
  isOpen,
29
31
  onClose,
30
32
  onApply,
31
33
  currentSorting,
32
34
  columnOptions
33
35
  }) {
36
+ const labels = useObjectTableLabels();
34
37
  const [selectedSortColumns, setSelectedSortColumns] = useState([]);
35
38
  // Initialize selected sort columns from current sorting
36
39
  useEffect(() => {
@@ -96,24 +99,27 @@ export function MultiColumnSortDialog({
96
99
  }, item.name), /*#__PURE__*/React.createElement(Button, {
97
100
  className: styles.sortDirectionButton,
98
101
  onClick: () => handleToggleSortDirection(item.id),
99
- "aria-label": `Toggle sort direction for ${item.name}`
102
+ "aria-label": labels.sortDialogToggleDirection(item.name)
100
103
  }, item.direction === "asc" ? /*#__PURE__*/React.createElement(SortAlphabetical, {
101
104
  className: styles.sortIcon
102
105
  }) : /*#__PURE__*/React.createElement(SortAlphabeticalDesc, {
103
106
  className: styles.sortIcon
104
107
  })))
105
108
  }));
106
- }, [selectedSortColumns, handleToggleSortDirection]);
109
+ }, [selectedSortColumns, handleToggleSortDirection, labels]);
107
110
  const footer = useMemo(() => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ActionButton, {
108
111
  onClick: onClose
109
- }, "Cancel"), /*#__PURE__*/React.createElement(ActionButton, {
112
+ }, labels.sortDialogCancel), /*#__PURE__*/React.createElement(ActionButton, {
110
113
  variant: "primary",
111
114
  onClick: handleApply
112
- }, "Apply")), [handleApply, onClose]);
115
+ }, labels.sortDialogApply)), [handleApply, onClose, labels]);
116
+ const dialogTitle = useMemo(() => /*#__PURE__*/React.createElement("div", {
117
+ className: styles.title
118
+ }, /*#__PURE__*/React.createElement(Cog, null), labels.sortDialogTitle), [labels]);
113
119
  return /*#__PURE__*/React.createElement(Dialog, {
114
120
  isOpen: isOpen,
115
121
  onOpenChange: onClose,
116
- title: DialogTitle,
122
+ title: dialogTitle,
117
123
  footer: footer
118
124
  }, /*#__PURE__*/React.createElement("div", {
119
125
  className: styles.sortColumnsList
@@ -129,14 +135,11 @@ export function MultiColumnSortDialog({
129
135
  className: styles.addIcon
130
136
  }), /*#__PURE__*/React.createElement("span", {
131
137
  className: styles.addColumnText
132
- }, "Add Column to Sort"), /*#__PURE__*/React.createElement(CaretDown, null)),
138
+ }, labels.sortDialogAddColumnToSort), /*#__PURE__*/React.createElement(CaretDown, null)),
133
139
  triggerClassName: styles.addColumnButton,
134
140
  disabled: availableColumns.length === 0,
135
- searchPlaceholder: "Search columns",
136
- emptyMessage: "No matching columns"
141
+ searchPlaceholder: labels.sortDialogSearchPlaceholder,
142
+ emptyMessage: labels.sortDialogNoMatchingColumns
137
143
  })));
138
144
  }
139
- const DialogTitle = /*#__PURE__*/React.createElement("div", {
140
- className: styles.title
141
- }, /*#__PURE__*/React.createElement(Cog, null), "Sort on Multiple Columns");
142
145
  //# sourceMappingURL=MultiColumnSortDialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultiColumnSortDialog.js","names":["Button","Add","CaretDown","Cog","SortAlphabetical","SortAlphabeticalDesc","arrayMove","classNames","React","useCallback","useEffect","useMemo","useState","ActionButton","Dialog","SearchableMenu","SortableItemsList","styles","MultiColumnSortDialog","isOpen","onClose","onApply","currentSorting","columnOptions","selectedSortColumns","setSelectedSortColumns","selectedColumns","sort","column","find","col","id","push","direction","desc","handleAddColumn","prev","handleRemoveSortColumn","filter","item","handleReorderSortColumns","fromIndex","toIndex","items","handleToggleSortDirection","map","handleApply","sortingState","availableColumns","canSort","some","selected","searchableMenuItems","key","label","name","handleMenuItemSelected","sortableItems","content","createElement","className","sortColumnItem","sortColumnName","truncate","sortDirectionButton","onClick","sortIcon","footer","Fragment","variant","onOpenChange","title","DialogTitle","sortColumnsList","onReorder","onRemove","sortableList","onItemSelected","trigger","addIcon","addColumnText","triggerClassName","addColumnButton","disabled","length","searchPlaceholder","emptyMessage"],"sources":["MultiColumnSortDialog.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Button } from \"@base-ui/react/button\";\nimport {\n Add,\n CaretDown,\n Cog,\n SortAlphabetical,\n SortAlphabeticalDesc,\n} from \"@blueprintjs/icons\";\nimport { arrayMove } from \"@dnd-kit/sortable\";\nimport type { SortingState } from \"@tanstack/react-table\";\nimport classNames from \"classnames\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { Dialog } from \"../base-components/dialog/Dialog.js\";\nimport { SearchableMenu } from \"../base-components/searchable-menu/SearchableMenu.js\";\nimport { type SortableItem, SortableItemsList } from \"./SortableItemsList.js\";\nimport type { ColumnOption } from \"./utils/types.js\";\n\nimport styles from \"./MultiColumnSortDialog.module.css\";\n\nexport interface SortColumnItem extends ColumnOption {\n direction: \"asc\" | \"desc\";\n}\n\nexport interface MultiColumnSortDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onApply: (sortColumns: SortingState) => void;\n currentSorting: SortingState;\n columnOptions: ColumnOption[];\n}\n\nexport function MultiColumnSortDialog({\n isOpen,\n onClose,\n onApply,\n currentSorting,\n columnOptions,\n}: MultiColumnSortDialogProps): React.ReactElement {\n const [selectedSortColumns, setSelectedSortColumns] = useState<\n SortColumnItem[]\n >([]);\n // Initialize selected sort columns from current sorting\n useEffect(() => {\n if (isOpen) {\n const selectedColumns: SortColumnItem[] = [];\n for (const sort of currentSorting) {\n const column = columnOptions.find((col) => col.id === sort.id);\n if (column) {\n selectedColumns.push({\n ...column,\n direction: sort.desc ? \"desc\" : \"asc\",\n });\n }\n }\n setSelectedSortColumns(selectedColumns);\n }\n }, [isOpen, currentSorting, columnOptions]);\n\n const handleAddColumn = useCallback((column: ColumnOption) => {\n setSelectedSortColumns((prev) => [\n ...prev,\n { ...column, direction: \"asc\" },\n ]);\n }, []);\n\n const handleRemoveSortColumn = useCallback((id: string) => {\n setSelectedSortColumns((prev) => prev.filter((item) => item.id !== id));\n }, []);\n\n const handleReorderSortColumns = useCallback(\n (fromIndex: number, toIndex: number) => {\n setSelectedSortColumns((items) => arrayMove(items, fromIndex, toIndex));\n },\n []\n );\n\n const handleToggleSortDirection = useCallback((id: string) => {\n setSelectedSortColumns((prev) =>\n prev.map((item) =>\n item.id === id\n ? { ...item, direction: item.direction === \"asc\" ? \"desc\" : \"asc\" }\n : item\n )\n );\n }, []);\n\n const handleApply = useCallback(() => {\n const sortingState: SortingState = selectedSortColumns.map((col) => ({\n id: col.id,\n desc: col.direction === \"desc\",\n }));\n onApply(sortingState);\n onClose();\n }, [selectedSortColumns, onApply, onClose]);\n\n const availableColumns = useMemo(\n () =>\n columnOptions.filter(\n (col) =>\n col.canSort &&\n !selectedSortColumns.some((selected) => selected.id === col.id)\n ),\n [columnOptions, selectedSortColumns]\n );\n\n const searchableMenuItems = useMemo(\n () => availableColumns.map((col) => ({ key: col.id, label: col.name })),\n [availableColumns]\n );\n\n const handleMenuItemSelected = useCallback(\n (key: string) => {\n const column = availableColumns.find((col) => col.id === key);\n if (column) {\n handleAddColumn(column);\n }\n },\n [availableColumns, handleAddColumn]\n );\n\n const sortableItems: SortableItem[] = useMemo(() => {\n return selectedSortColumns.map((item) => ({\n id: item.id,\n label: item.name,\n content: (\n <div className={styles.sortColumnItem}>\n <span className={classNames(styles.sortColumnName, styles.truncate)}>\n {item.name}\n </span>\n <Button\n className={styles.sortDirectionButton}\n onClick={() => handleToggleSortDirection(item.id)}\n aria-label={`Toggle sort direction for ${item.name}`}\n >\n {item.direction === \"asc\" ? (\n <SortAlphabetical className={styles.sortIcon} />\n ) : (\n <SortAlphabeticalDesc className={styles.sortIcon} />\n )}\n </Button>\n </div>\n ),\n }));\n }, [selectedSortColumns, handleToggleSortDirection]);\n\n const footer = useMemo(\n () => (\n <>\n <ActionButton onClick={onClose}>Cancel</ActionButton>\n <ActionButton variant=\"primary\" onClick={handleApply}>\n Apply\n </ActionButton>\n </>\n ),\n [handleApply, onClose]\n );\n\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onClose}\n title={DialogTitle}\n footer={footer}\n >\n <div className={styles.sortColumnsList}>\n <SortableItemsList\n items={sortableItems}\n onReorder={handleReorderSortColumns}\n onRemove={handleRemoveSortColumn}\n className={styles.sortableList}\n />\n <SearchableMenu\n items={searchableMenuItems}\n onItemSelected={handleMenuItemSelected}\n trigger={\n <>\n <Add className={styles.addIcon} />\n <span className={styles.addColumnText}>Add Column to Sort</span>\n <CaretDown />\n </>\n }\n triggerClassName={styles.addColumnButton}\n disabled={availableColumns.length === 0}\n searchPlaceholder=\"Search columns\"\n emptyMessage=\"No matching columns\"\n />\n </div>\n </Dialog>\n );\n}\n\nconst DialogTitle = (\n <div className={styles.title}>\n <Cog />\n Sort on Multiple Columns\n </div>\n);\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"MultiColumnSortDialog.js","names":["Button","Add","CaretDown","Cog","SortAlphabetical","SortAlphabeticalDesc","arrayMove","classNames","React","useCallback","useEffect","useMemo","useState","ActionButton","Dialog","SearchableMenu","useObjectTableLabels","withObjectTableLabels","SortableItemsList","styles","MultiColumnSortDialog","MultiColumnSortDialogInner","isOpen","onClose","onApply","currentSorting","columnOptions","labels","selectedSortColumns","setSelectedSortColumns","selectedColumns","sort","column","find","col","id","push","direction","desc","handleAddColumn","prev","handleRemoveSortColumn","filter","item","handleReorderSortColumns","fromIndex","toIndex","items","handleToggleSortDirection","map","handleApply","sortingState","availableColumns","canSort","some","selected","searchableMenuItems","key","label","name","handleMenuItemSelected","sortableItems","content","createElement","className","sortColumnItem","sortColumnName","truncate","sortDirectionButton","onClick","sortDialogToggleDirection","sortIcon","footer","Fragment","sortDialogCancel","variant","sortDialogApply","dialogTitle","title","sortDialogTitle","onOpenChange","sortColumnsList","onReorder","onRemove","sortableList","onItemSelected","trigger","addIcon","addColumnText","sortDialogAddColumnToSort","triggerClassName","addColumnButton","disabled","length","searchPlaceholder","sortDialogSearchPlaceholder","emptyMessage","sortDialogNoMatchingColumns"],"sources":["MultiColumnSortDialog.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Button } from \"@base-ui/react/button\";\nimport {\n Add,\n CaretDown,\n Cog,\n SortAlphabetical,\n SortAlphabeticalDesc,\n} from \"@blueprintjs/icons\";\nimport { arrayMove } from \"@dnd-kit/sortable\";\nimport type { SortingState } from \"@tanstack/react-table\";\nimport classNames from \"classnames\";\nimport React, { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { Dialog } from \"../base-components/dialog/Dialog.js\";\nimport { SearchableMenu } from \"../base-components/searchable-menu/SearchableMenu.js\";\nimport type { ObjectTableLabels } from \"./ObjectTableLabels.js\";\nimport {\n useObjectTableLabels,\n withObjectTableLabels,\n} from \"./ObjectTableLabels.js\";\nimport { type SortableItem, SortableItemsList } from \"./SortableItemsList.js\";\nimport type { ColumnOption } from \"./utils/types.js\";\n\nimport styles from \"./MultiColumnSortDialog.module.css\";\n\nexport interface SortColumnItem extends ColumnOption {\n direction: \"asc\" | \"desc\";\n}\n\nexport interface MultiColumnSortDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onApply: (sortColumns: SortingState) => void;\n currentSorting: SortingState;\n columnOptions: ColumnOption[];\n /**\n * Overrides for the dialog's user-facing strings. Provide any subset; unset\n * keys fall back to the built-in English defaults. When this dialog is\n * rendered inside a `BaseTable`/`ObjectTable`, it inherits that table's\n * `labels` and this prop is only needed to override further. See\n * {@link ObjectTableLabels}.\n */\n labels?: Partial<ObjectTableLabels>;\n}\n\nexport const MultiColumnSortDialog: React.FC<MultiColumnSortDialogProps> =\n withObjectTableLabels(MultiColumnSortDialogInner);\n\nfunction MultiColumnSortDialogInner({\n isOpen,\n onClose,\n onApply,\n currentSorting,\n columnOptions,\n}: Omit<MultiColumnSortDialogProps, \"labels\">): React.ReactElement {\n const labels = useObjectTableLabels();\n const [selectedSortColumns, setSelectedSortColumns] = useState<\n SortColumnItem[]\n >([]);\n // Initialize selected sort columns from current sorting\n useEffect(() => {\n if (isOpen) {\n const selectedColumns: SortColumnItem[] = [];\n for (const sort of currentSorting) {\n const column = columnOptions.find((col) => col.id === sort.id);\n if (column) {\n selectedColumns.push({\n ...column,\n direction: sort.desc ? \"desc\" : \"asc\",\n });\n }\n }\n setSelectedSortColumns(selectedColumns);\n }\n }, [isOpen, currentSorting, columnOptions]);\n\n const handleAddColumn = useCallback((column: ColumnOption) => {\n setSelectedSortColumns((prev) => [\n ...prev,\n { ...column, direction: \"asc\" },\n ]);\n }, []);\n\n const handleRemoveSortColumn = useCallback((id: string) => {\n setSelectedSortColumns((prev) => prev.filter((item) => item.id !== id));\n }, []);\n\n const handleReorderSortColumns = useCallback(\n (fromIndex: number, toIndex: number) => {\n setSelectedSortColumns((items) => arrayMove(items, fromIndex, toIndex));\n },\n []\n );\n\n const handleToggleSortDirection = useCallback((id: string) => {\n setSelectedSortColumns((prev) =>\n prev.map((item) =>\n item.id === id\n ? { ...item, direction: item.direction === \"asc\" ? \"desc\" : \"asc\" }\n : item\n )\n );\n }, []);\n\n const handleApply = useCallback(() => {\n const sortingState: SortingState = selectedSortColumns.map((col) => ({\n id: col.id,\n desc: col.direction === \"desc\",\n }));\n onApply(sortingState);\n onClose();\n }, [selectedSortColumns, onApply, onClose]);\n\n const availableColumns = useMemo(\n () =>\n columnOptions.filter(\n (col) =>\n col.canSort &&\n !selectedSortColumns.some((selected) => selected.id === col.id)\n ),\n [columnOptions, selectedSortColumns]\n );\n\n const searchableMenuItems = useMemo(\n () => availableColumns.map((col) => ({ key: col.id, label: col.name })),\n [availableColumns]\n );\n\n const handleMenuItemSelected = useCallback(\n (key: string) => {\n const column = availableColumns.find((col) => col.id === key);\n if (column) {\n handleAddColumn(column);\n }\n },\n [availableColumns, handleAddColumn]\n );\n\n const sortableItems: SortableItem[] = useMemo(() => {\n return selectedSortColumns.map((item) => ({\n id: item.id,\n label: item.name,\n content: (\n <div className={styles.sortColumnItem}>\n <span className={classNames(styles.sortColumnName, styles.truncate)}>\n {item.name}\n </span>\n <Button\n className={styles.sortDirectionButton}\n onClick={() => handleToggleSortDirection(item.id)}\n aria-label={labels.sortDialogToggleDirection(item.name)}\n >\n {item.direction === \"asc\" ? (\n <SortAlphabetical className={styles.sortIcon} />\n ) : (\n <SortAlphabeticalDesc className={styles.sortIcon} />\n )}\n </Button>\n </div>\n ),\n }));\n }, [selectedSortColumns, handleToggleSortDirection, labels]);\n\n const footer = useMemo(\n () => (\n <>\n <ActionButton onClick={onClose}>{labels.sortDialogCancel}</ActionButton>\n <ActionButton variant=\"primary\" onClick={handleApply}>\n {labels.sortDialogApply}\n </ActionButton>\n </>\n ),\n [handleApply, onClose, labels]\n );\n\n const dialogTitle = useMemo(\n () => (\n <div className={styles.title}>\n <Cog />\n {labels.sortDialogTitle}\n </div>\n ),\n [labels]\n );\n\n return (\n <Dialog\n isOpen={isOpen}\n onOpenChange={onClose}\n title={dialogTitle}\n footer={footer}\n >\n <div className={styles.sortColumnsList}>\n <SortableItemsList\n items={sortableItems}\n onReorder={handleReorderSortColumns}\n onRemove={handleRemoveSortColumn}\n className={styles.sortableList}\n />\n <SearchableMenu\n items={searchableMenuItems}\n onItemSelected={handleMenuItemSelected}\n trigger={\n <>\n <Add className={styles.addIcon} />\n <span className={styles.addColumnText}>\n {labels.sortDialogAddColumnToSort}\n </span>\n <CaretDown />\n </>\n }\n triggerClassName={styles.addColumnButton}\n disabled={availableColumns.length === 0}\n searchPlaceholder={labels.sortDialogSearchPlaceholder}\n emptyMessage={labels.sortDialogNoMatchingColumns}\n />\n </div>\n </Dialog>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -61,6 +61,7 @@ export function ObjectTable({
61
61
  focusedRow,
62
62
  onFocusedRowChanged,
63
63
  tableRef,
64
+ labels,
64
65
  ...props
65
66
  }) {
66
67
  const {
@@ -230,7 +231,8 @@ export function ObjectTable({
230
231
  getRowAttributes: props.getRowAttributes,
231
232
  showEditFooter: props.showEditFooter,
232
233
  focusedRowId: focusedRow == null ? focusedRow : getRowIdFromPrimaryKey(focusedRow),
233
- onFocusedRowChanged: onFocusedRowChanged
234
+ onFocusedRowChanged: onFocusedRowChanged,
235
+ labels: labels
234
236
  });
235
237
  }
236
238
  //# sourceMappingURL=ObjectTable.js.map