Skip to content

Commit

Permalink
fix: Added some missing exports and props documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
schummar committed Mar 15, 2022
1 parent 2f9af45 commit fdf96ad
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 13 deletions.
3 changes: 3 additions & 0 deletions src/components/dateFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ export function DateFilter<T, V>({
filterBy = convertDateOrArray,
...props
}: {
/** Which locale to use to render the calendar. */
locale?: string;
/** Which day of the week should be in the first column. */
firstDayOfWeek?: DatePickerProps['firstDayOfWeek'];
/** If enabled, only single days can be selected. Ranges otherwise. */
singleSelect?: boolean;
} & CommonFilterProps<T, V, Date | DateRange | null, Date | DateRange | null>): JSX.Element {
const {
Expand Down
8 changes: 8 additions & 0 deletions src/components/datePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,28 @@ import { useCssVariables } from '../theme/useCssVariables';
export type DateRange = { min: Date; max: Date };

export type DatePickerProps = {
/** Currently selected day or range of days. */
value: Date | DateRange | null;
/** Callback for when the day (range) changes. */
onChange: (value: Date | DateRange | null) => void;
/** If enabled, ranges can be selected. */
rangeSelect?: boolean;
/** Which locale to use to render the calendar. */
locale?: string;
/** Which day of the week should be in the first column. */
firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
};

const weekDays = [0, 1, 2, 3, 4, 5, 6] as const;
const months = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] as const;

/** Rounds a date down to the start of the day. */
export const startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate());

/** Rounds a date up to the end of the day. */
export const endOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1, 0, 0, 0, -1);

/** Returns whether two dates and/or date ranges intersect. Intersection is considered per day. */
export function dateIntersect(a: Date | null | DateRange, b: Date | null | DateRange) {
if (a instanceof Date) {
a = { min: a, max: a };
Expand Down
4 changes: 4 additions & 0 deletions src/components/selectFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ export function SelectFilter<T, V, F extends SerializableValue>({
singleSelect,
...props
}: {
/** Which options are provided to select. By default all unique item values are used. */
options?: F[];
/** String representation of a value. Used to filter options via the text field. */
stringValue?: (value: F) => string;
/** Render values. By default a string representation of the value is used. */
render?: (value: F) => ReactNode;
/** If enabled, only one option can be selected at a time. */
singleSelect?: boolean;
} & CommonFilterProps<T, V, F, Set<F>>): JSX.Element {
const {
Expand Down
5 changes: 4 additions & 1 deletion src/components/textFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ export function TextFilter<T, V>({
filterBy = asStringOrArray,
...props
}: {
compare?: (a: string, b: string) => boolean;
/** Custom comparison function. Should return true if an item value matches the current filter value.
* By default a fuzzy text comparison is used.
*/
compare?: (itemValue: string, filterValue: string) => boolean;
} & CommonFilterProps<T, V, string, string>): JSX.Element {
const {
components: { IconButton },
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function useFilter<T, V, F, S extends SerializableValue>(impl: FilterImpl
state.filters.delete(columnId);
});
};
}, [table, columnId, ...(impl.dependencies ?? [impl])]);
}, [table, columnId, impl]);

// Track local value and update it globally after delay
const value = table.useState((state) => state.filterValues.get(columnId) as S | undefined);
Expand Down
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export { AutoFocusTextField } from './components/autoFocusTextField';
export { DateFilter } from './components/dateFilter';
export { dateIntersect, DatePicker, endOfDay, startOfDay } from './components/datePicker';
export type { DatePickerProps, DateRange } from './components/datePicker';
export { SelectFilter } from './components/selectFilter';
export { ColumnContext, Table, TableContext, useColumnContext, useTableContext } from './components/table';
export { TextFilter } from './components/textFilter';
Expand All @@ -8,4 +10,4 @@ export { useTheme } from './hooks/useTheme';
export type { TableStateStorage } from './internalState/tableStateStorage';
export { termMatch, textMatch } from './misc/textMatch';
export { configureTableTheme, mergeThemes, TableThemeContext, TableThemeProvider } from './theme/tableTheme';
export type { Column, Id, InternalColumn, PartialTableTheme, Rows, Sort, SortDirection, TableProps } from './types';
export type { Column, Id, InternalColumn, PartialTableTheme, Sort, SortDirection, TableProps } from './types';
35 changes: 25 additions & 10 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CSSInterpolation } from '@emotion/serialize';
import React, { ComponentType, CSSProperties, ReactNode, Ref } from 'react';
import React, { ComponentType, ReactNode, Ref } from 'react';
import { TableStateStorage } from './internalState/tableStateStorage';
import { CsvExportOptions } from './misc/csvExport';

Expand Down Expand Up @@ -232,22 +232,30 @@ export type InternalTableProps<T> = Omit<TableProps<T>, 'id' | 'parentId' | 'col
export type TableItem<T = unknown> = T & { id: Id; parentId?: Id; children: TableItem<T>[] };

export type Column<T, V> = {
/** Column id. If not provided, the index in the column array will be used.
* An explicit id is better however for controlling column related states, persitance etc.
*/
id?: string;
/** Render table header for this column. */
header?: ReactNode;
/** Extract value for this column */
value: (item: T) => V;
/** Render table cell. If not provided, a string representation of the value will be rendered. */
renderCell?: (value: V, item: T) => ReactNode;
/** Serialize column value for exports. If not provided, a string representation of the value will be used. */
exportCell?: (value: V, item: T) => string | number;
/** Customize sort criteria. By default it will be the value itself in case it's a number or Date, or a string representation of the value otherwise. */
sortBy?: ((value: V, item: T) => unknown) | ((value: V) => unknown)[];

/** Set filter component that will be displayed in the column header */
filter?: ReactNode;

/** Prevent hiding the column. */
cannotHide?: boolean;

/** Specify a css width.
* @default 'max-content'
*/
width?: string;
justifyContent?: CSSProperties['justifyContent'];

/** Provide css class names to override columns styles. */
classes?: TableTheme<T>['classes'];

/** If the column definition changes, supply parameters that it depends on. If not set, the column will not update */
dependencies?: any[];
};
Expand All @@ -260,8 +268,6 @@ type Required<T, S> = T & {
[P in keyof T as P extends S ? P : never]-?: T[P];
};

export type Rows<T, V> = [{ value: V; item: T }, ...{ value: V; item: T }[]];

export type InternalTableState<T> = {
// Basically the passed in props, but normalized
props: InternalTableProps<T>;
Expand Down Expand Up @@ -289,17 +295,26 @@ export type InternalTableState<T> = {
};

export type CommonFilterProps<T, V, F, S extends SerializableValue> = {
/** Filter by? By default the column value will be used. If filterBy returns an array, an items will be active if at least one entry matches the active filter. */
filterBy?: (value: V, item: T) => F | F[];
/** Preselected filter value. */
defaultValue?: S;
/** Controlled filter value. */
value?: S;
/** Notifies on filter change. */
onChange?: (value?: S) => void;
dependencies?: any[];
/** Whether to persist filter value (given that filter persitance is enabled for the table).
* @default true
*/
persist?: boolean;
};

export type FilterImplementation<T, V, F, S extends SerializableValue> = CommonFilterProps<T, V, F, S> & {
/** Unique filter id. Used to persist filter values. */
id: string;
/** Whether the filter is active currently. */
isActive: (filterValue: S) => boolean;
/** When the filter is active, this function is used to filter the items to be displayed. */
test: (filterValue: S, value: F) => boolean;
};

Expand Down

0 comments on commit fdf96ad

Please sign in to comment.