@inandu-solutions/grid-react 0.1.2 → 0.1.4

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.
Files changed (39) hide show
  1. package/dist/components/InanduGrid.d.ts +99 -0
  2. package/dist/core/aggregate.d.ts +5 -0
  3. package/dist/core/columns.d.ts +11 -0
  4. package/dist/core/constants.d.ts +14 -0
  5. package/dist/core/dom.d.ts +8 -0
  6. package/dist/core/export/csv.d.ts +2 -0
  7. package/dist/core/export/download.d.ts +2 -0
  8. package/dist/core/export/markup.d.ts +2 -0
  9. package/dist/core/export/pdf.d.ts +3 -0
  10. package/dist/core/filter.d.ts +26 -0
  11. package/dist/core/format.d.ts +24 -0
  12. package/dist/core/i18n/en.d.ts +46 -0
  13. package/dist/core/i18n/es.d.ts +46 -0
  14. package/dist/core/i18n/fr.d.ts +46 -0
  15. package/dist/core/i18n/index.d.ts +8 -0
  16. package/dist/core/i18n/it.d.ts +46 -0
  17. package/dist/core/i18n/zh.d.ts +46 -0
  18. package/dist/core/index.d.ts +17 -0
  19. package/dist/core/parse.d.ts +14 -0
  20. package/dist/core/sort.d.ts +1 -0
  21. package/dist/core/tree.d.ts +28 -0
  22. package/dist/core/types.d.ts +46 -0
  23. package/dist/hooks/useInanduGrid.d.ts +197 -0
  24. package/dist/html2canvas-BE2ZQbtv.js +4021 -0
  25. package/dist/html2canvas-o9-HsXBE.cjs +5 -0
  26. package/dist/inandu-grid-react.cjs +2 -0
  27. package/dist/inandu-grid-react.js +1684 -0
  28. package/dist/index.d.ts +11 -0
  29. package/dist/index.es-BqzICVsf.cjs +5 -0
  30. package/dist/index.es-CPZG9pTc.js +5752 -0
  31. package/dist/jspdf.es.min-D_8zJvYC.cjs +78 -0
  32. package/dist/jspdf.es.min-DiTFVZBc.js +18250 -0
  33. package/dist/purify.es-3_UFdOhH.js +805 -0
  34. package/dist/purify.es-DXMFKXT6.cjs +3 -0
  35. package/dist/style.css +350 -0
  36. package/dist/utils/exporters.d.ts +29 -0
  37. package/dist/utils/measureColumn.d.ts +15 -0
  38. package/dist/utils/translate.d.ts +10 -0
  39. package/package.json +4 -2
