boneless-table 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -41,6 +41,28 @@ when `scroller="fill"`, which must be placed in a parent with a stable height. V
41
41
  measured after rendering, so cells may wrap or render variable-height content. Use
42
42
  `virtualization={false}` to opt out in a fill layout.
43
43
 
44
+ ## Column sizing and resizing
45
+
46
+ Put layout decisions on the column that owns them. `widthPx` starts a column at a fixed width;
47
+ otherwise `minPx` and `flex` define its shared grid track. Set `resizable: true` to render a
48
+ resize handle. User resizing is local to the table instance and replaces that column's flex or
49
+ initial width until Reset is selected. `minPx` and `maxPx` bound the resulting width.
50
+
51
+ ```tsx
52
+ const columns = [
53
+ {
54
+ key: 'account',
55
+ header: 'Account',
56
+ meta: { bonelessTable: { sizing: { minPx: 180, flex: 2, resizable: true } } },
57
+ },
58
+ {
59
+ key: 'renewal',
60
+ header: 'Renewal',
61
+ meta: { bonelessTable: { sizing: { widthPx: 160, minPx: 120, maxPx: 240, resizable: true } } },
62
+ },
63
+ ] satisfies BonelessTableColumn<Account>[]
64
+ ```
65
+
44
66
  For non-text column headers, set `meta.columnLabel` to provide the label shown in the built-in
45
67
  column chooser; otherwise the chooser falls back to the column id.
46
68
 
package/dist/index.d.mts CHANGED
@@ -7,11 +7,17 @@ type ColumnAlignment = 'left' | 'right';
7
7
  type ColumnBorders = 'none' | 'left' | 'right' | 'both';
8
8
  type FilterType = 'text' | 'select';
9
9
  type RevealMode = 'always' | 'hover';
10
+ /**
11
+ * Column layout belongs with the column definition. A width is the column's initial fixed width;
12
+ * a flex value shares remaining space until the user resizes that column. `resizable` is opt-in
13
+ * so existing unstyled tables do not gain controls unexpectedly.
14
+ */
10
15
  type BonelessTableColumnSizing = {
11
- widthPx: number;
12
- } | {
13
- minPx: number;
16
+ widthPx?: number;
17
+ minPx?: number;
18
+ maxPx?: number;
14
19
  flex?: number;
20
+ resizable?: boolean;
15
21
  };
16
22
  type BonelessTableColumnSettings = {
17
23
  sizing?: BonelessTableColumnSizing;
@@ -24,20 +30,26 @@ type BonelessTableColumnSettings = {
24
30
  filtering?: {
25
31
  type: FilterType;
26
32
  options?: readonly string[];
27
- reveal?: RevealMode;
28
33
  };
29
34
  valueDisplay?: {
30
35
  truncateAt: number;
31
36
  suffix?: string;
32
37
  };
33
38
  };
39
+ type ResolvedBonelessTableColumnSettings = {
40
+ sizing: BonelessTableColumnSizing;
41
+ align: ColumnAlignment;
42
+ borders: ColumnBorders;
43
+ sorting: Required<NonNullable<BonelessTableColumnSettings['sorting']>>;
44
+ filtering: BonelessTableColumnSettings['filtering'];
45
+ valueDisplay: BonelessTableColumnSettings['valueDisplay'];
46
+ };
34
47
  type BonelessTableSettings = {
35
48
  columnDefaults: Required<Pick<BonelessTableColumnSettings, 'align' | 'borders'>> & {
36
- sizing: Required<NonNullable<BonelessTableColumnSettings['sizing']>>;
49
+ sizing: Required<Pick<BonelessTableColumnSizing, 'minPx' | 'flex'>>;
37
50
  sorting: Required<NonNullable<BonelessTableColumnSettings['sorting']>>;
38
51
  };
39
52
  interactions: {
40
- filterReveal: RevealMode;
41
53
  horizontalOverflow: 'auto' | 'scroll';
42
54
  };
43
55
  };
@@ -49,31 +61,7 @@ declare function resolveColumnSettings(settings: BonelessTableSettings, column:
49
61
  bonelessTable?: BonelessTableColumnSettings;
50
62
  };
51
63
  };
