Skip to content

Commit b9dc6a5

Browse files
committed
Beginnings of Picker Table support (#1858)
1 parent 1ca0015 commit b9dc6a5

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

packages/jsapi-components/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from './HookTestUtils';
22
export { default as TableInput } from './TableInput';
33
export * from './RefreshTokenBootstrap';
44
export * from './RefreshTokenUtils';
5+
export * from './spectrum';
56
export * from './TableDropdown';
67
export { default as useBroadcastChannel } from './useBroadcastChannel';
78
export { default as useBroadcastLoginListener } from './useBroadcastLoginListener';
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import {
2+
NormalizedPickerItemData,
3+
Picker as PickerBase,
4+
PickerProps as PickerPropsBase,
5+
} from '@deephaven/components';
6+
import { dh } from '@deephaven/jsapi-types';
7+
import { useCallback, useMemo } from 'react';
8+
import { useViewportData } from '../useViewportData';
9+
10+
function formatValue(value: unknown): string | number | boolean {
11+
if (
12+
typeof value === 'string' ||
13+
typeof value === 'number' ||
14+
typeof value === 'boolean'
15+
) {
16+
return value;
17+
}
18+
19+
// TODO: Add support for formatting date values
20+
return String(value);
21+
}
22+
23+
function usePickerItemRowDeserializer({
24+
table,
25+
keyColumnName,
26+
labelColumnName,
27+
}: {
28+
table: dh.Table;
29+
keyColumnName?: string;
30+
labelColumnName?: string;
31+
}) {
32+
const keyColumn = useMemo(
33+
() =>
34+
table.findColumn(
35+
keyColumnName == null ? table.columns[0].name : keyColumnName
36+
),
37+
[keyColumnName, table]
38+
);
39+
40+
const labelColumn = useMemo(
41+
() =>
42+
labelColumnName == null ? keyColumn : table.findColumn(labelColumnName),
43+
[keyColumn, labelColumnName, table]
44+
);
45+
46+
const deserializeRow = useCallback(
47+
(row: dh.Row): NormalizedPickerItemData => {
48+
const key = formatValue(row.get(keyColumn));
49+
const content = formatValue(row.get(labelColumn));
50+
51+
return {
52+
key,
53+
content,
54+
};
55+
},
56+
[keyColumn, labelColumn]
57+
);
58+
59+
return deserializeRow;
60+
}
61+
62+
export interface PickerProps extends PickerPropsBase {
63+
table: dh.Table;
64+
/* The column of values to use as item keys. Defaults to the first column. */
65+
keyColumn?: string;
66+
/* The column of values to display as primary text. Defaults to the `keyColumn` value. */
67+
labelColumn?: string;
68+
}
69+
70+
export function Picker({
71+
table,
72+
keyColumn: keyColumnName,
73+
labelColumn: labelColumnName,
74+
...props
75+
}: PickerProps): JSX.Element {
76+
const deserializeRow = usePickerItemRowDeserializer({
77+
table,
78+
keyColumnName,
79+
labelColumnName,
80+
});
81+
82+
const { viewportData } = useViewportData<NormalizedPickerItemData, dh.Table>({
83+
reuseItemsOnTableResize: true,
84+
table,
85+
deserializeRow,
86+
});
87+
88+
return (
89+
// eslint-disable-next-line react/jsx-props-no-spreading
90+
<PickerBase {...props}>{viewportData.items}</PickerBase>
91+
);
92+
}
93+
94+
export default Picker;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Picker';

0 commit comments

Comments
 (0)