@jini-ai/admin 0.1.0 → 0.3.6

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,4 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
+ import type { DataTableSortDirection, DataTableSortState } from '../../core/data-table/types.js';
2
3
  /**
3
4
  * @file The admin list table.
4
5
  *
@@ -12,16 +13,37 @@ import type { ReactNode } from 'react';
12
13
  *
13
14
  * What the corpus did **not** contain is just as load-bearing:
14
15
  *
15
- * - **No sorting.** Zero of 25.
16
16
  * - **No pagination.** Zero of 25.
17
17
  * - **No row selection.** Zero of 25 — the checkboxes that appear inside some of those tables are
18
18
  * field controls belonging to the row's own data, not a selection model.
19
19
  *
20
- * None of the three is implemented here. A table component that ships sorting nobody asked for has
21
- * to guess at comparator semantics, controlled-vs-uncontrolled state, and multi-column precedence,
22
- * and every one of those guesses becomes a compatibility obligation the moment it ships. When a
23
- * host needs sorting, it will arrive with a real requirement attached and can be added then —
24
- * additively, since `columns` is already a descriptor list with somewhere to put it.
20
+ * Pagination and row selection stay cut for the same reason sorting originally was: nobody in the
21
+ * corpus asked for either, and guessing at their shape (page-size defaults, single- vs. multi-select)
22
+ * would be a compatibility obligation nobody has paid for yet.
23
+ *
24
+ * ## Sorting (added once two hosts needed it)
25
+ *
26
+ * Sorting **did** ship — this component's own history is the case study for the plan above. Posts
27
+ * and Pages both hand-rolled an identical click-to-sort header (a button, a caret, an `aria-label`
28
+ * carrying the accessible state) because this component had nowhere to put it, and more screens were
29
+ * about to make it a third and fourth copy. The three guesses the original cut worried about each
30
+ * resolved to something concrete once real callers existed:
31
+ *
32
+ * - **Comparator semantics** — a column that wants to sort supplies
33
+ * {@link DataTableColumnSort.compare}, an ascending-order comparator exactly like `Array#sort`'s
34
+ * own contract. `DataTable` negates it for `"desc"` rather than taking two functions — a column's
35
+ * ordering is one relation, not two.
36
+ * - **Controlled vs. uncontrolled** — controlled, via {@link DataTableProps.sort} and
37
+ * {@link DataTableProps.onSortChange}. `DataTable` holds no sort state of its own: direction is
38
+ * transient view state the owning screen already held before this existed, and centralizing the
39
+ * comparator/caret/`aria-sort` plumbing does not change who owns that state.
40
+ * - **Multi-column precedence** — not built. Exactly one column sorts at a time: activating a
41
+ * different sortable column's header replaces the active one outright; activating the same
42
+ * column's header again toggles its direction. Nobody asked for combined multi-column sort.
43
+ *
44
+ * A column that omits {@link DataTableColumn.sort} renders its `<th>` exactly as it always has — no
45
+ * button, no caret, no `aria-sort` — so every existing caller that never mentions sorting sees no
46
+ * change at all.
25
47
  *
26
48
  * `<tfoot>` appeared exactly once, so it is an optional prop rather than part of the core shape.
27
49
  *
@@ -42,8 +64,30 @@ import type { ReactNode } from 'react';
42
64
  * a wide table scroll instead of breaking the page, and it is also why `RowMenu` portals its popup
43
65
  * out to `document.body` rather than positioning inside this box.
44
66
  */