52
- }): {
53
- sizing: {
54
- minPx?: number | undefined;
55
- flex?: number;
56
- widthPx: number;
57
- } | {
58
- minPx: number;
59
- flex: number;
60
- };
61
- align: ColumnAlignment;
62
- borders: ColumnBorders;
63
- sorting: {
64
- enabled: boolean;
65
- reveal: RevealMode;
66
- };
67
- filtering: {
68
- type: FilterType;
69
- options?: readonly string[];
70
- reveal?: RevealMode;
71
- } | undefined;
72
- valueDisplay: {
73
- truncateAt: number;
74
- suffix?: string;
75
- } | undefined;
76
- };
64
+ }): ResolvedBonelessTableColumnSettings;
77
65
  declare function compactValue(value: unknown, settings?: BonelessTableColumnSettings): string;
78
66
 
79
67
  declare module '@tanstack/react-table' {
@@ -137,6 +125,7 @@ type BonelessTableToolbarLayout<TData extends RowData> = (context: {
137
125
  actions: ReactNode;
138
126
  }) => ReactNode;
139
127
  type BonelessTableSlot<TData extends RowData> = boolean | ReactNode | ((table: Table<TData>) => ReactNode);
128
+ type BonelessTableFilterPlacement = 'above' | 'below';
140
129
  type BonelessTableRowClickEvent = MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>;
141
130
  /**
142
131
  * Named hooks for your stylesheet. The renderer applies no default class names or visual styles.
@@ -145,15 +134,23 @@ type BonelessTableClassNames = Partial<{
145
134
  root: string;
146
135
  toolbar: string;
147
136
  toolbarSummary: string;
137
+ toolbarCount: string;
138
+ toolbarLabel: string;
148
139
  toolbarHint: string;
149
140
  toolbarActions: string;
150
141
  scroller: string;
142
+ headerScroller: string;
151
143
  table: string;
152
144
  headerGroup: string;
153
145
  headerRow: string;
154
146
  header: string;
155
147
  headerButton: string;
148
+ headerLabel: string;
149
+ resizeHandle: string;
156
150
  sortIndicator: string;
151
+ filters: string;
152
+ filterItem: string;
153
+ filterLabel: string;
157
154
  rowGroup: string;
158
155
  row: string;
159
156
  cell: string;
@@ -203,6 +200,10 @@ type BonelessTablePresentationOptions<TData extends RowData> = {
203
200
  toolbar?: BonelessTableSlot<TData>;
204
201
  /** Reposition the default summary and action controls without rebuilding their behavior. */
205
202
  toolbarLayout?: BonelessTableToolbarLayout<TData>;
203
+ /** Built-in filters, custom filter content, or a render function receiving the table instance. */
204
+ filters?: BonelessTableSlot<TData>;
205
+ /** Places the filter region outside the table scroll area. Defaults to "above". */
206
+ filterPlacement?: BonelessTableFilterPlacement;
206
207
  footer?: BonelessTableSlot<TData>;
207
208
  totalCount?: number;
208
209
  resultLabel?: string;
@@ -232,7 +233,7 @@ type BonelessTableProps<TData extends RowData> = BonelessTableOptions<TData> & B
232
233
  data: TData[];
233
234
  columns: BonelessTableColumn<TData>[];
234
235
  };
235
- declare function BonelessTable<TData extends RowData>({ data, columns, settings: settingsOverride, className, classNames, icons, tree: treeOption, isLoading, isFetchingMore, skeletonRows, skeletonLabel, onNearEnd, canLoadMore, nearEndOffset, filterDebounceMs, scroller, toolbar, toolbarLayout, footer, totalCount, resultLabel, resultHint, onReset, onRowClick, scrollToTopOn, rowLink, emptyState, virtualization, ...tableOptions }: BonelessTableProps<TData>): react.JSX.Element;
236
+ declare function BonelessTable<TData extends RowData>({ data, columns, settings: settingsOverride, className, classNames, icons, tree: treeOption, isLoading, isFetchingMore, skeletonRows, skeletonLabel, onNearEnd, canLoadMore, nearEndOffset, filterDebounceMs, scroller, toolbar, toolbarLayout, filters, filterPlacement, footer, totalCount, resultLabel, resultHint, onReset, onRowClick, scrollToTopOn, rowLink, emptyState, virtualization, ...tableOptions }: BonelessTableProps<TData>): react.JSX.Element;
236
237
 