@@ -0,0 +1,99 @@
1
+ import { ReactNode } from 'react';
2
+ import { InanduGridRow } from '../core';
3
+ import { InanduGridCellPaste, InanduGridColumn, InanduGridRowSave } from '../hooks/useInanduGrid';
4
+ export interface InanduGridProps {
5
+ rows: InanduGridRow[];
6
+ columns: InanduGridColumn[];
7
+ /** Drives number/date formatting (`Intl`-based). Default: 'en'. */
8
+ locale?: string;
9
+ /** Drives built-in UI string translation (one of `INANDU_GRID_TRANSLATIONS`'s keys). Default: `locale`'s primary subtag. */
10
+ lang?: string;
11
+ /** 0 (default) disables pagination — every filtered/sorted row renders. Ignored while grouped. */
12
+ pageSize?: number;
13
+ /** Adds a checkbox column with row + select-all selection. Default: false. */
14
+ selectable?: boolean;
15
+ /** Called after every selection change with the current full selection, as an array. */
16
+ onSelectionChange?: (selectedRows: InanduGridRow[]) => void;
17
+ /** Adds a CSV/Excel/PDF export toolbar above the table. Default: false. */
18
+ exportable?: boolean;
19
+ /** Base filename (without extension) for exports. Default: 'inandu-grid'. */
20
+ exportFilenameBase?: string;
21
+ /** Adds a per-row "Delete" button. Default: false. */
22
+ deletable?: boolean;
23
+ /** `window.confirm()`-gates a single row's delete. Unset: deletes immediately. */
24
+ deleteConfirmMessage?: string;
25
+ /** `window.confirm()`-gates the "Delete selected" bulk action (shown when `selectable && deletable` with at least one row selected). Unset: deletes immediately. */
26
+ bulkDeleteConfirmMessage?: string;
27
+ /** Adds an "Add row" trigger with a blank draft row. Default: false. Has no effect unless at least one column is `editable`. */
28
+ creatable?: boolean;
29
+ /** Called once a row edit passes validation. The grid never mutates `rows` itself — applying `values` onto `row` is the caller's job. */
30
+ onRowSave?: (event: InanduGridRowSave) => void;
31
+ /** Called once a new row's draft passes validation. No row reference — it doesn't exist in `rows` yet. */
32
+ onRowCreate?: (values: Record<string, unknown>) => void;
33
+ /** Called after a single-row delete is confirmed (or clicked, if no `deleteConfirmMessage`). */
34
+ onRowDelete?: (row: InanduGridRow) => void;
35
+ /** Called after the bulk "Delete selected" action is confirmed (or clicked, if no `bulkDeleteConfirmMessage`). */
36
+ onRowsDelete?: (rows: InanduGridRow[]) => void;
37
+ /** Opts into `Ctrl+C`/`Ctrl+V` cell copy/paste (Excel-style TSV). Default: false. */
38
+ clipboard?: boolean;
39
+ /** Called with every parsed cell update from a `Ctrl+V`. The grid never mutates `rows` itself. */
40
+ onCellsPaste?: (updates: InanduGridCellPaste[]) => void;
41
+ /** Adds a "Columns" toolbar button + popup letting the user show/hide individual columns at runtime. Default: false. */
42
+ columnToggle?: boolean;
43
+ /** Adds a per-row drag handle to reorder rows. Default: false. Auto-disabled while grouped, same as grid-angular. */
44
+ rowReorder?: boolean;
45
+ /** Called with the fully reordered row array after a row drag-and-drop. The grid never mutates `rows` itself. */
46
+ onRowOrderChange?: (rows: InanduGridRow[]) => void;
47
+ /**
48
+ * Turns on tree mode: the field on each row holding its child rows (a nested array of the same
49
+ * shape). `rows` is then the root rows. Auto-disabled while grouped. Tree rows are display +
50
+ * expand only — inline editing, drag-reorder and clipboard don't apply to them, same as
51
+ * grid-angular.
52
+ */
53
+ treeChildrenKey?: string;
54
+ /** Initial expand state for tree mode. Default: `'none'`. */
55
+ treeDefaultExpanded?: 'none' | 'all' | number;
56
+ /**
57
+ * Enables master-detail: renders a leading expand/collapse toggle per row, and (while expanded)
58
+ * a full-width detail row right below it, with whatever this returns. Auto-disabled while
59
+ * grouped, same as grid-angular's `detailTemplate`/`hasMasterDetail`. Unset (default): off.
60
+ */
61
+ renderDetail?: (row: InanduGridRow) => ReactNode;
62
+ /** Collapses any other expanded row first, accordion-style, when a new one expands. Off (any number of rows can be expanded at once) by default. */
63
+ singleDetailExpand?: boolean;
64
+ /** An extra per-row predicate ANDed onto the free-text + column filters — same as grid-angular's `extraRowFilter`. Lets a caller layer its own filtering (e.g. an advanced-filter query) on top of the grid's own. Unset: no extra filtering. */
65
+ extraRowFilter?: (row: InanduGridRow) => boolean;
66
+ /**
67
+ * Opt-in row virtualization for large datasets — only rows scrolled into view (plus a small
68
+ * overscan runway) are actually mounted. Bypasses pagination entirely, same as grouping.
69
+ * Auto-disabled while grouped (this port doesn't interleave group headers into the virtualized
70
+ * window the way grid-angular does); also disables master-detail, row drag-reorder, tree data,
71
+ * and the totals `<tfoot>`, same restrictions grid-angular's `virtualScroll` has. Default: false.
72
+ */
73
+ virtualScroll?: boolean;
74
+ /**
75
+ * Fixed row height (px) the virtualization math uses to compute scroll position and how many
76
+ * rows to render. Unlike grid-angular, this port doesn't auto-measure a rendered row's real
77
+ * height (that needs a real layout engine to verify, which unit tests can't provide) — pass the
78
+ * actual rendered row height for correct scrolling. Default: 40.
79
+ */
80
+ virtualRowHeight?: number;
81
+ /** The scrollable viewport's own height (px) — only used while `virtualScroll`. Default: 400. */
82
+ height?: number;
83
+ /** Extra rows rendered above/below the visible window, so a fast scroll doesn't flash empty space before the next render catches up. Default: 4. */
84
+ overscan?: number;
85
+ /**
86
+ * Double-click a column's resize handle to fit its width to its widest currently-rendered value
87
+ * (header included). Measures real rendered text width via the DOM (`measureColumnContentWidth`)
88
+ * — like grid-angular's own autosize, this only measures what's actually mounted (one page, or
89
+ * the virtual window), not the full dataset. Default: false.
90
+ */
91
+ autosize?: boolean;
92
+ }
93
+ /**
94
+ * Batteries-included table over `useInanduGrid`: sorting, free-text search, a per-column filter
95
+ * row, pagination, single-column grouping with per-group + grand-total aggregates, row selection,
96
+ * CSV/Excel/PDF export, i18n, inline row editing/creation/deletion with validation, and row
97
+ * virtualization for large datasets.
98
+ */
99
+ export declare function InanduGrid({ rows, columns, locale, lang, pageSize, selectable, onSelectionChange, exportable, exportFilenameBase, deletable, deleteConfirmMessage, bulkDeleteConfirmMessage, creatable, onRowSave, onRowCreate, onRowDelete, onRowsDelete, clipboard, onCellsPaste, columnToggle, rowReorder, onRowOrderChange, treeChildrenKey, treeDefaultExpanded, renderDetail, singleDetailExpand, extraRowFilter, virtualScroll, virtualRowHeight, height, overscan, autosize, }: InanduGridProps): import('react').JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { ColumnConfig, InanduColumnAggregate, InanduGridRow } from './types';
2
+ /** Short, language-agnostic symbol shown for each `InanduColumnAggregate` kind — deliberately not translated (the same way units like "CSV"/"PDF" aren't). */
3
+ export declare const AGGREGATE_SYMBOLS: Record<Exclude<InanduColumnAggregate, ''>, string>;
4
+ /** One numeric aggregate per `aggregateColumns` entry, computed over `rows` — `'count'` just counts rows (works for any column type); the rest ignore rows whose raw value isn't a finite number. */
5
+ export declare function computeGroupAggregates(rows: InanduGridRow[], aggregateColumns: readonly ColumnConfig[]): Record<string, number>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Columns with an explicit `order` land at that 0-based slot; columns without one
3
+ * fill the remaining slots in declaration order. Equal/out-of-range `order` values
4
+ * degrade gracefully by falling back to declaration order among themselves.
5
+ *
6
+ * Generic over the column type: works for `InanduColumnComponent` instances or any object with
7
+ * an `order()` accessor.
8
+ */
9
+ export declare function placeColumnsByOrder<C extends {
10
+ order(): number | undefined;
11
+ }>(columns: readonly C[]): C[];
@@ -0,0 +1,14 @@
1
+ /** Floor enforced while dragging a resize handle, so a column can never be shrunk to zero/negative width. */
2
+ export declare const MIN_COLUMN_WIDTH = 30;
3
+ /** Ceiling `autosize` (double-click a resize handle to fit content) will grow a column to, so one
4
+ * very long value can't blow the column out to the width of the page. The drag handle itself is
5
+ * not capped by this. */
6
+ export declare const MAX_COLUMN_WIDTH = 600;
7
+ /** Must match `.inandu-select-column`'s CSS width — used by `stickyOffset()` to account for the (always-sticky) checkbox column. */
8
+ export declare const SELECT_COLUMN_WIDTH = 36;
9
+ /** Must match `.inandu-row-drag-column`'s CSS width — used by `stickyOffset()` to account for the (always-leading, when enabled) drag-handle column. */
10
+ export declare const ROW_DRAG_COLUMN_WIDTH = 32;
11
+ /** Must match `.inandu-detail-toggle-column`'s CSS width — used by `stickyOffset()` to account for the (always-leading-most, when enabled) master-detail expand/collapse column. */
12
+ export declare const DETAIL_TOGGLE_COLUMN_WIDTH = 32;
13
+ /** `localStorage` key prefix for `stateKey`-based persistence, so this library's own saved blobs don't collide with anything else a host app stores. */
14
+ export declare const STATE_STORAGE_PREFIX = "inandu-grid-state:";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Escapes `value` for use inside a double-quoted CSS attribute-selector value (e.g.
3
+ * `` `td[data-field="${escaped}"]` ``), for the rare runtime with no native `CSS.escape`. Backslashes
4
+ * MUST be escaped before quotes — escaping only quotes lets a value containing a backslash (e.g.
5
+ * `a\"b`) smuggle an unescaped quote through (`\"` in the output reads back as an escaped backslash
6
+ * followed by a bare, string-terminating `"`), letting the selector break out of the attribute value.
7
+ */
8
+ export declare function escapeAttributeSelectorValue(value: string): string;
@@ -0,0 +1,2 @@
1
+ /** Quotes `value` for a CSV cell (doubling internal quotes) only if it contains a comma, quote, or newline. */
2
+ export declare function escapeCsvValue(value: string): string;
@@ -0,0 +1,2 @@
1
+ /** Triggers a browser download of `content` as `filename`, via a throwaway object URL + `<a>` click. */
2
+ export declare function downloadBlob(content: string | Blob, filename: string, mimeType?: string): void;
@@ -0,0 +1,2 @@
1
+ /** Escapes `&`/`</>` for safe use as XML/HTML element text content — shared by `exportExcel()` and `printTable()`. */
2
+ export declare function escapeMarkup(value: string): string;
@@ -0,0 +1,3 @@
1
+ import { jsPDF } from 'jspdf';
2
+ /** Shortens `text` with a trailing "…" until it fits `maxWidth` (in the PDF's current font), unchanged if it already fits. */
3
+ export declare function truncatePdfText(doc: jsPDF, text: string, maxWidth: number): string;
@@ -0,0 +1,26 @@
1
+ import { ColumnConfig, InanduGridColumnFilterValue, InanduGridRow } from './types';
2
+ import { NumberFormatter } from './format';
3
+ /**
4
+ * Whether `value` has at least one non-empty key — an entry can exist (e.g. after typing then
5
+ * clearing) without actually narrowing anything. `values` is the one exception: unlike every other
6
+ * key, an *empty* array is still meaningful (see `matchesColumnFilter`) — the presence of the key
7
+ * at all is what counts, not its length. Only an entirely absent/`undefined` `values` reads as "no
8
+ * set-filter constraint".
9
+ */
10
+ export declare function hasMeaningfulFilterValue(value: InanduGridColumnFilterValue | undefined): boolean;
11
+ /**
12
+ * Whether `row` satisfies `column`'s own filter control. An empty/absent `filterValue` (no
13
+ * constraint entered for this column yet) always matches. Range checks (`'number'`/`'date'`) are
14
+ * inclusive on both ends; a cell that can't be parsed as that column's type never matches once at
15
+ * least one bound is set.
16
+ *
17
+ * `filterValue.values` (the set filter) is the one key that's *present-vs-absent*, not
18
+ * *non-empty-vs-empty*: an `undefined` `values` falls through to the type-specific checks below,
19
+ * same as omitting it; a *defined* `values` — even `[]` — takes over matching for the column
20
+ * entirely, checked against the formatted display value. This is deliberate: `[]` is how "every
21
+ * checkbox is unchecked" (match nothing) is told apart from "the set filter was never touched"
22
+ * (match everything, i.e. don't constrain) — collapsing them to the same "no constraint" meaning,
23
+ * like every other filter key's blank state does, would make unchecking every box a no-op instead
24
+ * of the empty result a consumer building a set-filter checklist actually needs.
25
+ */
26
+ export declare function matchesColumnFilter(column: ColumnConfig, row: InanduGridRow, filterValue: InanduGridColumnFilterValue, locale: string, numberFormatter?: NumberFormatter): boolean;
@@ -0,0 +1,24 @@
1
+ import { InanduColumnType } from './types';
2
+ /**
3
+ * Turns a raw numeric value into its display string. `digitsInfo` is a `DecimalPipe`-style
4
+ * `'{minInt}.{minFrac}-{maxFrac}'` string (e.g. `"1.2-2"`), or empty for the default.
5
+ *
6
+ * Injected into `formatCellValue()` so the framework layer can choose the implementation: the
7
+ * Angular component passes one backed by `@angular/common`'s `formatNumber` (honouring whatever
8
+ * locale data the host app registered), keeping its output byte-identical to before this folder
9
+ * existed. `defaultNumberFormatter` below is the standalone fallback for a non-Angular consumer.
10
+ */
11
+ export type NumberFormatter = (value: number, locale: string, digitsInfo?: string) => string;
12
+ /** `Intl.NumberFormat`-based `NumberFormatter`. Parses the `digitsInfo` mini-syntax; falls back to Angular's own default of up to 3 fraction digits (`'1.0-3'`) when it's absent. */
13
+ export declare function defaultNumberFormatter(value: number, locale: string, digitsInfo?: string): string;
14
+ /**
15
+ * Coerces a raw cell value to a `Date` for `type="date"` columns — accepts a `Date`, a timestamp,
16
+ * or a string. Safari's `Date` string parser is stricter than Chrome's; notably it returns an
17
+ * Invalid Date for a space-separated `"yyyy-mm-dd hh:mm[:ss]"` that Chrome happily parses. That one
18
+ * common case is normalised to the ISO `T` form before parsing, so a `type="date"` column renders
19
+ * and filters identically in both. Anything still unparseable comes back as an Invalid Date — every
20
+ * caller already guards with `Number.isNaN(date.getTime())`.
21
+ */
22
+ export declare function coerceToDate(value: unknown): Date;
23
+ export declare function formatDateValue(date: Date, format: string): string;
24
+ export declare function formatCellValue(value: unknown, type: InanduColumnType, format: string, locale: string, numberFormatter?: NumberFormatter): string;
@@ -0,0 +1,46 @@
1
+ export declare const en: {
2
+ MsgNoData: string;
3
+ MsgFirstPage: string;
4
+ MsgPreviousPage: string;
5
+ MsgNextPage: string;
6
+ MsgLastPage: string;
7
+ MsgSortBy: string;
8
+ MsgPageOf: string;
9
+ MsgFilterPlaceholder: string;
10
+ MsgFilterColumn: string;
11
+ MsgFilterMin: string;
12
+ MsgFilterMax: string;
13
+ MsgFilterFrom: string;
14
+ MsgFilterTo: string;
15
+ MsgAll: string;
16
+ MsgCancelFilter: string;
17
+ MsgCancelAllFilters: string;
18
+ MsgGroupByHint: string;
19
+ MsgGroupedBy: string;
20
+ MsgGroupHeader: string;
21
+ MsgCancelGrouping: string;
22
+ MsgSelectAll: string;
23
+ MsgSelectRow: string;
24
+ MsgExportCsv: string;
25
+ MsgExportExcel: string;
26
+ MsgExportPdf: string;
27
+ MsgPrint: string;
28
+ MsgToggleColumns: string;
29
+ MsgToggleColumn: string;
30
+ MsgEditCell: string;
31
+ MsgEditRow: string;
32
+ MsgSaveRow: string;
33
+ MsgCancelRowEdit: string;
34
+ MsgDeleteRow: string;
35
+ MsgAddRow: string;
36
+ MsgLoading: string;
37
+ MsgDragRow: string;
38
+ MsgAutosizeColumn: string;
39
+ MsgExpandDetail: string;
40
+ MsgCollapseDetail: string;
41
+ MsgDeleteSelected: string;
42
+ MsgValidationRequired: string;
43
+ MsgValidationMin: string;
44
+ MsgValidationMax: string;
45
+ MsgValidationPattern: string;
46
+ };
@@ -0,0 +1,46 @@
1
+ export declare const es: {
2
+ MsgNoData: string;
3
+ MsgFirstPage: string;
4
+ MsgPreviousPage: string;
5
+ MsgNextPage: string;
6
+ MsgLastPage: string;
7
+ MsgSortBy: string;
8
+ MsgPageOf: string;
9
+ MsgFilterPlaceholder: string;
10
+ MsgFilterColumn: string;
11
+ MsgFilterMin: string;
12
+ MsgFilterMax: string;
13
+ MsgFilterFrom: string;
14
+ MsgFilterTo: string;
15
+ MsgAll: string;
16
+ MsgCancelFilter: string;
17
+ MsgCancelAllFilters: string;
18
+ MsgGroupByHint: string;
19
+ MsgGroupedBy: string;
20
+ MsgGroupHeader: string;
21
+ MsgCancelGrouping: string;
22
+ MsgSelectAll: string;
23
+ MsgSelectRow: string;
24
+ MsgExportCsv: string;
25
+ MsgExportExcel: string;
26
+ MsgExportPdf: string;
27
+ MsgPrint: string;
28
+ MsgToggleColumns: string;
29
+ MsgToggleColumn: string;
30
+ MsgEditCell: string;
31
+ MsgEditRow: string;
32
+ MsgSaveRow: string;
33
+ MsgCancelRowEdit: string;
34
+ MsgDeleteRow: string;
35
+ MsgAddRow: string;
36
+ MsgLoading: string;
37
+ MsgDragRow: string;
38
+ MsgAutosizeColumn: string;
39
+ MsgExpandDetail: string;
40
+ MsgCollapseDetail: string;
41
+ MsgDeleteSelected: string;
42
+ MsgValidationRequired: string;
43
+ MsgValidationMin: string;
44
+ MsgValidationMax: string;
45
+ MsgValidationPattern: string;
46
+ };
@@ -0,0 +1,46 @@
1
+ export declare const fr: {
2
+ MsgNoData: string;
3
+ MsgFirstPage: string;
4
+ MsgPreviousPage: string;
5
+ MsgNextPage: string;
6
+ MsgLastPage: string;
7
+ MsgSortBy: string;
8
+ MsgPageOf: string;
9
+ MsgFilterPlaceholder: string;
10
+ MsgFilterColumn: string;
11
+ MsgFilterMin: string;
12
+ MsgFilterMax: string;
13
+ MsgFilterFrom: string;
14
+ MsgFilterTo: string;
15
+ MsgAll: string;
16
+ MsgCancelFilter: string;
17
+ MsgCancelAllFilters: string;
18
+ MsgGroupByHint: string;
19
+ MsgGroupedBy: string;
20
+ MsgGroupHeader: string;
21
+ MsgCancelGrouping: string;
22
+ MsgSelectAll: string;
23
+ MsgSelectRow: string;
24
+ MsgExportCsv: string;
25
+ MsgExportExcel: string;
26
+ MsgExportPdf: string;
27
+ MsgPrint: string;
28
+ MsgToggleColumns: string;
29
+ MsgToggleColumn: string;
30
+ MsgEditCell: string;
31
+ MsgEditRow: string;
32
+ MsgSaveRow: string;
33
+ MsgCancelRowEdit: string;
34
+ MsgDeleteRow: string;
35
+ MsgAddRow: string;
36
+ MsgLoading: string;
37
+ MsgDragRow: string;
38
+ MsgAutosizeColumn: string;
39
+ MsgExpandDetail: string;
40
+ MsgCollapseDetail: string;
41
+ MsgDeleteSelected: string;
42
+ MsgValidationRequired: string;
43
+ MsgValidationMin: string;
44
+ MsgValidationMax: string;
45
+ MsgValidationPattern: string;
46
+ };
@@ -0,0 +1,8 @@
1
+ import { en } from './en';
2
+ import { es } from './es';
3
+ import { fr } from './fr';
4
+ import { it } from './it';
5
+ import { zh } from './zh';
6
+ export { en, es, fr, it, zh };
7
+ /** Every built-in dictionary, keyed by primary language subtag. */
8
+ export declare const INANDU_GRID_TRANSLATIONS: Record<string, Record<string, string>>;
@@ -0,0 +1,46 @@
1
+ export declare const it: {
2
+ MsgNoData: string;
3
+ MsgFirstPage: string;
4
+ MsgPreviousPage: string;
5
+ MsgNextPage: string;
6
+ MsgLastPage: string;
7
+ MsgSortBy: string;
8
+ MsgPageOf: string;
9
+ MsgFilterPlaceholder: string;
10
+ MsgFilterColumn: string;
11
+ MsgFilterMin: string;
12
+ MsgFilterMax: string;
13
+ MsgFilterFrom: string;
14
+ MsgFilterTo: string;
15
+ MsgAll: string;
16
+ MsgCancelFilter: string;
17
+ MsgCancelAllFilters: string;
18
+ MsgGroupByHint: string;
19
+ MsgGroupedBy: string;
20
+ MsgGroupHeader: string;
21
+ MsgCancelGrouping: string;
22
+ MsgSelectAll: string;
23
+ MsgSelectRow: string;
24
+ MsgExportCsv: string;
25
+ MsgExportExcel: string;
26
+ MsgExportPdf: string;
27
+ MsgPrint: string;
28
+ MsgToggleColumns: string;
29
+ MsgToggleColumn: string;
30
+ MsgEditCell: string;
31
+ MsgEditRow: string;
32
+ MsgSaveRow: string;
33
+ MsgCancelRowEdit: string;
34
+ MsgDeleteRow: string;
35
+ MsgAddRow: string;
36
+ MsgLoading: string;
37
+ MsgDragRow: string;
38
+ MsgAutosizeColumn: string;
39
+ MsgExpandDetail: string;
40
+ MsgCollapseDetail: string;
41
+ MsgDeleteSelected: string;
42
+ MsgValidationRequired: string;
43
+ MsgValidationMin: string;
44
+ MsgValidationMax: string;
45
+ MsgValidationPattern: string;
46
+ };
@@ -0,0 +1,46 @@
1
+ export declare const zh: {
2
+ MsgNoData: string;
3
+ MsgFirstPage: string;
4
+ MsgPreviousPage: string;
5
+ MsgNextPage: string;
6
+ MsgLastPage: string;
7
+ MsgSortBy: string;
8
+ MsgPageOf: string;
9
+ MsgFilterPlaceholder: string;
10
+ MsgFilterColumn: string;
11
+ MsgFilterMin: string;
12
+ MsgFilterMax: string;
13
+ MsgFilterFrom: string;
14
+ MsgFilterTo: string;
15
+ MsgAll: string;
16
+ MsgCancelFilter: string;
17
+ MsgCancelAllFilters: string;
18
+ MsgGroupByHint: string;
19
+ MsgGroupedBy: string;
20
+ MsgGroupHeader: string;
21
+ MsgCancelGrouping: string;
22
+ MsgSelectAll: string;
23
+ MsgSelectRow: string;
24
+ MsgExportCsv: string;
25
+ MsgExportExcel: string;
26
+ MsgExportPdf: string;
27
+ MsgPrint: string;
28
+ MsgToggleColumns: string;
29
+ MsgToggleColumn: string;
30
+ MsgEditCell: string;
31
+ MsgEditRow: string;
32
+ MsgSaveRow: string;
33
+ MsgCancelRowEdit: string;
34
+ MsgDeleteRow: string;
35
+ MsgAddRow: string;
36
+ MsgLoading: string;
37
+ MsgDragRow: string;
38
+ MsgAutosizeColumn: string;
39
+ MsgExpandDetail: string;
40
+ MsgCollapseDetail: string;
41
+ MsgDeleteSelected: string;
42
+ MsgValidationRequired: string;
43
+ MsgValidationMin: string;
44
+ MsgValidationMax: string;
45
+ MsgValidationPattern: string;
46
+ };
@@ -0,0 +1,17 @@
1
+ export type { InanduColumnType, InanduColumnStickySide, InanduColumnAggregate, InanduGridRow, InanduGridColumnFilterValue, ColumnConfig, } from './types';
2
+ export { MIN_COLUMN_WIDTH, MAX_COLUMN_WIDTH, SELECT_COLUMN_WIDTH, ROW_DRAG_COLUMN_WIDTH, DETAIL_TOGGLE_COLUMN_WIDTH, STATE_STORAGE_PREFIX, } from './constants';
3
+ export { coerceToDate, formatDateValue, formatCellValue, defaultNumberFormatter, } from './format';
4
+ export type { NumberFormatter } from './format';
5
+ export { compareCellValues } from './sort';
6
+ export { flattenTree, collectTreeRows } from './tree';
7
+ export type { TreeVisibleRow, FlattenTreeOptions } from './tree';
8
+ export { hasMeaningfulFilterValue, matchesColumnFilter } from './filter';
9
+ export { AGGREGATE_SYMBOLS, computeGroupAggregates } from './aggregate';
10
+ export { placeColumnsByOrder } from './columns';
11
+ export { parseDraftValue, parsePastedCellValue } from './parse';
12
+ export { escapeAttributeSelectorValue } from './dom';
13
+ export { escapeCsvValue } from './export/csv';
14
+ export { escapeMarkup } from './export/markup';
15
+ export { truncatePdfText } from './export/pdf';
16
+ export { downloadBlob } from './export/download';
17
+ export { en, es, fr, it, zh, INANDU_GRID_TRANSLATIONS } from './i18n';
@@ -0,0 +1,14 @@
1
+ import { InanduColumnType } from './types';
2
+ /**
3
+ * Parses a row-edit draft's raw control value (a string for text/number/date, a boolean for the
4
+ * checkbox — see `InanduGridComponent.onRowFieldChange`) per the column's `type`. Returns `undefined` for
5
+ * an unparseable `'number'`/`'date'`, the signal `saveRow()` uses to omit that field from `values`
6
+ * rather than committing garbage.
7
+ */
8
+ export declare function parseDraftValue(raw: unknown, type: InanduColumnType): unknown;
9
+ /**
10
+ * Parses one pasted TSV cell's raw text per `type` — like `parseDraftValue()`, except `'boolean'`:
11
+ * a pasted cell is always plain text (`"true"`/`"false"`, whatever the clipboard actually held),
12
+ * never an already-boolean checkbox `.checked` the way a manual row edit's draft value is.
13
+ */
14
+ export declare function parsePastedCellValue(raw: string, type: InanduColumnType): unknown;
@@ -0,0 +1 @@
1
+ export declare function compareCellValues(a: unknown, b: unknown, locale?: string): number;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tree-data flattening (#3) — pure, framework-agnostic. Walks a nested-children hierarchy into the
3
+ * flat list of rows that should render right now: a node's children appear directly below it, but
4
+ * only while that node is expanded. Filtering keeps a node when it (or any descendant) matches, and
5
+ * force-expands the ancestors of a match so it's visible; an optional comparator sorts each level.
6
+ */
7
+ export interface TreeVisibleRow<T> {
8
+ row: T;
9
+ /** 0 for a root, +1 per level. Drives the first cell's indentation. */
10
+ depth: number;
11
+ /** Has at least one (surviving) child — i.e. worth showing a toggle. */
12
+ expandable: boolean;
13
+ /** Currently showing its children. */
14
+ expanded: boolean;
15
+ }
16
+ export interface FlattenTreeOptions<T> {
17
+ /** A node's children array (or `undefined` / `[]` for a leaf). */
18
+ getChildren: (row: T) => readonly T[] | undefined;
19
+ /** Whether `row` is expanded — consulted only when there is no active `match`. */
20
+ isExpanded: (row: T) => boolean;
21
+ /** When set, a node survives iff it or a descendant returns `true`; matches render expanded. */
22
+ match?: (row: T) => boolean;
23
+ /** Sorts the siblings at every level (applied after filtering). */
24
+ compare?: (a: T, b: T) => number;
25
+ }
26
+ export declare function flattenTree<T>(roots: readonly T[], options: FlattenTreeOptions<T>): TreeVisibleRow<T>[];
27
+ /** Every node in the hierarchy, depth-first — used for "expand all" / counting. */
28
+ export declare function collectTreeRows<T>(roots: readonly T[], getChildren: (row: T) => readonly T[] | undefined): T[];
@@ -0,0 +1,46 @@
1
+ /** How a column's raw cell value is interpreted and formatted. See `InanduColumnComponent.type`. */
2
+ export type InanduColumnType = 'string' | 'number' | 'boolean' | 'date';
3
+ /** Which side of the grid a `sticky="true"` column pins to. See `InanduColumnComponent.stickySide`. */
4
+ export type InanduColumnStickySide = 'left' | 'right';
5
+ /** Aggregate shown in a group's header row when the grid is grouped. See `InanduColumnComponent.aggregate`. */
6
+ export type InanduColumnAggregate = 'sum' | 'avg' | 'min' | 'max' | 'count' | '';
7
+ /** A grid row — a plain bag of field values. The grid never assumes any particular key. */
8
+ export type InanduGridRow = Record<string, unknown>;
9
+ /**
10
+ * The subset of a column definition the pure helpers read, expressed as the signal-getter shape
11
+ * `InanduColumnComponent` already exposes (so an `InanduColumnComponent` instance satisfies this
12
+ * structurally, with no adapter). A non-Angular consumer can pass any object with these five
13
+ * zero-arg accessors — e.g. `{ field: () => 'name', type: () => 'string', ... }`.
14
+ */
15
+ export interface ColumnConfig {
16
+ field(): string;
17
+ type(): InanduColumnType;
18
+ format(): string;
19
+ order(): number | undefined;
20
+ aggregate(): InanduColumnAggregate;
21
+ }
22
+ /** Raw values from a single column's filter controls; which keys are used depends on that column's `type`. */
23
+ export interface InanduGridColumnFilterValue {
24
+ /** `'string'` columns. */
25
+ text?: string;
26
+ /** `'number'` columns. */
27
+ min?: string;
28
+ max?: string;
29
+ /** `'date'` columns, `yyyy-mm-dd` (native `<input type="date">` value format). */
30
+ from?: string;
31
+ to?: string;
32
+ /** `'boolean'` columns: `''` (no filter), `'true'`, or `'false'`. */
33
+ bool?: string;
34
+ /**
35
+ * Excel-style "set filter" — an explicit list of the column's own *formatted* display values to
36
+ * match (OR within the column, same as every other filter key combines with AND across
37
+ * columns). Works the same regardless of `type` — unlike `text`/`min`/`max`/`from`/`to`/`bool`,
38
+ * which are each specific to one `type` — since it compares against the already-formatted
39
+ * string, not the raw value. Whenever this key is *present* (defined) at all, it takes over
40
+ * matching for the column entirely and the type-specific keys above are ignored — including an
41
+ * **empty array**, which means "every value unchecked" and matches nothing, not "no
42
+ * constraint". Omit the key (or set it to `undefined`) for "no constraint" instead. See
43
+ * `matchesColumnFilter`/`hasMeaningfulFilterValue`.
44
+ */
45
+ values?: string[];
46
+ }