67
+ export type { DataTableSortDirection, DataTableSortState };
68
+ /** Enables click-to-sort on one column (`DataTableColumn.sort`). Everything a host needs to decide
69
+ * is here; `DataTable` only wires the click, renders the caret, and sets `aria-sort`. */
70
+ export interface DataTableColumnSort<Row> {
71
+ /** Ascending-order comparator, exactly like `Array#sort`'s own contract. `DataTable` negates its
72
+ * result when the active direction is `"desc"` rather than asking for a second function — a
73
+ * column's ordering is one relation, not two. Reach for `Date.parse` on an ISO-8601 **text**
74
+ * column (never a plain string compare — that breaks the moment a non-`Z` UTC-offset value shows
75
+ * up) and `localeCompare` for free text. */
76
+ compare: (a: Row, b: Row) => number;
77
+ /** Direction this column starts at the first time it becomes active — a click while a DIFFERENT
78
+ * column was active, or the first sort of a session. Defaults to `"asc"`; override for a column
79
+ * whose natural first read runs the other way, e.g. a date column's "newest first". Has no effect
80
+ * on the same column's own toggle, which always flips. */
81
+ defaultDirection?: DataTableSortDirection;
82
+ /** This column's accessible name for every sort state — `direction` is `null` when a different
83
+ * column is currently active. State the current state and what activating the control does next;
84
+ * `DataTable` does not synthesize this from `header`, since `header` may be arbitrary markup with
85
+ * no reliable plain-text form. */
86
+ label: (direction: DataTableSortDirection | null) => string;
87
+ }
45
88
  export interface DataTableColumn<Row> {
46
- /** Stable identity for this column. Not rendered — used as the React key. */
89
+ /** Stable identity for this column. Not rendered — used as the React key, and as the `column`
90
+ * value in {@link DataTableSortState} when this column is sortable. */
47
91
  key: string;
48
92
  /** Header content. Omit for a column that carries no visible heading (a row-actions column);
49
93
  * supply {@link headerLabel} when you do, so the column is still named for assistive tech. */
@@ -56,6 +100,9 @@ export interface DataTableColumn<Row> {
56
100
  headerClassName?: string;
57
101
  /** Class on this column's `<td>`. A function receives the row, for per-row variation. */
58
102
  cellClassName?: string | ((row: Row, index: number) => string | undefined);
103
+ /** Makes this column's header clickable to sort. Omit for a column that never sorts — its `<th>`
104
+ * renders exactly as it always has, with no button, no caret, and no `aria-sort`. */
105
+ sort?: DataTableColumnSort<Row>;
59
106
  }
60
107
  export interface DataTableProps<Row> {
61
108
  rows: readonly Row[];
@@ -89,9 +136,24 @@ export interface DataTableProps<Row> {
89
136
  className?: string;
90
137
  /** Appended to `.table-scroll`. */
91
138
  scrollClassName?: string;
139
+ /**
140
+ * Controlled sort state: the active column's `key` plus direction, or `null`/`undefined` for "no
141
+ * column is the active sort". `DataTable` never derives or persists this itself — sort direction
142
+ * is transient view state the owning screen already held before this existed; centralizing the
143
+ * comparator/caret/`aria-sort` plumbing here does not change who owns that state.
144
+ */
145
+ sort?: DataTableSortState | null;
146
+ /**
147
+ * Called with the state a header click produces. Activating a different sortable column's header
148
+ * replaces `sort` outright (single active column — no multi-column precedence); activating the
149
+ * already-active column's header toggles its direction. `DataTable` computes the next value; the
150
+ * host only stores it and passes it back as `sort`.
151
+ */
152
+ onSortChange?: (next: DataTableSortState) => void;
92
153
  }
93
154
  /**
94
- * @complexity O(rows × columns) per render — one pass, no sorting or grouping work.
155
+ * @complexity O(rows × columns) per render for cell rendering, same as always; see
156
+ * {@link sortedTableRows} for the one added cost, paid only when `sort` names an active column.
95
157
  */
96
158
  export declare function DataTable<Row>(props: DataTableProps<Row>): import("react").JSX.Element;
97
159
  //# sourceMappingURL=DataTable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/react/components/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,MAAM,WAAW,eAAe,CAAC,GAAG;IAClC,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ;mGAC+F;IAC/F,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAC7C,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;CAC5E;AAED,MAAM,WAAW,cAAc,CAAC,GAAG;IACjC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C;;2DAEuD;IACvD,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;qBAGiB;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,wEAAwE;IACxE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;4BACwB;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,sEAAsE;IACtE,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC/D,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAYD;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,+BAwCxD"}
1
+ {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/react/components/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEjG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAIH,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,CAAC;AAE3D;0FAC0F;AAC1F,MAAM,WAAW,mBAAmB,CAAC,GAAG;IACtC;;;;iDAI6C;IAC7C,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,MAAM,CAAC;IACpC;;;+DAG2D;IAC3D,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C;;;uCAGmC;IACnC,KAAK,EAAE,CAAC,SAAS,EAAE,sBAAsB,GAAG,IAAI,KAAK,MAAM,CAAC;CAC7D;AAED,MAAM,WAAW,eAAe,CAAC,GAAG;IAClC;4EACwE;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ;mGAC+F;IAC/F,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAC7C,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3E;0FACsF;IACtF,IAAI,CAAC,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,cAAc,CAAC,GAAG;IACjC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IACrB,OAAO,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C;;2DAEuD;IACvD,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;qBAGiB;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,wEAAwE;IACxE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;4BACwB;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,sEAAsE;IACtE,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC/D,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACjC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACnD;AAmED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,+BAiExD"}
@@ -5,7 +5,56 @@ function resolveCellClassName(column, row, index) {
5
5
  : column.cellClassName;
6
6
  }
7
7
  /**
8
- * @complexity O(rows × columns) per render — one pass, no sorting or grouping work.
8
+ * `rows` in display order: unchanged when there is no active sort, or the active column declares no
9
+ * `sort` of its own (defensive against a stale `sort.column` naming a column that no longer exists,
10
+ * or never did). A fresh array is only allocated on the path that actually sorts, so the 20+ callers
11
+ * with no `sort` prop at all pay nothing beyond the `Array#find`.
12
+ *
13
+ * @complexity O(columns) to find the active column, plus O(n log n) in `rows.length` when it has a
14
+ * comparator; O(1)/no allocation otherwise.
15
+ */
16
+ function sortedTableRows(rows, columns, sort) {
17
+ const activeColumn = sort ? columns.find((column) => column.key === sort.column) : undefined;
18
+ if (!sort || !activeColumn?.sort)
19
+ return rows;
20
+ const sign = sort.direction === 'asc' ? 1 : -1;
21
+ const { compare } = activeColumn.sort;
22
+ return [...rows].sort((a, b) => sign * compare(a, b));
23
+ }
24
+ /**
25
+ * The sort state a click on `column`'s header produces: toggles direction when `column` is already
26
+ * active, otherwise switches to it at its own {@link DataTableColumnSort.defaultDirection}.
27
+ *
28
+ * @complexity Time/space: O(1).
29
+ */
30
+ function nextSortState(current, column) {
31
+ if (current?.column === column.key) {
32
+ return { column: column.key, direction: current.direction === 'asc' ? 'desc' : 'asc' };
33
+ }
34
+ return { column: column.key, direction: column.sort?.defaultDirection ?? 'asc' };
35
+ }
36
+ /** The `aria-sort` value for a sortable `<th>` — the APG table-sorting pattern's `"none"` for a
37
+ * sortable-but-currently-inactive column, so assistive tech still discovers it is sortable. */
38
+ function ariaSortValue(direction) {
39
+ if (direction === 'asc')
40
+ return 'ascending';
41
+ if (direction === 'desc')
42
+ return 'descending';
43
+ return 'none';
44
+ }
45
+ /** The caret glyph for a sortable header. `"⇅"` — a neutral, always-visible both-direction glyph —
46
+ * when `direction` is `null` (not the active sort), so an unsorted column still visibly reads as
47
+ * clickable rather than only revealing that fact after the first click; `"▲"`/`"▼"` once it is.
48
+ * `aria-hidden` at the call site: the real accessible state is the button's `aria-label` plus the
49
+ * `<th>`'s own `aria-sort`, not this glyph. */
50
+ function sortCaretGlyph(direction) {
51
+ if (direction === null)
52
+ return ' ⇅';
53
+ return direction === 'asc' ? ' ▲' : ' ▼';
54
+ }
55
+ /**
56
+ * @complexity O(rows × columns) per render for cell rendering, same as always; see
57
+ * {@link sortedTableRows} for the one added cost, paid only when `sort` names an active column.
9
58
  */
10
59
  export function DataTable(props) {
11
60
  // Loading wins over empty deliberately: `rows` is legitimately `[]` during a first fetch, and
@@ -15,6 +64,13 @@ export function DataTable(props) {
15
64
  return _jsx(_Fragment, { children: props.loadingContent });
16
65
  if (!props.loading && props.rows.length === 0 && props.empty !== undefined)
17
66
  return _jsx(_Fragment, { children: props.empty });
18
- return (_jsx("div", { className: ['table-scroll', props.scrollClassName].filter(Boolean).join(' '), children: _jsxs("table", { className: ['list-table', props.className].filter(Boolean).join(' '), "aria-label": props.label, children: [props.caption === undefined ? null : _jsx("caption", { children: props.caption }), _jsx("thead", { children: _jsx("tr", { children: props.columns.map((column) => (_jsx("th", { scope: "col", className: column.headerClassName, "aria-label": column.header === undefined ? column.headerLabel : undefined, children: column.header }, column.key))) }) }), _jsx("tbody", { children: props.rows.map((row, index) => (_jsx("tr", { className: props.rowClassName?.(row, index), children: props.columns.map((column) => (_jsx("td", { className: resolveCellClassName(column, row, index), children: column.cell(row, index) }, column.key))) }, props.rowKey(row, index)))) }), props.footer === undefined ? null : _jsx("tfoot", { children: props.footer })] }) }));
67
+ const rows = sortedTableRows(props.rows, props.columns, props.sort);
68
+ return (_jsx("div", { className: ['table-scroll', props.scrollClassName].filter(Boolean).join(' '), children: _jsxs("table", { className: ['list-table', props.className].filter(Boolean).join(' '), "aria-label": props.label, children: [props.caption === undefined ? null : _jsx("caption", { children: props.caption }), _jsx("thead", { children: _jsx("tr", { children: props.columns.map((column) => {
69
+ if (!column.sort) {
70
+ return (_jsx("th", { scope: "col", className: column.headerClassName, "aria-label": column.header === undefined ? column.headerLabel : undefined, children: column.header }, column.key));
71
+ }
72
+ const direction = props.sort?.column === column.key ? props.sort.direction : null;
73
+ return (_jsx("th", { scope: "col", className: column.headerClassName, "aria-sort": ariaSortValue(direction), children: _jsxs("button", { type: "button", className: "sortable-column-header", onClick: () => props.onSortChange?.(nextSortState(props.sort, column)), "aria-label": column.sort.label(direction), children: [column.header, _jsx("span", { "aria-hidden": "true", children: sortCaretGlyph(direction) })] }) }, column.key));
74
+ }) }) }), _jsx("tbody", { children: rows.map((row, index) => (_jsx("tr", { className: props.rowClassName?.(row, index), children: props.columns.map((column) => (_jsx("td", { className: resolveCellClassName(column, row, index), children: column.cell(row, index) }, column.key))) }, props.rowKey(row, index)))) }), props.footer === undefined ? null : _jsx("tfoot", { children: props.footer })] }) }));
19
75
  }
20
76
  //# sourceMappingURL=DataTable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.js","sourceRoot":"","sources":["../../../src/react/components/DataTable.tsx"],"names":[],"mappings":";AAgGA,SAAS,oBAAoB,CAC3B,MAA4B,EAC5B,GAAQ,EACR,KAAa;IAEb,OAAO,OAAO,MAAM,CAAC,aAAa,KAAK,UAAU;QAC/C,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC;QAClC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAM,KAA0B;IACvD,8FAA8F;IAC9F,6FAA6F;IAC7F,SAAS;IACT,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS;QAAE,OAAO,4BAAG,KAAK,CAAC,cAAc,GAAI,CAAC;IAC5F,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,4BAAG,KAAK,CAAC,KAAK,GAAI,CAAC;IAEtG,OAAO,CACL,cAAK,SAAS,EAAE,CAAC,cAAc,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAC/E,iBAAO,SAAS,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAc,KAAK,CAAC,KAAK,aACjG,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,4BAAU,KAAK,CAAC,OAAO,GAAW,EACxE,0BACE,uBACG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC7B,aAEE,KAAK,EAAC,KAAK,EACX,SAAS,EAAE,MAAM,CAAC,eAAe,gBACrB,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,YAEvE,MAAM,CAAC,MAAM,IALT,MAAM,CAAC,GAAG,CAMZ,CACN,CAAC,GACC,GACC,EACR,0BACG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAC9B,aAAmC,SAAS,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,YAC3E,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC7B,aAAqB,SAAS,EAAE,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,YACrE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IADjB,MAAM,CAAC,GAAG,CAEd,CACN,CAAC,IALK,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAM5B,CACN,CAAC,GACI,EACP,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,0BAAQ,KAAK,CAAC,MAAM,GAAS,IAC5D,GACJ,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"DataTable.js","sourceRoot":"","sources":["../../../src/react/components/DataTable.tsx"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@ export { ConfirmDialog } from './components/ConfirmDialog/ConfirmDialog.js';
39
39
  export type { ConfirmDialogProps } from './components/ConfirmDialog/ConfirmDialog.js';
40
40
  export type { ConfirmDialogController, UseConfirmDialog } from './components/ConfirmDialog/ConfirmDialog.hooks.js';
41
41
  export { DataTable } from './components/DataTable.js';
42
- export type { DataTableColumn, DataTableProps } from './components/DataTable.js';
42
+ export type { DataTableColumn, DataTableColumnSort, DataTableProps, DataTableSortDirection, DataTableSortState, } from './components/DataTable.js';
43
43
  export { InteractiveHtmlEditor } from './components/InteractiveHtmlEditor/InteractiveHtmlEditor.js';
44
44
  export type { InteractiveHtmlEditorProps } from './components/InteractiveHtmlEditor/InteractiveHtmlEditor.js';
45
45
  export { RowMenu } from './components/RowMenu/RowMenu.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAGtF,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AAInH,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAKjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,YAAY,EAAE,0BAA0B,EAAE,MAAM,6DAA6D,CAAC;AAE9G,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAKjF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC/F,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC/F,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAGtF,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AAKnH,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AAKnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,YAAY,EAAE,0BAA0B,EAAE,MAAM,6DAA6D,CAAC;AAE9G,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAKjF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,eAAe,EACf,YAAY,EACZ,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC/F,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC/F,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC"}
@@ -36,8 +36,9 @@
36
36
  export { resolveTone, toneClassName } from './types.js';
37
37
  export { ConfirmButton } from './components/ConfirmButton/ConfirmButton.js';
38
38
  export { ConfirmDialog } from './components/ConfirmDialog/ConfirmDialog.js';
39
- // The list table. Deliberately has no sorting, pagination or row selection — see its file header
40
- // for the corpus evidence behind each omission.
39
+ // The list table. Sorting is opt-in per column (`DataTableColumn.sort`); pagination and row
40
+ // selection are still deliberately absent — see its file header for the corpus evidence behind
41
+ // every one of these decisions.
41
42
  export { DataTable } from './components/DataTable.js';
42
43
  // Visual click-into-text editing surface for a bespoke HTML document, built on GrapesJS. See its
43
44
  // own file header for the styling-contract exception it carries (vendor CSS import) and the
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,gGAAgG;AAChG,kDAAkD;AAClD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAG5E,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAM5E,iGAAiG;AACjG,gDAAgD;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAGtD,iGAAiG;AACjG,4FAA4F;AAC5F,wCAAwC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AAGpG,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAG1D,qGAAqG;AACrG,iGAAiG;AACjG,uFAAuF;AACvF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAW9D,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE/F,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,gGAAgG;AAChG,kDAAkD;AAClD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAG5E,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAM5E,4FAA4F;AAC5F,+FAA+F;AAC/F,gCAAgC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAStD,iGAAiG;AACjG,4FAA4F;AAC5F,wCAAwC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AAGpG,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAG1D,qGAAqG;AACrG,iGAAiG;AACjG,uFAAuF;AACvF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAW9D,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE/F,OAAO,EAAE,gCAAgC,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jini-ai/admin",
3
- "version": "0.1.0",
3
+ "version": "0.3.6",
4
4
  "description": "Composable admin surface for Jini-hosted products: framework-free contracts, panel registry, and route model in `/core`; React shell and panels in `/react`. Import only the layers you need.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -80,8 +80,8 @@
80
80
  "react-dom": "^19.2.0"
81
81
  },
82
82
  "dependencies": {
83
- "@jini-ai/agentic": "0.1.2",
84
- "@jini-ai/ui": "0.1.2"
83
+ "@jini-ai/ui": "0.3.6",
84
+ "@jini-ai/agentic": "0.3.0"
85
85
  },
86
86
  "scripts": {
87
87
  "build": "tsc -p tsconfig.json",