Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instrument picker #923

Merged
merged 4 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion vuu-ui/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
inlined-worker.js
# inlined-worker.js
1 change: 1 addition & 0 deletions vuu-ui/packages/vuu-data/src/inlined-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const workerSourceCode = "";
1 change: 1 addition & 0 deletions vuu-ui/packages/vuu-datagrid-types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface TableAttributes {
columnDefaultWidth?: number;
columnFormatHeader?: "capitalize" | "uppercase";
columnSeparators?: boolean;
showHighlightedRow?: boolean;
rowSeparators?: boolean;
zebraStripes?: boolean;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
} from "@finos/vuu-utils";
import { getIndexOfEditedItem } from "./toolbar-dom-utils";
import { NavigationOutOfBoundsHandler } from "./Toolbar";
import { PopupCloseCallback } from "packages/vuu-popups/src";
import { PopupCloseCallback } from "@finos/vuu-popups";

type directionType = "bwd" | "fwd" | "start" | "end";
type directionMap = { [key: string]: directionType };
Expand Down
2 changes: 1 addition & 1 deletion vuu-ui/packages/vuu-layout/src/toolbar/useToolbar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { OverflowItem, ToolbarProps } from "@finos/vuu-layout";
import { isValidNumber } from "@finos/vuu-utils";
import { PopupCloseCallback } from "packages/vuu-popups/src";
import { PopupCloseCallback } from "@finos/vuu-popups";
import {
KeyboardEvent,
MouseEvent as ReactMouseEvent,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ColumnDescriptor } from "packages/vuu-datagrid-types";
import { ColumnDescriptor } from "@finos/vuu-datagrid-types";
import cx from "classnames";

import {
Expand Down
4 changes: 4 additions & 0 deletions vuu-ui/packages/vuu-table/src/table-next/TableNext.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
--row-borderColor: var(--salt-separable-tertiary-borderColor);
}

.vuuTableNext-highlight .vuuTableNextRow:hover {
background-color: var(--vuu-color-pink-10-fade-20);
}