237
238
  declare function defineColumns<TData extends RowData>(columns: BonelessTableColumn<TData>[]): BonelessTableColumn<TData>[];
238
239
  declare function resolveColumns<TData extends RowData>(columns: BonelessTableColumn<TData>[]): ResolvedBonelessTableColumn<TData>[];
@@ -255,4 +256,4 @@ declare function TableSkeleton({ columnCount, rows, label, classNames, }: {
255
256
  classNames?: Pick<BonelessTableClassNames, 'row' | 'cell' | 'skeleton'>;
256
257
  }): react.JSX.Element;
257
258
 
258
- export { BonelessTable, type BonelessTableClassNames, type BonelessTableColumn, type BonelessTableColumnSettings, type BonelessTableIcons, type BonelessTableOptions, type BonelessTablePresentationOptions, type BonelessTableProps, type BonelessTableRowClickEvent, type BonelessTableRowLink, type BonelessTableRowLinkComponentProps, type BonelessTableSettings, type BonelessTableSlot, type BonelessTableToolbarLayout, type BonelessTableTreeOptions, type ColumnAlignment, type ColumnBorders, ColumnFilter, ColumnMenu, type DeepPartial, type FilterType, type ResolvedBonelessTableColumn, type RevealMode, TableSkeleton, compactValue, defaultBonelessTableSettings, defineColumns, getColumnIds, mergeBonelessTableSettings, resolveColumnSettings, resolveColumns, resolveRowHref, resolveRowLinkLabel, withDefaultCells };
259
+ export { BonelessTable, type BonelessTableClassNames, type BonelessTableColumn, type BonelessTableColumnSettings, type BonelessTableColumnSizing, type BonelessTableFilterPlacement, type BonelessTableIcons, type BonelessTableOptions, type BonelessTablePresentationOptions, type BonelessTableProps, type BonelessTableRowClickEvent, type BonelessTableRowLink, type BonelessTableRowLinkComponentProps, type BonelessTableSettings, type BonelessTableSlot, type BonelessTableToolbarLayout, type BonelessTableTreeOptions, type ColumnAlignment, type ColumnBorders, ColumnFilter, ColumnMenu, type DeepPartial, type FilterType, type ResolvedBonelessTableColumn, type ResolvedBonelessTableColumnSettings, type RevealMode, TableSkeleton, compactValue, defaultBonelessTableSettings, defineColumns, getColumnIds, mergeBonelessTableSettings, resolveColumnSettings, resolveColumns, resolveRowHref, resolveRowLinkLabel, withDefaultCells };
package/dist/index.d.ts CHANGED
@@ -7,11 +7,17 @@ type ColumnAlignment = 'left' | 'right';
7
7
  type ColumnBorders = 'none' | 'left' | 'right' | 'both';
8
8
  type FilterType = 'text' | 'select';
9
9
  type RevealMode = 'always' | 'hover';
10
+ /**
11
+ * Column layout belongs with the column definition. A width is the column's initial fixed width;
12
+ * a flex value shares remaining space until the user resizes that column. `resizable` is opt-in
13
+ * so existing unstyled tables do not gain controls unexpectedly.
14
+ */
10
15
  type BonelessTableColumnSizing = {
11
- widthPx: number;
12
- } | {
13
- minPx: number;
16
+ widthPx?: number;
17
+ minPx?: number;
18
+ maxPx?: number;
14
19
  flex?: number;
20
+ resizable?: boolean;
15
21
  };
