impact-nova 2.1.0-alpha.6 → 2.1.0-alpha.7

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,8 +1,8 @@
1
1
  import { jsx as t, jsxs as c } from "react/jsx-runtime";
2
- import d, { useState as b, useEffect as f, useCallback as T } from "react";
2
+ import d, { useState as b, useEffect as u, useCallback as T } from "react";
3
3
  import { createPortal as g } from "react-dom";
4
4
  import { Cross as C } from "impact-nova-icons";
5
- import { cn as m } from "../../../lib/utils.js";
5
+ import { cn as f } from "../../../lib/utils.js";
6
6
  import { Button as x } from "../../primitives/button/button.js";
7
7
  import { useDataTable as w, useDataTableSheetPortal as D } from "./data-table-context.js";
8
8
  import { DATA_TABLE_SCOPED_SHEET_HOST_MIN_HEIGHT_PX as v } from "./data-table-constants.js";
@@ -13,14 +13,14 @@ const I = ({
13
13
  open: e,
14
14
  onOpenChange: o
15
15
  }) => {
16
- const { registerScopedSheetDepth: a } = w(), [s, i] = b(r), l = e !== void 0 ? e : s, p = d.useRef(o);
17
- f(() => {
18
- p.current = o;
16
+ const { registerScopedSheetDepth: a } = w(), [s, i] = b(r), l = e !== void 0 ? e : s, h = d.useRef(o);
17
+ u(() => {
18
+ h.current = o;
19
19
  });
20
- const y = T((u) => {
21
- e === void 0 && i(u), p.current?.(u);
20
+ const y = T((p) => {
21
+ e === void 0 && i(p), h.current?.(p);
22
22
  }, [e]);
23
- return f(() => {
23
+ return u(() => {
24
24
  if (l)
25
25
  return a(1), () => {
26
26
  a(-1);
@@ -51,7 +51,7 @@ const I = ({
51
51
  return /* @__PURE__ */ c(
52
52
  "div",
53
53
  {
54
- className: m(
54
+ className: f(
55
55
  "flex shrink-0 flex-row justify-between items-center px-4 py-3 mb-2 bg-brand-tint",
56
56
  e
57
57
  ),
@@ -80,14 +80,12 @@ const I = ({
80
80
  children: n,
81
81
  className: r
82
82
  }) => {
83
- const { open: e } = S(), { sheetTarget: o } = D(), [a, s] = b(e);
84
- if (f(() => {
85
- e && s(!0);
86
- }, [e]), !a) return null;
83
+ const { open: e } = S(), { sheetTarget: o } = D(), [a, s] = b(!1);
84
+ if (e && !a && s(!0), !a) return null;
87
85
  const i = /* @__PURE__ */ c(
88
86
  "div",
89
87
  {
90
- className: m(
88
+ className: f(
91
89
  "-my-px flex h-[calc(100%_+_2px)]",
92
90
  e && "animate-in slide-in-from-right-[100%] duration-200 ease-in-out fade-in fill-mode-forwards motion-reduce:animate-none motion-reduce:transition-none"
93
91
  ),
@@ -101,7 +99,7 @@ const I = ({
101
99
  "div",
102
100
  {
103
101
  "data-component": "data-table-sheet-panel",
104
- className: m(
102
+ className: f(
105
103
  "relative flex h-full w-[355px] flex-col overflow-y-auto bg-canvas-elevated border-t border-l border-stroke-hairline pointer-events-auto shadow-elevation-floating",
106
104
  r
107
105
  ),
@@ -111,7 +109,7 @@ const I = ({
111
109
  /* @__PURE__ */ t("div", { className: "w-[16px] bg-canvas-elevated border-l border-stroke-hairline shrink-0" })
112
110
  ]
113
111
  }
114
- ), h = /* @__PURE__ */ t(
112
+ ), m = /* @__PURE__ */ t(
115
113
  "div",
116
114
  {
117
115
  className: "pointer-events-none absolute inset-0 z-[35] flex justify-end overflow-x-hidden overflow-y-visible",
@@ -119,7 +117,7 @@ const I = ({
119
117
  children: i
120
118
  }
121
119
  );
122
- return o ? g(h, o) : /* @__PURE__ */ t(
120
+ return o ? g(m, o) : /* @__PURE__ */ t(
123
121
  "div",
124
122
  {
125
123
  className: "pointer-events-none fixed inset-0 z-[35] flex justify-end overflow-x-hidden overflow-y-visible",
@@ -1,52 +1,52 @@
1
- import { jsx as n, jsxs as G } from "react/jsx-runtime";
2
- import { useState as h, useRef as E, useCallback as D, useMemo as g, useEffect as y, memo as v } from "react";
3
- import { AgGridWrapper as O } from "../ag-grid-react/index.js";
1
+ import { jsx as n, jsxs as R } from "react/jsx-runtime";
2
+ import { useState as g, useMemo as m, useCallback as D, useEffect as y, memo as v } from "react";
3
+ import { AgGridWrapper as E } from "../ag-grid-react/index.js";
4
4
  import { cn as H } from "../../../lib/utils.js";
5
- import { DataTableContext as F, DataTableSheetPortalStoreContext as N, useDataTable as I, useDataTableSheetPortal as A } from "./data-table-context.js";
6
- import { createDataTableSheetPortalStore as z } from "./data-table-sheet-portal-store.js";
7
- import { DATA_TABLE_SCOPED_SHEET_HOST_MIN_HEIGHT_PX as B } from "./data-table-constants.js";
8
- import { extractRuntimeColumnDefs as M, mergeInitialGridRuntimeState as j } from "./data-table-column-def-pin.js";
5
+ import { DataTableContext as O, DataTableSheetPortalStoreContext as F, useDataTable as N, useDataTableSheetPortal as A } from "./data-table-context.js";
6
+ import { createDataTableSheetPortalStore as I } from "./data-table-sheet-portal-store.js";
7
+ import { DATA_TABLE_SCOPED_SHEET_HOST_MIN_HEIGHT_PX as z } from "./data-table-constants.js";
8
+ import { extractRuntimeColumnDefs as B, mergeInitialGridRuntimeState as M } from "./data-table-column-def-pin.js";
9
9
  const P = {
10
10
  default: 46,
11
11
  compact: 30,
12
12
  comfort: 52
13
- }, U = ({
13
+ }, Q = ({
14
14
  children: a,
15
15
  className: t
16
16
  }) => {
17
- const [r, e] = h(null), [o, c] = h("medium"), [i, S] = h("full"), [s, m] = h("default"), d = E(z()), u = D((l) => {
18
- d.current.registerScopedSheetDepth(l);
19
- }, []), f = D((l) => {
20
- e(l);
17
+ const [r, e] = g(null), [o, d] = g("medium"), [i, S] = g("full"), [s, u] = g("default"), l = m(() => I(), []), f = D((c) => {
18
+ l.registerScopedSheetDepth(c);
19
+ }, [l]), p = D((c) => {
20
+ e(c);
21
21
  }, []), x = {
22
22
  small: "12px",
23
23
  medium: "14px",
24
24
  large: "16px"
25
- }[o], b = `${P[s]}px`, T = g(
25
+ }[o], b = `${P[s]}px`, T = m(
26
26
  () => ({
27
27
  gridApi: r,
28
- registerApi: f,
29
- registerScopedSheetDepth: u,
28
+ registerApi: p,
29
+ registerScopedSheetDepth: f,
30
30
  fontSize: o,
31
- setFontSize: c,
31
+ setFontSize: d,
32
32
  numericFormat: i,
33
33
  setNumericFormat: S,
34
34
  rowHeight: s,
35
- setRowHeight: m
35
+ setRowHeight: u
36
36
  }),
37
37
  [
38
38
  r,
39
+ p,
39
40
  f,
40
- u,
41
41
  o,
42
42
  i,
43
43
  s
44
44
  ]
45
45
  );
46
- return /* @__PURE__ */ n(F.Provider, { value: T, children: /* @__PURE__ */ n(
47
- N.Provider,
46
+ return /* @__PURE__ */ n(O.Provider, { value: T, children: /* @__PURE__ */ n(
47
+ F.Provider,
48
48
  {
49
- value: d.current,
49
+ value: l,
50
50
  children: /* @__PURE__ */ n(
51
51
  "div",
52
52
  {
@@ -70,7 +70,7 @@ const P = {
70
70
  m: "mil",
71
71
  b: "bil",
72
72
  full_precision: "full_precision"
73
- }, k = v(function() {
73
+ }, j = v(function() {
74
74
  const { setSheetTarget: t } = A();
75
75
  return /* @__PURE__ */ n(
76
76
  "div",
@@ -79,67 +79,67 @@ const P = {
79
79
  className: "absolute inset-0 pointer-events-none z-[39] flex overflow-x-hidden overflow-y-visible"
80
80
  }
81
81
  );
82
- }), L = v(function({
82
+ }), k = v(function({
83
83
  className: t,
84
84
  children: r
85
85
  }) {
86
86
  const { scopedSheetOpen: e } = A();
87
- return /* @__PURE__ */ G(
87
+ return /* @__PURE__ */ R(
88
88
  "div",
89
89
  {
90
90
  className: H(
91
91
  "relative flex-1 min-h-0 w-full bg-canvas-elevated rounded-b-[inherit] grid-rounded-bottom",
92
92
  t
93
93
  ),
94
- style: e ? { minHeight: B } : void 0,
94
+ style: e ? { minHeight: z } : void 0,
95
95
  children: [
96
96
  r,
97
- /* @__PURE__ */ n(k, {})
97
+ /* @__PURE__ */ n(j, {})
98
98
  ]
99
99
  }
100
100
  );
101
- }), W = v(function({
101
+ }), L = v(function({
102
102
  resolvedRowHeight: t,
103
103
  mergedContext: r,
104
104
  onGridReady: e,
105
105
  columnDefs: o,
106
- maintainColumnOrder: c = !0,
106
+ maintainColumnOrder: d = !0,
107
107
  ...i
108
108
  }) {
109
109
  return /* @__PURE__ */ n(
110
- O,
110
+ E,
111
111
  {
112
112
  ...i,
113
113
  columnDefs: o,
114
114
  rowHeight: t,
115
115
  onGridReady: e,
116
116
  context: r,
117
- maintainColumnOrder: c
117
+ maintainColumnOrder: d
118
118
  }
119
119
  );
120
120
  });
121
- function Z(a) {
121
+ function U(a) {
122
122
  const {
123
123
  registerApi: t,
124
124
  rowHeight: r,
125
125
  gridApi: e,
126
126
  numericFormat: o
127
- } = I(), {
128
- className: c,
127
+ } = N(), {
128
+ className: d,
129
129
  onGridReady: i,
130
130
  rowHeight: S,
131
131
  context: s,
132
- columnDefs: m,
133
- initialState: d,
134
- maintainColumnOrder: u = !0,
135
- ...f
136
- } = a, x = P[r], b = S ?? x, { runtimeColumnDefs: T, extractedRuntimeDefaults: l } = g(
137
- () => M(m ?? void 0),
138
- [m]
139
- ), _ = g(
140
- () => j(d, l),
141
- [d, l]
142
- ), C = g(
132
+ columnDefs: u,
133
+ initialState: l,
134
+ maintainColumnOrder: f = !0,
135
+ ...p
136
+ } = a, x = P[r], b = S ?? x, { runtimeColumnDefs: T, extractedRuntimeDefaults: c } = m(
137
+ () => B(u ?? void 0),
138
+ [u]
139
+ ), _ = m(
140
+ () => M(l, c),
141
+ [l, c]
142
+ ), C = m(
143
143
  () => ({
144
144
  ...s,
145
145
  formatType: w[o]
@@ -150,33 +150,33 @@ function Z(a) {
150
150
  e?.resetRowHeights();
151
151
  }, [r, e]), y(() => {
152
152
  if (e) {
153
- const p = e.getGridOption("context") || {};
153
+ const h = e.getGridOption("context") || {};
154
154
  e.setGridOption("context", {
155
- ...p,
155
+ ...h,
156
156
  formatType: w[o]
157
157
  }), e.refreshCells({ force: !0 });
158
158
  }
159
159
  }, [o, e]);
160
- const R = D(
161
- (p) => {
162
- t(p.api), i?.(p);
160
+ const G = D(
161
+ (h) => {
162
+ t(h.api), i?.(h);
163
163
  },
164
164
  [t, i]
165
165
  );
166
- return /* @__PURE__ */ n(L, { className: c, children: /* @__PURE__ */ n(
167
- W,
166
+ return /* @__PURE__ */ n(k, { className: d, children: /* @__PURE__ */ n(
167
+ L,
168
168
  {
169
- ...f,
169
+ ...p,
170
170
  columnDefs: T,
171
171
  initialState: _,
172
- maintainColumnOrder: u,
172
+ maintainColumnOrder: f,
173
173
  resolvedRowHeight: b,
174
174
  mergedContext: C,
175
- onGridReady: R
175
+ onGridReady: G
176
176
  }
177
177
  ) });
178
178
  }
179
- const ee = ({
179
+ const Z = ({
180
180
  children: a,
181
181
  className: t
182
182
  }) => /* @__PURE__ */ n(
@@ -191,7 +191,7 @@ const ee = ({
191
191
  }
192
192
  );
193
193
  export {
194
- U as DataTable,
195
- Z as DataTableContent,
196
- ee as DataTableToolbar
194
+ Q as DataTable,
195
+ U as DataTableContent,
196
+ Z as DataTableToolbar
197
197
  };
@@ -1,53 +1,53 @@
1
- import { useState as M, useRef as h, useCallback as a, useEffect as x } from "react";
2
- import { mergePartialOrderedColumnState as L } from "./data-table-column-state.js";
3
- import { afterSynchronousColumnApply as b, normalizeColumnPinned as q, GRID_AUTO_UNPIN_WAIT_MS as H, alignColumnTreePinMetadata as N, EXTERNAL_SYNC_DEBOUNCE_MS as J, readGridColumnPinned as Q } from "./data-table-column-apply.js";
4
- import { buildColumnTreeFromGrid as Z } from "./build-column-tree-from-grid.js";
1
+ import { useState as O, useRef as h, useCallback as a, useEffect as x } from "react";
2
+ import { mergePartialOrderedColumnState as N } from "./data-table-column-state.js";
3
+ import { afterSynchronousColumnApply as R, normalizeColumnPinned as q, GRID_AUTO_UNPIN_WAIT_MS as J, alignColumnTreePinMetadata as L, EXTERNAL_SYNC_DEBOUNCE_MS as Q, readGridColumnPinned as Z } from "./data-table-column-apply.js";
4
+ import { buildColumnTreeFromGrid as $ } from "./build-column-tree-from-grid.js";
5
5
  import { computeColumnListSyncFingerprints as z, resolveColumnListSyncMode as A } from "./data-table-column-list-sync.js";
6
6
  import { subscribeGridApiEvent as j } from "../ag-grid-react/grid-api-event-subscription.js";
7
7
  function se({
8
- gridApi: n,
9
- frozenColumnsLabel: O,
10
- scrollableColumnsLabel: _
8
+ gridApi: r,
9
+ frozenColumnsLabel: D,
10
+ scrollableColumnsLabel: U
11
11
  }) {
12
- const [K, v] = M([]), [V, W] = M(!1), [w, B] = M(!1), i = h(!1), E = h(null), S = h(0), y = h(""), P = h(""), C = a(() => !n || i.current ? null : Z(n, {
13
- frozenColumns: O,
14
- scrollableColumns: _
15
- }), [n, O, _]), g = a(
16
- (t, e, o) => {
17
- const l = y.current, c = z(t);
18
- y.current = c.structural, P.current = c.indicators, v(t), W(!0), e === "structural" && l !== "" && B((d) => !d);
12
+ const [K, b] = O([]), [V, W] = O(!1), [_, B] = O(!1), i = h(!1), E = h(null), S = h(0), y = h(""), G = h(""), C = a(() => !r || i.current ? null : $(r, {
13
+ frozenColumns: D,
14
+ scrollableColumns: U
15
+ }), [r, D, U]), I = a(
16
+ (t, e) => {
17
+ const o = y.current, l = z(t);
18
+ y.current = l.structural, G.current = l.indicators, b(t), W(!0), e === "structural" && o !== "" && B((n) => !n);
19
19
  },
20
- [n]
21
- ), p = a(
22
- (t = "unknown") => {
23
- const e = C();
24
- e && g(e, "structural", t);
20
+ []
21
+ ), m = a(
22
+ () => {
23
+ const t = C();
24
+ t && I(t, "structural");
25
25
  },
26
- [g, C, n]
27
- ), D = a(
28
- (t) => {
29
- const e = C();
30
- if (!e) return;
31
- const o = A(
32
- e,
26
+ [I, C]
27
+ ), k = a(
28
+ () => {
29
+ const t = C();
30
+ if (!t) return;
31
+ const e = A(
32
+ t,
33
33
  y.current,
34
- P.current
34
+ G.current
35
35
  );
36
- if (o !== "skip") {
37
- if (o === "structural") {
38
- const l = E.current?.querySelector(
36
+ if (e !== "skip") {
37
+ if (e === "structural") {
38
+ const o = E.current?.querySelector(
39
39
  '[data-component="nested-list"] .overflow-y-auto'
40
40
  );
41
- l && (S.current = l.scrollTop);
41
+ o && (S.current = o.scrollTop);
42
42
  }
43
- g(e, o, t);
43
+ I(t, e);
44
44
  }
45
45
  },
46
- [g, C]
46
+ [I, C]
47
47
  );
48
48
  x(() => {
49
- if (!n) return;
50
- queueMicrotask(() => p("initial"));
49
+ if (!r) return;
50
+ queueMicrotask(() => m());
51
51
  const t = [
52
52
  "columnVisible",
53
53
  "columnPinned",
@@ -65,19 +65,19 @@ function se({
65
65
  "newColumnsLoaded"
66
66
  ];
67
67
  let e = null;
68
- const o = (c) => {
68
+ const o = () => {
69
69
  i.current || (e && clearTimeout(e), e = setTimeout(() => {
70
- e = null, !(i.current || n.isDestroyed()) && D(`grid:${c}`);
71
- }, J));
70
+ e = null, !(i.current || r.isDestroyed()) && k();
71
+ }, Q));
72
72
  }, l = t.map(
73
- (c) => j(n, c, () => {
74
- o(c);
73
+ (u) => j(r, u, () => {
74
+ o();
75
75
  })
76
76
  );
77
77
  return () => {
78
- e && clearTimeout(e), l.forEach((c) => c());
78
+ e && clearTimeout(e), l.forEach((u) => u());
79
79
  };
80
- }, [n, p, D]), x(() => {
80
+ }, [r, m, k]), x(() => {
81
81
  if (S.current === 0) return;
82
82
  const t = requestAnimationFrame(() => {
83
83
  const e = E.current?.querySelector(
@@ -86,33 +86,33 @@ function se({
86
86
  e && (e.scrollTop = S.current, S.current = 0);
87
87
  });
88
88
  return () => cancelAnimationFrame(t);
89
- }, [w]);
90
- const U = a(
89
+ }, [_]);
90
+ const w = a(
91
91
  (t) => {
92
- const e = [], o = (l, c) => {
93
- l.forEach((r) => {
94
- if (r.id === "root-frozen") {
95
- r.children && o(r.children, "left");
92
+ const e = [], o = (l, u) => {
93
+ l.forEach((n) => {
94
+ if (n.id === "root-frozen") {
95
+ n.children && o(n.children, "left");
96
96
  return;
97
97
  }
98
- if (r.id === "root-scrollable") {
99
- r.children && o(r.children, null);
98
+ if (n.id === "root-scrollable") {
99
+ n.children && o(n.children, null);
100
100
  return;
101
101
  }
102
- if (r.category === "group" || r.children && r.children.length > 0)
103
- r.children && o(r.children, c);
102
+ if (n.category === "group" || n.children && n.children.length > 0)
103
+ n.children && o(n.children, u);
104
104
  else {
105
- let u;
106
- if (c === null)
107
- u = null;
105
+ let c;
106
+ if (u === null)
107
+ c = null;
108
108
  else {
109
- const f = r.data?.pinned;
110
- u = f === "left" || f === "right" ? f : c;
109
+ const d = n.data?.pinned;
110
+ c = d === "left" || d === "right" ? d : u;
111
111
  }
112
112
  e.push({
113
- colId: r.id,
114
- pinned: u,
115
- hide: !r.checked
113
+ colId: n.id,
114
+ pinned: c,
115
+ hide: !n.checked
116
116
  });
117
117
  }
118
118
  });
@@ -120,101 +120,101 @@ function se({
120
120
  return o(t, null), e;
121
121
  },
122
122
  []
123
- ), I = a(
123
+ ), g = a(
124
124
  (t) => {
125
- if (!n) return;
125
+ if (!r) return;
126
126
  i.current = !0;
127
- const e = U(t);
127
+ const e = w(t);
128
128
  if (e.length === 0) {
129
- b(() => {
129
+ R(() => {
130
130
  i.current = !1;
131
131
  });
132
132
  return;
133
133
  }
134
- const o = n.getColumnState(), l = L(o, e), c = new Set(
134
+ const o = r.getColumnState(), l = N(o, e), u = new Set(
135
135
  o.filter((s) => q(s.pinned)).map((s) => s.colId)
136
- ), r = l.filter(
137
- (s) => q(s.pinned) && !c.has(s.colId)
138
- ), d = new Set(r.map((s) => s.colId));
139
- n.applyColumnState({ state: l, applyOrder: !0 });
140
- const u = () => {
141
- i.current = !1, p("handleChanges:releaseLockAndSync");
136
+ ), n = l.filter(
137
+ (s) => q(s.pinned) && !u.has(s.colId)
138
+ ), p = new Set(n.map((s) => s.colId));
139
+ r.applyColumnState({ state: l, applyOrder: !0 });
140
+ const c = () => {
141
+ i.current = !1, m();
142
142
  };
143
- if (d.size === 0) {
144
- b(u);
143
+ if (p.size === 0) {
144
+ R(c);
145
145
  return;
146
146
  }
147
- let T = !1, f = null, G = null;
148
- G = j(n, "columnPinned", () => {
149
- if (T || n.isDestroyed()) return;
150
- const s = n.getColumnState();
151
- if (r.filter((R) => {
152
- const m = s.find((F) => F.colId === R.colId);
153
- return m && !m.pinned;
147
+ let T = !1, d = null, P = null;
148
+ P = j(r, "columnPinned", () => {
149
+ if (T || r.isDestroyed()) return;
150
+ const s = r.getColumnState();
151
+ if (n.filter((v) => {
152
+ const f = s.find((F) => F.colId === v.colId);
153
+ return f && !f.pinned;
154
154
  }).length > 0) {
155
- T = !0, f && clearTimeout(f), G?.();
156
- const R = l.filter(
157
- (m) => m.pinned && !d.has(m.colId)
155
+ T = !0, d && clearTimeout(d), P?.();
156
+ const v = l.filter(
157
+ (f) => f.pinned && !p.has(f.colId)
158
158
  );
159
- if (R.length > 0) {
160
- const m = R[0], F = l.map(
161
- (k) => k.colId === m.colId ? { ...k, pinned: null } : k
159
+ if (v.length > 0) {
160
+ const f = v[0], F = l.map(
161
+ (M) => M.colId === f.colId ? { ...M, pinned: null } : M
162
162
  );
163
- n.applyColumnState({ state: F, applyOrder: !0 });
163
+ r.applyColumnState({ state: F, applyOrder: !0 });
164
164
  }
165
- b(u);
165
+ R(c);
166
166
  }
167
- }), f = setTimeout(() => {
168
- G?.(), T || u();
169
- }, H);
167
+ }), d = setTimeout(() => {
168
+ P?.(), T || c();
169
+ }, J);
170
170
  },
171
- [n, U, p]
171
+ [r, w, m]
172
172
  ), X = a(
173
173
  (t) => {
174
- I(N(t));
174
+ g(L(t));
175
175
  },
176
- [I]
176
+ [g]
177
177
  ), Y = a(
178
178
  (t, e) => {
179
- const o = N(t);
180
- e || I(o), v(o);
179
+ const o = L(t);
180
+ e || g(o), b(o);
181
181
  const l = z(o);
182
- y.current = l.structural, P.current = l.indicators;
182
+ y.current = l.structural, G.current = l.indicators;
183
183
  },
184
- [I]
185
- ), $ = a(
184
+ [g]
185
+ ), H = a(
186
186
  (t, e) => {
187
- if (v((c) => {
188
- const r = (d) => d.map((u) => u.id === t ? {
189
- ...u,
187
+ if (b((u) => {
188
+ const n = (p) => p.map((c) => c.id === t ? {
189
+ ...c,
190
190
  data: {
191
- ...u.data,
191
+ ...c.data,
192
192
  pinned: e
193
193
  }
194
- } : u.children ? {
195
- ...u,
196
- children: r(u.children)
197
- } : u);
198
- return r(c);
199
- }), !n) return;
194
+ } : c.children ? {
195
+ ...c,
196
+ children: n(c.children)
197
+ } : c);
198
+ return n(u);
199
+ }), !r) return;
200
200
  i.current = !0;
201
- const o = n.getColumnState(), l = L(o, [
201
+ const o = r.getColumnState(), l = N(o, [
202
202
  { colId: t, pinned: e }
203
203
  ]);
204
- n.applyColumnState({ state: l, applyOrder: !0 }), b(() => {
205
- i.current = !1, Q(n, t) !== e && p("handlePinChange");
204
+ r.applyColumnState({ state: l, applyOrder: !0 }), R(() => {
205
+ i.current = !1, Z(r, t) !== e && m();
206
206
  });
207
207
  },
208
- [n, p]
208
+ [r, m]
209
209
  );
210
210
  return {
211
211
  items: K,
212
212
  isReady: V,
213
- externalSyncKey: w,
213
+ externalSyncKey: _,
214
214
  listWrapperRef: E,
215
215
  handleChange: Y,
216
216
  handleSubmit: X,
217
- handlePinChange: $
217
+ handlePinChange: H
218
218
  };
219
219
  }
220
220
  export {
@@ -6,4 +6,4 @@ export interface CreateComponentOptions {
6
6
  /**
7
7
  * Creates a forwardRef component with a stable displayName.
8
8
  */
9
- export declare function createComponent<P extends object, R = HTMLElement>(displayName: string, render: React.ForwardRefRenderFunction<R, P>, _options?: CreateComponentOptions): React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<R>>;
9
+ export declare function createComponent<P extends object, R = HTMLElement>(displayName: string, render: React.ForwardRefRenderFunction<R, P>): React.ForwardRefExoticComponent<React.PropsWithoutRef<P> & React.RefAttributes<R>>;
@@ -1,10 +1,10 @@
1
1
  import * as n from "react";
2
- function a(t, e, r) {
2
+ function r(e, t) {
3
3
  const o = n.forwardRef(
4
- e
4
+ t
5
5
  );
6
- return o.displayName = t, o;
6
+ return o.displayName = e, o;
7
7
  }
8
8
  export {
9
- a as createComponent
9
+ r as createComponent
10
10
  };
@@ -1,34 +1,33 @@
1
1
  import { jsx as o, jsxs as c } from "react/jsx-runtime";
2
2
  import * as l from "react";
3
- import { createComponent as H } from "./create-component.js";
3
+ import { createComponent as O } from "./create-component.js";
4
4
  import { cn as r } from "../utils.js";
5
- import { isFieldError as M, fieldErrorMessage as O } from "./field.types.js";
5
+ import { isFieldError as R, fieldErrorMessage as V } from "./field.types.js";
6
6
  const b = l.createContext(null);
7
7
  function A() {
8
8
  return l.useContext(b) ?? {};
9
9
  }
10
- const v = H(
10
+ const v = O(
11
11
  "Field",
12
12
  (e, t) => {
13
13
  const {
14
- label: p,
14
+ label: m,
15
15
  description: I,
16
16
  helperText: j,
17
- helperTextPosition: R = "flow",
18
17
  labelOrientation: w = "top",
19
- error: m,
18
+ error: p,
20
19
  required: D,
21
20
  disabled: n,
22
21
  size: a,
23
22
  htmlFor: L,
24
- className: P,
23
+ className: z,
25
24
  children: x
26
- } = e, s = j ?? I, T = l.useId(), f = l.useId(), u = l.useId(), F = M(m), d = O(m), i = l.Children.only(x), h = L ?? (l.isValidElement(i) && typeof i.props.id == "string" ? i.props.id : T), z = [
27
- s ? f : null,
28
- d ? u : null
29
- ].filter(Boolean).join(" "), B = l.isValidElement(i) && (s || d) ? l.cloneElement(i, {
25
+ } = e, s = j ?? I, B = l.useId(), u = l.useId(), f = l.useId(), F = R(p), d = V(p), i = l.Children.only(x), h = L ?? (l.isValidElement(i) && typeof i.props.id == "string" ? i.props.id : B), H = [
26
+ s ? u : null,
27
+ d ? f : null
28
+ ].filter(Boolean).join(" "), M = l.isValidElement(i) && (s || d) ? l.cloneElement(i, {
30
29
  id: i.props.id ?? h,
31
- "aria-describedby": z || void 0,
30
+ "aria-describedby": H || void 0,
32
31
  "aria-invalid": F || void 0,
33
32
  ...a ? { size: a } : {},
34
33
  ...n !== void 0 ? { disabled: n } : {}
@@ -40,11 +39,11 @@ const v = H(
40
39
  className: r(
41
40
  "flex w-full gap-1.5",
42
41
  N ? "flex-row items-start gap-3" : "flex-col",
43
- P
42
+ z
44
43
  ),
45
44
  "data-component": "field",
46
45
  children: [
47
- p ? /* @__PURE__ */ c(
46
+ m ? /* @__PURE__ */ c(
48
47
  "label",
49
48
  {
50
49
  htmlFor: h,
@@ -54,15 +53,15 @@ const v = H(
54
53
  N && "shrink-0 pt-2"
55
54
  ),
56
55
  children: [
57
- p,
56
+ m,
58
57
  D ? /* @__PURE__ */ o("span", { className: "text-destructive", children: " *" }) : null
59
58
  ]
60
59
  }
61
60
  ) : null,
62
61
  /* @__PURE__ */ c("div", { className: r("min-w-0 flex-1 flex flex-col gap-1.5"), children: [
63
- B,
64
- s ? /* @__PURE__ */ o("p", { id: f, className: "text-xs text-content-muted", children: s }) : null,
65
- d ? /* @__PURE__ */ o("p", { id: u, className: "text-xs text-destructive", role: "alert", children: d }) : null
62
+ M,
63
+ s ? /* @__PURE__ */ o("p", { id: u, className: "text-xs text-content-muted", children: s }) : null,
64
+ d ? /* @__PURE__ */ o("p", { id: f, className: "text-xs text-destructive", role: "alert", children: d }) : null
66
65
  ] })
67
66
  ]
68
67
  }
@@ -27,8 +27,7 @@ export interface VirtualizedListSelectAllProps extends Omit<React.ButtonHTMLAttr
27
27
  getVisibleIds?: (list: UseVirtualizedListResult<unknown>) => string[];
28
28
  }
29
29
  export declare const VirtualizedListSelectAll: React.ForwardRefExoticComponent<VirtualizedListSelectAllProps & React.RefAttributes<HTMLButtonElement>>;
30
- export interface VirtualizedListViewportProps extends React.HTMLAttributes<HTMLDivElement> {
31
- }
30
+ export type VirtualizedListViewportProps = React.HTMLAttributes<HTMLDivElement>;
32
31
  export declare const VirtualizedListViewport: React.ForwardRefExoticComponent<VirtualizedListViewportProps & React.RefAttributes<HTMLDivElement>>;
33
32
  export interface VirtualizedListContentProps<TData> {
34
33
  children: (row: VirtualRowModel<TData>, virtualItem: VirtualItem) => React.ReactNode;
@@ -1,12 +1,12 @@
1
- import { jsx as l } from "react/jsx-runtime";
1
+ import { jsx as o } from "react/jsx-runtime";
2
2
  import * as d from "react";
3
3
  import { useRef as m, useLayoutEffect as P, useMemo as H } from "react";
4
4
  import { useComposedRefs as N } from "../compose-refs.js";
5
5
  import { createCompoundPart as c } from "../primitives/create-compound.js";
6
6
  import { cn as p } from "../utils.js";
7
7
  import { VirtualizedListProvider as R, useVirtualizedListContext as f } from "./virtualized-list-context.js";
8
- import { getVisibleReadyRowIds as _ } from "./virtualized-list-utils.js";
9
- import { useVirtualizedList as T } from "./useVirtualizedList.js";
8
+ import { getVisibleReadyRowIds as T } from "./virtualized-list-utils.js";
9
+ import { useVirtualizedList as _ } from "./useVirtualizedList.js";
10
10
  const y = c("virtualized-list", {
11
11
  part: "root",
12
12
  displayName: "VirtualizedList",
@@ -17,22 +17,22 @@ function D({
17
17
  children: a,
18
18
  ...r
19
19
  }) {
20
- const e = m(null), i = T({
20
+ const e = m(null), i = _({
21
21
  ...r,
22
22
  scrollElementRef: e
23
23
  }), s = H(
24
24
  () => ({ list: i, scrollRef: e }),
25
25
  [i, e]
26
26
  );
27
- return /* @__PURE__ */ l(R, { value: s, children: /* @__PURE__ */ l(y, { className: t, children: a }) });
27
+ return /* @__PURE__ */ o(R, { value: s, children: /* @__PURE__ */ o(y, { className: t, "data-component": "virtualized", children: a }) });
28
28
  }
29
29
  function F(t) {
30
30
  if ("value" in t && t.value) {
31
- const { value: i, className: s, children: o } = t;
32
- return /* @__PURE__ */ l(R, { value: i, children: /* @__PURE__ */ l(y, { className: s, children: o }) });
31
+ const { value: i, className: s, children: l } = t;
32
+ return /* @__PURE__ */ o(R, { value: i, children: /* @__PURE__ */ o(y, { className: s, "data-component": "virtualized", children: l }) });
33
33
  }
34
34
  const { className: a, children: r, ...e } = t;
35
- return /* @__PURE__ */ l(D, { className: a, ...e, children: r });
35
+ return /* @__PURE__ */ o(D, { className: a, ...e, children: r });
36
36
  }
37
37
  F.displayName = "VirtualizedList";
38
38
  const $ = c("virtualized-list", {
@@ -52,11 +52,11 @@ const $ = c("virtualized-list", {
52
52
  displayName: "VirtualizedListSearch",
53
53
  className: "min-w-0 flex-1"
54
54
  }), j = d.forwardRef(({ className: t, children: a, getVisibleIds: r, ...e }, i) => {
55
- const { list: s } = f(), o = d.useMemo(
56
- () => r ? r(s) : _(s),
55
+ const { list: s } = f(), l = d.useMemo(
56
+ () => r ? r(s) : T(s),
57
57
  [r, s]
58
- ), n = o.length > 0 && s.rowState.isAllSelected(o), u = typeof a == "function" ? a({ allVisibleSelected: n }) : a ?? (n ? "Deselect visible" : "Select all visible");
59
- return /* @__PURE__ */ l(
58
+ ), n = l.length > 0 && s.rowState.isAllSelected(l), u = typeof a == "function" ? a({ allVisibleSelected: n }) : a ?? (n ? "Deselect visible" : "Select all visible");
59
+ return /* @__PURE__ */ o(
60
60
  "button",
61
61
  {
62
62
  ref: i,
@@ -66,7 +66,7 @@ const $ = c("virtualized-list", {
66
66
  "shrink-0 text-sm font-medium text-brand hover:underline",
67
67
  t
68
68
  ),
69
- onClick: () => s.rowState.toggleSelectAll(o),
69
+ onClick: () => s.rowState.toggleSelectAll(l),
70
70
  ...e,
71
71
  children: u
72
72
  }
@@ -75,7 +75,7 @@ const $ = c("virtualized-list", {
75
75
  j.displayName = "VirtualizedListSelectAll";
76
76
  const I = d.forwardRef(({ className: t, children: a, ...r }, e) => {
77
77
  const { scrollRef: i } = f(), s = N(i, e);
78
- return /* @__PURE__ */ l(
78
+ return /* @__PURE__ */ o(
79
79
  "div",
80
80
  {
81
81
  ref: s,
@@ -93,20 +93,20 @@ function se({
93
93
  getItemMeasure: r
94
94
  }) {
95
95
  const { list: e } = f();
96
- return /* @__PURE__ */ l(
96
+ return /* @__PURE__ */ o(
97
97
  "div",
98
98
  {
99
99
  "data-component": "virtualized-list-content",
100
100
  className: p("relative w-full", a),
101
101
  style: { height: e.totalHeight },
102
102
  children: e.virtualItems.map((i) => {
103
- const s = e.getRow(i.index), o = r ? r(s) : !0;
104
- return /* @__PURE__ */ l(
103
+ const s = e.getRow(i.index), l = r ? r(s) : !0;
104
+ return /* @__PURE__ */ o(
105
105
  b,
106
106
  {
107
107
  virtualItem: i,
108
108
  row: s,
109
- measure: o,
109
+ measure: l,
110
110
  children: t(s, i)
111
111
  },
112
112
  String(i.key)
@@ -116,8 +116,8 @@ function se({
116
116
  );
117
117
  }
118
118
  const K = 220, b = d.forwardRef(
119
- ({ virtualItem: t, children: a, className: r, measure: e, row: i, ...s }, o) => {
120
- const { list: n } = f(), u = m(null), x = m(i?.isExpanded), h = m(e), S = n.getItemProps(t, { measure: e }), { key: U, ref: E, style: g, ...k } = S, A = N(E, o, u);
119
+ ({ virtualItem: t, children: a, className: r, measure: e, row: i, ...s }, l) => {
120
+ const { list: n } = f(), u = m(null), x = m(i?.isExpanded), h = m(e), S = n.getItemProps(t, { measure: e }), { key: U, ref: E, style: g, ...k } = S, A = N(E, l, u);
121
121
  return P(() => {
122
122
  const M = x.current, L = i?.isExpanded, C = h.current, z = e !== !1, V = M === !0 && L === !1;
123
123
  (V || C && !z) && n.resetRowSize(t.index);
@@ -128,7 +128,7 @@ const K = 220, b = d.forwardRef(
128
128
  }, K)), x.current = L, h.current = z, () => {
129
129
  v !== void 0 && window.clearTimeout(v);
130
130
  };
131
- }, [i?.isExpanded, e, t.index, n]), /* @__PURE__ */ l(
131
+ }, [i?.isExpanded, e, t.index, n]), /* @__PURE__ */ o(
132
132
  "div",
133
133
  {
134
134
  ref: A,
@@ -143,14 +143,14 @@ const K = 220, b = d.forwardRef(
143
143
  }
144
144
  );
145
145
  b.displayName = "VirtualizedListItem";
146
- const O = d.forwardRef(({ className: t, children: a, ...r }, e) => /* @__PURE__ */ l(
146
+ const O = d.forwardRef(({ className: t, children: a, ...r }, e) => /* @__PURE__ */ o(
147
147
  "div",
148
148
  {
149
149
  ref: e,
150
150
  "data-component": "virtualized-list-item-skeleton",
151
151
  className: p("px-3 py-2", t),
152
152
  ...r,
153
- children: a ?? /* @__PURE__ */ l(
153
+ children: a ?? /* @__PURE__ */ o(
154
154
  "div",
155
155
  {
156
156
  className: "h-12 w-full animate-pulse rounded-md bg-muted",
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Public types for `impact-nova/virtualized` (registry co-location SSOT).
3
+ */
4
+ export type { DataSourceApi, DataSourceConfig, RowSelectionMode, RowSelectionState, SelectionCounts, UseRowStateOptions, UseRowStateResult, VirtualItem, VirtualListKey, VirtualRowDataStatus, VirtualRowModel, } from './types';
5
+ export type { DataSectionBlock, HeaderSectionBlock, SectionBlock, SectionedFlatList, SectionedFlatRow, } from './sectioned';
6
+ export type { DataGridVirtualRowsResult } from './useDataGrid';
7
+ export type { UseVirtualizedListOptions, UseVirtualizedListResult } from './useVirtualizedList';
8
+ export type { UseVirtualizedRowsOptions } from './useVirtualizedRows';
9
+ export type { VirtualizedListContextValue } from './virtualized-list-context';
10
+ export type { VirtualizedListContentProps, VirtualizedListItemProps, VirtualizedListItemSkeletonProps, VirtualizedListProps, VirtualizedListSelectAllProps, VirtualizedListViewportProps, } from './virtualized-list-parts';
@@ -1 +1 @@
1
- export default "# Install and configure Impact Nova\n\nUse these steps to add Impact Nova to an existing project. Run the commands in your project root and apply the code changes to your entry file and layout.\n\n## 0. Scaffold a new app (recommended)\n\n**`create-impact-nova@^1.1.0`** is on npm. Scaffold auto-detects dependency mode:\n\n| Where you run | `impact-nova` dependency |\n|---------------|--------------------------|\n| Published CLI / MCP (outside monorepo) | `impact-nova@alpha` (`^2.1.0-alpha.6`) from npm |\n| Inside impact-nova monorepo | `file:` link to repo root |\n\n```bash\nnpx create-impact-nova my-dashboard\ncd my-dashboard\nnpm run dev\n```\n\nMCP: **`scaffold_impact_nova_app`** with `projectName` and optional `modules[]` from the user prompt.\n\n**Overrides:** CLI `--from-npm` · `--link-monorepo` · MCP `usePublishedPackages: true | false`\n\n```bash\nnpx create-impact-nova my-dashboard --from-npm\n```\n\nBase template is shell-only (Home + shared primitives). Feature pages come from recipes — see `create-impact-nova/recipes/README.md`.\n\n**Local link in an existing app** (manual):\n\n```bash\nnpm install impact-nova@file:../path-to-impact-nova-repo\n```\n\nRun `npm run build` in the impact-nova repo after design-system changes.\n\n## 1. Install the package and peer dependencies\n\n```bash\nnpm install impact-nova impact-nova-icons\nnpm install react@^19 react-dom@^19\n```\n\n**Required peers:** `react@^19`, `react-dom@^19`, `impact-nova-icons@^0.1.1`\n\n**Optional peers** (install when you use these features):\n\n| Package | Version | When needed |\n|---------|---------|-------------|\n| `ag-grid-community` | `36.0.1` | AG Grid types/API (pin with react + enterprise) |\n| `ag-grid-react` | `36.0.1` | DataTable / AG Grid |\n| `ag-grid-enterprise` | `36.0.1` | Enterprise grid features |\n| `highcharts` | `^12` | Chart component |\n| `highcharts-react-official` | `^3` | Chart component |\n| `highcharts-border-radius` | `^0.0.4` | Rounded chart corners |\n\nIf you use AG Grid or Highcharts in your app, also install:\n\n```bash\nnpm install ag-grid-community@36.0.1 ag-grid-react@36.0.1 ag-grid-enterprise@36.0.1\n# Optional, for charts:\nnpm install highcharts@^12 highcharts-react-official@^3 highcharts-border-radius@^0.0.4\n```\n\n## 2. Import styles in your root entry\n\nIn your app root (e.g. `main.tsx`, `App.tsx`, or `layout.tsx`), **import the CSS before your app component**:\n\n```tsx\nimport 'impact-nova/dist/impact-nova.css';\nimport App from './App';\n// ... rest of your bootstrap\n```\n\n## 3. Add Manrope font (recommended)\n\nIn your `index.html` or layout:\n\n```html\n<link href=\"https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap\" rel=\"stylesheet\" />\n```\n\nIn your global CSS or Tailwind base:\n\n```css\n@layer base {\n body {\n font-family: 'Manrope', sans-serif;\n }\n}\n```\n\n## 4. Wrap your app with providers (recommended)\n\nMount **`ImpactNovaProviders`** once at the app root. It bundles i18n (`ImpactNovaI18nProvider`) and `TooltipProvider` (required for tooltips since v2.0.8):\n\n```tsx\nimport { ImpactNovaProviders } from 'impact-nova/form';\n\nfunction Root() {\n return (\n <ImpactNovaProviders locale=\"en\">\n <App />\n </ImpactNovaProviders>\n );\n}\n```\n\nFor another locale, pass a locale pack:\n\n```tsx\nimport { ImpactNovaProviders } from 'impact-nova/form';\nimport { de } from 'impact-nova/locale/de';\n\n<ImpactNovaProviders locale=\"de\" messages={de}>\n <App />\n</ImpactNovaProviders>\n```\n\n**Barrel exception:** locale packs may use `import { de } from 'impact-nova'`. All UI components still use subpaths (see §5).\n\n## 5. Subpath imports (recommended)\n\nPrefer subpath imports in feature code for tree-shaking:\n\n```tsx\nimport { Button } from 'impact-nova/button';\nimport { Card, CardContent } from 'impact-nova/card';\nimport { DataTable, DataTableContent, useDataTable } from 'impact-nova/data-table';\nimport { CheckCircle } from 'impact-nova-icons';\n```\n\nThe barrel `import { Button } from 'impact-nova'` still works but pulls a larger module graph. **Use subpaths for all UI components**; reserve the barrel for locale packs at app root only. Use `ImpactNovaProviders` from `impact-nova/form` for app setup.\n\n## 6. Using Impact Nova with CSS or SCSS (no Tailwind)\n\nIf your app uses **plain CSS or SCSS** and does **not** use Tailwind, you can still use Impact Nova. Tailwind is optional. Impact Nova ships a single built CSS file (no SCSS source).\n\n- **Import the library CSS** in your app root (e.g. `main.tsx`, `App.tsx`):\n ```tsx\n import 'impact-nova/dist/impact-nova.css';\n ```\n **CSS split exports** (optional, for layered theming): `impact-nova/impact-nova-tokens.scss`, `impact-nova/impact-nova-base.scss`, `impact-nova/impact-nova-components.css`\n Or from your main stylesheet: `@import 'impact-nova/dist/impact-nova.css';` in your main.css or main.scss.\n- **Component styling** comes from Impact Nova's CSS. Use each component's `variant` and `size` props; no Tailwind classes are required.\n- **Your layout and spacing** stay in your CSS or SCSS (margins, padding, flexbox, grid). Use your usual class names; the design system does not require Tailwind utilities.\n- **Manrope font:** Add the font link in `index.html` and in your CSS/SCSS set `body { font-family: 'Manrope', sans-serif; }` (see section 3).\n- **Summary:** No Tailwind, no Tailwind config. Load `impact-nova.css` once; use components with their props; use your existing CSS/SCSS for the rest.\n\n## 7. Using Impact Nova with Webpack\n\nIf your app is built with **Webpack** (including Create React App, which uses Webpack):\n\n- **CSS import:** Webpack will bundle the library CSS as long as you have a rule for `.css`. Ensure your config includes something like:\n ```js\n module: {\n rules: [\n {\n test: /\\.css$/,\n use: ['style-loader', 'css-loader'],\n // or with MiniCssExtractPlugin:\n // use: [MiniCssExtractPlugin.loader, 'css-loader'],\n },\n // ... other rules (e.g. for .tsx, .js)\n ],\n },\n ```\n Then in your root component or entry:\n ```tsx\n import 'impact-nova/dist/impact-nova.css';\n ```\n- **Create React App (CRA):** No extra config. Add `import 'impact-nova/dist/impact-nova.css';` in `index.tsx` or `App.tsx`.\n- **Dedupe React / AG Grid:** If you see “multiple copies of React” or AG Grid issues, use Webpack’s `resolve.alias` so the app uses a single version:\n ```js\n resolve: {\n alias: {\n react: path.resolve(__dirname, 'node_modules/react'),\n 'react-dom': path.resolve(__dirname, 'node_modules/react-dom'),\n // If using AG Grid:\n 'ag-grid-react': path.resolve(__dirname, 'node_modules/ag-grid-react'),\n 'ag-grid-community': path.resolve(__dirname, 'node_modules/ag-grid-community'),\n 'ag-grid-enterprise': path.resolve(__dirname, 'node_modules/ag-grid-enterprise'),\n },\n },\n ```\n- **Tailwind + Webpack:** If you use Tailwind, add the Impact Nova preset and include the package in `content` (see section 7 below).\n\n## 8. Optional: extend Tailwind with Impact Nova preset\n\nIf your project uses Tailwind and you want the same theme (colors, radius), extend your `tailwind.config.js` with the preset from the package:\n\n```js\n// tailwind.config.js\nimport impactNovaPreset from 'impact-nova/tailwind.config.js';\n\nexport default {\n presets: [impactNovaPreset],\n content: [\n './index.html',\n './src/**/*.{js,ts,jsx,tsx}',\n './node_modules/impact-nova/dist/**/*.js',\n ],\n // ... rest of your config\n};\n```\n\n## Summary checklist\n\n- [ ] `npm install impact-nova impact-nova-icons` (and react, react-dom; optional: ag-grid, highcharts)\n- [ ] `import 'impact-nova/dist/impact-nova.css'` in root entry (or @import in main.css/main.scss if using CSS or SCSS without Tailwind; see §6)\n- [ ] Add Manrope font link and body font-family\n- [ ] Wrap app with `<ImpactNovaProviders locale=\"en\">` from `impact-nova/form`\n- [ ] Use subpath imports in feature code (see §5)\n- [ ] (Optional) Add Tailwind preset and content path for impact-nova\n- [ ] **Webpack:** Ensure a CSS rule (style-loader + css-loader) and, if needed, resolve.alias for React/AG Grid\n\nAfter this, import components via subpaths: `import { Button } from 'impact-nova/button';`\n\n## 9. Dashboard app shell (optional)\n\nTo scaffold a full dashboard (sidebar, header, breadcrumb, filters), read resource **`impact-nova://layout`** or call `get_real_world_patterns` with `topic: \"layout\"`. Use `Layout` from `impact-nova/layout` — not `DynamicLayout` (grid/flex utility only).\n";
1
+ export default "# Install and configure Impact Nova\n\nUse these steps to add Impact Nova to an existing project. Run the commands in your project root and apply the code changes to your entry file and layout.\n\n## 0. Scaffold a new app (recommended)\n\n**`create-impact-nova@^1.2.0`** is on npm. Scaffold auto-detects dependency mode:\n\n| Where you run | `impact-nova` dependency |\n|---------------|--------------------------|\n| Published CLI / MCP (outside monorepo) | `impact-nova@alpha` (`^2.1.0-alpha.6`) from npm |\n| Inside impact-nova monorepo | `file:` link to repo root |\n\n```bash\nnpx create-impact-nova my-dashboard\ncd my-dashboard\nnpm run dev\n```\n\nMCP: **`scaffold_impact_nova_app`** with `projectName` and optional `modules[]` from the user prompt.\n\n**Overrides:** CLI `--from-npm` · `--link-monorepo` · MCP `usePublishedPackages: true | false`\n\n```bash\nnpx create-impact-nova my-dashboard --from-npm\n```\n\nBase template is shell-only (Home + shared primitives). Feature pages come from recipes — see `create-impact-nova/recipes/README.md`.\n\n**Local link in an existing app** (manual):\n\n```bash\nnpm install impact-nova@file:../path-to-impact-nova-repo\n```\n\nRun `npm run build` in the impact-nova repo after design-system changes.\n\n## 1. Install the package and peer dependencies\n\n```bash\nnpm install impact-nova impact-nova-icons\nnpm install react@^19 react-dom@^19\n```\n\n**Required peers:** `react@^19`, `react-dom@^19`, `impact-nova-icons@^0.1.1`\n\n**Optional peers** (install when you use these features):\n\n| Package | Version | When needed |\n|---------|---------|-------------|\n| `ag-grid-community` | `36.0.1` | AG Grid types/API (pin with react + enterprise) |\n| `ag-grid-react` | `36.0.1` | DataTable / AG Grid |\n| `ag-grid-enterprise` | `36.0.1` | Enterprise grid features |\n| `highcharts` | `^12` | Chart component |\n| `highcharts-react-official` | `^3` | Chart component |\n| `highcharts-border-radius` | `^0.0.4` | Rounded chart corners |\n\nIf you use AG Grid or Highcharts in your app, also install:\n\n```bash\nnpm install ag-grid-community@36.0.1 ag-grid-react@36.0.1 ag-grid-enterprise@36.0.1\n# Optional, for charts:\nnpm install highcharts@^12 highcharts-react-official@^3 highcharts-border-radius@^0.0.4\n```\n\n## 2. Import styles in your root entry\n\nIn your app root (e.g. `main.tsx`, `App.tsx`, or `layout.tsx`), **import the CSS before your app component**:\n\n```tsx\nimport 'impact-nova/dist/impact-nova.css';\nimport App from './App';\n// ... rest of your bootstrap\n```\n\n## 3. Add Manrope font (recommended)\n\nIn your `index.html` or layout:\n\n```html\n<link href=\"https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap\" rel=\"stylesheet\" />\n```\n\nIn your global CSS or Tailwind base:\n\n```css\n@layer base {\n body {\n font-family: 'Manrope', sans-serif;\n }\n}\n```\n\n## 4. Wrap your app with providers (recommended)\n\nMount **`ImpactNovaProviders`** once at the app root. It bundles i18n (`ImpactNovaI18nProvider`) and `TooltipProvider` (required for tooltips since v2.0.8):\n\n```tsx\nimport { ImpactNovaProviders } from 'impact-nova/form';\n\nfunction Root() {\n return (\n <ImpactNovaProviders locale=\"en\">\n <App />\n </ImpactNovaProviders>\n );\n}\n```\n\nFor another locale, pass a locale pack:\n\n```tsx\nimport { ImpactNovaProviders } from 'impact-nova/form';\nimport { de } from 'impact-nova/locale/de';\n\n<ImpactNovaProviders locale=\"de\" messages={de}>\n <App />\n</ImpactNovaProviders>\n```\n\n**Barrel exception:** locale packs may use `import { de } from 'impact-nova'`. All UI components still use subpaths (see §5).\n\n## 5. Subpath imports (recommended)\n\nPrefer subpath imports in feature code for tree-shaking:\n\n```tsx\nimport { Button } from 'impact-nova/button';\nimport { Card, CardContent } from 'impact-nova/card';\nimport { DataTable, DataTableContent, useDataTable } from 'impact-nova/data-table';\nimport { CheckCircle } from 'impact-nova-icons';\n```\n\nThe barrel `import { Button } from 'impact-nova'` still works but pulls a larger module graph. **Use subpaths for all UI components**; reserve the barrel for locale packs at app root only. Use `ImpactNovaProviders` from `impact-nova/form` for app setup.\n\n## 6. Using Impact Nova with CSS or SCSS (no Tailwind)\n\nIf your app uses **plain CSS or SCSS** and does **not** use Tailwind, you can still use Impact Nova. Tailwind is optional. Impact Nova ships a single built CSS file (no SCSS source).\n\n- **Import the library CSS** in your app root (e.g. `main.tsx`, `App.tsx`):\n ```tsx\n import 'impact-nova/dist/impact-nova.css';\n ```\n **CSS split exports** (optional, for layered theming): `impact-nova/impact-nova-tokens.scss`, `impact-nova/impact-nova-base.scss`, `impact-nova/impact-nova-components.css`\n Or from your main stylesheet: `@import 'impact-nova/dist/impact-nova.css';` in your main.css or main.scss.\n- **Component styling** comes from Impact Nova's CSS. Use each component's `variant` and `size` props; no Tailwind classes are required.\n- **Your layout and spacing** stay in your CSS or SCSS (margins, padding, flexbox, grid). Use your usual class names; the design system does not require Tailwind utilities.\n- **Manrope font:** Add the font link in `index.html` and in your CSS/SCSS set `body { font-family: 'Manrope', sans-serif; }` (see section 3).\n- **Summary:** No Tailwind, no Tailwind config. Load `impact-nova.css` once; use components with their props; use your existing CSS/SCSS for the rest.\n\n## 7. Using Impact Nova with Webpack\n\nIf your app is built with **Webpack** (including Create React App, which uses Webpack):\n\n- **CSS import:** Webpack will bundle the library CSS as long as you have a rule for `.css`. Ensure your config includes something like:\n ```js\n module: {\n rules: [\n {\n test: /\\.css$/,\n use: ['style-loader', 'css-loader'],\n // or with MiniCssExtractPlugin:\n // use: [MiniCssExtractPlugin.loader, 'css-loader'],\n },\n // ... other rules (e.g. for .tsx, .js)\n ],\n },\n ```\n Then in your root component or entry:\n ```tsx\n import 'impact-nova/dist/impact-nova.css';\n ```\n- **Create React App (CRA):** No extra config. Add `import 'impact-nova/dist/impact-nova.css';` in `index.tsx` or `App.tsx`.\n- **Dedupe React / AG Grid:** If you see “multiple copies of React” or AG Grid issues, use Webpack’s `resolve.alias` so the app uses a single version:\n ```js\n resolve: {\n alias: {\n react: path.resolve(__dirname, 'node_modules/react'),\n 'react-dom': path.resolve(__dirname, 'node_modules/react-dom'),\n // If using AG Grid:\n 'ag-grid-react': path.resolve(__dirname, 'node_modules/ag-grid-react'),\n 'ag-grid-community': path.resolve(__dirname, 'node_modules/ag-grid-community'),\n 'ag-grid-enterprise': path.resolve(__dirname, 'node_modules/ag-grid-enterprise'),\n },\n },\n ```\n- **Tailwind + Webpack:** If you use Tailwind, add the Impact Nova preset and include the package in `content` (see section 7 below).\n\n## 8. Optional: extend Tailwind with Impact Nova preset\n\nIf your project uses Tailwind and you want the same theme (colors, radius), extend your `tailwind.config.js` with the preset from the package:\n\n```js\n// tailwind.config.js\nimport impactNovaPreset from 'impact-nova/tailwind.config.js';\n\nexport default {\n presets: [impactNovaPreset],\n content: [\n './index.html',\n './src/**/*.{js,ts,jsx,tsx}',\n './node_modules/impact-nova/dist/**/*.js',\n ],\n // ... rest of your config\n};\n```\n\n## Summary checklist\n\n- [ ] `npm install impact-nova impact-nova-icons` (and react, react-dom; optional: ag-grid, highcharts)\n- [ ] `import 'impact-nova/dist/impact-nova.css'` in root entry (or @import in main.css/main.scss if using CSS or SCSS without Tailwind; see §6)\n- [ ] Add Manrope font link and body font-family\n- [ ] Wrap app with `<ImpactNovaProviders locale=\"en\">` from `impact-nova/form`\n- [ ] Use subpath imports in feature code (see §5)\n- [ ] (Optional) Add Tailwind preset and content path for impact-nova\n- [ ] **Webpack:** Ensure a CSS rule (style-loader + css-loader) and, if needed, resolve.alias for React/AG Grid\n\nAfter this, import components via subpaths: `import { Button } from 'impact-nova/button';`\n\n## 9. Dashboard app shell (optional)\n\nTo scaffold a full dashboard (sidebar, header, breadcrumb, filters), read resource **`impact-nova://layout`** or call `get_real_world_patterns` with `topic: \"layout\"`. Use `Layout` from `impact-nova/layout` — not `DynamicLayout` (grid/flex utility only).\n";
@@ -1 +1 @@
1
- export default "# Impact Nova — baseline\n\nUse **Impact Nova** design-system components and tokens. Prefer subpath imports (e.g. `impact-nova/button`) when you only need a few modules. For live component lists, specs, and codegen, use the **impact-nova-mcp** MCP server (see npm `impact-nova-mcp`). Browse **Storybook**: https://impact-nova.iaproducts.ai/\n\n## Peer dependency summary\n\n```json\n{\n \"impactNova\": {\n \"package\": \"impact-nova\",\n \"recommendedVersion\": \"2.1.0-alpha.6\",\n \"recommendedDistTag\": \"alpha\",\n \"description\": \"Design system package — ESM with 90+ subpath exports. Install: npm install impact-nova@alpha\"\n },\n \"createImpactNova\": {\n \"package\": \"create-impact-nova\",\n \"recommendedVersion\": \"^1.1.0\",\n \"description\": \"Vite + React scaffold with recipe-based modules\"\n },\n \"localDevelopment\": {\n \"defaultScaffoldDependency\": \"auto\",\n \"description\": \"create-impact-nova auto-detects: file: link when run inside the impact-nova monorepo; npm (impact-nova@alpha / ^2.1.0-alpha.6) otherwise. CLI: --from-npm or --link-monorepo to override. Rebuild impact-nova (npm run build) after DS changes when using file: link.\",\n \"cliFlagForNpm\": \"--from-npm\",\n \"cliFlagForMonorepo\": \"--link-monorepo\",\n \"mcpScaffoldFlag\": \"usePublishedPackages: true | false (omit for auto-detect)\"\n },\n \"mandatoryRules\": {\n \"componentsOnly\": \"Use Impact Nova components only — never create new custom UI components\",\n \"tables\": \"Any table/grid/spreadsheet → DataTable from impact-nova/data-table (not HTML table, not raw ag-grid-react)\",\n \"validateBeforeDone\": \"Call validate_snippet on generated UI code\",\n \"resource\": \"impact-nova://design-system-mandate\"\n },\n \"requiredPeers\": [\n {\n \"package\": \"react\",\n \"recommendedVersion\": \"^19.0.0\",\n \"description\": \"React 19 required\"\n },\n {\n \"package\": \"react-dom\",\n \"recommendedVersion\": \"^19.0.0\",\n \"description\": \"React DOM 19 required\"\n },\n {\n \"package\": \"impact-nova-icons\",\n \"recommendedVersion\": \"^0.1.1\",\n \"description\": \"Icons peer — not bundled in impact-nova\"\n }\n ],\n \"optionalPeers\": [\n {\n \"package\": \"ag-grid-community\",\n \"recommendedVersion\": \"36.0.1\",\n \"description\": \"AG Grid community types/API; pin to the same version as ag-grid-react\"\n },\n {\n \"package\": \"ag-grid-react\",\n \"recommendedVersion\": \"36.0.1\",\n \"description\": \"For DataTable and grid components; use exact version to match Impact Nova\"\n },\n {\n \"package\": \"ag-grid-enterprise\",\n \"recommendedVersion\": \"36.0.1\",\n \"description\": \"Required if using ag-grid-react with enterprise features\"\n },\n {\n \"package\": \"highcharts\",\n \"recommendedVersion\": \"^12.0.0\",\n \"description\": \"For Chart component\"\n },\n {\n \"package\": \"highcharts-react-official\",\n \"recommendedVersion\": \"^3.0.0\",\n \"description\": \"For Chart component\"\n },\n {\n \"package\": \"highcharts-border-radius\",\n \"recommendedVersion\": \"^0.0.4\",\n \"description\": \"Optional Highcharts plugin for rounded corners\"\n }\n ]\n}\n```\n";
1
+ export default "# Impact Nova — baseline\n\nUse **Impact Nova** design-system components and tokens. Prefer subpath imports (e.g. `impact-nova/button`) when you only need a few modules. For live component lists, specs, and codegen, use the **impact-nova-mcp** MCP server (see npm `impact-nova-mcp`). Browse **Storybook**: https://impact-nova.iaproducts.ai/\n\n## Peer dependency summary\n\n```json\n{\n \"impactNova\": {\n \"package\": \"impact-nova\",\n \"recommendedVersion\": \"2.1.0-alpha.6\",\n \"recommendedDistTag\": \"alpha\",\n \"description\": \"Design system package — ESM with 90+ subpath exports. Install: npm install impact-nova@alpha\"\n },\n \"createImpactNova\": {\n \"package\": \"create-impact-nova\",\n \"recommendedVersion\": \"^1.2.0\",\n \"description\": \"Vite + React scaffold with recipe-based modules\"\n },\n \"localDevelopment\": {\n \"defaultScaffoldDependency\": \"auto\",\n \"description\": \"create-impact-nova auto-detects: file: link when run inside the impact-nova monorepo; npm (impact-nova@alpha / ^2.1.0-alpha.6) otherwise. CLI: --from-npm or --link-monorepo to override. Rebuild impact-nova (npm run build) after DS changes when using file: link.\",\n \"cliFlagForNpm\": \"--from-npm\",\n \"cliFlagForMonorepo\": \"--link-monorepo\",\n \"mcpScaffoldFlag\": \"usePublishedPackages: true | false (omit for auto-detect)\"\n },\n \"mandatoryRules\": {\n \"componentsOnly\": \"Use Impact Nova components only — never create new custom UI components\",\n \"tables\": \"Any table/grid/spreadsheet → DataTable from impact-nova/data-table (not HTML table, not raw ag-grid-react)\",\n \"validateBeforeDone\": \"Call validate_snippet on generated UI code\",\n \"resource\": \"impact-nova://design-system-mandate\"\n },\n \"requiredPeers\": [\n {\n \"package\": \"react\",\n \"recommendedVersion\": \"^19.0.0\",\n \"description\": \"React 19 required\"\n },\n {\n \"package\": \"react-dom\",\n \"recommendedVersion\": \"^19.0.0\",\n \"description\": \"React DOM 19 required\"\n },\n {\n \"package\": \"impact-nova-icons\",\n \"recommendedVersion\": \"^0.1.1\",\n \"description\": \"Icons peer — not bundled in impact-nova\"\n }\n ],\n \"optionalPeers\": [\n {\n \"package\": \"ag-grid-community\",\n \"recommendedVersion\": \"36.0.1\",\n \"description\": \"AG Grid community types/API; pin to the same version as ag-grid-react\"\n },\n {\n \"package\": \"ag-grid-react\",\n \"recommendedVersion\": \"36.0.1\",\n \"description\": \"For DataTable and grid components; use exact version to match Impact Nova\"\n },\n {\n \"package\": \"ag-grid-enterprise\",\n \"recommendedVersion\": \"36.0.1\",\n \"description\": \"Required if using ag-grid-react with enterprise features\"\n },\n {\n \"package\": \"highcharts\",\n \"recommendedVersion\": \"^12.0.0\",\n \"description\": \"For Chart component\"\n },\n {\n \"package\": \"highcharts-react-official\",\n \"recommendedVersion\": \"^3.0.0\",\n \"description\": \"For Chart component\"\n },\n {\n \"package\": \"highcharts-border-radius\",\n \"recommendedVersion\": \"^0.0.4\",\n \"description\": \"Optional Highcharts plugin for rounded corners\"\n }\n ]\n}\n```\n";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "impact-nova",
3
- "version": "2.1.0-alpha.6",
3
+ "version": "2.1.0-alpha.7",
4
4
  "description": "Enterprise-grade React design system built with React 19, Vite, Tailwind CSS, and Radix UI. Built-in internationalization (i18n) and comprehensive UI component library for scalable, accessible, and performant applications.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -701,7 +701,7 @@
701
701
  },
702
702
  "scripts": {
703
703
  "dev": "vite",
704
- "prepublishOnly": "npm i && npm run build",
704
+ "prepublishOnly": "npm run ci",
705
705
  "publish:alpha": "npm publish --tag alpha --access public",
706
706
  "validate-imports": "node scripts/validate-imports.mjs",
707
707
  "build:registry": "node scripts/build-registry.mjs && node scripts/sync-registry-to-mcp.mjs",