.vuuTableNext-scrollbarContainer {
--scroll-content-width: 1100px;
border-bottom: none !important;
Expand Down
3 changes: 3 additions & 0 deletions vuu-ui/packages/vuu-table/src/table-next/TableNext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const TableNext = forwardRef(function TableNext(
config,
dataSource,
id: idProp,
navigationStyle = "cell",
onAvailableColumnsChange,
onConfigChange,
onFeatureEnabled,
Expand Down Expand Up @@ -69,6 +70,7 @@ export const TableNext = forwardRef(function TableNext(
containerRef,
dataSource,
headerHeight,
navigationStyle,
onAvailableColumnsChange,
onConfigChange,
onFeatureEnabled,
Expand Down Expand Up @@ -98,6 +100,7 @@ export const TableNext = forwardRef(function TableNext(
const className = cx(classBase, classNameProp, {
[`${classBase}-colLines`]: tableAttributes.columnSeparators,
[`${classBase}-rowLines`]: tableAttributes.rowSeparators,
[`${classBase}-highlight`]: tableAttributes.showHighlightedRow,
[`${classBase}-zebra`]: tableAttributes.zebraStripes,
// [`${classBase}-loading`]: isDataLoading(tableProps.columns),
});
Expand Down
31 changes: 22 additions & 9 deletions vuu-ui/packages/vuu-table/src/table-next/useKeyboardNavigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,33 @@ import {
getTableCell,
headerCellQuery,
} from "./table-dom-utils";
import { TableNavigationStyle } from "../table/dataTableTypes";

const navigationKeys = new Set<NavigationKey>([
const rowNavigationKeys = new Set<NavigationKey>([
"Home",
"End",
"PageUp",
"PageDown",
"ArrowDown",
"ArrowLeft",
"ArrowRight",
"ArrowUp",
]);

export const isNavigationKey = (key: string): key is NavigationKey => {
return navigationKeys.has(key as NavigationKey);
const cellNavigationKeys = new Set(rowNavigationKeys);
cellNavigationKeys.add("ArrowLeft");
cellNavigationKeys.add("ArrowRight");

export const isNavigationKey = (
key: string,
navigationStyle: TableNavigationStyle
): key is NavigationKey => {
switch (navigationStyle) {
case "cell":
return cellNavigationKeys.has(key as NavigationKey);
case "row":
return rowNavigationKeys.has(key as NavigationKey);
default:
return false;
}
};

type ArrowKey = "ArrowUp" | "ArrowDown" | "ArrowLeft" | "ArrowRight";
Expand Down Expand Up @@ -114,6 +127,7 @@ export interface NavigationHookProps {
columnCount?: number;
disableHighlightOnFocus?: boolean;
label?: string;
navigationStyle: TableNavigationStyle;
viewportRange: VuuRange;
requestScroll?: ScrollRequestHandler;
restoreLastFocus?: boolean;
Expand All @@ -126,6 +140,7 @@ export const useKeyboardNavigation = ({
columnCount = 0,
containerRef,
disableHighlightOnFocus,
navigationStyle,
requestScroll,
rowCount = 0,
viewportRowCount,
Expand Down Expand Up @@ -233,7 +248,6 @@ NavigationHookProps) => {
// click handler.
const focusedCell = getFocusedCell(document.activeElement);
if (focusedCell) {
console.log({ focusedCell });
focusedCellPos.current = getTableCellPos(focusedCell);
}
}
Expand All @@ -242,7 +256,6 @@ NavigationHookProps) => {

const navigateChildItems = useCallback(
async (key: NavigationKey) => {
console.log(`navigate child items ${key}`);
const [nextRowIdx, nextColIdx] = isPagingKey(key)
? await nextPageItemIdx(key, activeCellPos.current)
: nextCellPos(key, activeCellPos.current, columnCount, rowCount);
Expand All @@ -258,13 +271,13 @@ NavigationHookProps) => {

const handleKeyDown = useCallback(
(e: KeyboardEvent) => {
if (rowCount > 0 && isNavigationKey(e.key)) {
if (rowCount > 0 && isNavigationKey(e.key, navigationStyle)) {
e.preventDefault();
e.stopPropagation();
void navigateChildItems(e.key);
}
},
[rowCount, navigateChildItems]
[rowCount, navigationStyle, navigateChildItems]
);

const handleClick = useCallback(
Expand Down
3 changes: 3 additions & 0 deletions vuu-ui/packages/vuu-table/src/table-next/useTableNext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export interface TableHookProps
| "availableColumns"
| "config"
| "dataSource"
| "navigationStyle"
| "onAvailableColumnsChange"
| "onConfigChange"
| "onFeatureEnabled"
Expand Down Expand Up @@ -98,6 +99,7 @@ export const useTable = ({
containerRef,
dataSource,
headerHeight = 25,
navigationStyle,
onAvailableColumnsChange,
onConfigChange,
onFeatureEnabled,
Expand Down Expand Up @@ -408,6 +410,7 @@ export const useTable = ({
} = useKeyboardNavigation({
columnCount: columns.filter((c) => c.hidden !== true).length,
containerRef,
navigationStyle,
requestScroll,
rowCount: dataSource?.size,
viewportRange: range,
Expand Down
7 changes: 7 additions & 0 deletions vuu-ui/packages/vuu-table/src/table/dataTableTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export type TableRowClickHandler = (row: VuuDataRow) => void;
// TODO implement a Model object to represent a row data for better API
export type TableRowSelectHandler = (row: DataSourceRow) => void;

export type TableNavigationStyle = "none" | "cell" | "row";

export interface TableProps
extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect"> {
Row?: FC<RowProps>;
Expand All @@ -32,6 +34,11 @@ export interface TableProps
dataSource: DataSource;
headerHeight?: number;
height?: number;
/**
* Defined how focus navigation within data cells will be handled by table.
* Default is cell.
*/
navigationStyle?: TableNavigationStyle;
/**
* required if a fully featured column picker is to be available.
* Available columns can be changed by the addition or removal of
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { FocusEvent, KeyboardEvent, RefObject } from "react";
import { CollectionItem } from "./collectionTypes";

export interface NavigationProps<Item = unknown> {
export interface NavigationProps {
cycleFocus?: boolean;
defaultHighlightedIndex?: number;
disableHighlightOnFocus?: boolean;
focusOnHighlight?: boolean;
focusVisible?: number;
highlightedIndex?: number;
indexPositions: CollectionItem<Item>[];
itemCount: number;
onHighlight?: (idx: number) => void;
onKeyboardNavigation?: (evt: KeyboardEvent, idx: number) => void;
restoreLastFocus?: boolean;
viewportItemCount: number;
}

export interface NavigationHookProps<Item> extends NavigationProps<Item> {
export interface NavigationHookProps extends NavigationProps {
containerRef: RefObject<HTMLElement>;
label?: string;
selected?: string[];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { TableSchema } from "@finos/vuu-data";
import { DataSourceRow } from "@finos/vuu-data-types";
import { useId } from "@finos/vuu-layout";
import { TableNext, TableProps, TableRowSelectHandler } from "@finos/vuu-table";
import { ColumnMap } from "@finos/vuu-utils";
Expand All @@ -17,6 +18,14 @@ export interface InstrumentPickerProps
TableProps: Pick<TableProps, "config" | "dataSource">;
columnMap: ColumnMap;
disabled?: boolean;
/**
* Used to form the display value to render in input following selection. If
* not provided, default will be the values from rendered columns.
*
* @param row DataSourceRow
* @returns string
*/
itemToString?: (row: DataSourceRow) => string;
onSelect: TableRowSelectHandler;
schema: TableSchema;
searchColumns: string[];
Expand All @@ -30,6 +39,7 @@ export const InstrumentPicker = forwardRef(function InstrumentPicker(
columnMap,
disabled,
id: idProp,
itemToString,
onSelect,
schema,
searchColumns,
Expand All @@ -47,7 +57,16 @@ export const InstrumentPicker = forwardRef(function InstrumentPicker(
onOpenChange,
tableHandlers,
value,
} = useInstrumentPicker({ columnMap, dataSource, onSelect, searchColumns });
} = useInstrumentPicker({
columnMap,
columns: TableProps.config.columns,
dataSource,
itemToString,
onSelect,
searchColumns,
});

console.log({ value });

const endAdornment = useMemo(() => <span data-icon="chevron-down" />, []);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
import { DataSource } from "@finos/vuu-data";
import { DataSourceRow } from "@finos/vuu-data-types";
import { ColumnDescriptor } from "@finos/vuu-datagrid-types";
import { TableRowSelectHandler } from "@finos/vuu-table";
import { ColumnMap } from "@finos/vuu-utils";
import { ChangeEvent, useCallback, useMemo, useState } from "react";
import { useControlled } from "../common-hooks";
import { InstrumentPickerProps } from "./InstrumentPicker";

export interface InstrumentPickerHookProps {
columnMap: ColumnMap;
export interface InstrumentPickerHookProps
extends Pick<
InstrumentPickerProps,
"columnMap" | "itemToString" | "onSelect" | "searchColumns"
> {
columns: ColumnDescriptor[];
dataSource: DataSource;
defaultIsOpen?: boolean;
isOpen?: boolean;
onSelect: TableRowSelectHandler;
searchColumns: string[];
}

const defaultItemToString =
(columns: ColumnDescriptor[], columnMap: ColumnMap) =>
(row: DataSourceRow) => {
return columns.map(({ name }) => row[columnMap[name]]).join(" ");
};

export const useInstrumentPicker = ({
columnMap,
columns,
dataSource,
defaultIsOpen,
isOpen: isOpenProp,
itemToString = defaultItemToString(columns, columnMap),
onSelect,
searchColumns,
}: InstrumentPickerHookProps) => {
Expand Down Expand Up @@ -65,13 +78,12 @@ export const useInstrumentPicker = ({

const handleSelectRow = useCallback<TableRowSelectHandler>(
(row) => {
const { name } = columnMap;
const { [name]: value } = row;
setValue(value as string);
const value = itemToString(row);
setValue(value);
setIsOpen(false);
onSelect(row);
},
[columnMap, onSelect, setIsOpen]
[itemToString, onSelect, setIsOpen]
);

const inputProps = {
Expand Down
5 changes: 3 additions & 2 deletions vuu-ui/packages/vuu-ui-controls/src/list/List.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@
overflow: auto;
}

.vuuListItemHeader {
.vuuListHeader {
--saltList-item-background: var(--list-item-header-background);
color: var(--list-item-header-color);
font-weight: 600;
}

.vuuListItemHeader[data-sticky="true"] {
.vuuListHeader[data-sticky="true"] {
--saltList-item-background: var(--list-background);
position: sticky;
top: 0;
Expand Down
2 changes: 1 addition & 1 deletion vuu-ui/packages/vuu-ui-controls/src/list/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,12 @@ export const List = forwardRef(function List<
focusVisible: collapsibleHeaders && appliedFocusVisible === idx.value,
})}
aria-expanded={expanded}
data-idx={collapsibleHeaders ? idx.value : undefined}
data-index={collapsibleHeaders ? idx.value : undefined}
data-highlighted={idx.value === highlightedIndex || undefined}
data-sticky={stickyHeaders}
data-selectable={false}
id={headerId}
itemHeight={getItemHeight(idx.value)}
key={`header-${idx.value}`}
label={title}
// role="presentation"
Expand Down
Loading
Loading