16
22
  type BonelessTableColumnSettings = {
17
23
  sizing?: BonelessTableColumnSizing;
@@ -24,20 +30,26 @@ type BonelessTableColumnSettings = {
24
30
  filtering?: {
25
31
  type: FilterType;
26
32
  options?: readonly string[];
27
- reveal?: RevealMode;
28
33
  };
29
34
  valueDisplay?: {
30
35
  truncateAt: number;
31
36
  suffix?: string;
32
37
  };
33
38
  };
39
+ type ResolvedBonelessTableColumnSettings = {
40
+ sizing: BonelessTableColumnSizing;
41
+ align: ColumnAlignment;
42
+ borders: ColumnBorders;
43
+ sorting: Required<NonNullable<BonelessTableColumnSettings['sorting']>>;
44
+ filtering: BonelessTableColumnSettings['filtering'];
45
+ valueDisplay: BonelessTableColumnSettings['valueDisplay'];
46
+ };
34
47
  type BonelessTableSettings = {
35
48
  columnDefaults: Required<Pick<BonelessTableColumnSettings, 'align' | 'borders'>> & {
36
- sizing: Required<NonNullable<BonelessTableColumnSettings['sizing']>>;
49
+ sizing: Required<Pick<BonelessTableColumnSizing, 'minPx' | 'flex'>>;
37
50
  sorting: Required<NonNullable<BonelessTableColumnSettings['sorting']>>;
38
51
  };
39
52
  interactions: {
40
- filterReveal: RevealMode;
41
53
  horizontalOverflow: 'auto' | 'scroll';
42
54
  };
43
55
  };
@@ -49,31 +61,7 @@ declare function resolveColumnSettings(settings: BonelessTableSettings, column:
49
61
  bonelessTable?: BonelessTableColumnSettings;
50
62
  };
51
63
  };
52
- }): {
53
- sizing: {
54
- minPx?: number | undefined;
55
- flex?: number;
56
- widthPx: number;
57
- } | {
58
- minPx: number;
59
- flex: number;
60
- };
61
- align: ColumnAlignment;
62
- borders: ColumnBorders;
63
- sorting: {
64
- enabled: boolean;
65
- reveal: RevealMode;
66
- };
67
- filtering: {
68
- type: FilterType;
69
- options?: readonly string[];
70
- reveal?: RevealMode;
71
- } | undefined;
72
- valueDisplay: {
73
- truncateAt: number;
74
- suffix?: string;
75
- } | undefined;
76
- };
64
+ }): ResolvedBonelessTableColumnSettings;
77
65
  declare function compactValue(value: unknown, settings?: BonelessTableColumnSettings): string;
78
66
 
79
67
  declare module '@tanstack/react-table' {
@@ -137,6 +125,7 @@ type BonelessTableToolbarLayout<TData extends RowData> = (context: {
137
125
  actions: ReactNode;
138
126
  }) => ReactNode;
139
127
  type BonelessTableSlot<TData extends RowData> = boolean | ReactNode | ((table: Table<TData>) => ReactNode);
128
+ type BonelessTableFilterPlacement = 'above' | 'below';
140
129
  type BonelessTableRowClickEvent = MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>;
141
130
  /**
142
131
  * Named hooks for your stylesheet. The renderer applies no default class names or visual styles.
@@ -145,15 +134,23 @@ type BonelessTableClassNames = Partial<{
145
134
  root: string;
146
135
  toolbar: string;
147
136
  toolbarSummary: string;
137
+ toolbarCount: string;
138
+ toolbarLabel: string;
148
139
  toolbarHint: string;
149
140
  toolbarActions: string;
150
141
  scroller: string;
142
+ headerScroller: string;
151
143
  table: string;
152
144
  headerGroup: string;
153
145
  headerRow: string;
154
146
  header: string;
155
147
  headerButton: string;
148
+ headerLabel: string;
149
+ resizeHandle: string;
156
150
  sortIndicator: string;
151
+ filters: string;
152
+ filterItem: string;
153
+ filterLabel: string;
157
154
  rowGroup: string;
158
155
  row: string;
159
156
  cell: string;
@@ -203,6 +200,10 @@ type BonelessTablePresentationOptions<TData extends RowData> = {
203
200
  toolbar?: BonelessTableSlot<TData>;
204
201
  /** Reposition the default summary and action controls without rebuilding their behavior. */
205
202
  toolbarLayout?: BonelessTableToolbarLayout<TData>;
203
+ /** Built-in filters, custom filter content, or a render function receiving the table instance. */
204
+ filters?: BonelessTableSlot<TData>;
205
+ /** Places the filter region outside the table scroll area. Defaults to "above". */
206
+ filterPlacement?: BonelessTableFilterPlacement;
206
207
  footer?: BonelessTableSlot<TData>;
207
208
  totalCount?: number;
208
209
  resultLabel?: string;
@@ -232,7 +233,7 @@ type BonelessTableProps<TData extends RowData> = BonelessTableOptions<TData> & B
232
233
  data: TData[];
233
234
  columns: BonelessTableColumn<TData>[];
234
235
  };
