@vinorcola/dynamic-table 1.2.0 → 1.2.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.
@@ -1,21 +1,25 @@
1
+ import type { ReactNode } from "react";
1
2
  import type { BaseItem, Dictionary, ItemKey, Primitive } from "./index.js";
3
+ export type ValueDecorator<Item extends BaseItem, Value extends Primitive> = (value: Value, defaultDisplay: ReactNode, item: Item) => ReactNode;
2
4
  export type ValueResolver<Item extends BaseItem, Value extends Primitive> = (item: Item) => Value | null;
3
- interface BaseColumneDefinition<Value extends Primitive> {
5
+ interface BaseColumneDefinition<Item extends BaseItem, Value extends Primitive> {
4
6
  readonly title: string;
5
7
  readonly dictionary?: Dictionary<Value> | Promise<Dictionary<Value>>;
8
+ readonly decorateValue?: ValueDecorator<Item, Value>;
9
+ readonly decorateNoValue?: () => ReactNode;
6
10
  }
7
11
  /**
8
12
  * A column that will access an item's attribute.
9
13
  */
10
- interface AccessorColumnDefinition<Item extends BaseItem, Value extends Primitive> extends BaseColumneDefinition<Value> {
14
+ interface AccessorColumnDefinition<Item extends BaseItem, Value extends Primitive> extends BaseColumneDefinition<Item, Value> {
11
15
  readonly id: ItemKey<Item>;
12
16
  }
13
17
  /**
14
18
  * A column where the value must be resolved.
15
19
  */
16
- interface ResolvedColumnDefinition<Item extends BaseItem, Value extends Primitive> extends BaseColumneDefinition<Value> {
20
+ interface ResolvedColumnDefinition<Item extends BaseItem, Value extends Primitive> extends BaseColumneDefinition<Item, Value> {
17
21
  readonly id: string;
18
- readonly resolveValue: (item: Item) => Value | null;
22
+ readonly resolveValue: ValueResolver<Item, Value>;
19
23
  }
20
24
  export type ColumnDefinition<Item extends BaseItem, Value extends Primitive> = AccessorColumnDefinition<Item, Value> | ResolvedColumnDefinition<Item, Value>;
21
25
  export declare function isAccessorColumnDefinition<Item extends BaseItem, Value extends Primitive>(definition: ColumnDefinition<Item, Value>): definition is AccessorColumnDefinition<Item, Value>;
@@ -120,14 +120,14 @@ export function Cell(props) {
120
120
  return _jsx("td", { children: props.children });
121
121
  }
122
122
  export function ClickableCell(props) {
123
- return (_jsx("td", { className: "!p-0", children: _jsx("a", { href: props.target, className: "block size-full px-4 py-2", children: props.children }) }));
123
+ return (_jsx("td", { className: "p-0!", children: _jsx("a", { href: props.target, className: "block size-full px-4 py-2", children: props.children }) }));
124
124
  }
125
125
  export function FooterContainer(props) {
126
- return (_jsx("tfoot", { children: _jsx("tr", { children: _jsxs("td", { className: "relative py-0! px-16 h-9 text-center", colSpan: props.totalColums, children: [props.pageSelector, props.itemsPerPageSelector] }) }) }));
126
+ return (_jsx("tfoot", { children: _jsx("tr", { className: "bg-transparent", children: _jsxs("td", { className: "relative py-0! px-16 h-9 text-center", colSpan: props.totalColums, children: [props.pageSelector, props.itemsPerPageSelector] }) }) }));
127
127
  }
128
128
  const ITEM_PER_PAGE_CHOICES = [12, 24, 50, 100, 250, 500];
129
129
  export function ItemsPerPageSelector(props) {
130
- return (_jsx("select", { className: "absolute top-0 right-0 h-full w-14 bg-white outline-none", name: "items-per-page", value: props.itemsPerPage, onChange: (event) => {
130
+ return (_jsx("select", { className: "absolute top-0 right-0 h-full w-14 bg-white outline-none", value: props.itemsPerPage, onChange: (event) => {
131
131
  props.onItemsPerPageChange(Number.parseInt(event.target.value, 10));
132
132
  }, children: ITEM_PER_PAGE_CHOICES.map((choice) => (_jsx("option", { value: choice, children: choice }, choice))) }));
133
133
  }
package/lib/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export type BaseItem = Record<string, any> & {
11
11
  };
12
12
  export type ItemKey<Item extends BaseItem> = Extract<keyof Item, string>;
13
13
  export type { ColumnDefinition, ValueResolver } from "./ColumnDefinition.js";
14
- export { default as Dictionary } from "./Dictionary.js";
14
+ export { default as Dictionary, DictionaryEntry } from "./Dictionary.js";
15
15
  export type { FilterState } from "./useFilterState.js";
16
16
  export type { SortDirection, SortState } from "./useSortState.js";
17
17
  export type { ColumnsMaskState } from "./useMaskableColumns.js";
@@ -1,3 +1,5 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ValueDecorator } from "./ColumnDefinition.js";
1
3
  import type { BaseItem, ColumnDefinition, Dictionary, Primitive, ValueResolver } from "./index.js";
2
4
  /**
3
5
  * A column that is loading a dictionary.
@@ -8,6 +10,8 @@ export interface LoadingInternalColumn<Item extends BaseItem, Value extends Prim
8
10
  readonly loadingDictionary: true;
9
11
  readonly dictionary: Promise<Dictionary<Value>>;
10
12
  readonly resolveValue: ValueResolver<Item, Value>;
13
+ readonly decorateValue?: ValueDecorator<Item, Value>;
14
+ readonly decorateNoValue?: () => ReactNode;
11
15
  }
12
16
  /**
13
17
  * A column fully loaded and usable.
@@ -18,6 +22,8 @@ export interface LoadedInternalColumn<Item extends BaseItem, Value extends Primi
18
22
  readonly loadingDictionary: false;
19
23
  readonly dictionary?: Dictionary<Value>;
20
24
  readonly resolveValue: ValueResolver<Item, Value>;
25
+ readonly decorateValue?: ValueDecorator<Item, Value>;
26
+ readonly decorateNoValue?: () => ReactNode;
21
27
  }
22
28
  /**
23
29
  * A column, either in loading state or in loaded state.
package/lib/useColumns.js CHANGED
@@ -29,6 +29,8 @@ export default function useColumns(definitions) {
29
29
  resolveValue: isAccessorColumnDefinition(definition)
30
30
  ? (item) => item[definition.id]
31
31
  : definition.resolveValue,
32
+ decorateValue: definition.decorateValue,
33
+ decorateNoValue: definition.decorateNoValue,
32
34
  }));
33
35
  }
34
36
  });
@@ -47,6 +49,8 @@ function resolveInitialColumnState(definitions) {
47
49
  resolveValue: isAccessorColumnDefinition(definition)
48
50
  ? (item) => item[definition.id]
49
51
  : definition.resolveValue,
52
+ decorateValue: definition.decorateValue,
53
+ decorateNoValue: definition.decorateNoValue,
50
54
  }
51
55
  : {
52
56
  id: definition.id,
@@ -56,5 +60,7 @@ function resolveInitialColumnState(definitions) {
56
60
  resolveValue: isAccessorColumnDefinition(definition)
57
61
  ? (item) => item[definition.id]
58
62
  : definition.resolveValue,
63
+ decorateValue: definition.decorateValue,
64
+ decorateNoValue: definition.decorateNoValue,
59
65
  });
60
66
  }
package/lib/useItems.js CHANGED
@@ -13,20 +13,32 @@ export default function useItems(items, itemTarget, columns, canSelectItem) {
13
13
  }
14
14
  function resolveInternalValue(item, column) {
15
15
  const raw = column.resolveValue(item);
16
- return column.loadingDictionary
17
- ? {
16
+ if (column.loadingDictionary) {
17
+ return {
18
18
  column: column.id,
19
19
  loading: true,
20
20
  raw,
21
- }
22
- : {
23
- column: column.id,
24
- loading: false,
25
- raw,
26
- search: resolveSearchableValue(raw, column.dictionary),
27
- sort: resolveSortableValue(raw, column.dictionary),
28
- display: resolveDisplayableValue(raw, column.dictionary),
29
21
  };
22
+ }
23
+ let display = resolveDisplayableValue(raw, column.dictionary);
24
+ if (raw === null || raw === undefined || raw === "") {
25
+ if (column.decorateNoValue !== undefined) {
26
+ display = column.decorateNoValue();
27
+ }
28
+ }
29
+ else {
30
+ if (column.decorateValue !== undefined) {
31
+ display = column.decorateValue(raw, display, item);
32
+ }
33
+ }
34
+ return {
35
+ column: column.id,
36
+ loading: false,
37
+ raw,
38
+ search: resolveSearchableValue(raw, column.dictionary),
39
+ sort: resolveSortableValue(raw, column.dictionary),
40
+ display,
41
+ };
30
42
  }
31
43
  function resolveSearchableValue(value, dictionary) {
32
44
  if (dictionary !== undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vinorcola/dynamic-table",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "A table to ease the display of a filterable, sortable and paginable dataset.",
5
5
  "keywords": [
6
6
  "table",