@standardbeagle/edit-db 0.4.484 → 0.4.581

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 (111) hide show
  1. package/dist/common/fetcher.d.ts +7 -2
  2. package/dist/common/saved-objects.d.ts +40 -0
  3. package/dist/common/schema-queries.d.ts +1 -0
  4. package/dist/components/bulk-edit-dialog.d.ts +18 -0
  5. package/dist/components/content-panel.d.ts +5 -2
  6. package/dist/components/content-viewer.d.ts +8 -1
  7. package/dist/components/content-viewer.test.d.ts +1 -0
  8. package/dist/components/data-table.d.ts +49 -2
  9. package/dist/components/detail-panel.d.ts +2 -2
  10. package/dist/components/export-button.d.ts +19 -0
  11. package/dist/components/export-button.test.d.ts +1 -0
  12. package/dist/components/filters/fk-filter.d.ts +2 -0
  13. package/dist/components/filters/fk-filter.test.d.ts +1 -0
  14. package/dist/components/filters/number-filter.d.ts +8 -0
  15. package/dist/components/filters/number-filter.test.d.ts +1 -0
  16. package/dist/components/fk-cell-popover.d.ts +12 -5
  17. package/dist/components/fk-cell-popover.test.d.ts +1 -0
  18. package/dist/components/form-runner-host.d.ts +14 -0
  19. package/dist/components/form-runner.d.ts +43 -0
  20. package/dist/components/form-runner.test.d.ts +0 -0
  21. package/dist/components/form-subform.d.ts +11 -0
  22. package/dist/components/form-subform.test.d.ts +0 -0
  23. package/dist/components/grouped-grid-summary.d.ts +17 -0
  24. package/dist/components/grouped-grid-summary.test.d.ts +0 -0
  25. package/dist/components/m2m-panel.d.ts +4 -5
  26. package/dist/components/ui/table.test.d.ts +1 -0
  27. package/dist/data-edit.d.ts +25 -4
  28. package/dist/data-panel.d.ts +0 -11
  29. package/dist/edit-db.css +1 -1
  30. package/dist/editor.d.ts +22 -1
  31. package/dist/editor.es.js +7368 -4589
  32. package/dist/editor.stories.d.ts +0 -1
  33. package/dist/editor.umd.cjs +48 -27
  34. package/dist/hooks/useColumnNav.d.ts +3 -3
  35. package/dist/hooks/useColumnSizingPersistence.d.ts +19 -0
  36. package/dist/hooks/useColumnVisibilityPersistence.d.ts +34 -0
  37. package/dist/hooks/useColumnVisibilityPersistence.test.d.ts +1 -0
  38. package/dist/hooks/useCompositeTableRef.d.ts +20 -2
  39. package/dist/hooks/useCompositeTableRef.test.d.ts +1 -0
  40. package/dist/hooks/useDataTable.d.ts +59 -6
  41. package/dist/hooks/useDebouncedCommit.d.ts +19 -0
  42. package/dist/hooks/useDebouncedCommit.test.d.ts +1 -0
  43. package/dist/hooks/useDeltaMutation.d.ts +20 -0
  44. package/dist/hooks/useDeltaMutation.test.d.ts +0 -0
  45. package/dist/hooks/useEditorConfig.d.ts +27 -0
  46. package/dist/hooks/useFitMode.d.ts +23 -0
  47. package/dist/hooks/useFitMode.test.d.ts +1 -0
  48. package/dist/hooks/usePanelSize.d.ts +28 -0
  49. package/dist/hooks/usePanelSize.test.d.ts +1 -0
  50. package/dist/hooks/usePath.d.ts +2 -5
  51. package/dist/hooks/useRowHoverActions.d.ts +26 -0
  52. package/dist/hooks/useSchema.d.ts +8 -2
  53. package/dist/hooks/useSchemaFilter.test.d.ts +1 -0
  54. package/dist/hooks/useTableExport.d.ts +13 -0
  55. package/dist/hooks/useTableMutation.d.ts +1 -4
  56. package/dist/hooks/useTableMutation.test.d.ts +0 -0
  57. package/dist/hooks/useTableRef.d.ts +23 -2
  58. package/dist/hooks/useTableRef.test.d.ts +1 -0
  59. package/dist/hooks/useTableStats.d.ts +7 -24
  60. package/dist/hooks/useToast.d.ts +15 -0
  61. package/dist/index.d.ts +13 -1
  62. package/dist/lib/column-order.d.ts +17 -0
  63. package/dist/lib/column-order.test.d.ts +1 -0
  64. package/dist/lib/content-detect.d.ts +39 -0
  65. package/dist/lib/content-detect.sniff.test.d.ts +1 -0
  66. package/dist/lib/date-input.d.ts +21 -0
  67. package/dist/lib/date-input.test.d.ts +1 -0
  68. package/dist/lib/drill-stack.d.ts +19 -2
  69. package/dist/lib/export.d.ts +122 -0
  70. package/dist/lib/export.test.d.ts +1 -0
  71. package/dist/lib/field-validation.d.ts +16 -0
  72. package/dist/lib/fk.d.ts +23 -2
  73. package/dist/lib/form-definition.d.ts +57 -0
  74. package/dist/lib/form-definition.test.d.ts +1 -0
  75. package/dist/lib/form-runner-nav.d.ts +19 -0
  76. package/dist/lib/form-runner-nav.test.d.ts +1 -0
  77. package/dist/lib/form-subform.d.ts +12 -0
  78. package/dist/lib/form-subform.test.d.ts +1 -0
  79. package/dist/lib/form-widget.d.ts +36 -0
  80. package/dist/lib/form-widget.test.d.ts +1 -0
  81. package/dist/lib/format-value.d.ts +26 -0
  82. package/dist/lib/grid-grouping.d.ts +63 -0
  83. package/dist/lib/grid-grouping.test.d.ts +1 -0
  84. package/dist/lib/invalidate.d.ts +7 -0
  85. package/dist/lib/invalidate.test.d.ts +1 -0
  86. package/dist/lib/label-match.d.ts +13 -0
  87. package/dist/lib/label-match.test.d.ts +1 -0
  88. package/dist/lib/m2m.d.ts +45 -6
  89. package/dist/lib/mutation-payload.d.ts +37 -0
  90. package/dist/lib/mutation-payload.test.d.ts +1 -0
  91. package/dist/lib/query-builder.d.ts +137 -8
  92. package/dist/lib/row-id.d.ts +20 -0
  93. package/dist/lib/rows-by-pk-query.test.d.ts +1 -0
  94. package/dist/lib/scalar-types.d.ts +30 -0
  95. package/dist/lib/scalar-types.test.d.ts +1 -0
  96. package/dist/lib/table-action.d.ts +24 -0
  97. package/dist/lib/table-ref.d.ts +45 -0
  98. package/dist/lib/table-ref.test.d.ts +1 -0
  99. package/dist/{tableList.d.ts → table-list.d.ts} +1 -1
  100. package/dist/table-list.test.d.ts +0 -0
  101. package/dist/table-view.chart.test.d.ts +1 -0
  102. package/dist/table-view.d.ts +22 -0
  103. package/dist/table-view.test.d.ts +0 -0
  104. package/dist/types/schema.d.ts +54 -10
  105. package/package.json +2 -4
  106. package/dist/common/schema.d.ts +0 -2
  107. package/dist/data-data-table.d.ts +0 -17
  108. package/dist/error-panel.d.ts +0 -1
  109. /package/dist/common/{schema.test.d.ts → saved-objects.test.d.ts} +0 -0
  110. /package/dist/{components/table-dimensions.test.d.ts → common/schema-queries.test.d.ts} +0 -0
  111. /package/dist/{tableList.test.d.ts → components/bulk-edit-dialog.test.d.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { ReactNode } from 'react';
2
- import { ColumnPanel } from '../data-panel';
2
+ import { DrillFrame } from '../lib/drill-stack';
3
3
  interface ColumnNavEntry {
4
- panel: ColumnPanel;
4
+ panel: DrillFrame;
5
5
  element: HTMLElement | null;
6
6
  }
7
7
  interface ColumnNavState {
@@ -13,7 +13,7 @@ interface ColumnNavState {
13
13
  }
14
14
  interface ColumnNavRegistration {
15
15
  mainTable: string | null;
16
- columns: ColumnPanel[];
16
+ columns: DrillFrame[];
17
17
  columnRefs: Map<number, HTMLElement | null>;
18
18
  onClose: (index: number) => void;
19
19
  }
@@ -0,0 +1,19 @@
1
+ import { ColumnSizingState } from '@tanstack/react-table';
2
+ export declare const COL_MIN_WIDTH = 60;
3
+ export declare const COL_MAX_AUTO_WIDTH = 450;
4
+ export declare const COL_DEFAULT_WIDTH = 150;
5
+ export interface UseColumnSizingPersistenceResult {
6
+ columnSizing: ColumnSizingState;
7
+ setColumnSizing: React.Dispatch<React.SetStateAction<ColumnSizingState>>;
8
+ }
9
+ /**
10
+ * Owns per-table column sizing, persisted to localStorage.
11
+ *
12
+ * Writes are debounced so a live ('onChange') resize drag doesn't write on every
13
+ * mousemove. `skipPersistRef` suppresses the first run after mount/table-switch,
14
+ * which would only write back the sizing just loaded from storage.
15
+ * `pendingSizingRef` carries the latest unsaved state so a table switch or
16
+ * unmount flushes it instead of dropping a resize made less than the debounce
17
+ * window ago.
18
+ */
19
+ export declare function useColumnSizingPersistence(tableName?: string): UseColumnSizingPersistenceResult;
@@ -0,0 +1,34 @@
1
+ import { VisibilityState } from '@tanstack/react-table';
2
+ /**
3
+ * Read a stored selection. Returns null — not `{}` — when there is nothing
4
+ * stored, because "no stored preference" (fall back to the host defaults) and
5
+ * "stored: everything visible" are different states.
6
+ */
7
+ export declare function loadColumnVisibility(tableName: string): VisibilityState | null;
8
+ export declare function saveColumnVisibility(tableName: string, visibility: VisibilityState): void;
9
+ export declare function clearColumnVisibility(tableName: string): void;
10
+ /**
11
+ * Turn a host's list of columns to show into table state: everything named is
12
+ * visible, everything else in `allColumnIds` is hidden. Columns the host names
13
+ * that this table doesn't have are ignored, so one config can cover a schema
14
+ * that varies between deployments.
15
+ */
16
+ export declare function visibilityFromDefaults(allColumnIds: string[], defaultVisible?: string[]): VisibilityState;
17
+ export interface UseColumnVisibilityPersistenceResult {
18
+ columnVisibility: VisibilityState;
19
+ setColumnVisibility: React.Dispatch<React.SetStateAction<VisibilityState>>;
20
+ /** Drop the stored selection and go back to the host defaults for this table. */
21
+ resetColumnVisibility: () => void;
22
+ }
23
+ /**
24
+ * Owns which columns a table shows, persisted per table to localStorage.
25
+ *
26
+ * A viewer picking columns is a durable preference, not a per-visit one: the
27
+ * selection survives reload and return visits. Host defaults apply until the
28
+ * viewer makes a choice, and `resetColumnVisibility` puts them back.
29
+ *
30
+ * Only a change through the returned setter is written. Merely opening a table
31
+ * must not store its defaults — that would freeze today's defaults into every
32
+ * viewer's storage and make a later change to them invisible.
33
+ */
34
+ export declare function useColumnVisibilityPersistence(tableName: string | undefined, defaultVisibility: VisibilityState): UseColumnVisibilityPersistenceResult;
@@ -1,4 +1,4 @@
1
- import { Schema } from '../types/schema';
1
+ import { SchemaContextValue } from '../types/schema';
2
2
  export interface CompositeTableRefValue {
3
3
  /** Route-encoded composite key (`v1::v2`) suitable as a Select value. */
4
4
  route: string;
@@ -10,10 +10,28 @@ export interface CompositeTableRef {
10
10
  loading: boolean;
11
11
  error: unknown;
12
12
  data: CompositeTableRefValue[];
13
+ /** True when `search` narrows server-side (String label column, `_contains`);
14
+ * false means the caller must filter the fetched window client-side. */
15
+ serverSearch: boolean;
16
+ }
17
+ export interface CompositeTableRefOptions {
18
+ /** Free-text search term. Applied server-side when the label column is String. */
19
+ search?: string;
20
+ /** Defer the list fetch until the dropdown is opened (fetch-on-open). */
21
+ enabled?: boolean;
22
+ /** The currently-selected destination-column values, so the selected parent row
23
+ * can be looked up and shown even when it falls outside the fetched window. */
24
+ currentValues?: Record<string, unknown> | null;
13
25
  }
14
26
  /**
15
27
  * Fetch parent rows for a composite-FK Select widget. Returns one row per parent
16
28
  * with its label plus every destination column value so the caller can write
17
29
  * each composite-FK source column on the child form when a selection is made.
30
+ *
31
+ * Mirrors the single-column FK data source (table-ref.ts / useTableRef +
32
+ * useTableRefValue): the window is sorted by the label column (deterministic),
33
+ * narrowed server-side when a search term is given and the label is String-typed,
34
+ * and the currently-selected row is resolved via a single-row lookup when it lies
35
+ * outside the fetched window so it stays selectable instead of showing blank.
18
36
  */
19
- export declare function useCompositeTableRef(schema: Schema, destTableName: string, destColumnNames: string[]): CompositeTableRef;
37
+ export declare function useCompositeTableRef(schema: SchemaContextValue, destTableName: string, destColumnNames: string[], options?: CompositeTableRefOptions): CompositeTableRef;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,19 +1,44 @@
1
- import { Table, Join } from '../types/schema';
1
+ import { Table, Column, Join } from '../types/schema';
2
2
  import { ColumnDef, ColumnFiltersState, SortingState } from '@tanstack/react-table';
3
- import { ColumnPanel } from '../data-panel';
3
+ import { DrillFrame } from '../lib/drill-stack';
4
+ import { ExportRunner } from '../lib/export';
5
+ import { GridGroupMemberRequest, GroupingRow, GroupingSort } from '../lib/grid-grouping';
4
6
  export { getFilterOperators } from '../lib/query-builder';
5
7
  export type { ColumnFilterValue } from '../lib/query-builder';
6
8
  interface RowData {
7
9
  id?: number | string;
8
10
  [key: string]: unknown;
9
11
  }
12
+ export declare function getJoinedRowPkValue(row: RowData | undefined, joinSchema: Table | undefined): string;
10
13
  /**
11
14
  * Clamp a page index into the valid [0, pageCount-1] range. Guards against a
12
15
  * stale/out-of-range page (e.g. "page 2 of 1" after switching to a smaller
13
16
  * table or when the row count shrinks).
14
17
  */
15
18
  export declare function clampPageIndex(pageIndex: number, pageCount: number): number;
19
+ /**
20
+ * Reconcile in-memory column-filter state with the URL `cf` param, which is the
21
+ * source of truth. Returns `prev` unchanged when it already serializes to the
22
+ * same string as `cfParam` — this both preserves referential identity (no
23
+ * needless re-render) and stops the setState → syncFiltersToUrl → cfParam →
24
+ * effect cycle from looping on our own writes. Otherwise it deserializes the URL
25
+ * value so browser back/forward and table switches (which drop the query string)
26
+ * drive the filters instead of leaving stale state behind.
27
+ */
28
+ export declare function reconcileColumnFiltersFromUrl(prev: ColumnFiltersState, cfParam: string): ColumnFiltersState;
16
29
  export declare function getMultiJoinRows(row: RowData, join: Join): RowData[];
30
+ /**
31
+ * Reads the joined parent object a single-link column renders.
32
+ *
33
+ * Keyed on the join's FIELD name, not its destination table: a table that
34
+ * references the same target through several foreign keys has one field per key
35
+ * (billing_address, shipping_address) and no field named for the table, so a
36
+ * lookup by table name finds nothing and the cell renders as null. Mirrors
37
+ * getMultiJoinRows, which has always had to do this for aliased child
38
+ * collections.
39
+ */
40
+ export declare function getSingleJoinRow(row: RowData, join: Join): RowData | undefined;
41
+ export declare function getMultiJoinTotal(row: RowData, join: Join): number;
17
42
  /**
18
43
  * Return type for the useDataTable hook.
19
44
  * @interface UseDataTableResult
@@ -35,8 +60,33 @@ interface UseDataTableResult {
35
60
  pageCount: number;
36
61
  /** Current page data rows */
37
62
  rows: RowData[];
38
- /** Whether data is currently loading */
63
+ /** Total matching rows for the active filter/sort (across all pages). */
64
+ totalRows: number;
65
+ /** Server aggregate rows for URL-selected grouping; never derived from the page. */
66
+ grouping: {
67
+ column: Column;
68
+ sumColumn: Column | null;
69
+ rows: GroupingRow[];
70
+ loading: boolean;
71
+ error: Error | null;
72
+ sort: GroupingSort;
73
+ onSortChange: (sort: GroupingSort) => void;
74
+ memberRequest: (value: unknown) => GridGroupMemberRequest;
75
+ } | null;
76
+ /**
77
+ * Export the FULL result set for the current filters + sort, paging through
78
+ * the same fetcher/query — not just the visible page. Null when there is no
79
+ * active query/table to export.
80
+ */
81
+ exportRows: ExportRunner;
82
+ /** Whether data is currently loading (no rows to show yet) */
39
83
  loading: boolean;
84
+ /**
85
+ * A refresh is in flight while previous rows remain on screen as
86
+ * placeholder data (page turn, sort, filter change). Drives the grid's
87
+ * in-flight indicator; `loading` alone blanks the rows.
88
+ */
89
+ fetching: boolean;
40
90
  /** Error object if the query failed */
41
91
  error: Error | null;
42
92
  /** Update sorting state */
@@ -47,6 +97,9 @@ interface UseDataTableResult {
47
97
  onPageIndexChange: (pageIndex: number) => void;
48
98
  /** Update page size */
49
99
  onPageSizeChange: (pageSize: number) => void;
100
+ /** Rewrites only the URL-owned grouping parameter. */
101
+ onGroupingChange: (columnName: string | null) => void;
102
+ onGroupingSumChange: (columnName: string | null) => void;
50
103
  }
51
104
  /**
52
105
  * Hook for managing data table state including sorting, filtering, and pagination.
@@ -65,15 +118,15 @@ interface UseDataTableResult {
65
118
  * pageCount,
66
119
  * onSortingChange,
67
120
  * onPageIndexChange,
68
- * } = useDataTable(table, recordId, parentTable);
121
+ * } = useDataTable(table, id, filterTable);
69
122
  * ```
70
123
  *
71
124
  * @param table - Table schema definition
72
- * @param id - Optional record ID for filtering to a specific row
125
+ * @param id - Optional row ID for filtering to a specific row
73
126
  * @param filterTable - Optional parent table name for relationship filtering
74
127
  * @param filterColumn - Optional column name for explicit FK filtering
75
128
  * @param onExpandContent - Callback when content expansion is requested
76
129
  * @param onOpenColumn - Callback when opening a side panel column
77
130
  * @returns Data table state and control functions
78
131
  */
79
- export declare function useDataTable(table: Table | null, id?: string, filterTable?: string, filterColumn?: string, onExpandContent?: (rowIndex: number, columnName: string) => void, onOpenColumn?: (panel: ColumnPanel) => void): UseDataTableResult;
132
+ export declare function useDataTable(table: Table | null, id?: string, filterTable?: string, filterColumn?: string, onExpandContent?: (rowIndex: number, columnName: string) => void, onOpenColumn?: (panel: DrillFrame) => void): UseDataTableResult;
@@ -0,0 +1,19 @@
1
+ export interface DebouncedCommit {
2
+ /** Debounce `commit`: it replaces any pending commit and runs after the delay. */
3
+ schedule: (commit: () => void) => void;
4
+ /** Drop the pending commit (if any) without running it. */
5
+ cancel: () => void;
6
+ /** Run the pending commit (if any) immediately instead of waiting out the delay. */
7
+ flush: () => void;
8
+ }
9
+ /**
10
+ * Debounce a commit callback with a pending-flush guarantee: the last scheduled
11
+ * commit either runs after `delayMs`, runs early via `flush()`, or is dropped
12
+ * via `cancel()` — and a pending commit is flushed automatically on unmount, so
13
+ * a value entered just before the host unmounts (e.g. Radix closing a dropdown
14
+ * that contains the filter input) isn't silently lost.
15
+ *
16
+ * Shared by the column-filter widgets so debounce/flush bookkeeping isn't
17
+ * re-implemented per filter type.
18
+ */
19
+ export declare function useDebouncedCommit(delayMs: number): DebouncedCommit;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ import { Table } from '../types/schema';
2
+ /**
3
+ * The server's collection-diff save shape (`<t>_delta`): three optional lists
4
+ * that apply in inserted → updated → deleted order inside ONE transaction — a
5
+ * failure anywhere applies nothing — and ride the server's set-based bulk fast
6
+ * path at batch scale. Payloads must already be wire-ready (coerceDetail /
7
+ * delete key payloads); this hook only carries the document.
8
+ */
9
+ export interface DeltaDocument {
10
+ inserted?: Record<string, unknown>[];
11
+ updated?: Record<string, unknown>[];
12
+ deleted?: Record<string, unknown>[];
13
+ }
14
+ export interface UseDeltaMutationResult {
15
+ saveDelta: (delta: DeltaDocument) => Promise<unknown>;
16
+ isPending: boolean;
17
+ error: Error | null;
18
+ }
19
+ export declare function deltaChangeCount(delta: DeltaDocument): number;
20
+ export declare function useDeltaMutation(table: Table): UseDeltaMutationResult;
File without changes
@@ -1,4 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
+ import { TableAction } from '../lib/table-action';
2
3
  /**
3
4
  * Optional, opt-in editor features. Kept tiny and separate from the data/schema
4
5
  * contexts so feature flags don't force those providers to re-render and so
@@ -11,6 +12,32 @@ export interface EditorConfig {
11
12
  * may not want on every connect. Hosts opt in via `<Editor showStats />`.
12
13
  */
13
14
  showStats: boolean;
15
+ /**
16
+ * Restrict the editor to these tables, by GraphQL name or db name. Undefined
17
+ * exposes everything the server returns — which on a managed host also means
18
+ * its own bookkeeping tables (Azure SQL surfaces firewall rules this way).
19
+ * Filtering here rather than in the sidebar keeps excluded tables out of
20
+ * routing and FK lookups too, not just out of the list.
21
+ */
22
+ tables?: string[];
23
+ /**
24
+ * Columns visible by default per table, keyed by table name; every other
25
+ * column starts hidden. Only the starting point — a viewer's own choices are
26
+ * stored per table and win from then on.
27
+ */
28
+ defaultColumns?: Record<string, string[]>;
29
+ /**
30
+ * Columns to move to the right end of every grid, in this order. For audit
31
+ * stamps (created/modified) that are read far less often than the data they
32
+ * annotate but sit in the middle of the natural column order.
33
+ */
34
+ trailingColumns?: string[];
35
+ /**
36
+ * Host-contributed actions on each table in the navigation list, rendered in
37
+ * the table's kebab menu AFTER the built-in Download actions. The host owns
38
+ * what an action does; edit-db just invokes it with the schema table.
39
+ */
40
+ tableActions?: TableAction[];
14
41
  }
15
42
  export declare function EditorConfigProvider({ config, children }: {
16
43
  config: EditorConfig;
@@ -0,0 +1,23 @@
1
+ import { RefObject } from 'react';
2
+ /** Sentinel page-size value meaning "fit as many rows as the viewport allows". */
3
+ export declare const FIT_SENTINEL = -1;
4
+ /**
5
+ * Rows that fit a container of `containerHeight` px: header subtracted, floor
6
+ * to whole rows, never below 5. The single source of the fit formula — the
7
+ * hook and its tests both use this.
8
+ */
9
+ export declare function computeFitRowCount(containerHeight: number): number;
10
+ export interface UseFitModeResult {
11
+ fitMode: boolean;
12
+ setFitMode: React.Dispatch<React.SetStateAction<boolean>>;
13
+ /** Rows that fit the current scroll container height. */
14
+ computeFitSize: () => number;
15
+ }
16
+ /**
17
+ * "Fit" page-sizing: derive the page size from the scroll container's height so
18
+ * the grid shows exactly as many rows as fit, re-fitting when the container
19
+ * resizes. The resize path is debounced so dragging a splitter/window doesn't
20
+ * fire a burst of queries (each distinct page size is a new query key) — only
21
+ * the settled size runs.
22
+ */
23
+ export declare function useFitMode(scrollRef: RefObject<HTMLDivElement>, onPageSizeChange: (pageSize: number) => void): UseFitModeResult;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Persistent, drag-resizable panel dimension.
3
+ *
4
+ * Returns the current size plus a pointerdown handler to put on a separator
5
+ * element. Dragging follows the pointer along the given axis; the size is
6
+ * clamped to [min, max] and persisted per `key` so a layout survives reload.
7
+ * `invert` flips the drag direction for separators that sit BEFORE the panel
8
+ * they size (e.g. a bottom panel resized by the handle above it: dragging the
9
+ * handle UP must grow the panel).
10
+ *
11
+ * The separator also supports keyboard resizing (arrow keys, 16px steps) via
12
+ * the returned onKeyDown — a drag-only separator is unreachable to keyboard
13
+ * users. Callers should render the handle with role="separator" and an
14
+ * aria-orientation matching the axis.
15
+ */
16
+ export interface PanelSizeOptions {
17
+ key: string;
18
+ initial: number;
19
+ min: number;
20
+ max: number;
21
+ axis: 'x' | 'y';
22
+ invert?: boolean;
23
+ }
24
+ export declare function usePanelSize({ key, initial, min, max, axis, invert }: PanelSizeOptions): {
25
+ size: number;
26
+ onPointerDown: (e: React.PointerEvent<HTMLElement>) => void;
27
+ onKeyDown: (e: React.KeyboardEvent<HTMLElement>) => void;
28
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -23,10 +23,6 @@ interface SearchParamsResult {
23
23
  search: URLSearchParams;
24
24
  hash: string;
25
25
  }
26
- interface RouteError {
27
- message?: string;
28
- status?: number;
29
- }
30
26
  interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
31
27
  to: string;
32
28
  children?: ReactNode;
@@ -41,7 +37,6 @@ export declare function useNavigate(): (url: string) => void;
41
37
  export declare function useNavigation(): NavigationState;
42
38
  export declare function useParams<T extends RouteParams = RouteParams>(): T;
43
39
  export declare function useSearchParams(): SearchParamsResult;
44
- export declare function useRouteError(): RouteError;
45
40
  export declare function PathProvider({ path, children }: {
46
41
  path: string;
47
42
  children: ReactNode;
@@ -68,4 +63,6 @@ export declare function Route({ path, element }: {
68
63
  path: string;
69
64
  element: ReactElement;
70
65
  }): ReactElement;
66
+ export declare const combinePaths: (current: string, newPath: string) => string;
67
+ export declare const matchPath: (route: string, path: string) => PathMatch;
71
68
  export {};
@@ -0,0 +1,26 @@
1
+ import { PointerEvent, MutableRefObject } from 'react';
2
+ export interface HoveredRow {
3
+ rowId: string;
4
+ el: HTMLElement;
5
+ }
6
+ export interface UseRowHoverActionsResult {
7
+ hoveredRow: HoveredRow | null;
8
+ hoverRow: (rowId: string, el: HTMLElement) => void;
9
+ scheduleDismiss: () => void;
10
+ cancelDismiss: () => void;
11
+ /** Suppresses the click that follows a long-press so it doesn't also select the row. */
12
+ suppressClick: MutableRefObject<boolean>;
13
+ startPress: (rowId: string, el: HTMLElement, e: PointerEvent) => void;
14
+ onPressMove: () => void;
15
+ cancelPress: () => void;
16
+ }
17
+ /**
18
+ * Row hover/long-press action tracking for the data grid.
19
+ *
20
+ * Mouse: hovering a row opens its action toolbar (with a small dismiss delay so
21
+ * moving onto the toolbar doesn't close it). Touch: a long-press (hold) opens
22
+ * the same actions since hover doesn't exist on touch; a finger move (scroll)
23
+ * cancels the press, and a fired press suppresses the click that follows the
24
+ * lift so it doesn't also select.
25
+ */
26
+ export declare function useRowHoverActions(): UseRowHoverActionsResult;
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { Schema } from '../types/schema';
2
+ import { SchemaContextValue, Table } from '../types/schema';
3
3
  /**
4
4
  * Provider component for database schema context.
5
5
  * Fetches schema via GraphQL and makes it available to child components.
@@ -28,4 +28,10 @@ export declare const SchemaProvider: ({ children }: {
28
28
  *
29
29
  * @returns Schema context value with tables and metadata
30
30
  */
31
- export declare function useSchema(): Schema;
31
+ export declare function useSchema(): SchemaContextValue;
32
+ /**
33
+ * Keep only the tables a host allow-listed, matching on either name and ignoring
34
+ * case so a host can list them the way they read in its own docs. An empty or
35
+ * absent list means no restriction.
36
+ */
37
+ export declare function filterAllowedTables(tables: Table[], allowed?: string[]): Table[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { Table } from '../types/schema';
2
+ import { ExportFormat, ExportResult } from '../lib/export';
3
+ /**
4
+ * Downloads a whole table WITHOUT opening it: the navigation-level counterpart
5
+ * of the grid toolbar's export. Reuses the grid's export projection
6
+ * (`buildQuery` with `fields: 'export'` — long text included, non-PK binary
7
+ * excluded, no join blocks), the shared page-draining serializer, and the same
8
+ * browser download path, so the two exports cannot drift. Unfiltered by design:
9
+ * a filtered export belongs to the grid, where the filters live.
10
+ * <see cref="DEFAULT_ROW_CAP"/> bounds the drain; the result reports
11
+ * `truncated` so the caller can warn instead of silently shipping a partial file.
12
+ */
13
+ export declare function useTableExport(): (table: Table, format: ExportFormat) => Promise<ExportResult>;
@@ -1,7 +1,5 @@
1
1
  import { Table, Column } from '../types/schema';
2
- interface ColumnJoin {
3
- column: Column;
4
- }
2
+ import { ColumnJoin } from '../lib/mutation-payload';
5
3
  export interface UseTableMutationResult {
6
4
  update: (detail: Record<string, unknown>) => Promise<unknown>;
7
5
  insert: (detail: Record<string, unknown>) => Promise<unknown>;
@@ -9,4 +7,3 @@ export interface UseTableMutationResult {
9
7
  error: Error | null;
10
8
  }
11
9
  export declare function useTableMutation(table: Table, editColumns: ColumnJoin[], idColumns: Column[], editId?: string): UseTableMutationResult;
12
- export {};
File without changes
@@ -1,5 +1,4 @@
1
- import { Schema } from '../types/schema';
2
- export declare function useTableRef(schema: Schema, tableName: string, columnName: string): TableRef;
1
+ import { SchemaContextValue } from '../types/schema';
3
2
  export interface TableRefValue {
4
3
  key: string;
5
4
  label: string;
@@ -8,4 +7,26 @@ export interface TableRef {
8
7
  loading: boolean;
9
8
  error: unknown;
10
9
  data: TableRefValue[];
10
+ /** True when `search` narrows server-side (String label column, `_contains`);
11
+ * false means the caller must filter the fetched window client-side. */
12
+ serverSearch: boolean;
11
13
  }
14
+ /**
15
+ * Fetch the option rows for an FK dropdown (key + label per parent row).
16
+ * When `search` is non-empty and the parent's label column is String-typed the
17
+ * list is narrowed server-side, so parents beyond the fetch window stay
18
+ * findable; otherwise one window is fetched and the caller filters it.
19
+ */
20
+ export declare function useTableRef(schema: SchemaContextValue, tableName: string, columnName: string, search?: string, enabled?: boolean): TableRef;
21
+ export interface TableRefLookup {
22
+ loading: boolean;
23
+ error: unknown;
24
+ value: TableRefValue | null;
25
+ }
26
+ /**
27
+ * Resolve key + label for a single parent row by its key value. Used when the
28
+ * currently stored FK value falls outside the fetched dropdown window, so the
29
+ * Select can still display the stored value instead of a misleading
30
+ * placeholder. Pass `key` as null/'' to disable the lookup.
31
+ */
32
+ export declare function useTableRefValue(schema: SchemaContextValue, tableName: string, columnName: string, key: unknown): TableRefLookup;
@@ -0,0 +1 @@
1
+ export {};
@@ -33,6 +33,13 @@ export interface UseTableStatsResult {
33
33
  message: string;
34
34
  } | null;
35
35
  }
36
+ /**
37
+ * Builds a GraphQL query to fetch row counts for all tables.
38
+ *
39
+ * @param tableNames - Array of table GraphQL names
40
+ * @returns GraphQL query string
41
+ */
42
+ export declare function buildRowCountQuery(tableNames: string[]): string | null;
36
43
  /**
37
44
  * Hook to fetch table statistics including row counts.
38
45
  *
@@ -50,27 +57,3 @@ export interface UseTableStatsResult {
50
57
  * @returns Table statistics map and loading state
51
58
  */
52
59
  export declare function useTableStats(enabled?: boolean): UseTableStatsResult;
53
- /**
54
- * Formats a number into an abbreviated string representation.
55
- *
56
- * @example
57
- * ```typescript
58
- * abbreviateNumber(12) // "12"
59
- * abbreviateNumber(1200) // "1.2k"
60
- * abbreviateNumber(45000) // "45k"
61
- * abbreviateNumber(1200000) // "1.2M"
62
- * ```
63
- *
64
- * @param num - Number to abbreviate
65
- * @returns Abbreviated string representation
66
- */
67
- export declare function abbreviateNumber(num: number | null): string;
68
- /**
69
- * Calculates a visual bar width (1-10) based on row count.
70
- * Used for sparkline visualization.
71
- *
72
- * @param count - Row count
73
- * @param maxCount - Maximum row count across all tables for scaling
74
- * @returns Width value from 1-10
75
- */
76
- export declare function calculateBarWidth(count: number | null, maxCount: number): number;
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * Minimal dependency-free toast system for transient success/error feedback
4
+ * after mutations (create, save, delete, inline content edits). Kept small and
5
+ * self-contained so the published editor pulls in no extra runtime dependency.
6
+ */
7
+ export type ToastVariant = 'success' | 'error';
8
+ interface ToastApi {
9
+ toast: (message: string, variant?: ToastVariant) => void;
10
+ }
11
+ export declare function ToastProvider({ children }: {
12
+ children: ReactNode;
13
+ }): import("react").JSX.Element;
14
+ export declare function useToast(): ToastApi;
15
+ export {};
package/dist/index.d.ts CHANGED
@@ -2,6 +2,18 @@ import { Editor } from './editor';
2
2
  export default Editor;
3
3
  export { Editor };
4
4
  export type { GraphQLFetcher } from './common/fetcher';
5
- export { HttpGraphQLFetcher } from './common/fetcher';
5
+ export { HttpGraphQLFetcher, GraphQLRequestError } from './common/fetcher';
6
6
  export { useTableMutation } from './hooks/useTableMutation';
7
7
  export type { UseTableMutationResult } from './hooks/useTableMutation';
8
+ export { createSavedObjectsClient, parseSavedObject, SavedObjectConflictError, SAVED_OBJECTS_PATH, } from './common/saved-objects';
9
+ export type { SavedObject, SavedObjectType, SavedObjectsClient, } from './common/saved-objects';
10
+ export { FormRunner, FormRunnerView, resolveDefinitionTable } from './components/form-runner';
11
+ export { FormRunnerHost } from './components/form-runner-host';
12
+ export { parseFormDefinition, visibleFields } from './lib/form-definition';
13
+ export type { FormDefinition, FormField, FormControlType } from './lib/form-definition';
14
+ export type { FieldWidgetHint } from './lib/form-widget';
15
+ export { buildCsv, buildJson, formatCsvCell, exportAllRows, downloadTextFile, filenameFor, mimeFor, UTF8_BOM, DEFAULT_ROW_CAP, } from './lib/export';
16
+ export type { ExportFormat, JsonMode, CsvOptions, JsonOptions, ExportPage, ExportResult, ExportRunner, RunExportOptions, } from './lib/export';
17
+ export { serializeColumnFilters, deserializeColumnFilters } from './lib/query-builder';
18
+ export type { TableAction } from './lib/table-action';
19
+ export type { Table, Column } from './types/schema';
@@ -0,0 +1,17 @@
1
+ import { ColumnDef } from '@tanstack/react-table';
2
+ export interface ColumnOrderConfig {
3
+ /** Columns to place first, in this order. */
4
+ leading?: string[];
5
+ /** Columns to place last, in this order. */
6
+ trailing?: string[];
7
+ }
8
+ /**
9
+ * Reorder columns around a host's preferences: named leading columns first in the
10
+ * order named, named trailing columns last in the order named, everything else
11
+ * keeping its schema order in between. Names the table doesn't have are skipped,
12
+ * so one host config can cover tables that don't all carry the same columns.
13
+ *
14
+ * Order is independent of visibility: a column the viewer switches back on lands
15
+ * in its configured place rather than at the end.
16
+ */
17
+ export declare function orderColumns<TData>(columns: ColumnDef<TData, unknown>[], { leading, trailing }: ColumnOrderConfig): ColumnDef<TData, unknown>[];
@@ -0,0 +1 @@
1
+ export {};