235
- declare function BonelessTable<TData extends RowData>({ data, columns, settings: settingsOverride, className, classNames, icons, tree: treeOption, isLoading, isFetchingMore, skeletonRows, skeletonLabel, onNearEnd, canLoadMore, nearEndOffset, filterDebounceMs, scroller, toolbar, toolbarLayout, footer, totalCount, resultLabel, resultHint, onReset, onRowClick, scrollToTopOn, rowLink, emptyState, virtualization, ...tableOptions }: BonelessTableProps<TData>): react.JSX.Element;
236
+ declare function BonelessTable<TData extends RowData>({ data, columns, settings: settingsOverride, className, classNames, icons, tree: treeOption, isLoading, isFetchingMore, skeletonRows, skeletonLabel, onNearEnd, canLoadMore, nearEndOffset, filterDebounceMs, scroller, toolbar, toolbarLayout, filters, filterPlacement, footer, totalCount, resultLabel, resultHint, onReset, onRowClick, scrollToTopOn, rowLink, emptyState, virtualization, ...tableOptions }: BonelessTableProps<TData>): react.JSX.Element;
236
237
 
237
238
  declare function defineColumns<TData extends RowData>(columns: BonelessTableColumn<TData>[]): BonelessTableColumn<TData>[];
238
239
  declare function resolveColumns<TData extends RowData>(columns: BonelessTableColumn<TData>[]): ResolvedBonelessTableColumn<TData>[];
@@ -255,4 +256,4 @@ declare function TableSkeleton({ columnCount, rows, label, classNames, }: {
255
256
  classNames?: Pick<BonelessTableClassNames, 'row' | 'cell' | 'skeleton'>;
256
257
  }): react.JSX.Element;
257
258
 
258
- export { BonelessTable, type BonelessTableClassNames, type BonelessTableColumn, type BonelessTableColumnSettings, type BonelessTableIcons, type BonelessTableOptions, type BonelessTablePresentationOptions, type BonelessTableProps, type BonelessTableRowClickEvent, type BonelessTableRowLink, type BonelessTableRowLinkComponentProps, type BonelessTableSettings, type BonelessTableSlot, type BonelessTableToolbarLayout, type BonelessTableTreeOptions, type ColumnAlignment, type ColumnBorders, ColumnFilter, ColumnMenu, type DeepPartial, type FilterType, type ResolvedBonelessTableColumn, type RevealMode, TableSkeleton, compactValue, defaultBonelessTableSettings, defineColumns, getColumnIds, mergeBonelessTableSettings, resolveColumnSettings, resolveColumns, resolveRowHref, resolveRowLinkLabel, withDefaultCells };
259
+ export { BonelessTable, type BonelessTableClassNames, type BonelessTableColumn, type BonelessTableColumnSettings, type BonelessTableColumnSizing, type BonelessTableFilterPlacement, type BonelessTableIcons, type BonelessTableOptions, type BonelessTablePresentationOptions, type BonelessTableProps, type BonelessTableRowClickEvent, type BonelessTableRowLink, type BonelessTableRowLinkComponentProps, type BonelessTableSettings, type BonelessTableSlot, type BonelessTableToolbarLayout, type BonelessTableTreeOptions, type ColumnAlignment, type ColumnBorders, ColumnFilter, ColumnMenu, type DeepPartial, type FilterType, type ResolvedBonelessTableColumn, type ResolvedBonelessTableColumnSettings, type RevealMode, TableSkeleton, compactValue, defaultBonelessTableSettings, defineColumns, getColumnIds, mergeBonelessTableSettings, resolveColumnSettings, resolveColumns, resolveRowHref, resolveRowLinkLabel, withDefaultCells };