impact-nova 2.1.0-alpha.9 → 2.2.1
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.
- package/README.md +6 -0
- package/dist/components/data/ag-grid-react/cell-renderers/editors/split-cell-editor.js +73 -94
- package/dist/components/data/ag-grid-react/cell-renderers/editors/split-cell-focus.d.ts +53 -0
- package/dist/components/data/ag-grid-react/cell-renderers/editors/split-cell-focus.js +98 -0
- package/dist/components/data/ag-grid-react/headers/column-menu/column-settings-menu.js +15 -13
- package/dist/components/data/ag-grid-react/headers/custom-header.js +56 -58
- package/dist/components/data/ag-grid-react/headers/custom-inner-header-group.d.ts +12 -0
- package/dist/components/data/ag-grid-react/headers/custom-inner-header-group.js +31 -0
- package/dist/components/data/ag-grid-react/headers/header-search-active-state.d.ts +10 -0
- package/dist/components/data/ag-grid-react/headers/header-search-active-state.js +38 -0
- package/dist/components/data/ag-grid-react/index.js +166 -163
- package/dist/components/data/ag-grid-react/notify-column-indicator-sync.d.ts +3 -4
- package/dist/components/data/ag-grid-react/theme.js +0 -2
- package/dist/components/data/data-table/data-table-column-list.js +1 -1
- package/dist/components/data/data-table/data-table-saved-views.js +1 -1
- package/dist/components/data/expandable-list-item/expandable-list-item-attributes.js +7 -6
- package/dist/components/data/nested-list/components/SortableItem.d.ts +3 -1
- package/dist/components/data/nested-list/components/SortableItem.js +111 -109
- package/dist/components/data-display/calendar/calendar-footer-emphasis.d.ts +28 -0
- package/dist/components/data-display/calendar/calendar-footer-emphasis.js +8 -0
- package/dist/components/data-display/calendar/calendar-footer.d.ts +4 -1
- package/dist/components/data-display/calendar/calendar-footer.js +60 -38
- package/dist/components/data-display/calendar/calendar.js +86 -82
- package/dist/components/data-display/calendar/calendar.types.d.ts +2 -0
- package/dist/components/data-display/calendar/use-calendar-state.d.ts +3 -0
- package/dist/components/feedback/tooltip/tab-tooltip-render.js +3 -2
- package/dist/components/flows/filter-strip/filter-strip.js +36 -29
- package/dist/components/flows/filter-strip/filter-summary.js +2 -2
- package/dist/components/forms/date-picker/date-input-behavior.d.ts +118 -0
- package/dist/components/forms/date-picker/date-input-behavior.js +164 -0
- package/dist/components/forms/date-picker/date-picker.js +202 -138
- package/dist/components/forms/date-picker/date-range-picker.js +302 -215
- package/dist/components/forms/date-picker/month-picker.js +160 -119
- package/dist/components/forms/date-picker/month-range-picker.js +302 -245
- package/dist/components/forms/date-picker/multi-date-picker.js +94 -80
- package/dist/components/forms/date-picker/multi-month-picker.js +97 -83
- package/dist/components/forms/date-picker/multi-week-picker.js +107 -93
- package/dist/components/forms/date-picker/week-picker.js +230 -140
- package/dist/components/forms/date-picker/week-range-picker.js +332 -226
- package/dist/components/forms/file-upload/file-upload.js +312 -174
- package/dist/components/forms/file-upload/file-upload.types.d.ts +17 -2
- package/dist/components/layout/dynamic-layout/dynamic-layout.variants.d.ts +1 -1
- package/dist/components/layout/header/header.js +45 -38
- package/dist/components/layout/horizontal-scroller/index.d.ts +1 -0
- package/dist/components/layout/horizontal-scroller/index.js +3 -2
- package/dist/components/ui/local-raster-icons/assets/excel-error-icon.webp.js +4 -0
- package/dist/components/ui/local-raster-icons/assets/file-upload-error.webp.js +4 -0
- package/dist/components/ui/local-raster-icons/rasterIcons.d.ts +2 -0
- package/dist/components/ui/local-raster-icons/rasterIcons.js +32 -22
- package/dist/components/ui/show.d.ts +10 -0
- package/dist/components/ui/show.js +7 -0
- package/dist/components/ui/show.types.d.ts +5 -0
- package/dist/i18n/defaultMessages.d.ts +17 -0
- package/dist/i18n/defaultMessages.js +29 -17
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/locales/de.js +12 -0
- package/dist/i18n/locales/es.js +12 -0
- package/dist/i18n/locales/hi.js +12 -0
- package/dist/i18n/locales/kn.js +12 -0
- package/dist/impact-nova-base.scss +6 -2
- package/dist/impact-nova-components.css +141 -16
- package/dist/impact-nova-tokens.scss +12 -0
- package/dist/impact-nova.css +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +273 -271
- package/dist/lib/utils.js +40 -24
- package/dist/llms/rules/ag-grid.js +1 -1
- package/dist/llms/rules/installation.js +1 -1
- package/dist/llms/rules/requirements.js +1 -1
- package/dist/tailwind.config.js +36 -4
- package/dist/theme/tailwind-colors.js +3 -1
- package/package.json +15 -6
- package/tailwind.config.d.ts +3 -0
- package/dist/components/data/ag-grid-react/headers/custom-header-group.d.ts +0 -10
- package/dist/components/data/ag-grid-react/headers/custom-header-group.js +0 -58
package/dist/lib/utils.js
CHANGED
|
@@ -1,34 +1,50 @@
|
|
|
1
|
-
import { clsx as
|
|
2
|
-
import { twMerge as
|
|
3
|
-
function
|
|
4
|
-
return
|
|
1
|
+
import { clsx as p } from "clsx";
|
|
2
|
+
import { twMerge as u } from "tailwind-merge";
|
|
3
|
+
function S(...e) {
|
|
4
|
+
return u(p(e));
|
|
5
5
|
}
|
|
6
|
-
function
|
|
7
|
-
if (!
|
|
8
|
-
const
|
|
9
|
-
for (let
|
|
10
|
-
let
|
|
11
|
-
const
|
|
12
|
-
if (
|
|
13
|
-
const
|
|
14
|
-
|
|
6
|
+
function $(e, r, t = "") {
|
|
7
|
+
if (!e) return "";
|
|
8
|
+
const s = r.replace(/[a-zA-Z]/g, "")[0] || "/", g = t && e.length < t.length, i = e.split(s), a = r.split(s), o = [];
|
|
9
|
+
for (let n = 0; n < i.length && !(n >= a.length); n++) {
|
|
10
|
+
let l = i[n].replace(/[^0-9]/g, "");
|
|
11
|
+
const c = a[n].length;
|
|
12
|
+
if (l.length > c) {
|
|
13
|
+
const f = l.substring(c);
|
|
14
|
+
l = l.substring(0, c), i[n + 1] !== void 0 ? i[n + 1] = f + i[n + 1] : i.push(f);
|
|
15
15
|
}
|
|
16
|
-
!
|
|
16
|
+
!g && n < i.length - 1 && l.length > 0 && l.length < c && (l = l.padStart(c, "0")), o.push(l);
|
|
17
17
|
}
|
|
18
|
-
let h =
|
|
19
|
-
if (!
|
|
20
|
-
const
|
|
21
|
-
|
|
18
|
+
let h = o.join(s);
|
|
19
|
+
if (!g) {
|
|
20
|
+
const n = o.length - 1;
|
|
21
|
+
n < a.length - 1 && o[n].length === a[n].length && (h.endsWith(s) || (h += s));
|
|
22
22
|
}
|
|
23
23
|
return h;
|
|
24
24
|
}
|
|
25
|
-
function
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
function d(e) {
|
|
26
|
+
return e.replace(/[a-zA-Z]/g, "")[0] || "/";
|
|
27
|
+
}
|
|
28
|
+
function m(e, r) {
|
|
29
|
+
const t = e.replace(/[^0-9]/g, "");
|
|
30
|
+
if (!t) return "";
|
|
31
|
+
if (/^y+$/i.test(r)) {
|
|
32
|
+
if (t.length === 1) return `200${t}`;
|
|
33
|
+
if (t.length === 2) {
|
|
34
|
+
const s = Number.parseInt(t, 10), g = t.padStart(2, "0");
|
|
35
|
+
return s <= 69 ? `20${g}` : `19${g}`;
|
|
36
|
+
}
|
|
37
|
+
return t.length === 3 ? `2${t}` : t.length >= r.length ? t.slice(0, r.length) : t.padStart(r.length, "0");
|
|
38
|
+
}
|
|
39
|
+
return t.padStart(r.length, "0");
|
|
40
|
+
}
|
|
41
|
+
function b(e, r) {
|
|
42
|
+
if (!e) return "";
|
|
43
|
+
const t = d(r), s = e.split(t), g = r.split(t);
|
|
44
|
+
return s.map((i, a) => g[a] ? m(i, g[a]) : i).join(t);
|
|
29
45
|
}
|
|
30
46
|
export {
|
|
31
|
-
|
|
32
|
-
|
|
47
|
+
S as cn,
|
|
48
|
+
$ as maskDate,
|
|
33
49
|
b as padValidDateString
|
|
34
50
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default "# AG Grid & Data Table — Mandatory Rules\n\n**When working with DataTable, or any data table that uses AG Grid (including Impact Nova's grid components), the following rules are mandatory. Do not deviate.**\n\n---\n\n## 1. Use AG Grid documentation only\n\n- **Refer only to AG Grid's official documentation** for grid behavior, APIs, column definitions, filtering, sorting, and all grid features.\n- Do not rely on third-party tutorials or generic \"data grid\" patterns that contradict or bypass AG Grid's docs.\n- Official docs: [ag-grid.com/documentation](https://www.ag-grid.com/documentation/) (React: [AG Grid React](https://www.ag-grid.com/react-data-grid/)).\n\n---\n\n## 2. Follow AG Grid recommended patterns\n\n- **Always follow AG Grid's recommended patterns** for:\n - Column definitions (`ColDef`, `ColGroupDef`)\n - Cell renderers and editors\n - Filtering, sorting, and row selection\n - API ref access (`gridRef.current?.api`)\n - Theming and styling (AG Grid theme / CSS variables)\n- Do not invent custom patterns that bypass or replace AG Grid's intended usage.\n\n---\n\n## 3. Use the AG Grid API only\n\n- **Rely on the AG Grid API only** for all grid operations:\n - Getting/setting data, refreshing cells, updating columns\n - Export (CSV/Excel if using Enterprise)\n - Filter/sort state, row selection, pinned columns\n - Any behavior that AG Grid exposes via its API\n- Do not manipulate the DOM or internal structure of the grid directly. Do not use non-API workarounds unless AG Grid docs explicitly suggest them.\n\n---\n\n## 4. Collaboration with ag-mcp (when installed)\n\n- **If the user has installed the ag-mcp server** (AG Grid MCP), this MCP can collaborate with it:\n - Use **ag-mcp** for AG Grid–specific questions: API reference, column config, React integration, and official examples.\n - Use **impact-nova-mcp** for Impact Nova wrappers (`DataTable`, `DataTableContent`, `processBackendColumnDefs`, `BackendColDef`, cell renderers from `impact-nova/ag-grid-react/cell-renderers`).\n - When generating or editing grid code: prefer fetching AG Grid details from ag-mcp when available, and combine with Impact Nova's DataTable/column/cell-renderer patterns from this MCP.\n- If ag-mcp is not installed, still follow rules 1–3 using AG Grid's official documentation only.\n\n---\n\n**Summary:** For any code or design involving AG Grid or Impact Nova's DataTable (which uses AG Grid), use **only** AG Grid documentation, **only** AG Grid recommended patterns, and **only** the AG Grid API—with no deviation. When ag-mcp is available, use it to get accurate AG Grid API and docs; use this MCP for Impact Nova–specific integration.\n\n---\n\n## 5. Mandatory Data Table component usage\n\n**CRITICAL RULE:** If you see a table in a screenshot, or if the user asks for a table by default, you **MUST** use **Impact Nova DataTable** from `impact-nova/data-table`. **Do not build a raw AG Grid or HTML table.**\n\n```tsx\nimport {\n DataTable,\n DataTableContent,\n DataTableToolbar,\n useDataTable,\n} from 'impact-nova/data-table';\n```\n\nA typical Default Data Table in Impact Nova features this exact structure:\n\n```tsx\nconst DataTableWithFilters = () => {\n const { tStory } = useStorybookStoryI18n();\n const [sheetOpen, setSheetOpen] = useState(false);\n const [activeTab, setActiveTab] = useState(\"columns\");\n const [showFilterStrip, setShowFilterStrip] = useState(false);\n\n return (\n <div className=\"h-[800px] w-full p-8 bg-slate-50 flex flex-col items-center justify-center\">\n <div className=\"w-full max-w-[1200px] h-[600px] bg-white rounded-lg overflow-hidden flex flex-col [box-shadow:0px_0px_4px_0px_rgba(0,0,0,0.12)]\">\n <DataTable className=\"h-full\">\n <DataTableToolbar className=\"border-b border-[#e6e8f0]\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"font-bold text-sm text-slate-800\">Sales Report</h2>\n </div>\n \n <div className=\"flex items-center gap-2\">\n <Button \n variant=\"secondary\" \n size=\"icon\" \n onClick={() => setShowFilterStrip(!showFilterStrip)}\n aria-label={showFilterStrip ? tStory('filterStrip.hideFilters') : tStory('filterStrip.showFilters')}\n >\n {showFilterStrip ? <FunnelHide size=\"xs\" /> : <FunnelShow size=\"xs\" />}\n </Button>\n\n <div className=\"h-4 w-[1px] bg-[#e6e8f0] mx-1\" />\n\n {/* Scoped Sheet for Settings - Renders inside this relative container */}\n <DataTableSheet open={sheetOpen} onOpenChange={setSheetOpen}>\n <DropdownMenu>\n <DataTableViewMenuTrigger />\n <DataTableViewMenuContent>\n <DataTableViewMenuSettingsItem />\n <DataTableViewMenuDensity />\n </DataTableViewMenuContent>\n </DropdownMenu>\n \n <DataTableSheetContent>\n <DataTableSheetHeader title=\"Table Settings\" />\n <Tabs value={activeTab} onValueChange={setActiveTab} variant=\"line\" hideInactiveLabel tooltipClassName=\"z-[110]\" className=\"flex-1 flex flex-col min-h-0 w-full px-4\">\n <TabsList>\n <TabsTrigger \n value=\"columns\" \n icon={<Column size={16} />}\n >\n Columns\n </TabsTrigger>\n <TabsTrigger \n value=\"format\" \n icon={<Font size={16} />}\n >\n Format\n </TabsTrigger>\n <TabsTrigger \n value=\"custom-filters\" \n icon={<Filter size={16} />}\n >\n Filters\n </TabsTrigger>\n </TabsList>\n \n <TabsContent value=\"columns\" className=\"flex-1 min-h-0 relative p-0 data-[state=inactive]:hidden mt-0\">\n <div className=\"flex-1 h-full p-2\">\n <DataTableColumnList />\n </div>\n </TabsContent>\n <TabsContent value=\"format\" className=\"flex-1 min-h-0 relative p-4 pt-1 data-[state=inactive]:hidden overflow-y-auto mt-0\">\n <DataTableFormatOptions />\n </TabsContent>\n <TabsContent value=\"custom-filters\" className=\"flex-1 min-h-0 relative p-4 pt-1 data-[state=inactive]:hidden overflow-y-auto mt-0\">\n <div className=\"flex flex-col gap-4 text-sm text-[#60697d]\">\n <p>Custom filter configuration would go here.</p>\n <Button variant=\"outline\" className=\"w-full justify-start\">\n + Add Condition\n </Button>\n </div>\n </TabsContent>\n </Tabs>\n </DataTableSheetContent>\n </DataTableSheet>\n </div>\n </DataTableToolbar>\n \n <DataTableContent\n rowData={rowData}\n columnDefs={columnDefs}\n // Standard AG Grid props work here\n pagination={true}\n paginationPageSize={20}\n />\n </DataTable>\n </div>\n <p className=\"mt-4 text-slate-400 text-sm\">\n Note: The settings panel opens *inside* the table container, respecting its boundaries.\n </p>\n </div>\n );\n};\n```\nNote: This component (`DataTable`) internally uses `ag-grid-react` as a customized version. Rely on it rather than naked AG Grid.\n\n---\n\n## 6. Built-in Clipboard Handlers for JSON Objects\n\n**All DataTable and AG Grid instances in Impact Nova automatically support copying and pasting JSON objects.**\n\nThe `AgGridWrapper` component includes built-in clipboard handlers that:\n- **When copying**: Automatically stringify object values to JSON format\n- **When pasting**: Automatically parse JSON strings back to objects\n\n### How it works\n\n```tsx\n// When you copy a cell with an object value like:\n{ \n wp: { value: 6479, _isDisabled: true, cellMetadata: {...} },\n iaf: { value: 6090, _isDisabled: true, cellMetadata: {...} }\n}\n\n// It's automatically converted and split into separate Excel columns:\n// Column 1 Column 2\n// WP: 6479 IAF: 6090\n\n// Technical metadata (_isDisabled, cellMetadata) is hidden for clarity\n// Only the meaningful \"value\" is shown - perfect for PMs and non-technical users\n// Tab-separated format automatically expands into multiple columns in Excel\n```\n\n**Example with simple properties:**\n```tsx\n// Copy this object:\n{ name: \"John\", age: 30, status: \"active\" }\n\n// Expands into 3 Excel columns:\n// Column 1 Column 2 Column 3\n// name: John age: 30 status: active\n```\n\n**When pasting:**\n```tsx\n// You can paste JSON strings and they'll be parsed back to objects:\n'{\"name\":\"Jane\",\"age\":25}' → { name: \"Jane\", age: 25 }\n```\n\n**Benefits:**\n- ✅ Simple and readable for non-technical users (PMs, stakeholders)\n- ✅ Extracts only meaningful values, hides technical metadata\n- ✅ Automatically expands object properties into separate Excel columns\n- ✅ Perfect for analysis - each property gets its own column\n- ✅ Works seamlessly for both single-cell and multi-cell copy operations\n- ✅ Still supports pasting JSON back for developers\n\n### Usage\n\n**No configuration needed!** This works automatically for all DataTable instances:\n\n```tsx\n<DataTable>\n <DataTableContent\n rowData={data}\n columnDefs={columns}\n // Clipboard handlers are already active ✅\n />\n</DataTable>\n```\n\n### Override if needed\n\nYou can override the default behavior by passing your own handlers:\n\n```tsx\n<DataTableContent\n rowData={data}\n columnDefs={columns}\n processCellForClipboard={(params) => {\n // Custom copy logic\n return customFormat(params.value);\n }}\n processCellFromClipboard={(params) => {\n // Custom paste logic\n return customParse(params.value);\n }}\n/>\n```\n\n**Key benefits:**\n- ✅ Works automatically for all tables\n- ✅ No code duplication needed\n- ✅ Handles complex object structures\n- ✅ Gracefully falls back to string if JSON parsing fails\n- ✅ Can be overridden when custom behavior is needed\n\n---\n\n## 6. Column autosize on container resize\n\n**AgGridWrapper** (from `impact-nova/ag-grid-react`) automatically re-runs `autoSizeStrategy` when the grid container width changes (accordion expand, viewport resize, responsive layout).\n\n- Pass `autoSizeStrategy` to DataTable/AgGridWrapper props (e.g. `{ type: 'fitCellContents', scaleUpToFitGridWidth: true }`).\n- **Do not** add app-level ResizeObserver hacks or deferred grid mount delays — the framework handles this.\n- When applying saved column views, wait for `firstDataRendered` or `newColumnsLoaded` grid events before applying column state — not `setTimeout(0)`.\n- Strip `width`/`flex` from saved column state when applying structural views so autosize can recalculate correctly.\n\n---\n\n## 7. AG Grid v36 version pin (mandatory)\n\nImpact Nova **2.1.0-alpha.7+** targets **AG Grid v36**. Consumer apps must install all three packages at the **exact same version**:\n\n```bash\nnpm install ag-grid-community@36.0.1 ag-grid-react@36.0.1 ag-grid-enterprise@36.0.1\n```\n\n**Rules:**\n\n- Pin `36.0.1` in `package.json` — do not float `^36` across community/react/enterprise.\n- Vite/webpack: `resolve.dedupe: ['ag-grid-community', 'ag-grid-enterprise', 'ag-grid-react']` (see `create-impact-nova` template).\n- **Do not** import legacy AG Grid CSS theme files (`ag-grid.css`, `ag-theme-*`). Impact Nova `AgGridWrapper` applies the v36 Quartz theme (`themeQuartz.withPart(iconSetMaterial)`) via the `theme` prop.\n- Column settings (`DataTableColumnList`) sync pin/sort/filter from the live `GridApi` — do not mirror column state in app-level React state.\n\n**Column settings sheet pattern:**\n\n```tsx\n<DataTableSheet open={sheetOpen} onOpenChange={setSheetOpen}>\n <DataTableSheetContent>\n <DataTableSheetHeader title=\"Table Settings\" />\n <Tabs defaultValue=\"columns\">\n <TabsList>\n <TabsTrigger value=\"columns\">Columns</TabsTrigger>\n <TabsTrigger value=\"format\">Format</TabsTrigger>\n </TabsList>\n <TabsContent value=\"columns\">\n <DataTableColumnList />\n </TabsContent>\n <TabsContent value=\"format\">\n <DataTableFormatOptions />\n </TabsContent>\n </Tabs>\n </DataTableSheetContent>\n</DataTableSheet>\n```\n\nStorybook reference: `Data/DataTable/Column settings scenarios` (`PinSortSearchAndReset`).\n\n---\n";
|
|
1
|
+
export default "# AG Grid & Data Table — Mandatory Rules\n\n**When working with DataTable, or any data table that uses AG Grid (including Impact Nova's grid components), the following rules are mandatory. Do not deviate.**\n\n---\n\n## 1. Use AG Grid documentation only\n\n- **Refer only to AG Grid's official documentation** for grid behavior, APIs, column definitions, filtering, sorting, and all grid features.\n- Do not rely on third-party tutorials or generic \"data grid\" patterns that contradict or bypass AG Grid's docs.\n- Official docs: [ag-grid.com/documentation](https://www.ag-grid.com/documentation/) (React: [AG Grid React](https://www.ag-grid.com/react-data-grid/)).\n\n---\n\n## 2. Follow AG Grid recommended patterns\n\n- **Always follow AG Grid's recommended patterns** for:\n - Column definitions (`ColDef`, `ColGroupDef`)\n - Cell renderers and editors\n - Filtering, sorting, and row selection\n - API ref access (`gridRef.current?.api`)\n - Theming and styling (AG Grid theme / CSS variables)\n- Do not invent custom patterns that bypass or replace AG Grid's intended usage.\n\n---\n\n## 3. Use the AG Grid API only\n\n- **Rely on the AG Grid API only** for all grid operations:\n - Getting/setting data, refreshing cells, updating columns\n - Export (CSV/Excel if using Enterprise)\n - Filter/sort state, row selection, pinned columns\n - Any behavior that AG Grid exposes via its API\n- Do not manipulate the DOM or internal structure of the grid directly. Do not use non-API workarounds unless AG Grid docs explicitly suggest them.\n\n---\n\n## 4. Collaboration with ag-mcp (when installed)\n\n- **If the user has installed the ag-mcp server** (AG Grid MCP), this MCP can collaborate with it:\n - Use **ag-mcp** for AG Grid–specific questions: API reference, column config, React integration, and official examples.\n - Use **impact-nova-mcp** for Impact Nova wrappers (`DataTable`, `DataTableContent`, `processBackendColumnDefs`, `BackendColDef`, cell renderers from `impact-nova/ag-grid-react/cell-renderers`).\n - When generating or editing grid code: prefer fetching AG Grid details from ag-mcp when available, and combine with Impact Nova's DataTable/column/cell-renderer patterns from this MCP.\n- If ag-mcp is not installed, still follow rules 1–3 using AG Grid's official documentation only.\n\n---\n\n**Summary:** For any code or design involving AG Grid or Impact Nova's DataTable (which uses AG Grid), use **only** AG Grid documentation, **only** AG Grid recommended patterns, and **only** the AG Grid API—with no deviation. When ag-mcp is available, use it to get accurate AG Grid API and docs; use this MCP for Impact Nova–specific integration.\n\n---\n\n## 5. Mandatory Data Table component usage\n\n**CRITICAL RULE:** If you see a table in a screenshot, or if the user asks for a table by default, you **MUST** use **Impact Nova DataTable** from `impact-nova/data-table`. **Do not build a raw AG Grid or HTML table.**\n\n```tsx\nimport {\n DataTable,\n DataTableContent,\n DataTableToolbar,\n useDataTable,\n} from 'impact-nova/data-table';\n```\n\nA typical Default Data Table in Impact Nova features this exact structure:\n\n```tsx\nconst DataTableWithFilters = () => {\n const { tStory } = useStorybookStoryI18n();\n const [sheetOpen, setSheetOpen] = useState(false);\n const [activeTab, setActiveTab] = useState(\"columns\");\n const [showFilterStrip, setShowFilterStrip] = useState(false);\n\n return (\n <div className=\"h-[800px] w-full p-8 bg-slate-50 flex flex-col items-center justify-center\">\n <div className=\"w-full max-w-[1200px] h-[600px] bg-white rounded-lg overflow-hidden flex flex-col [box-shadow:0px_0px_4px_0px_rgba(0,0,0,0.12)]\">\n <DataTable className=\"h-full\">\n <DataTableToolbar className=\"border-b border-[#e6e8f0]\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"font-bold text-sm text-slate-800\">Sales Report</h2>\n </div>\n \n <div className=\"flex items-center gap-2\">\n <Button \n variant=\"secondary\" \n size=\"icon\" \n onClick={() => setShowFilterStrip(!showFilterStrip)}\n aria-label={showFilterStrip ? tStory('filterStrip.hideFilters') : tStory('filterStrip.showFilters')}\n >\n {showFilterStrip ? <FunnelHide size=\"xs\" /> : <FunnelShow size=\"xs\" />}\n </Button>\n\n <div className=\"h-4 w-[1px] bg-[#e6e8f0] mx-1\" />\n\n {/* Scoped Sheet for Settings - Renders inside this relative container */}\n <DataTableSheet open={sheetOpen} onOpenChange={setSheetOpen}>\n <DropdownMenu>\n <DataTableViewMenuTrigger />\n <DataTableViewMenuContent>\n <DataTableViewMenuSettingsItem />\n <DataTableViewMenuDensity />\n </DataTableViewMenuContent>\n </DropdownMenu>\n \n <DataTableSheetContent>\n <DataTableSheetHeader title=\"Table Settings\" />\n <Tabs value={activeTab} onValueChange={setActiveTab} variant=\"line\" hideInactiveLabel tooltipClassName=\"z-[110]\" className=\"flex-1 flex flex-col min-h-0 w-full px-4\">\n <TabsList>\n <TabsTrigger \n value=\"columns\" \n icon={<Column size={16} />}\n >\n Columns\n </TabsTrigger>\n <TabsTrigger \n value=\"format\" \n icon={<Font size={16} />}\n >\n Format\n </TabsTrigger>\n <TabsTrigger \n value=\"custom-filters\" \n icon={<Filter size={16} />}\n >\n Filters\n </TabsTrigger>\n </TabsList>\n \n <TabsContent value=\"columns\" className=\"flex-1 min-h-0 relative p-0 data-[state=inactive]:hidden mt-0\">\n <div className=\"flex-1 h-full p-2\">\n <DataTableColumnList />\n </div>\n </TabsContent>\n <TabsContent value=\"format\" className=\"flex-1 min-h-0 relative p-4 pt-1 data-[state=inactive]:hidden overflow-y-auto mt-0\">\n <DataTableFormatOptions />\n </TabsContent>\n <TabsContent value=\"custom-filters\" className=\"flex-1 min-h-0 relative p-4 pt-1 data-[state=inactive]:hidden overflow-y-auto mt-0\">\n <div className=\"flex flex-col gap-4 text-sm text-[#60697d]\">\n <p>Custom filter configuration would go here.</p>\n <Button variant=\"outline\" className=\"w-full justify-start\">\n + Add Condition\n </Button>\n </div>\n </TabsContent>\n </Tabs>\n </DataTableSheetContent>\n </DataTableSheet>\n </div>\n </DataTableToolbar>\n \n <DataTableContent\n rowData={rowData}\n columnDefs={columnDefs}\n // Standard AG Grid props work here\n pagination={true}\n paginationPageSize={20}\n />\n </DataTable>\n </div>\n <p className=\"mt-4 text-slate-400 text-sm\">\n Note: The settings panel opens *inside* the table container, respecting its boundaries.\n </p>\n </div>\n );\n};\n```\nNote: This component (`DataTable`) internally uses `ag-grid-react` as a customized version. Rely on it rather than naked AG Grid.\n\n---\n\n## 6. Built-in Clipboard Handlers for JSON Objects\n\n**All DataTable and AG Grid instances in Impact Nova automatically support copying and pasting JSON objects.**\n\nThe `AgGridWrapper` component includes built-in clipboard handlers that:\n- **When copying**: Automatically stringify object values to JSON format\n- **When pasting**: Automatically parse JSON strings back to objects\n\n### How it works\n\n```tsx\n// When you copy a cell with an object value like:\n{ \n wp: { value: 6479, _isDisabled: true, cellMetadata: {...} },\n iaf: { value: 6090, _isDisabled: true, cellMetadata: {...} }\n}\n\n// It's automatically converted and split into separate Excel columns:\n// Column 1 Column 2\n// WP: 6479 IAF: 6090\n\n// Technical metadata (_isDisabled, cellMetadata) is hidden for clarity\n// Only the meaningful \"value\" is shown - perfect for PMs and non-technical users\n// Tab-separated format automatically expands into multiple columns in Excel\n```\n\n**Example with simple properties:**\n```tsx\n// Copy this object:\n{ name: \"John\", age: 30, status: \"active\" }\n\n// Expands into 3 Excel columns:\n// Column 1 Column 2 Column 3\n// name: John age: 30 status: active\n```\n\n**When pasting:**\n```tsx\n// You can paste JSON strings and they'll be parsed back to objects:\n'{\"name\":\"Jane\",\"age\":25}' → { name: \"Jane\", age: 25 }\n```\n\n**Benefits:**\n- ✅ Simple and readable for non-technical users (PMs, stakeholders)\n- ✅ Extracts only meaningful values, hides technical metadata\n- ✅ Automatically expands object properties into separate Excel columns\n- ✅ Perfect for analysis - each property gets its own column\n- ✅ Works seamlessly for both single-cell and multi-cell copy operations\n- ✅ Still supports pasting JSON back for developers\n\n### Usage\n\n**No configuration needed!** This works automatically for all DataTable instances:\n\n```tsx\n<DataTable>\n <DataTableContent\n rowData={data}\n columnDefs={columns}\n // Clipboard handlers are already active ✅\n />\n</DataTable>\n```\n\n### Override if needed\n\nYou can override the default behavior by passing your own handlers:\n\n```tsx\n<DataTableContent\n rowData={data}\n columnDefs={columns}\n processCellForClipboard={(params) => {\n // Custom copy logic\n return customFormat(params.value);\n }}\n processCellFromClipboard={(params) => {\n // Custom paste logic\n return customParse(params.value);\n }}\n/>\n```\n\n**Key benefits:**\n- ✅ Works automatically for all tables\n- ✅ No code duplication needed\n- ✅ Handles complex object structures\n- ✅ Gracefully falls back to string if JSON parsing fails\n- ✅ Can be overridden when custom behavior is needed\n\n---\n\n## 6. Column autosize on container resize\n\n**AgGridWrapper** (from `impact-nova/ag-grid-react`) automatically re-runs `autoSizeStrategy` when the grid container width changes (accordion expand, viewport resize, responsive layout).\n\n- Pass `autoSizeStrategy` to DataTable/AgGridWrapper props (e.g. `{ type: 'fitCellContents', scaleUpToFitGridWidth: true }`).\n- **Do not** add app-level ResizeObserver hacks or deferred grid mount delays — the framework handles this.\n- When applying saved column views, wait for `firstDataRendered` or `newColumnsLoaded` grid events before applying column state — not `setTimeout(0)`.\n- Strip `width`/`flex` from saved column state when applying structural views so autosize can recalculate correctly.\n\n---\n\n## 7. AG Grid v36 version pin (mandatory)\n\nImpact Nova **2.2.0+** targets **AG Grid v36**. Consumer apps must install all three packages at the **exact same version**:\n\n```bash\nnpm install ag-grid-community@36.0.1 ag-grid-react@36.0.1 ag-grid-enterprise@36.0.1\n```\n\n**Rules:**\n\n- Pin `36.0.1` in `package.json` — do not float `^36` across community/react/enterprise.\n- Vite/webpack: `resolve.dedupe: ['ag-grid-community', 'ag-grid-enterprise', 'ag-grid-react']` (see `create-impact-nova` template).\n- **Do not** import legacy AG Grid CSS theme files (`ag-grid.css`, `ag-theme-*`). Impact Nova `AgGridWrapper` applies the v36 Quartz theme (`themeQuartz.withPart(iconSetMaterial)`) via the `theme` prop.\n- Column settings (`DataTableColumnList`) sync pin/sort/filter from the live `GridApi` — do not mirror column state in app-level React state.\n\n**Column settings sheet pattern:**\n\n```tsx\n<DataTableSheet open={sheetOpen} onOpenChange={setSheetOpen}>\n <DataTableSheetContent>\n <DataTableSheetHeader title=\"Table Settings\" />\n <Tabs defaultValue=\"columns\">\n <TabsList>\n <TabsTrigger value=\"columns\">Columns</TabsTrigger>\n <TabsTrigger value=\"format\">Format</TabsTrigger>\n </TabsList>\n <TabsContent value=\"columns\">\n <DataTableColumnList />\n </TabsContent>\n <TabsContent value=\"format\">\n <DataTableFormatOptions />\n </TabsContent>\n </Tabs>\n </DataTableSheetContent>\n</DataTableSheet>\n```\n\nStorybook reference: `Data/DataTable/Column settings scenarios` (`PinSortSearchAndReset`).\n\n---\n";
|
|
@@ -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.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
|
|
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@^2.2.0` from npm (`latest` tag) |\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## 6b. Theming in consumer apps\n\n| Surface | What ships |\n|---------|------------|\n| **npm / consumer apps** | **Impact Light** only — `import 'impact-nova/dist/impact-nova.css'` (from `src/theme/tokens/light.json`) |\n| **Storybook / dev** | 10 curated **theme presets** (Impact Dark, Midnight, Ocean, …) — preview switcher only |\n\n**Do not** copy Storybook preset JSON or `theme-presets.ts` into consumer apps. Presets are not in the published package.\n\n**Custom branding:** override CSS variables on `:root` or a scoped class (e.g. `.my-brand`). Use Storybook **Theme Builder** / **Token Catalog** to explore tokens, then export CSS/JSON for your overrides.\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// → dist/tailwind.config.js (bundled theme; no package src/ required)\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
|
+
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.2.0\",\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@^2.2.0) 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/dist/tailwind.config.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Published Tailwind preset — generated by scripts/build-tailwind-preset.mjs. Do not edit. */
|
|
2
2
|
// tailwind.config.js
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
3
5
|
import tailwindcssAnimate from "tailwindcss-animate";
|
|
4
6
|
import tailwindPlugin from "tailwindcss/plugin.js";
|
|
5
7
|
|
|
@@ -198,7 +200,9 @@ var generatedBoxShadow = {
|
|
|
198
200
|
"elevation-select": "var(--shadow-elevation-select)",
|
|
199
201
|
"elevation-settings": "var(--shadow-elevation-settings)",
|
|
200
202
|
"elevation-toast": "var(--shadow-elevation-toast)",
|
|
201
|
-
"elevation-wizard-footer": "var(--shadow-elevation-wizard-footer)"
|
|
203
|
+
"elevation-wizard-footer": "var(--shadow-elevation-wizard-footer)",
|
|
204
|
+
"file-upload-drag": "var(--shadow-file-upload-drag)",
|
|
205
|
+
"file-upload-error": "var(--shadow-file-upload-error)"
|
|
202
206
|
};
|
|
203
207
|
|
|
204
208
|
// tailwind.config.js
|
|
@@ -238,6 +242,10 @@ var baseConfig = {
|
|
|
238
242
|
md: "var(--radius)",
|
|
239
243
|
sm: "calc(var(--radius) - 4px)"
|
|
240
244
|
},
|
|
245
|
+
backgroundImage: {
|
|
246
|
+
"file-upload-drag": "var(--gradient-file-upload-drag)",
|
|
247
|
+
"file-upload-error": "var(--gradient-file-upload-error)"
|
|
248
|
+
},
|
|
241
249
|
boxShadow: generatedBoxShadow,
|
|
242
250
|
keyframes: {
|
|
243
251
|
"accordion-down": {
|
|
@@ -264,6 +272,14 @@ var baseConfig = {
|
|
|
264
272
|
"notification-waves": {
|
|
265
273
|
"0%": { width: "8px", height: "8px" },
|
|
266
274
|
"100%": { width: "16px", height: "16px" }
|
|
275
|
+
},
|
|
276
|
+
"flash-highlight": {
|
|
277
|
+
"0%": {
|
|
278
|
+
boxShadow: "inset 0 0 0 100vmax var(--flash-overlay, color-mix(in srgb, var(--color-primary) 45%, transparent))"
|
|
279
|
+
},
|
|
280
|
+
"100%": {
|
|
281
|
+
boxShadow: "inset 0 0 0 100vmax transparent"
|
|
282
|
+
}
|
|
267
283
|
}
|
|
268
284
|
},
|
|
269
285
|
animation: {
|
|
@@ -273,13 +289,24 @@ var baseConfig = {
|
|
|
273
289
|
"collapsible-up": "collapsible-up 0.2s ease-out",
|
|
274
290
|
"header-bot-gradient": "header-bot-gradient 5s ease infinite",
|
|
275
291
|
"header-bot-gradient-fast": "header-bot-gradient 2s ease infinite",
|
|
276
|
-
"notification-waves": "notification-waves 1.5s ease-out infinite"
|
|
292
|
+
"notification-waves": "notification-waves 1.5s ease-out infinite",
|
|
293
|
+
"flash-highlight": "flash-highlight 0.5s ease-out 3 forwards"
|
|
277
294
|
}
|
|
278
295
|
}
|
|
279
296
|
},
|
|
280
297
|
plugins: [tailwindcssAnimate, scrollbarUtilities]
|
|
281
298
|
};
|
|
282
299
|
var tailwind_config_default = baseConfig;
|
|
300
|
+
function getImpactNovaContentGlob() {
|
|
301
|
+
const configDirectory = dirname(fileURLToPath(import.meta.url)).replace(
|
|
302
|
+
/\\/g,
|
|
303
|
+
"/"
|
|
304
|
+
);
|
|
305
|
+
if (configDirectory.endsWith("/dist")) {
|
|
306
|
+
return `${configDirectory}/**/*.{js,ts,jsx,tsx}`;
|
|
307
|
+
}
|
|
308
|
+
return `${configDirectory}/dist/**/*.{js,ts,jsx,tsx}`;
|
|
309
|
+
}
|
|
283
310
|
function createTailwindConfig(contentPaths) {
|
|
284
311
|
return {
|
|
285
312
|
...baseConfig,
|
|
@@ -288,10 +315,15 @@ function createTailwindConfig(contentPaths) {
|
|
|
288
315
|
}
|
|
289
316
|
function createAppTailwindConfig(appRootDir, appContentPaths) {
|
|
290
317
|
const impactNovaSourceGlob = `${appRootDir.replace(/\\/g, "/")}/../impact-nova/src/**/*.{js,ts,jsx,tsx}`;
|
|
291
|
-
return createTailwindConfig([
|
|
318
|
+
return createTailwindConfig([
|
|
319
|
+
...appContentPaths,
|
|
320
|
+
impactNovaSourceGlob,
|
|
321
|
+
getImpactNovaContentGlob()
|
|
322
|
+
]);
|
|
292
323
|
}
|
|
293
324
|
export {
|
|
294
325
|
createAppTailwindConfig,
|
|
295
326
|
createTailwindConfig,
|
|
296
|
-
tailwind_config_default as default
|
|
327
|
+
tailwind_config_default as default,
|
|
328
|
+
getImpactNovaContentGlob
|
|
297
329
|
};
|
|
@@ -195,5 +195,7 @@ export const generatedBoxShadow = {
|
|
|
195
195
|
"elevation-select": "var(--shadow-elevation-select)",
|
|
196
196
|
"elevation-settings": "var(--shadow-elevation-settings)",
|
|
197
197
|
"elevation-toast": "var(--shadow-elevation-toast)",
|
|
198
|
-
"elevation-wizard-footer": "var(--shadow-elevation-wizard-footer)"
|
|
198
|
+
"elevation-wizard-footer": "var(--shadow-elevation-wizard-footer)",
|
|
199
|
+
"file-upload-drag": "var(--shadow-file-upload-drag)",
|
|
200
|
+
"file-upload-error": "var(--shadow-file-upload-error)"
|
|
199
201
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "impact-nova",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
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",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
],
|
|
66
66
|
"repository": {
|
|
67
67
|
"type": "git",
|
|
68
|
-
"url": "https://
|
|
68
|
+
"url": "git+https://bitbucket.org/insideinsight/impact-nova.git"
|
|
69
69
|
},
|
|
70
70
|
"bugs": {
|
|
71
71
|
"url": "https://impactanalytics.atlassian.net/jira/software/c/projects/DES/issues"
|
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
"README.md"
|
|
83
83
|
],
|
|
84
84
|
"exports": {
|
|
85
|
+
"./package.json": "./package.json",
|
|
85
86
|
".": {
|
|
86
87
|
"types": "./dist/index.d.ts",
|
|
87
88
|
"import": "./dist/index.js"
|
|
@@ -287,6 +288,10 @@
|
|
|
287
288
|
"types": "./dist/components/feedback/sheet/index.d.ts",
|
|
288
289
|
"import": "./dist/components/feedback/sheet/index.js"
|
|
289
290
|
},
|
|
291
|
+
"./show": {
|
|
292
|
+
"types": "./dist/components/ui/show.d.ts",
|
|
293
|
+
"import": "./dist/components/ui/show.js"
|
|
294
|
+
},
|
|
290
295
|
"./sidebar": {
|
|
291
296
|
"types": "./dist/components/layout/sidebar/sidebar.d.ts",
|
|
292
297
|
"import": "./dist/components/layout/sidebar/sidebar.js"
|
|
@@ -457,7 +462,10 @@
|
|
|
457
462
|
},
|
|
458
463
|
"scripts": {
|
|
459
464
|
"dev": "vite",
|
|
465
|
+
"prepublishOnly": "npm run ci",
|
|
460
466
|
"publish:alpha": "npm publish --tag alpha --access public",
|
|
467
|
+
"publish:stable": "npm publish --access public",
|
|
468
|
+
"release:notes": "node scripts/create-release.mjs",
|
|
461
469
|
"validate-imports": "node scripts/validate-imports.mjs",
|
|
462
470
|
"build:registry": "node scripts/build-registry.mjs && node scripts/sync-registry-to-mcp.mjs",
|
|
463
471
|
"validate:registry": "node scripts/validate-registry.mjs",
|
|
@@ -470,7 +478,8 @@
|
|
|
470
478
|
"changeset": "changeset",
|
|
471
479
|
"version:release": "changeset version && npm run sync:storybook-releases",
|
|
472
480
|
"sync:storybook-releases": "node scripts/sync-storybook-releases.mjs",
|
|
473
|
-
"
|
|
481
|
+
"sync:storybook-test-status": "node scripts/sync-storybook-test-status.mjs",
|
|
482
|
+
"validate:story-docs": "node scripts/validate-story-docs.mjs && node scripts/sync-storybook-releases.mjs --check && node scripts/sync-storybook-test-status.mjs --check",
|
|
474
483
|
"validate:layering": "node scripts/validate-layering.mjs",
|
|
475
484
|
"validate:mcp-sync": "node scripts/validate-mcp-sync.mjs",
|
|
476
485
|
"validate:charter": "node scripts/validate-charter.mjs",
|
|
@@ -490,7 +499,7 @@
|
|
|
490
499
|
"validate:theme-presets": "node scripts/validate-theme-presets.mjs",
|
|
491
500
|
"build:tailwind-preset": "node scripts/build-tailwind-preset.mjs",
|
|
492
501
|
"validate:published-package": "node scripts/validate-published-package.mjs",
|
|
493
|
-
"build": "node scripts/validate-imports.mjs && npm run build:tokens && npm run
|
|
502
|
+
"build": "node scripts/validate-imports.mjs && npm run build:tokens && npm run validate:token-usage && npm run build:registry && npm run validate:registry && tsc -b && vite build && node scripts/build-css-splits.mjs && node scripts/build-llms.mjs && node src/theme/scripts/generate-tailwind-colors.mjs && npm run build:tailwind-preset && node scripts/validate-declaration-exports.mjs && npm run validate:published-package",
|
|
494
503
|
"analyze": "ANALYZE=true npm run build",
|
|
495
504
|
"lint": "eslint packages/mcp/src scripts --max-warnings 0",
|
|
496
505
|
"lint:src": "eslint src --max-warnings 0",
|
|
@@ -581,7 +590,7 @@
|
|
|
581
590
|
"highcharts": "^12.5.0",
|
|
582
591
|
"highcharts-border-radius": "^0.0.4",
|
|
583
592
|
"highcharts-react-official": "^3.2.3",
|
|
584
|
-
"impact-nova-icons": "^0.
|
|
593
|
+
"impact-nova-icons": "^0.2.0",
|
|
585
594
|
"playwright": "^1.58.0",
|
|
586
595
|
"postcss": "^8.5.6",
|
|
587
596
|
"sass": "^1.97.3",
|
|
@@ -603,7 +612,7 @@
|
|
|
603
612
|
"highcharts": "^12.5.0",
|
|
604
613
|
"highcharts-border-radius": "^0.0.4",
|
|
605
614
|
"highcharts-react-official": "^3.2.3",
|
|
606
|
-
"impact-nova-icons": "
|
|
615
|
+
"impact-nova-icons": ">=0.1.0",
|
|
607
616
|
"react": "^19.0.0",
|
|
608
617
|
"react-dom": "^19.0.0"
|
|
609
618
|
},
|
package/tailwind.config.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ import type { Config } from "tailwindcss";
|
|
|
3
3
|
declare const config: Config;
|
|
4
4
|
export default config;
|
|
5
5
|
|
|
6
|
+
/** Content glob for scanning published impact-nova `dist/` components. */
|
|
7
|
+
export function getImpactNovaContentGlob(): string;
|
|
8
|
+
|
|
6
9
|
export function createTailwindConfig(contentPaths: string[]): Config;
|
|
7
10
|
|
|
8
11
|
export function createAppTailwindConfig(
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { IHeaderGroupParams } from 'ag-grid-community';
|
|
2
|
-
import { ExtendedHeaderComponentParams } from '../ag-grid.types';
|
|
3
|
-
/**
|
|
4
|
-
* CustomHeaderGroup — optimized for large column trees.
|
|
5
|
-
*
|
|
6
|
-
* Not wrapped in React.memo: AG Grid mutates `columnGroup` in place on expand/collapse;
|
|
7
|
-
* memo would serve stale `isExpanded` and break collapse. `toggleExpand` reads
|
|
8
|
-
* `columnGroup.isExpanded()` at click time.
|
|
9
|
-
*/
|
|
10
|
-
export declare function CustomHeaderGroup(props: IHeaderGroupParams & ExtendedHeaderComponentParams): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { jsxs as g, jsx as o } from "react/jsx-runtime";
|
|
2
|
-
import { useRef as h } from "react";
|
|
3
|
-
import { ChevronRight as E } from "impact-nova-icons";
|
|
4
|
-
import { cn as N } from "../../../../lib/utils.js";
|
|
5
|
-
import { HeaderInfo as b } from "./components/header-info.js";
|
|
6
|
-
import { useGridHeader as C } from "./context/grid-header-context.js";
|
|
7
|
-
import { useAgGridTruncationTooltip as G } from "../use-ag-grid-truncation-tooltip.js";
|
|
8
|
-
function w(r) {
|
|
9
|
-
const {
|
|
10
|
-
displayName: d,
|
|
11
|
-
setTooltip: p,
|
|
12
|
-
showInfoIcon: c = !1,
|
|
13
|
-
columnGroup: e,
|
|
14
|
-
setExpanded: a
|
|
15
|
-
} = r, s = h(null), t = d || "";
|
|
16
|
-
G(p, t, s, "ellipsis");
|
|
17
|
-
const i = C(), m = e ? e.isExpanded() : !1, l = e ? e.isExpandable() : !1, f = (n) => {
|
|
18
|
-
n && n.stopPropagation(), a && e && a(!e.isExpanded());
|
|
19
|
-
}, u = (n) => {
|
|
20
|
-
if (n.preventDefault(), n.stopPropagation(), i && e) {
|
|
21
|
-
const x = e.getGroupId() || "group";
|
|
22
|
-
i.openMenu(x, n.currentTarget, "group");
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
return !t && c === !1 ? null : /* @__PURE__ */ g(
|
|
26
|
-
"div",
|
|
27
|
-
{
|
|
28
|
-
className: "ag-header-group-cell-label ag-sticky-label flex items-center h-full min-w-0 cursor-pointer select-none",
|
|
29
|
-
onClick: l ? f : void 0,
|
|
30
|
-
onContextMenu: u,
|
|
31
|
-
role: "presentation",
|
|
32
|
-
children: [
|
|
33
|
-
/* @__PURE__ */ o(
|
|
34
|
-
"span",
|
|
35
|
-
{
|
|
36
|
-
ref: s,
|
|
37
|
-
className: "ag-header-group-text min-w-0 flex-1 truncate font-bold text-content",
|
|
38
|
-
children: t
|
|
39
|
-
}
|
|
40
|
-
),
|
|
41
|
-
/* @__PURE__ */ o(b, { ...r, className: "ml-1 shrink-0" }),
|
|
42
|
-
l && /* @__PURE__ */ o(
|
|
43
|
-
"span",
|
|
44
|
-
{
|
|
45
|
-
className: N(
|
|
46
|
-
"ag-header-icon ag-header-expand-icon ml-[6px] shrink-0 flex items-center justify-center",
|
|
47
|
-
m ? "ag-header-expand-icon-expanded rotate-180" : "ag-header-expand-icon-collapsed"
|
|
48
|
-
),
|
|
49
|
-
children: /* @__PURE__ */ o(E, { size: 16, className: "text-content-tertiary" })
|
|
50
|
-
}
|
|
51
|
-
)
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
export {
|
|
57
|
-
w as CustomHeaderGroup
|
|
58
|
-
};
|