Skip to content

Commit

Permalink
AppPattern example to show search with recents
Browse files Browse the repository at this point in the history
  • Loading branch information
heswell committed Nov 12, 2024
1 parent 7d922f5 commit f06c9cb
Show file tree
Hide file tree
Showing 23 changed files with 752 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export class ArrayDataSource

constructor({
aggregations,
baseFilterSpec,
// different from RemoteDataSource
columnDescriptors,
data,
Expand Down Expand Up @@ -176,6 +177,7 @@ export class ArrayDataSource
this.config = {
...this._config,
aggregations: aggregations || this._config.aggregations,
baseFilterSpec,
columns,
filterSpec: filterSpec || this._config.filterSpec,
groupBy: groupBy || this._config.groupBy,
Expand All @@ -190,6 +192,7 @@ export class ArrayDataSource
viewport = this.viewport ?? (this.viewport = uuid()),
columns,
aggregations,
baseFilterSpec,
range,
selectedIndexValues,
selectedKeyValues,
Expand Down Expand Up @@ -220,6 +223,7 @@ export class ArrayDataSource
config = {
...config,
aggregations: aggregations || this._config.aggregations,
baseFilterSpec: baseFilterSpec || this._config.baseFilterSpec,
columns: columns || this._config.columns,
filterSpec: filterSpec || this._config.filterSpec,
groupBy: groupBy || this._config.groupBy,
Expand Down
12 changes: 12 additions & 0 deletions vuu-ui/packages/vuu-icons/index.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions vuu-ui/packages/vuu-table-types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,13 @@ export interface ColumnDescriptor extends DataValueDescriptor {
pin?: PinLocation;
resizeable?: boolean;
sortable?: boolean;
/**
* 'client' columns will not receive data from dataSource.
* They can be used with a custom renderer, e.g to render
* action buttons.
* default is 'server'
*/
source?: "client" | "server";
width?: number;
}

Expand Down
10 changes: 5 additions & 5 deletions vuu-ui/packages/vuu-table/src/Table.css
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@
}

.vuuTable-table {
border: none;
border-collapse: separate;
border-spacing: 0;
left: 0;
margin: 0;
position: absolute;
top: 0;
left: 0;
table-layout: fixed;
width: var(--content-width);
margin: 0;
border: none;
border-collapse: separate;
border-spacing: 0;
}

.vuuTable-body {
Expand Down
13 changes: 13 additions & 0 deletions vuu-ui/packages/vuu-table/src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { useWindow } from "@salt-ds/window";
import cx from "clsx";
import {
CSSProperties,
ComponentType,
FC,
ForwardedRef,
RefObject,
Expand Down Expand Up @@ -59,6 +60,10 @@ export type TableNavigationStyle = "none" | "cell" | "row" | "tree";

export interface TableProps
extends Omit<MeasuredContainerProps, "onDragStart" | "onDrop" | "onSelect"> {
/**
* A react function componnet that will be rendered if there are no rows to display
*/
EmptyDisplay?: ComponentType;
Row?: FC<RowProps>;
/**
* Allow a block of cells to be selected. Typically to be copied.
Expand Down Expand Up @@ -249,6 +254,7 @@ export interface TableProps
}

const TableCore = ({
EmptyDisplay,
Row = DefaultRow,
allowCellBlockSelection,
allowDragColumnHeader = true,
Expand Down Expand Up @@ -384,6 +390,10 @@ const TableCore = ({
const headersReady = showColumnHeaders === false || headerHeight > 0;
const readyToRenderTableBody = headersReady && data.length > 0;

if (dataSource.size === 0 && EmptyDisplay) {
return <EmptyDisplay />;
}

return (
<ContextMenuProvider
menuActionHandler={handleContextMenuAction}
Expand Down Expand Up @@ -493,6 +503,7 @@ const TableCore = ({

export const Table = forwardRef(function Table(
{
EmptyDisplay,
Row,
allowCellBlockSelection,
allowDragColumnHeader,
Expand Down Expand Up @@ -629,6 +640,7 @@ export const Table = forwardRef(function Table(
ref={useForkRef(containerRef, forwardedRef)}
style={
{
...styleProp,
"--row-height-prop": rowHeight > 0 ? `${rowHeight}px` : undefined,
} as CSSProperties
}
Expand All @@ -639,6 +651,7 @@ export const Table = forwardRef(function Table(
rowHeight &&
(footerHeight || showPaginationControls !== true) ? (
<TableCore
EmptyDisplay={EmptyDisplay}
Row={Row}
allowCellBlockSelection={allowCellBlockSelection}
allowDragColumnHeader={allowDragColumnHeader}
Expand Down
5 changes: 3 additions & 2 deletions vuu-ui/packages/vuu-table/src/useTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export const useTable = ({
rowHeight = 20,
rowToObject = asDataSourceRowObject,
scrollingApiRef,
selectionBookendWidth,
selectionBookendWidth = 4,
selectionModel,
showColumnHeaders,
showPaginationControls,
Expand Down Expand Up @@ -213,7 +213,8 @@ export const useTable = ({
size.height - (headerState.height === -1 ? 0 : headerState.height);
const verticalScrollbarWidth =
virtualContentHeight > viewportBodyHeight ? 10 : 0;
const availableWidth = size.width - (verticalScrollbarWidth + 8);
const availableWidth =
size.width - (verticalScrollbarWidth + (2 & selectionBookendWidth));

const rowClassNameGenerator = useRowClassNameGenerators(config);

Expand Down
4 changes: 4 additions & 0 deletions vuu-ui/packages/vuu-table/src/useTableModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ function init(
tableSchema,
);

console.log(`useTableModel availableWidth ${availableWidth}`);

const runtimeColumns: RuntimeColumnDescriptor[] = [];
let colIndex = 1;
for (const column of columns.filter(
Expand Down Expand Up @@ -380,6 +382,7 @@ const columnDescriptorToRuntimeColumDescriptor =
align = getDefaultAlignment(serverDataType),
name,
label = getColumnLabel(column),
source = "server",
width = columnDefaultWidth,
...rest
} = column;
Expand All @@ -398,6 +401,7 @@ const columnDescriptorToRuntimeColumDescriptor =
name,
originalIdx: ariaColIndex,
serverDataType,
source,
valueFormatter: getValueFormatter(column, serverDataType),
width,
};
Expand Down
8 changes: 6 additions & 2 deletions vuu-ui/packages/vuu-theme/css/components/button.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
--vuu-icon-color: var(--button-text-color-disabled);
}

.saltButton-primary {
.saltButton-neutral {
--saltButton-borderColor: var(
--vuuButton-borderColor,
var(--salt-actionable-bold-foreground)
Expand All @@ -37,7 +37,7 @@
--saltButton-borderStyle: solid;
}

.saltButton-primary:not(:disabled):not(:active):not(
.saltButton-neutral:not(:disabled):not(:active):not(
.saltButton-active
):hover {
--saltButton-borderColor: var(
Expand All @@ -46,3 +46,7 @@
);
}
}

.saltButton[data-embedded]{
border: none;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const MeasuredContainer = forwardRef(function MeasuredContainer(
width,
...htmlAttributes
}: MeasuredContainerProps,
forwardedRef: ForwardedRef<HTMLDivElement>
forwardedRef: ForwardedRef<HTMLDivElement>,
) {
const targetWindow = useWindow();
useComponentCssInjection({
Expand All @@ -52,6 +52,7 @@ export const MeasuredContainer = forwardRef(function MeasuredContainer(
const getStyle = () => {
return unmeasured
? ({
...style,
"--measured-css-height": `${cssSize.height}`,
"--measured-css-width": `${cssSize.width}`,
} as CSSProperties)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,11 @@ export const useMeasuredContainer = ({

useEffect(() => {
if (size.inner) {
onResizeProp?.(size.inner);
if (containerRef.current) {
// reassign using clientWidth to correctly account for borders
size.inner.width = containerRef.current.clientWidth;
onResizeProp?.(size.inner);
}
}
}, [onResizeProp, size.inner]);

Expand Down
90 changes: 49 additions & 41 deletions vuu-ui/packages/vuu-utils/src/column-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -900,13 +900,13 @@ export const getTypeFormattingFromColumn = (
};

/**
*
* return a filter predicate that will reject columns, names of which
* are not in provided list.
* Return a filter predicate that will reject columns, names of which
* are not in provided list. Exception made for columns explicitly
* configured as client columns.
*/
export const subscribedOnly =
(columnNames?: string[]) => (column: ColumnDescriptor) =>
columnNames?.includes(column.name);
column.source === "client" || columnNames?.includes(column.name);

export const addColumnToSubscribedColumns = (
subscribedColumns: ColumnDescriptor[],
Expand Down Expand Up @@ -1142,7 +1142,6 @@ export function applyWidthToColumns(
totalWidth,
defaultMaxWidth,
defaultWidth,
flexCount,
);
}
}
Expand Down Expand Up @@ -1213,52 +1212,61 @@ const shrinkColumnsToFitAvailableSpace = (
}
};

const hasFlex = ({ flex }: ColumnDescriptor) => typeof flex === "number";

const stretchColumnsToFillAvailableSpace = (
columns: RuntimeColumnDescriptor[],
availableWidth: number,
totalWidth: number,
defaultMaxWidth: number,
defaultWidth: number,
flexCount: number,
) => {
let freeSpaceToBeFilled = availableWidth - totalWidth;
const additionalWidthPerColumn = Math.floor(
freeSpaceToBeFilled / (flexCount || columns.length),
);
const newColumns = columns.map((column) => {
const {
maxWidth = defaultMaxWidth,
width = defaultWidth,
flex = 0,
} = column;
if (flexCount > 0 && flex === 0) {
return column;
}
const adjustedWidth = width + additionalWidthPerColumn;
if (adjustedWidth > maxWidth) {
return { ...column, width: maxWidth };
} else {
freeSpaceToBeFilled -= additionalWidthPerColumn;
return { ...column, width: adjustedWidth, canStretch: true };
}
});
const columnsNotYetAtMaxWidth = newColumns.filter(
(col) => col.canStretch,
).length;
const finalAdjustmentPerColumn = Math.min(
1,
Math.ceil(freeSpaceToBeFilled / columnsNotYetAtMaxWidth),
);
return newColumns.map<RuntimeColumnDescriptor>(
({ canStretch, ...column }) => {
if (canStretch && freeSpaceToBeFilled) {
freeSpaceToBeFilled -= finalAdjustmentPerColumn;
return { ...column, width: column.width + finalAdjustmentPerColumn };
} else {
let adjustedColumns = columns;

const canGrow = ({
width = defaultWidth,
maxWidth = defaultMaxWidth,
}: ColumnDescriptor) => width < maxWidth;

while (freeSpaceToBeFilled > 0) {
const flexCols = adjustedColumns.filter(
(col) => hasFlex(col) && canGrow(col),
);
const columnsNotYetAtMaxWidth =
flexCols.length || adjustedColumns.filter(canGrow).length;

// THis deos not take flex correctly into account
const additionalWidthPerColumn = Math.ceil(
freeSpaceToBeFilled / columnsNotYetAtMaxWidth,
);
adjustedColumns = columns.map((column) => {
const {
maxWidth = defaultMaxWidth,
width = defaultWidth,
flex = 0,
} = column;
if (flexCols.length > 0 && flex === 0) {
return column;
}
},
);

// we rounded the additionalWidthPerColumn up, so make sure
// we don't over-assign
const adjustmentAmount = Math.min(
additionalWidthPerColumn,
freeSpaceToBeFilled,
);
const adjustedWidth = width + adjustmentAmount;
if (adjustedWidth > maxWidth) {
freeSpaceToBeFilled -= adjustedWidth - maxWidth;
return { ...column, width: maxWidth };
} else {
freeSpaceToBeFilled -= adjustmentAmount;
return { ...column, width: adjustedWidth };
}
});
}
return adjustedColumns;
};

/**
Expand Down
Loading

0 comments on commit f06c9cb

Please sign in to comment.