Skip to content

Commit

Permalink
Cleanup ListView (#366)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmingles committed May 1, 2024
1 parent 7acd275 commit e4c509f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 77 deletions.
44 changes: 6 additions & 38 deletions plugins/ui/src/js/src/elements/ListView.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,25 @@
import React, { ReactElement } from 'react';
import { useSelector } from 'react-redux';
import type { SelectionMode } from '@react-types/shared';
import { isElementOfType } from '@deephaven/react-hooks';
import { getSettings, RootState } from '@deephaven/redux';
import {
ListView as DHListView,
ListViewProps as DHListViewProps,
} from '@deephaven/components';
import {
ListView as DHListViewJSApi,
ListViewProps as DHListViewJSApiProps,
} from '@deephaven/jsapi-components';
import {
SerializedListViewEventProps,
useListViewProps,
} from './useListViewProps';
import ObjectView, { ObjectViewProps } from './ObjectView';
import { ListView as DHListView } from '@deephaven/components';
import { ListView as DHListViewJSApi } from '@deephaven/jsapi-components';
import { SerializedListViewProps, useListViewProps } from './useListViewProps';
import ObjectView from './ObjectView';
import useReExportedTable from './useReExportedTable';

type WrappedDHListViewJSApiProps = Omit<DHListViewJSApiProps, 'table'> & {
children: ReactElement<ObjectViewProps>;
};

type WrappedDHListViewProps = Omit<DHListViewProps, 'selectionMode'> & {
// The spec specifies that selectionMode should be uppercase, but the Spectrum
// prop is lowercase. We'll accept either to keep things more flexible.s
selectionMode?: SelectionMode | Uppercase<SelectionMode>;
};

export type ListViewProps = (
| WrappedDHListViewProps
| WrappedDHListViewJSApiProps
) &
SerializedListViewEventProps;

function ListView({ children, selectionMode, ...props }: ListViewProps) {
function ListView(props: SerializedListViewProps): JSX.Element | null {
const settings = useSelector(getSettings<RootState>);
const listViewProps = useListViewProps(props);
const { children, ...listViewProps } = useListViewProps(props);

const isObjectView = isElementOfType(children, ObjectView);
const table = useReExportedTable(children);

const selectionModeLc = (selectionMode?.toLowerCase() ??
'none') as SelectionMode;

if (isObjectView) {
return (
table && (
<DHListViewJSApi
// eslint-disable-next-line react/jsx-props-no-spreading
{...listViewProps}
selectionMode={selectionModeLc}
table={table}
settings={settings}
/>
Expand All @@ -62,7 +31,6 @@ function ListView({ children, selectionMode, ...props }: ListViewProps) {
<DHListView
// eslint-disable-next-line react/jsx-props-no-spreading
{...listViewProps}
selectionMode={selectionModeLc}
>
{children}
</DHListView>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function serializeSelectionEvent(
*/
export function useSelectionEventCallback(
callback?: SerializedSelectionEventCallback
) {
): (selection: ItemSelection) => void {
return useCallback(
(selection: ItemSelection) => {
callback?.(serializeSelectionEvent(selection));
Expand Down
69 changes: 31 additions & 38 deletions plugins/ui/src/js/src/elements/useListViewProps.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,61 @@
import {
SerializedFocusEventCallback,
useFocusEventCallback,
} from './spectrum/useFocusEventCallback';
import {
SerializedKeyboardEventCallback,
useKeyboardEventCallback,
} from './spectrum/useKeyboardEventCallback';
import { ReactElement } from 'react';
import type { SelectionMode } from '@react-types/shared';
import { ListViewProps as DHListViewProps } from '@deephaven/components';
import { ListViewProps as DHListViewJSApiProps } from '@deephaven/jsapi-components';
import { ObjectViewProps } from './ObjectView';
import {
SerializedSelectionEventCallback,
useSelectionEventCallback,
} from './spectrum/useSelectionEventCallback';

type WrappedDHListViewJSApiProps = Omit<DHListViewJSApiProps, 'table'> & {
children: ReactElement<ObjectViewProps>;
};

type WrappedDHListViewProps = Omit<DHListViewProps, 'selectionMode'> & {
// The dh UI spec specifies that selectionMode should be uppercase, but the
// Spectrum prop is lowercase. We'll accept either to keep things more
// flexible.
selectionMode?: SelectionMode | Uppercase<SelectionMode>;
};

export interface SerializedListViewEventProps {
/** Handler that is called when selection changes */
onChange?: SerializedSelectionEventCallback;

/** Handler that is called when the element receives focus. */
onFocus?: SerializedFocusEventCallback;

/** Handler that is called when the element loses focus. */
onBlur?: SerializedFocusEventCallback;

/** Handler that is called when a key is pressed */
onKeyDown?: SerializedKeyboardEventCallback;

/** Handler that is called when a key is released */
onKeyUp?: SerializedKeyboardEventCallback;

/**
* Handler that is called when the selection changes.
* @deprecated Use `onChange` instead
*/
onSelectionChange?: SerializedSelectionEventCallback;
}

export type SerializedListViewProps = (
| WrappedDHListViewProps
| WrappedDHListViewJSApiProps
) &
SerializedListViewEventProps;

/**
* Wrap ListView props with the appropriate serialized event callbacks.
* @param props Props to wrap
* @returns Wrapped props
*/
export function useListViewProps<T>(props: SerializedListViewEventProps & T) {
const {
onFocus,
onBlur,
onKeyDown,
onKeyUp,
onChange,
onSelectionChange,
...otherProps
} = props;
export function useListViewProps({
selectionMode,
onChange,
onSelectionChange,
...otherProps
}: SerializedListViewProps): DHListViewProps | WrappedDHListViewJSApiProps {
const selectionModeLc = (selectionMode?.toLowerCase() ??
'none') as SelectionMode;

const serializedOnChange = useSelectionEventCallback(onChange);
const serializedOnFocus = useFocusEventCallback(onFocus);
const serializedOnBlur = useFocusEventCallback(onBlur);
const serializedOnKeyDown = useKeyboardEventCallback(onKeyDown);
const serializedOnKeyUp = useKeyboardEventCallback(onKeyUp);
const serializedOnSelectionChange =
useSelectionEventCallback(onSelectionChange);

return {
onFocus: serializedOnFocus,
onBlur: serializedOnBlur,
onKeyDown: serializedOnKeyDown,
onKeyUp: serializedOnKeyUp,
selectionMode: selectionModeLc,
onChange: serializedOnChange,
onSelectionChange: serializedOnSelectionChange,
// The @deephaven/components `ListView` has its own normalization logic that
Expand Down

0 comments on commit e4c509f

Please sign in to comment.