@amstfn/td-design-system 0.3.0
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/CHANGELOG.md +45 -0
- package/README.md +219 -0
- package/dist/data-grid.cjs +2 -0
- package/dist/data-grid.cjs.map +1 -0
- package/dist/data-grid.d.ts +218 -0
- package/dist/data-grid.es.js +356 -0
- package/dist/data-grid.es.js.map +1 -0
- package/dist/design-system.css +1 -0
- package/dist/favicon.svg +1 -0
- package/dist/icons.svg +24 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2463 -0
- package/dist/index.es.js +3765 -0
- package/dist/index.es.js.map +1 -0
- package/dist/spacing-BkZfHpT0.cjs +2 -0
- package/dist/spacing-BkZfHpT0.cjs.map +1 -0
- package/dist/spacing-C8pTXcGE.js +15 -0
- package/dist/spacing-C8pTXcGE.js.map +1 -0
- package/package.json +129 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.3.0] - 2026-10-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Added `TdAlert`, `TdCollapse`, `TdFloatButton`, `TdRadio`, `TdSkeleton`, and `TdTag`.
|
|
15
|
+
- Added `TdText`, `TdTitle`, `TdParagraph`, and `TdLink` as Ant Design Typography wrappers.
|
|
16
|
+
- Added Figma token maps for palette, alias, component, and responsive values.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Packaging: AG Grid is a peer only, CommonJS publishes as `index.cjs`, and library types exclude Vitest and Vite client types.
|
|
21
|
+
- Replaced all MUI primitives, theme APIs, and peer dependencies with Ant Design 6.
|
|
22
|
+
- Changed component props to Ant Design-native contracts.
|
|
23
|
+
- Rebuilt `TdThemeProvider` with Ant Design `ConfigProvider`, including dark mode and RTL.
|
|
24
|
+
- Preserved Gregorian and Jalali date pickers using Day.js and `antd-jalali-v5`.
|
|
25
|
+
- Kept the `TdDataGrid` engine on AG Grid while migrating its toolbar and error state to Ant Design.
|
|
26
|
+
|
|
27
|
+
### Breaking
|
|
28
|
+
|
|
29
|
+
- `TdDataGrid` and its types moved off the root export to `@td/design-system/data-grid`.
|
|
30
|
+
- Date picker values now use Day.js instead of ISO strings.
|
|
31
|
+
- Modal callbacks and footer configuration now follow Ant Design's `ModalProps`.
|
|
32
|
+
- Theme overrides now use Ant Design `ThemeConfig`.
|
|
33
|
+
- MUI-specific variants, props, and event signatures have been removed.
|
|
34
|
+
|
|
35
|
+
## [0.1.0] - 2026-06-11
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- Initial release of `@td/design-system`
|
|
40
|
+
- Design token system (colors, spacing, radius, shadows, typography, z-index)
|
|
41
|
+
- `TdThemeProvider` with light/dark themes, RTL and localization preparation
|
|
42
|
+
- Core components: `TdButton`, `TdInput`, `TdSelect`, `TdModal`, `TdDataGrid`
|
|
43
|
+
- Storybook documentation
|
|
44
|
+
- Vitest test suite with 80% coverage target
|
|
45
|
+
- GitHub Actions CI/CD pipeline
|
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# @amstfn/td-design-system
|
|
2
|
+
|
|
3
|
+
Enterprise-grade React Design System built with TypeScript, Ant Design, and AG Grid.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install from the public npm registry, along with the peer dependencies:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @amstfn/td-design-system antd antd-jalali-v5 dayjs react react-dom
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Mohaymen applications can install the same version from Nexus. Copy `.npmrc.example` into the app instead of publishing registry credentials in source files.
|
|
14
|
+
|
|
15
|
+
`ag-grid-community` and `ag-grid-react` are optional. Install them only when the app imports `@amstfn/td-design-system/data-grid`.
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
Wrap your application with `TdThemeProvider`:
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { TdButton, TdThemeProvider } from "@amstfn/td-design-system";
|
|
23
|
+
import "@amstfn/td-design-system/styles.css";
|
|
24
|
+
|
|
25
|
+
export function App() {
|
|
26
|
+
return (
|
|
27
|
+
<TdThemeProvider mode="light">
|
|
28
|
+
<TdButton type="primary">Get Started</TdButton>
|
|
29
|
+
</TdThemeProvider>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
That file is the Ant Design reset extracted by the library build. AG Grid CSS is not inside `styles.css`. Importing `TdDataGrid` from `@amstfn/td-design-system/data-grid` loads `ag-grid.css` and `ag-theme-alpine.css` as a side effect of that module. The host app must load the `IRANSansX` font itself.
|
|
35
|
+
|
|
36
|
+
## Important Rules
|
|
37
|
+
|
|
38
|
+
### Public API only
|
|
39
|
+
|
|
40
|
+
Import from the package root. `TdDataGrid` is the exception and comes from `@amstfn/td-design-system/data-grid`:
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { TdButton, TdInput } from "@amstfn/td-design-system";
|
|
44
|
+
import { TdDataGrid } from "@amstfn/td-design-system/data-grid";
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Never import internal paths such as `@amstfn/td-design-system/src/components/TdButton`.
|
|
48
|
+
|
|
49
|
+
### Ant Design-native component APIs
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
<TdButton type="primary" htmlType="submit" loading={false}>
|
|
53
|
+
Save
|
|
54
|
+
</TdButton>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Components
|
|
58
|
+
|
|
59
|
+
| Component | Description |
|
|
60
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------- |
|
|
61
|
+
| `TdThemeProvider` | Theme, RTL, and localization foundation |
|
|
62
|
+
| `TdButton` | Primary action button with loading and variants |
|
|
63
|
+
| `TdInput` | Text input with validation and accessibility |
|
|
64
|
+
| `TdSelect` | Dropdown select with controlled/uncontrolled modes |
|
|
65
|
+
| `TdAutocomplete` | Searchable free-text suggestions |
|
|
66
|
+
| `TdCheckbox` | Checkbox with validation help |
|
|
67
|
+
| `TdRadio` | Radio and radio group |
|
|
68
|
+
| `TdDatePicker` | Ant DatePicker with Gregorian/Jalali support |
|
|
69
|
+
| `TdModal` | Ant Design modal |
|
|
70
|
+
| `TdAlert` | Inline status message |
|
|
71
|
+
| `TdCollapse` | Expandable content panels |
|
|
72
|
+
| `TdFloatButton` | Floating action button |
|
|
73
|
+
| `TdSkeleton` | Loading placeholder |
|
|
74
|
+
| `TdTag` | Status and category label |
|
|
75
|
+
| `TdText` | Ant Design Typography text |
|
|
76
|
+
| `TdTitle` | Ant Design Typography title |
|
|
77
|
+
| `TdParagraph` | Ant Design Typography paragraph |
|
|
78
|
+
| `TdLink` | Ant Design Typography link |
|
|
79
|
+
| `TdForm` | Closed form wrapper; consumers do not install or call `react-hook-form` to use `TdForm` / `TdFormField` |
|
|
80
|
+
| `TdDataGrid` | AG Grid abstraction with Ant Design toolbar. Import from `@amstfn/td-design-system/data-grid` |
|
|
81
|
+
|
|
82
|
+
## Theme
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
<TdThemeProvider mode="dark" direction="rtl" locale={{ locale: "fa-IR" }}>
|
|
86
|
+
<App />
|
|
87
|
+
</TdThemeProvider>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Extend the theme:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<TdThemeProvider
|
|
94
|
+
themeOptions={{
|
|
95
|
+
token: {
|
|
96
|
+
colorPrimary: "#004D40",
|
|
97
|
+
},
|
|
98
|
+
}}
|
|
99
|
+
>
|
|
100
|
+
<App />
|
|
101
|
+
</TdThemeProvider>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Design Tokens
|
|
105
|
+
|
|
106
|
+
All components consume centralized tokens:
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
import { TdSpacing, TdColors, TdRadius } from "@amstfn/td-design-system";
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Available token groups: `TdColors`, `TdSpacing`, `TdRadius`, `TdShadows`, `TdTypography`, `TdZIndex`.
|
|
113
|
+
|
|
114
|
+
## Development
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm install
|
|
118
|
+
npm run lint
|
|
119
|
+
npm run typecheck
|
|
120
|
+
npm run test
|
|
121
|
+
npm run build
|
|
122
|
+
npm run storybook
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Testing
|
|
126
|
+
|
|
127
|
+
Tests use Vitest and React Testing Library. Minimum coverage target: 80%.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npm run test:coverage
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Storybook
|
|
134
|
+
|
|
135
|
+
Component documentation and visual testing:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npm run storybook
|
|
139
|
+
npm run build-storybook
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Contribution Guide
|
|
143
|
+
|
|
144
|
+
1. Fork and clone the repository
|
|
145
|
+
2. Create a feature branch from `develop`
|
|
146
|
+
3. Follow existing patterns: compose Ant Design components, export props types, and use tokens
|
|
147
|
+
4. Add tests and Storybook stories for every public component
|
|
148
|
+
5. Ensure `npm run lint`, `npm run typecheck`, and `npm run test` pass
|
|
149
|
+
6. Open a pull request with a clear description
|
|
150
|
+
|
|
151
|
+
### Code standards
|
|
152
|
+
|
|
153
|
+
- TypeScript strict mode, no `any`
|
|
154
|
+
- Accessibility first (ARIA, keyboard navigation)
|
|
155
|
+
- No business logic in UI components
|
|
156
|
+
- No hardcoded design values
|
|
157
|
+
|
|
158
|
+
## Migration from the MUI-based API
|
|
159
|
+
|
|
160
|
+
This release changes component props to their Ant Design equivalents:
|
|
161
|
+
|
|
162
|
+
- `TdButton`: use `type="primary"` and `htmlType="submit"` instead of MUI variants/native `type`.
|
|
163
|
+
- `TdInput`, `TdSelect`, `TdAutocomplete`, and `TdDatePicker`: use `status="error"` and `help`.
|
|
164
|
+
- `TdDatePicker`: values and callbacks use Day.js objects.
|
|
165
|
+
- `TdModal`: use `onCancel`, `footer`, `closable`, `keyboard`, and `maskClosable`.
|
|
166
|
+
- `TdThemeProvider.themeOptions`: accepts Ant Design `ThemeConfig`.
|
|
167
|
+
|
|
168
|
+
`TdDataGrid` continues to use AG Grid; only its surrounding controls use Ant Design.
|
|
169
|
+
|
|
170
|
+
## CI/CD (GitLab)
|
|
171
|
+
|
|
172
|
+
This repository uses `.gitlab-ci.yml` for a **Node.js library pipeline** (lint, test, build).
|
|
173
|
+
|
|
174
|
+
**Important:** Disable GitLab Auto DevOps in your project:
|
|
175
|
+
|
|
176
|
+
`Settings → General → Auto DevOps → Disable Auto DevOps`
|
|
177
|
+
|
|
178
|
+
Auto DevOps uses Heroku buildpacks and tries to build a Docker web app. That is incorrect for this npm package and causes errors like:
|
|
179
|
+
|
|
180
|
+
- `invalid tag "/main:..."` (empty container registry path)
|
|
181
|
+
- Node.js download timeouts on Heroku buildpack
|
|
182
|
+
- Very slow builds (~5 minutes)
|
|
183
|
+
|
|
184
|
+
The included pipeline uses `node:22` directly and typically finishes in 2–3 minutes with npm cache.
|
|
185
|
+
|
|
186
|
+
Publish to Nexus (`npm-hosted-tax`) automatically when CI pushes a version tag (see **Release Process** below). Consumers install from the `moaadian-npm` group.
|
|
187
|
+
|
|
188
|
+
## Release Process
|
|
189
|
+
|
|
190
|
+
This project follows [Semantic Versioning](https://semver.org/).
|
|
191
|
+
|
|
192
|
+
On every successful merge to `main`, GitLab CI automatically:
|
|
193
|
+
|
|
194
|
+
1. Finds the latest `v*` tag (e.g. `v0.2.0`)
|
|
195
|
+
2. Bumps the **patch** version (`v0.2.1`)
|
|
196
|
+
3. Updates `package.json` and `package-lock.json`
|
|
197
|
+
4. Creates and pushes the new tag
|
|
198
|
+
5. Publishes to `https://repo.mohaymen.ir/repository/npm-hosted-tax/`
|
|
199
|
+
|
|
200
|
+
### One-time CI setup
|
|
201
|
+
|
|
202
|
+
Add a **Project Access Token** (Settings → Access tokens) with `write_repository` scope, then add it as a masked CI/CD variable:
|
|
203
|
+
|
|
204
|
+
| Variable | Value |
|
|
205
|
+
| --------------- | ------------------------ |
|
|
206
|
+
| `CI_PUSH_TOKEN` | `<project access token>` |
|
|
207
|
+
|
|
208
|
+
Without `CI_PUSH_TOKEN`, the `release` job cannot push tags.
|
|
209
|
+
|
|
210
|
+
Manual release (optional):
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
git tag v0.2.0
|
|
214
|
+
git push origin v0.2.0
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),x=require("antd"),O=require("ag-grid-community"),fe=require("ag-grid-react"),n=require("react"),w=require("./spacing-BkZfHpT0.cjs"),ce=require("react-dom/client");require("ag-grid-community/styles/ag-grid.css");require("ag-grid-community/styles/ag-theme-alpine.css");function V(e,t){return e?.some(a=>a.rowId===t.row.id&&a.field===t.field)??!1}function ge(e,t){return!(e.editableRowIds!==void 0&&!e.editableRowIds.includes(t.id)||e.isRowEditable&&!e.isRowEditable(t))}function be(e,t){return e.editable===!1?!1:typeof e.editable=="function"?e.editable(t):e.editable===!0}function Ce(e,t,a){return a.isCellEditable?a.isCellEditable(t):a.editableCells!==void 0&&!V(a.editableCells,t)||!ge(a,t.row)?!1:e.editable!==void 0?be(e,t):V(a.editableCells,t)?!0:a.defaultEditable}function K(e,t){return t.defaultEditable||t.editableRowIds!==void 0||t.isRowEditable!==void 0||t.editableCells!==void 0||t.isCellEditable!==void 0?!0:e.some(a=>a.editable===!0||typeof a.editable=="function")}function he(e,t){return K([e],t)?a=>{if(!a.data)return!1;const o={row:a.data,field:e.field,value:a.data[e.field]};return Ce(e,o,t)}:!1}function pe(e){return e==null?"":typeof e=="string"||typeof e=="number"||typeof e=="boolean"?String(e).replace(/<[^>]*>/g,""):""}const me="__td_row_actions";function ye(e){return e?"agTextColumnFilter":!1}function y(e){return pe(e)}class Ee{root=null;eGui;init(t){this.eGui=document.createElement("div"),this.eGui.className="td-datagrid-cell";const a=t.renderCell;if(!a||!t.data){this.eGui.textContent=y(t.value);return}const o=a({row:t.data,value:t.value,field:t.colDef?.field});if(typeof o=="string"||typeof o=="number"){this.eGui.textContent=y(o);return}if(n.isValidElement(o)){this.root=ce.createRoot(this.eGui),this.root.render(o);return}this.eGui.textContent=y(o)}getGui(){return this.eGui}refresh(t){return this.destroy(),this.init(t),!0}destroy(){this.root&&(this.root.unmount(),this.root=null)}}class Se{root=null;eGui;init(t){this.eGui=document.createElement("div"),this.eGui.className="td-datagrid-actions";const a=t.data,o=t.rowActions??[];if(!a)return;const l=o.filter(s=>!s.hidden?.(a));l.length!==0&&(this.eGui.style.display="flex",this.eGui.style.gap="8px",l.forEach(s=>{const d=document.createElement("button");d.type="button",d.textContent=s.label,d.disabled=s.disabled?.(a)??!1,d.className="td-datagrid-action-button",d.addEventListener("click",h=>{h.stopPropagation(),t.onActionClick?.(s.id,a),s.onClick(a)}),this.eGui.appendChild(d)}))}getGui(){return this.eGui}refresh(){return!1}destroy(){this.root&&(this.root.unmount(),this.root=null)}}function ve(e,t,a={defaultEditable:!1}){const o=e.filter(l=>!l.hidden).map(l=>{const s={field:l.field,headerName:l.headerName,width:l.width,minWidth:l.minWidth,flex:l.flex,sortable:l.sortable??!0,filter:ye(l.filterable),editable:he(l,a),valueFormatter:l.valueFormatter?d=>l.valueFormatter(d.value,d.data):d=>y(d.value)};return l.renderCell&&(s.cellRenderer=Ee,s.cellRendererParams={renderCell:l.renderCell}),s});return t&&t.length>0&&o.push({field:me,headerName:"",sortable:!1,filter:!1,width:Math.max(120,t.length*80),pinned:"right",cellRenderer:Se,cellRendererParams:{rowActions:t}}),o}O.ModuleRegistry.registerModules([O.AllCommunityModule]);const U=20,Ge=[10,20,25,50,100],Re="ag-theme-alpine";function xe(e,t){return e===!0?{enabled:!0,model:{page:0,pageSize:t??U}}:e&&typeof e=="object"?{enabled:!0,model:e}:{enabled:!1}}function we({columns:e,rows:t,loading:a=!1,height:o=400,selectable:l,checkboxSelection:s=!1,selectedRowIds:d,onSelectionChange:h,onRowSelect:N,onRowClick:T,pagination:B,pageSize:k,onPaginationChange:E,rowCount:Te,serverSidePagination:ke=!1,sortModel:S,onSortChange:p,filterModel:Pe,onFilterChange:_e,search:De,export:C,persistence:u,permissions:v,rowActions:P,editable:_=!1,editableRowIds:D,isRowEditable:A,editableCells:F,isCellEditable:I,editTrigger:W="doubleClick",onCellValueChanged:M,themeClassName:J=Re,className:Z,style:H,emptyMessage:$="No rows to display",error:Q=!1,errorMessage:X,"aria-label":j="Data grid"}){const f=n.useRef(null),L=l??s,m=n.useMemo(()=>({defaultEditable:_||(v?.canEdit??!1),editableRowIds:D,isRowEditable:A,editableCells:F,isCellEditable:I}),[_,v?.canEdit,D,A,F,I]),Y=n.useMemo(()=>K(e,m),[e,m]),g=xe(B,k),ee=C?.enabled&&(v?.canExport??!0),te=n.useMemo(()=>ve(e,P,m),[e,P,m]),ie=n.useMemo(()=>({resizable:!0,sortable:!0,filter:!1,editable:!1}),[]),q=n.useCallback(i=>{if(!(!u?.enabled||!u.storageKey))try{const r=localStorage.getItem(u.storageKey);r&&i.applyColumnState({state:JSON.parse(r),applyOrder:!0})}catch{}},[u]),z=n.useCallback(i=>{if(!u?.enabled||!u.storageKey)return;const r=i.getColumnState();localStorage.setItem(u.storageKey,JSON.stringify(r))},[u]),ae=n.useCallback(i=>{f.current=i.api,q(i.api),g.model&&i.api.paginationGoToPage(g.model.page)},[g.model,q]),le=n.useCallback(()=>{const i=f.current;if(!i)return;const r=i.getSelectedRows(),R=r.map(b=>b.id);h?.(R),N?.(r)},[h,N]),re=n.useCallback(()=>{const i=f.current;!i||!E||E({page:i.paginationGetCurrentPage(),pageSize:i.paginationGetPageSize()})},[E]),ne=n.useCallback(()=>{const i=f.current;if(!i||!p)return;const R=i.getColumnState().filter(b=>b.sort).map(b=>({field:b.colId,sort:b.sort==="desc"?"desc":"asc"}));p(R)},[p]),G=n.useCallback(()=>{const i=f.current;i&&z(i)},[z]),oe=n.useCallback(i=>{!i.data||!i.colDef.field||M?.({row:i.data,field:i.colDef.field,oldValue:i.oldValue,newValue:i.newValue})},[M]),de=n.useCallback(i=>{const r=f.current;if(r){if(i==="csv"){r.exportDataAsCsv({fileName:C?.fileName??"export"});return}r.exportDataAsCsv({fileName:C?.fileName??"export"})}},[C?.fileName]);if(n.useEffect(()=>{const i=f.current;!i||!d||i.forEachNode(r=>{r.data&&r.setSelected(d.includes(r.data.id))})},[d,t]),n.useEffect(()=>{const i=f.current;!i||!S||i.applyColumnState({state:S.map(r=>({colId:r.field,sort:r.sort})),defaultState:{sort:null}})},[S]),Q)return c.jsx("div",{"aria-label":j,style:{height:o,padding:w.TdSpacing.md},children:c.jsx(x.Alert,{type:"error",title:X??"Failed to load data"})});const se=C?.formats??["csv"],ue=[J,"td-datagrid",Z].filter(Boolean).join(" ");return c.jsxs("div",{"aria-label":j,style:{width:"100%"},children:[ee?c.jsx(x.Flex,{gap:w.TdSpacing.sm,style:{marginBottom:w.TdSpacing.sm},children:se.map(i=>c.jsxs(x.Button,{size:"small",variant:"outlined",onClick:()=>{de(i)},children:["Export ",i.toUpperCase()]},i))}):null,c.jsx("div",{className:ue,style:{height:o,width:"100%",...H},children:c.jsx(fe.AgGridReact,{rowData:t,columnDefs:te,defaultColDef:ie,loading:a,domLayout:"normal",getRowId:i=>String(i.data.id),rowSelection:L?{mode:"multiRow",checkboxes:!0,headerCheckbox:!0,enableClickSelection:!1}:void 0,onSelectionChanged:L?le:void 0,onRowClicked:T?i=>{i.data&&T(i.data)}:void 0,pagination:g.enabled,paginationPageSize:g.model?.pageSize??k??U,paginationPageSizeSelector:Ge,onPaginationChanged:g.enabled?re:void 0,suppressPaginationPanel:!1,onGridReady:ae,onSortChanged:p?ne:void 0,onColumnMoved:G,onColumnResized:G,onColumnVisible:G,singleClickEdit:W==="singleClick",stopEditingWhenCellsLoseFocus:!0,onCellValueChanged:Y?oe:void 0,overlayNoRowsTemplate:`<span>${$}</span>`,overlayLoadingTemplate:"<span>Loading...</span>"})})]})}const Ne=n.memo(we);exports.TdDataGrid=Ne;
|
|
2
|
+
//# sourceMappingURL=data-grid.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-grid.cjs","sources":["../src/components/TdDataGrid/TdDataGrid.edit.ts","../src/utils/sanitize.ts","../src/components/TdDataGrid/TdDataGrid.mapper.ts","../src/components/TdDataGrid/TdDataGrid.tsx"],"sourcesContent":["import type { EditableCallbackParams } from \"ag-grid-community\";\n\nimport type {\n TdDataGridCellContext,\n TdDataGridColumn,\n TdDataGridEditRules,\n TdDataGridRow,\n} from \"./TdDataGrid.types\";\n\nfunction isCellListed<T extends TdDataGridRow>(\n editableCells: TdDataGridEditRules<T>[\"editableCells\"],\n context: TdDataGridCellContext<T>,\n): boolean {\n return (\n editableCells?.some((cell) => cell.rowId === context.row.id && cell.field === context.field) ??\n false\n );\n}\n\nfunction passesRowRules<T extends TdDataGridRow>(rules: TdDataGridEditRules<T>, row: T): boolean {\n if (rules.editableRowIds !== undefined && !rules.editableRowIds.includes(row.id)) {\n return false;\n }\n\n if (rules.isRowEditable && !rules.isRowEditable(row)) {\n return false;\n }\n\n return true;\n}\n\nfunction passesColumnRules<T extends TdDataGridRow>(\n column: TdDataGridColumn<T>,\n context: TdDataGridCellContext<T>,\n): boolean {\n if (column.editable === false) {\n return false;\n }\n\n if (typeof column.editable === \"function\") {\n return column.editable(context);\n }\n\n if (column.editable === true) {\n return true;\n }\n\n return false;\n}\n\nexport function isCellEditableResolved<T extends TdDataGridRow>(\n column: TdDataGridColumn<T>,\n context: TdDataGridCellContext<T>,\n rules: TdDataGridEditRules<T>,\n): boolean {\n if (rules.isCellEditable) {\n return rules.isCellEditable(context);\n }\n\n if (rules.editableCells !== undefined && !isCellListed(rules.editableCells, context)) {\n return false;\n }\n\n if (!passesRowRules(rules, context.row)) {\n return false;\n }\n\n if (column.editable !== undefined) {\n return passesColumnRules(column, context);\n }\n\n if (isCellListed(rules.editableCells, context)) {\n return true;\n }\n\n return rules.defaultEditable;\n}\n\nexport function hasAnyEditingEnabled<T extends TdDataGridRow>(\n columns: TdDataGridColumn<T>[],\n rules: TdDataGridEditRules<T>,\n): boolean {\n if (\n rules.defaultEditable ||\n rules.editableRowIds !== undefined ||\n rules.isRowEditable !== undefined ||\n rules.editableCells !== undefined ||\n rules.isCellEditable !== undefined\n ) {\n return true;\n }\n\n return columns.some(\n (column) => column.editable === true || typeof column.editable === \"function\",\n );\n}\n\nexport function createCellEditableCallback<T extends TdDataGridRow>(\n column: TdDataGridColumn<T>,\n rules: TdDataGridEditRules<T>,\n): boolean | ((params: EditableCallbackParams<T>) => boolean) {\n if (!hasAnyEditingEnabled([column], rules)) {\n return false;\n }\n\n return (params: EditableCallbackParams<T>) => {\n if (!params.data) {\n return false;\n }\n\n const context: TdDataGridCellContext<T> = {\n row: params.data,\n field: column.field,\n value: params.data[column.field],\n };\n\n return isCellEditableResolved(column, context, rules);\n };\n}\n","/**\n * Strip HTML tags from a string value for safe grid cell display.\n */\nexport function sanitizeText(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value).replace(/<[^>]*>/g, \"\");\n }\n\n return \"\";\n}\n\n/**\n * Escape HTML entities so text can be rendered safely.\n */\nexport function escapeHtml(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n\n if (typeof value !== \"string\" && typeof value !== \"number\" && typeof value !== \"boolean\") {\n return \"\";\n }\n\n const text = String(value);\n\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","import type { ColDef, ICellRendererParams, ValueFormatterParams } from \"ag-grid-community\";\nimport { isValidElement } from \"react\";\nimport { createRoot, type Root } from \"react-dom/client\";\n\nimport { sanitizeText } from \"../../utils/sanitize\";\nimport { createCellEditableCallback } from \"./TdDataGrid.edit\";\nimport type {\n TdDataGridColumn,\n TdDataGridEditRules,\n TdDataGridRow,\n TdDataGridRowAction,\n} from \"./TdDataGrid.types\";\n\nconst ACTION_COLUMN_FIELD = \"__td_row_actions\";\n\n/** Maps filter operator to AG Grid text filter type */\nfunction mapFilterType(filterable?: boolean): boolean | string {\n return filterable ? \"agTextColumnFilter\" : false;\n}\n\n/** Safely stringify cell values for default rendering */\nfunction formatCellValue(value: unknown): string {\n return sanitizeText(value);\n}\n\nclass TdReactCellRenderer<T extends TdDataGridRow> {\n private root: Root | null = null;\n private eGui!: HTMLDivElement;\n\n init(params: ICellRendererParams<T> & { renderCell?: TdDataGridColumn<T>[\"renderCell\"] }) {\n this.eGui = document.createElement(\"div\");\n this.eGui.className = \"td-datagrid-cell\";\n\n const renderCell = params.renderCell;\n if (!renderCell || !params.data) {\n this.eGui.textContent = formatCellValue(params.value);\n return;\n }\n\n const content = renderCell({\n row: params.data,\n value: params.value,\n field: params.colDef?.field as keyof T & string,\n });\n\n if (typeof content === \"string\" || typeof content === \"number\") {\n this.eGui.textContent = formatCellValue(content);\n return;\n }\n\n if (isValidElement(content)) {\n this.root = createRoot(this.eGui);\n this.root.render(content);\n return;\n }\n\n this.eGui.textContent = formatCellValue(content);\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh(params: ICellRendererParams<T> & { renderCell?: TdDataGridColumn<T>[\"renderCell\"] }) {\n this.destroy();\n this.init(params);\n return true;\n }\n\n destroy() {\n if (this.root) {\n this.root.unmount();\n this.root = null;\n }\n }\n}\n\nclass TdRowActionsCellRenderer<T extends TdDataGridRow> {\n private root: Root | null = null;\n private eGui!: HTMLDivElement;\n\n init(\n params: ICellRendererParams<T> & {\n rowActions?: TdDataGridRowAction<T>[];\n onActionClick?: (actionId: string, row: T) => void;\n },\n ) {\n this.eGui = document.createElement(\"div\");\n this.eGui.className = \"td-datagrid-actions\";\n\n const row = params.data;\n const rowActions = params.rowActions ?? [];\n\n if (!row) {\n return;\n }\n\n const visibleActions = rowActions.filter((action) => !action.hidden?.(row));\n\n if (visibleActions.length === 0) {\n return;\n }\n\n this.eGui.style.display = \"flex\";\n this.eGui.style.gap = \"8px\";\n\n visibleActions.forEach((action) => {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.textContent = action.label;\n button.disabled = action.disabled?.(row) ?? false;\n button.className = \"td-datagrid-action-button\";\n button.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n params.onActionClick?.(action.id, row);\n action.onClick(row);\n });\n this.eGui.appendChild(button);\n });\n }\n\n getGui() {\n return this.eGui;\n }\n\n refresh() {\n return false;\n }\n\n destroy() {\n if (this.root) {\n this.root.unmount();\n this.root = null;\n }\n }\n}\n\nexport function mapColumnsToAgGrid<T extends TdDataGridRow>(\n columns: TdDataGridColumn<T>[],\n rowActions?: TdDataGridRowAction<T>[],\n editRules: TdDataGridEditRules<T> = { defaultEditable: false },\n): ColDef<T>[] {\n const mappedColumns: ColDef<T>[] = columns\n .filter((column) => !column.hidden)\n .map((column) => {\n const colDef: ColDef<T> = {\n field: column.field as ColDef<T>[\"field\"],\n headerName: column.headerName,\n width: column.width,\n minWidth: column.minWidth,\n flex: column.flex,\n sortable: column.sortable ?? true,\n filter: mapFilterType(column.filterable),\n editable: createCellEditableCallback(column, editRules),\n valueFormatter: column.valueFormatter\n ? (params: ValueFormatterParams<T>) => column.valueFormatter!(params.value, params.data!)\n : (params: ValueFormatterParams<T>) => formatCellValue(params.value),\n };\n\n if (column.renderCell) {\n colDef.cellRenderer = TdReactCellRenderer;\n colDef.cellRendererParams = { renderCell: column.renderCell };\n }\n\n return colDef;\n });\n\n if (rowActions && rowActions.length > 0) {\n mappedColumns.push({\n field: ACTION_COLUMN_FIELD as ColDef<T>[\"field\"],\n headerName: \"\",\n sortable: false,\n filter: false,\n width: Math.max(120, rowActions.length * 80),\n pinned: \"right\",\n cellRenderer: TdRowActionsCellRenderer,\n cellRendererParams: { rowActions },\n });\n }\n\n return mappedColumns;\n}\n\nexport function getActionColumnField(): string {\n return ACTION_COLUMN_FIELD;\n}\n","import { Alert, Button, Flex } from \"antd\";\nimport {\n AllCommunityModule,\n ModuleRegistry,\n type CellValueChangedEvent,\n type ColumnState,\n type GridApi,\n} from \"ag-grid-community\";\nimport { AgGridReact } from \"ag-grid-react\";\nimport { memo, useCallback, useEffect, useMemo, useRef } from \"react\";\n\nimport { TdSpacing } from \"../../tokens/spacing\";\nimport { hasAnyEditingEnabled } from \"./TdDataGrid.edit\";\nimport { mapColumnsToAgGrid } from \"./TdDataGrid.mapper\";\nimport type {\n TdDataGridEditRules,\n TdDataGridExportFormat,\n TdDataGridPaginationModel,\n TdDataGridProps,\n TdDataGridRow,\n TdDataGridSortModel,\n TdDataGridThemeClassName,\n} from \"./TdDataGrid.types\";\n\nimport \"ag-grid-community/styles/ag-grid.css\";\nimport \"ag-grid-community/styles/ag-theme-alpine.css\";\n\nModuleRegistry.registerModules([AllCommunityModule]);\n\nconst DEFAULT_PAGE_SIZE = 20;\nconst PAGE_SIZE_OPTIONS = [10, 20, 25, 50, 100];\nconst DEFAULT_THEME_CLASS: TdDataGridThemeClassName = \"ag-theme-alpine\";\n\nfunction resolvePaginationConfig(\n pagination: TdDataGridProps[\"pagination\"],\n pageSize?: number,\n): { enabled: boolean; model?: TdDataGridPaginationModel } {\n if (pagination === true) {\n return {\n enabled: true,\n model: { page: 0, pageSize: pageSize ?? DEFAULT_PAGE_SIZE },\n };\n }\n\n if (pagination && typeof pagination === \"object\") {\n return { enabled: true, model: pagination };\n }\n\n return { enabled: false };\n}\n\nfunction TdDataGridInner<T extends TdDataGridRow>({\n columns,\n rows,\n loading = false,\n height = 400,\n selectable,\n checkboxSelection = false,\n selectedRowIds,\n onSelectionChange,\n onRowSelect,\n onRowClick,\n pagination,\n pageSize,\n onPaginationChange,\n rowCount: _rowCount,\n serverSidePagination: _serverSidePagination = false,\n sortModel,\n onSortChange,\n filterModel: _filterModel,\n onFilterChange: _onFilterChange,\n search: _search,\n export: exportConfig,\n persistence,\n permissions,\n rowActions,\n editable = false,\n editableRowIds,\n isRowEditable,\n editableCells,\n isCellEditable,\n editTrigger = \"doubleClick\",\n onCellValueChanged,\n themeClassName = DEFAULT_THEME_CLASS,\n className,\n style,\n emptyMessage = \"No rows to display\",\n error = false,\n errorMessage,\n \"aria-label\": ariaLabel = \"Data grid\",\n}: TdDataGridProps<T>) {\n const gridApiRef = useRef<GridApi<T> | null>(null);\n const isSelectionEnabled = selectable ?? checkboxSelection;\n const editRules = useMemo<TdDataGridEditRules<T>>(\n () => ({\n defaultEditable: editable || (permissions?.canEdit ?? false),\n editableRowIds,\n isRowEditable,\n editableCells,\n isCellEditable,\n }),\n [editable, permissions?.canEdit, editableRowIds, isRowEditable, editableCells, isCellEditable],\n );\n const isEditingEnabled = useMemo(\n () => hasAnyEditingEnabled(columns, editRules),\n [columns, editRules],\n );\n const paginationConfig = resolvePaginationConfig(pagination, pageSize);\n const canExport = exportConfig?.enabled && (permissions?.canExport ?? true);\n\n const gridColumns = useMemo(\n () => mapColumnsToAgGrid(columns, rowActions, editRules),\n [columns, rowActions, editRules],\n );\n\n const defaultColDef = useMemo(\n () => ({\n resizable: true,\n sortable: true,\n filter: false,\n editable: false,\n }),\n [],\n );\n\n const restoreColumnState = useCallback(\n (api: GridApi<T>) => {\n if (!persistence?.enabled || !persistence.storageKey) {\n return;\n }\n\n try {\n const stored = localStorage.getItem(persistence.storageKey);\n if (stored) {\n api.applyColumnState({ state: JSON.parse(stored) as ColumnState[], applyOrder: true });\n }\n } catch {\n // Ignore invalid persisted state\n }\n },\n [persistence],\n );\n\n const persistColumnState = useCallback(\n (api: GridApi<T>) => {\n if (!persistence?.enabled || !persistence.storageKey) {\n return;\n }\n\n const state = api.getColumnState();\n localStorage.setItem(persistence.storageKey, JSON.stringify(state));\n },\n [persistence],\n );\n\n const handleGridReady = useCallback(\n (params: { api: GridApi<T> }) => {\n gridApiRef.current = params.api;\n restoreColumnState(params.api);\n\n if (paginationConfig.model) {\n params.api.paginationGoToPage(paginationConfig.model.page);\n }\n },\n [paginationConfig.model, restoreColumnState],\n );\n\n const handleSelectionChanged = useCallback(() => {\n const api = gridApiRef.current;\n if (!api) {\n return;\n }\n\n const selectedRows = api.getSelectedRows();\n const selectedIds = selectedRows.map((row) => row.id);\n\n onSelectionChange?.(selectedIds);\n onRowSelect?.(selectedRows);\n }, [onSelectionChange, onRowSelect]);\n\n const handlePaginationChanged = useCallback(() => {\n const api = gridApiRef.current;\n if (!api || !onPaginationChange) {\n return;\n }\n\n onPaginationChange({\n page: api.paginationGetCurrentPage(),\n pageSize: api.paginationGetPageSize(),\n });\n }, [onPaginationChange]);\n\n const handleSortChanged = useCallback(() => {\n const api = gridApiRef.current;\n if (!api || !onSortChange) {\n return;\n }\n\n const columnState = api.getColumnState();\n const nextSortModel: TdDataGridSortModel[] = columnState\n .filter((column) => column.sort)\n .map((column) => ({\n field: column.colId,\n sort: column.sort === \"desc\" ? \"desc\" : \"asc\",\n }));\n\n onSortChange(nextSortModel);\n }, [onSortChange]);\n\n const handleColumnChanged = useCallback(() => {\n const api = gridApiRef.current;\n if (api) {\n persistColumnState(api);\n }\n }, [persistColumnState]);\n\n const handleCellValueChanged = useCallback(\n (event: CellValueChangedEvent<T>) => {\n if (!event.data || !event.colDef.field) {\n return;\n }\n\n onCellValueChanged?.({\n row: event.data,\n field: event.colDef.field as keyof T & string,\n oldValue: event.oldValue,\n newValue: event.newValue,\n });\n },\n [onCellValueChanged],\n );\n\n const handleExport = useCallback(\n (format: TdDataGridExportFormat) => {\n const api = gridApiRef.current;\n if (!api) {\n return;\n }\n\n if (format === \"csv\") {\n api.exportDataAsCsv({\n fileName: exportConfig?.fileName ?? \"export\",\n });\n return;\n }\n\n // Excel export requires Enterprise; abstracted for future migration\n api.exportDataAsCsv({\n fileName: exportConfig?.fileName ?? \"export\",\n });\n },\n [exportConfig?.fileName],\n );\n\n useEffect(() => {\n const api = gridApiRef.current;\n if (!api || !selectedRowIds) {\n return;\n }\n\n api.forEachNode((node) => {\n if (node.data) {\n node.setSelected(selectedRowIds.includes(node.data.id));\n }\n });\n }, [selectedRowIds, rows]);\n\n useEffect(() => {\n const api = gridApiRef.current;\n if (!api || !sortModel) {\n return;\n }\n\n api.applyColumnState({\n state: sortModel.map((item) => ({\n colId: item.field,\n sort: item.sort,\n })),\n defaultState: { sort: null },\n });\n }, [sortModel]);\n\n if (error) {\n return (\n <div aria-label={ariaLabel} style={{ height, padding: TdSpacing.md }}>\n <Alert type=\"error\" title={errorMessage ?? \"Failed to load data\"} />\n </div>\n );\n }\n\n const exportFormats = exportConfig?.formats ?? [\"csv\"];\n const gridClassName = [themeClassName, \"td-datagrid\", className].filter(Boolean).join(\" \");\n\n return (\n <div aria-label={ariaLabel} style={{ width: \"100%\" }}>\n {canExport ? (\n <Flex gap={TdSpacing.sm} style={{ marginBottom: TdSpacing.sm }}>\n {exportFormats.map((format) => (\n <Button\n key={format}\n size=\"small\"\n variant=\"outlined\"\n onClick={() => {\n handleExport(format);\n }}\n >\n Export {format.toUpperCase()}\n </Button>\n ))}\n </Flex>\n ) : null}\n\n <div className={gridClassName} style={{ height, width: \"100%\", ...style }}>\n <AgGridReact<T>\n rowData={rows}\n columnDefs={gridColumns}\n defaultColDef={defaultColDef}\n loading={loading}\n domLayout=\"normal\"\n getRowId={(params) => String(params.data.id)}\n rowSelection={\n isSelectionEnabled\n ? {\n mode: \"multiRow\",\n checkboxes: true,\n headerCheckbox: true,\n enableClickSelection: false,\n }\n : undefined\n }\n onSelectionChanged={isSelectionEnabled ? handleSelectionChanged : undefined}\n onRowClicked={\n onRowClick\n ? (event) => {\n if (event.data) {\n onRowClick(event.data);\n }\n }\n : undefined\n }\n pagination={paginationConfig.enabled}\n paginationPageSize={paginationConfig.model?.pageSize ?? pageSize ?? DEFAULT_PAGE_SIZE}\n paginationPageSizeSelector={PAGE_SIZE_OPTIONS}\n onPaginationChanged={paginationConfig.enabled ? handlePaginationChanged : undefined}\n suppressPaginationPanel={false}\n onGridReady={handleGridReady}\n onSortChanged={onSortChange ? handleSortChanged : undefined}\n onColumnMoved={handleColumnChanged}\n onColumnResized={handleColumnChanged}\n onColumnVisible={handleColumnChanged}\n singleClickEdit={editTrigger === \"singleClick\"}\n stopEditingWhenCellsLoseFocus\n onCellValueChanged={isEditingEnabled ? handleCellValueChanged : undefined}\n overlayNoRowsTemplate={`<span>${emptyMessage}</span>`}\n overlayLoadingTemplate=\"<span>Loading...</span>\"\n />\n </div>\n </div>\n );\n}\n\nexport const TdDataGrid = memo(TdDataGridInner) as typeof TdDataGridInner;\n\nexport { DEFAULT_THEME_CLASS as TD_DATAGRID_DEFAULT_THEME_CLASS };\n"],"names":["isCellListed","editableCells","context","cell","passesRowRules","rules","row","passesColumnRules","column","isCellEditableResolved","hasAnyEditingEnabled","columns","createCellEditableCallback","params","sanitizeText","value","ACTION_COLUMN_FIELD","mapFilterType","filterable","formatCellValue","TdReactCellRenderer","renderCell","content","isValidElement","createRoot","TdRowActionsCellRenderer","rowActions","visibleActions","action","button","event","mapColumnsToAgGrid","editRules","mappedColumns","colDef","ModuleRegistry","AllCommunityModule","DEFAULT_PAGE_SIZE","PAGE_SIZE_OPTIONS","DEFAULT_THEME_CLASS","resolvePaginationConfig","pagination","pageSize","TdDataGridInner","rows","loading","height","selectable","checkboxSelection","selectedRowIds","onSelectionChange","onRowSelect","onRowClick","onPaginationChange","_rowCount","_serverSidePagination","sortModel","onSortChange","_filterModel","_onFilterChange","_search","exportConfig","persistence","permissions","editable","editableRowIds","isRowEditable","isCellEditable","editTrigger","onCellValueChanged","themeClassName","className","style","emptyMessage","error","errorMessage","ariaLabel","gridApiRef","useRef","isSelectionEnabled","useMemo","isEditingEnabled","paginationConfig","canExport","gridColumns","defaultColDef","restoreColumnState","useCallback","api","stored","persistColumnState","state","handleGridReady","handleSelectionChanged","selectedRows","selectedIds","handlePaginationChanged","handleSortChanged","nextSortModel","handleColumnChanged","handleCellValueChanged","handleExport","format","useEffect","node","item","TdSpacing","Alert","exportFormats","gridClassName","jsxs","jsx","Flex","Button","AgGridReact","TdDataGrid","memo"],"mappings":"gYASA,SAASA,EACPC,EACAC,EACS,CACT,OACED,GAAe,KAAME,GAASA,EAAK,QAAUD,EAAQ,IAAI,IAAMC,EAAK,QAAUD,EAAQ,KAAK,GAC3F,EAEJ,CAEA,SAASE,GAAwCC,EAA+BC,EAAiB,CAK/F,MAJI,EAAAD,EAAM,iBAAmB,QAAa,CAACA,EAAM,eAAe,SAASC,EAAI,EAAE,GAI3ED,EAAM,eAAiB,CAACA,EAAM,cAAcC,CAAG,EAKrD,CAEA,SAASC,GACPC,EACAN,EACS,CACT,OAAIM,EAAO,WAAa,GACf,GAGL,OAAOA,EAAO,UAAa,WACtBA,EAAO,SAASN,CAAO,EAG5BM,EAAO,WAAa,EAK1B,CAEO,SAASC,GACdD,EACAN,EACAG,EACS,CACT,OAAIA,EAAM,eACDA,EAAM,eAAeH,CAAO,EAGjCG,EAAM,gBAAkB,QAAa,CAACL,EAAaK,EAAM,cAAeH,CAAO,GAI/E,CAACE,GAAeC,EAAOH,EAAQ,GAAG,EAC7B,GAGLM,EAAO,WAAa,OACfD,GAAkBC,EAAQN,CAAO,EAGtCF,EAAaK,EAAM,cAAeH,CAAO,EACpC,GAGFG,EAAM,eACf,CAEO,SAASK,EACdC,EACAN,EACS,CACT,OACEA,EAAM,iBACNA,EAAM,iBAAmB,QACzBA,EAAM,gBAAkB,QACxBA,EAAM,gBAAkB,QACxBA,EAAM,iBAAmB,OAElB,GAGFM,EAAQ,KACZH,GAAWA,EAAO,WAAa,IAAQ,OAAOA,EAAO,UAAa,UAAA,CAEvE,CAEO,SAASI,GACdJ,EACAH,EAC4D,CAC5D,OAAKK,EAAqB,CAACF,CAAM,EAAGH,CAAK,EAIjCQ,GAAsC,CAC5C,GAAI,CAACA,EAAO,KACV,MAAO,GAGT,MAAMX,EAAoC,CACxC,IAAKW,EAAO,KACZ,MAAOL,EAAO,MACd,MAAOK,EAAO,KAAKL,EAAO,KAAK,CAAA,EAGjC,OAAOC,GAAuBD,EAAQN,EAASG,CAAK,CACtD,EAfS,EAgBX,CCnHO,SAASS,GAAaC,EAAwB,CACnD,OAAIA,GAAU,KACL,GAGL,OAAOA,GAAU,UAAY,OAAOA,GAAU,UAAY,OAAOA,GAAU,UACtE,OAAOA,CAAK,EAAE,QAAQ,WAAY,EAAE,EAGtC,EACT,CCAA,MAAMC,GAAsB,mBAG5B,SAASC,GAAcC,EAAwC,CAC7D,OAAOA,EAAa,qBAAuB,EAC7C,CAGA,SAASC,EAAgBJ,EAAwB,CAC/C,OAAOD,GAAaC,CAAK,CAC3B,CAEA,MAAMK,EAA6C,CACzC,KAAoB,KACpB,KAER,KAAKP,EAAqF,CACxF,KAAK,KAAO,SAAS,cAAc,KAAK,EACxC,KAAK,KAAK,UAAY,mBAEtB,MAAMQ,EAAaR,EAAO,WAC1B,GAAI,CAACQ,GAAc,CAACR,EAAO,KAAM,CAC/B,KAAK,KAAK,YAAcM,EAAgBN,EAAO,KAAK,EACpD,MACF,CAEA,MAAMS,EAAUD,EAAW,CACzB,IAAKR,EAAO,KACZ,MAAOA,EAAO,MACd,MAAOA,EAAO,QAAQ,KAAA,CACvB,EAED,GAAI,OAAOS,GAAY,UAAY,OAAOA,GAAY,SAAU,CAC9D,KAAK,KAAK,YAAcH,EAAgBG,CAAO,EAC/C,MACF,CAEA,GAAIC,EAAAA,eAAeD,CAAO,EAAG,CAC3B,KAAK,KAAOE,cAAW,KAAK,IAAI,EAChC,KAAK,KAAK,OAAOF,CAAO,EACxB,MACF,CAEA,KAAK,KAAK,YAAcH,EAAgBG,CAAO,CACjD,CAEA,QAAS,CACP,OAAO,KAAK,IACd,CAEA,QAAQT,EAAqF,CAC3F,YAAK,QAAA,EACL,KAAK,KAAKA,CAAM,EACT,EACT,CAEA,SAAU,CACJ,KAAK,OACP,KAAK,KAAK,QAAA,EACV,KAAK,KAAO,KAEhB,CACF,CAEA,MAAMY,EAAkD,CAC9C,KAAoB,KACpB,KAER,KACEZ,EAIA,CACA,KAAK,KAAO,SAAS,cAAc,KAAK,EACxC,KAAK,KAAK,UAAY,sBAEtB,MAAMP,EAAMO,EAAO,KACba,EAAab,EAAO,YAAc,CAAA,EAExC,GAAI,CAACP,EACH,OAGF,MAAMqB,EAAiBD,EAAW,OAAQE,GAAW,CAACA,EAAO,SAAStB,CAAG,CAAC,EAEtEqB,EAAe,SAAW,IAI9B,KAAK,KAAK,MAAM,QAAU,OAC1B,KAAK,KAAK,MAAM,IAAM,MAEtBA,EAAe,QAASC,GAAW,CACjC,MAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,KAAO,SACdA,EAAO,YAAcD,EAAO,MAC5BC,EAAO,SAAWD,EAAO,WAAWtB,CAAG,GAAK,GAC5CuB,EAAO,UAAY,4BACnBA,EAAO,iBAAiB,QAAUC,GAAU,CAC1CA,EAAM,gBAAA,EACNjB,EAAO,gBAAgBe,EAAO,GAAItB,CAAG,EACrCsB,EAAO,QAAQtB,CAAG,CACpB,CAAC,EACD,KAAK,KAAK,YAAYuB,CAAM,CAC9B,CAAC,EACH,CAEA,QAAS,CACP,OAAO,KAAK,IACd,CAEA,SAAU,CACR,MAAO,EACT,CAEA,SAAU,CACJ,KAAK,OACP,KAAK,KAAK,QAAA,EACV,KAAK,KAAO,KAEhB,CACF,CAEO,SAASE,GACdpB,EACAe,EACAM,EAAoC,CAAE,gBAAiB,IAC1C,CACb,MAAMC,EAA6BtB,EAChC,OAAQH,GAAW,CAACA,EAAO,MAAM,EACjC,IAAKA,GAAW,CACf,MAAM0B,EAAoB,CACxB,MAAO1B,EAAO,MACd,WAAYA,EAAO,WACnB,MAAOA,EAAO,MACd,SAAUA,EAAO,SACjB,KAAMA,EAAO,KACb,SAAUA,EAAO,UAAY,GAC7B,OAAQS,GAAcT,EAAO,UAAU,EACvC,SAAUI,GAA2BJ,EAAQwB,CAAS,EACtD,eAAgBxB,EAAO,eAClBK,GAAoCL,EAAO,eAAgBK,EAAO,MAAOA,EAAO,IAAK,EACrFA,GAAoCM,EAAgBN,EAAO,KAAK,CAAA,EAGvE,OAAIL,EAAO,aACT0B,EAAO,aAAed,GACtBc,EAAO,mBAAqB,CAAE,WAAY1B,EAAO,UAAA,GAG5C0B,CACT,CAAC,EAEH,OAAIR,GAAcA,EAAW,OAAS,GACpCO,EAAc,KAAK,CACjB,MAAOjB,GACP,WAAY,GACZ,SAAU,GACV,OAAQ,GACR,MAAO,KAAK,IAAI,IAAKU,EAAW,OAAS,EAAE,EAC3C,OAAQ,QACR,aAAcD,GACd,mBAAoB,CAAE,WAAAC,CAAA,CAAW,CAClC,EAGIO,CACT,CC1JAE,EAAAA,eAAe,gBAAgB,CAACC,EAAAA,kBAAkB,CAAC,EAEnD,MAAMC,EAAoB,GACpBC,GAAoB,CAAC,GAAI,GAAI,GAAI,GAAI,GAAG,EACxCC,GAAgD,kBAEtD,SAASC,GACPC,EACAC,EACyD,CACzD,OAAID,IAAe,GACV,CACL,QAAS,GACT,MAAO,CAAE,KAAM,EAAG,SAAUC,GAAYL,CAAA,CAAkB,EAI1DI,GAAc,OAAOA,GAAe,SAC/B,CAAE,QAAS,GAAM,MAAOA,CAAA,EAG1B,CAAE,QAAS,EAAA,CACpB,CAEA,SAASE,GAAyC,CAChD,QAAAhC,EACA,KAAAiC,EACA,QAAAC,EAAU,GACV,OAAAC,EAAS,IACT,WAAAC,EACA,kBAAAC,EAAoB,GACpB,eAAAC,EACA,kBAAAC,EACA,YAAAC,EACA,WAAAC,EACA,WAAAX,EACA,SAAAC,EACA,mBAAAW,EACA,SAAUC,GACV,qBAAsBC,GAAwB,GAC9C,UAAAC,EACA,aAAAC,EACA,YAAaC,GACb,eAAgBC,GAChB,OAAQC,GACR,OAAQC,EACR,YAAAC,EACA,YAAAC,EACA,WAAArC,EACA,SAAAsC,EAAW,GACX,eAAAC,EACA,cAAAC,EACA,cAAAjE,EACA,eAAAkE,EACA,YAAAC,EAAc,cACd,mBAAAC,EACA,eAAAC,EAAiB/B,GACjB,UAAAgC,EACA,MAAAC,EACA,aAAAC,EAAe,qBACf,MAAAC,EAAQ,GACR,aAAAC,EACA,aAAcC,EAAY,WAC5B,EAAuB,CACrB,MAAMC,EAAaC,EAAAA,OAA0B,IAAI,EAC3CC,EAAqBhC,GAAcC,EACnChB,EAAYgD,EAAAA,QAChB,KAAO,CACL,gBAAiBhB,IAAaD,GAAa,SAAW,IACtD,eAAAE,EACA,cAAAC,EACA,cAAAjE,EACA,eAAAkE,CAAA,GAEF,CAACH,EAAUD,GAAa,QAASE,EAAgBC,EAAejE,EAAekE,CAAc,CAAA,EAEzFc,EAAmBD,EAAAA,QACvB,IAAMtE,EAAqBC,EAASqB,CAAS,EAC7C,CAACrB,EAASqB,CAAS,CAAA,EAEfkD,EAAmB1C,GAAwBC,EAAYC,CAAQ,EAC/DyC,GAAYtB,GAAc,UAAYE,GAAa,WAAa,IAEhEqB,GAAcJ,EAAAA,QAClB,IAAMjD,GAAmBpB,EAASe,EAAYM,CAAS,EACvD,CAACrB,EAASe,EAAYM,CAAS,CAAA,EAG3BqD,GAAgBL,EAAAA,QACpB,KAAO,CACL,UAAW,GACX,SAAU,GACV,OAAQ,GACR,SAAU,EAAA,GAEZ,CAAA,CAAC,EAGGM,EAAqBC,EAAAA,YACxBC,GAAoB,CACnB,GAAI,GAAC1B,GAAa,SAAW,CAACA,EAAY,YAI1C,GAAI,CACF,MAAM2B,EAAS,aAAa,QAAQ3B,EAAY,UAAU,EACtD2B,GACFD,EAAI,iBAAiB,CAAE,MAAO,KAAK,MAAMC,CAAM,EAAoB,WAAY,GAAM,CAEzF,MAAQ,CAER,CACF,EACA,CAAC3B,CAAW,CAAA,EAGR4B,EAAqBH,EAAAA,YACxBC,GAAoB,CACnB,GAAI,CAAC1B,GAAa,SAAW,CAACA,EAAY,WACxC,OAGF,MAAM6B,EAAQH,EAAI,eAAA,EAClB,aAAa,QAAQ1B,EAAY,WAAY,KAAK,UAAU6B,CAAK,CAAC,CACpE,EACA,CAAC7B,CAAW,CAAA,EAGR8B,GAAkBL,EAAAA,YACrB1E,GAAgC,CAC/BgE,EAAW,QAAUhE,EAAO,IAC5ByE,EAAmBzE,EAAO,GAAG,EAEzBqE,EAAiB,OACnBrE,EAAO,IAAI,mBAAmBqE,EAAiB,MAAM,IAAI,CAE7D,EACA,CAACA,EAAiB,MAAOI,CAAkB,CAAA,EAGvCO,GAAyBN,EAAAA,YAAY,IAAM,CAC/C,MAAMC,EAAMX,EAAW,QACvB,GAAI,CAACW,EACH,OAGF,MAAMM,EAAeN,EAAI,gBAAA,EACnBO,EAAcD,EAAa,IAAKxF,GAAQA,EAAI,EAAE,EAEpD4C,IAAoB6C,CAAW,EAC/B5C,IAAc2C,CAAY,CAC5B,EAAG,CAAC5C,EAAmBC,CAAW,CAAC,EAE7B6C,GAA0BT,EAAAA,YAAY,IAAM,CAChD,MAAMC,EAAMX,EAAW,QACnB,CAACW,GAAO,CAACnC,GAIbA,EAAmB,CACjB,KAAMmC,EAAI,yBAAA,EACV,SAAUA,EAAI,sBAAA,CAAsB,CACrC,CACH,EAAG,CAACnC,CAAkB,CAAC,EAEjB4C,GAAoBV,EAAAA,YAAY,IAAM,CAC1C,MAAMC,EAAMX,EAAW,QACvB,GAAI,CAACW,GAAO,CAAC/B,EACX,OAIF,MAAMyC,EADcV,EAAI,eAAA,EAErB,OAAQhF,GAAWA,EAAO,IAAI,EAC9B,IAAKA,IAAY,CAChB,MAAOA,EAAO,MACd,KAAMA,EAAO,OAAS,OAAS,OAAS,KAAA,EACxC,EAEJiD,EAAayC,CAAa,CAC5B,EAAG,CAACzC,CAAY,CAAC,EAEX0C,EAAsBZ,EAAAA,YAAY,IAAM,CAC5C,MAAMC,EAAMX,EAAW,QACnBW,GACFE,EAAmBF,CAAG,CAE1B,EAAG,CAACE,CAAkB,CAAC,EAEjBU,GAAyBb,EAAAA,YAC5BzD,GAAoC,CAC/B,CAACA,EAAM,MAAQ,CAACA,EAAM,OAAO,OAIjCuC,IAAqB,CACnB,IAAKvC,EAAM,KACX,MAAOA,EAAM,OAAO,MACpB,SAAUA,EAAM,SAChB,SAAUA,EAAM,QAAA,CACjB,CACH,EACA,CAACuC,CAAkB,CAAA,EAGfgC,GAAed,EAAAA,YAClBe,GAAmC,CAClC,MAAMd,EAAMX,EAAW,QACvB,GAAKW,EAIL,IAAIc,IAAW,MAAO,CACpBd,EAAI,gBAAgB,CAClB,SAAU3B,GAAc,UAAY,QAAA,CACrC,EACD,MACF,CAGA2B,EAAI,gBAAgB,CAClB,SAAU3B,GAAc,UAAY,QAAA,CACrC,EACH,EACA,CAACA,GAAc,QAAQ,CAAA,EA+BzB,GA5BA0C,EAAAA,UAAU,IAAM,CACd,MAAMf,EAAMX,EAAW,QACnB,CAACW,GAAO,CAACvC,GAIbuC,EAAI,YAAagB,GAAS,CACpBA,EAAK,MACPA,EAAK,YAAYvD,EAAe,SAASuD,EAAK,KAAK,EAAE,CAAC,CAE1D,CAAC,CACH,EAAG,CAACvD,EAAgBL,CAAI,CAAC,EAEzB2D,EAAAA,UAAU,IAAM,CACd,MAAMf,EAAMX,EAAW,QACnB,CAACW,GAAO,CAAChC,GAIbgC,EAAI,iBAAiB,CACnB,MAAOhC,EAAU,IAAKiD,IAAU,CAC9B,MAAOA,EAAK,MACZ,KAAMA,EAAK,IAAA,EACX,EACF,aAAc,CAAE,KAAM,IAAA,CAAK,CAC5B,CACH,EAAG,CAACjD,CAAS,CAAC,EAEVkB,EACF,aACG,MAAA,CAAI,aAAYE,EAAW,MAAO,CAAE,OAAA9B,EAAQ,QAAS4D,YAAU,EAAA,EAC9D,eAACC,EAAAA,MAAA,CAAM,KAAK,QAAQ,MAAOhC,GAAgB,sBAAuB,EACpE,EAIJ,MAAMiC,GAAgB/C,GAAc,SAAW,CAAC,KAAK,EAC/CgD,GAAgB,CAACvC,EAAgB,cAAeC,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAEzF,OACEuC,EAAAA,KAAC,OAAI,aAAYlC,EAAW,MAAO,CAAE,MAAO,QACzC,SAAA,CAAAO,GACC4B,EAAAA,IAACC,OAAA,CAAK,IAAKN,EAAAA,UAAU,GAAI,MAAO,CAAE,aAAcA,EAAAA,UAAU,EAAA,EACvD,SAAAE,GAAc,IAAKN,GAClBQ,EAAAA,KAACG,EAAAA,OAAA,CAEC,KAAK,QACL,QAAQ,WACR,QAAS,IAAM,CACbZ,GAAaC,CAAM,CACrB,EACD,SAAA,CAAA,UACSA,EAAO,YAAA,CAAY,CAAA,EAPtBA,CAAA,CASR,EACH,EACE,KAEJS,EAAAA,IAAC,MAAA,CAAI,UAAWF,GAAe,MAAO,CAAE,OAAA/D,EAAQ,MAAO,OAAQ,GAAG0B,CAAA,EAChE,SAAAuC,EAAAA,IAACG,GAAAA,YAAA,CACC,QAAStE,EACT,WAAYwC,GACZ,cAAAC,GACA,QAAAxC,EACA,UAAU,SACV,SAAWhC,GAAW,OAAOA,EAAO,KAAK,EAAE,EAC3C,aACEkE,EACI,CACE,KAAM,WACN,WAAY,GACZ,eAAgB,GAChB,qBAAsB,EAAA,EAExB,OAEN,mBAAoBA,EAAqBc,GAAyB,OAClE,aACEzC,EACKtB,GAAU,CACLA,EAAM,MACRsB,EAAWtB,EAAM,IAAI,CAEzB,EACA,OAEN,WAAYoD,EAAiB,QAC7B,mBAAoBA,EAAiB,OAAO,UAAYxC,GAAYL,EACpE,2BAA4BC,GAC5B,oBAAqB4C,EAAiB,QAAUc,GAA0B,OAC1E,wBAAyB,GACzB,YAAaJ,GACb,cAAenC,EAAewC,GAAoB,OAClD,cAAeE,EACf,gBAAiBA,EACjB,gBAAiBA,EACjB,gBAAiB/B,IAAgB,cACjC,8BAA6B,GAC7B,mBAAoBa,EAAmBmB,GAAyB,OAChE,sBAAuB,SAAS3B,CAAY,UAC5C,uBAAuB,yBAAA,CAAA,CACzB,CACF,CAAA,EACF,CAEJ,CAEO,MAAM0C,GAAaC,EAAAA,KAAKzE,EAAe"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { JSX } from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
export declare const TdDataGrid: typeof TdDataGridInner;
|
|
5
|
+
|
|
6
|
+
/** Context passed to cell/row editability callbacks */
|
|
7
|
+
export declare interface TdDataGridCellContext<T extends TdDataGridRow = TdDataGridRow> {
|
|
8
|
+
row: T;
|
|
9
|
+
field: keyof T & string;
|
|
10
|
+
value: unknown;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export declare interface TdDataGridCellEditEvent<T extends TdDataGridRow = TdDataGridRow> {
|
|
14
|
+
row: T;
|
|
15
|
+
field: keyof T & string;
|
|
16
|
+
oldValue: unknown;
|
|
17
|
+
newValue: unknown;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export declare interface TdDataGridColumn<T extends TdDataGridRow = TdDataGridRow> {
|
|
21
|
+
/** Unique column identifier */
|
|
22
|
+
field: keyof T & string;
|
|
23
|
+
/** Column header label */
|
|
24
|
+
headerName: string;
|
|
25
|
+
/** Column width in pixels */
|
|
26
|
+
width?: number;
|
|
27
|
+
/** Minimum column width */
|
|
28
|
+
minWidth?: number;
|
|
29
|
+
/** Flex grow factor */
|
|
30
|
+
flex?: number;
|
|
31
|
+
/** Enable sorting for this column */
|
|
32
|
+
sortable?: boolean;
|
|
33
|
+
/** Enable filtering for this column */
|
|
34
|
+
filterable?: boolean;
|
|
35
|
+
/** Enable inline cell editing for this column */
|
|
36
|
+
editable?: boolean | ((params: TdDataGridCellContext<T>) => boolean);
|
|
37
|
+
/** Hide column */
|
|
38
|
+
hidden?: boolean;
|
|
39
|
+
/** Custom cell renderer */
|
|
40
|
+
renderCell?: (params: TdDataGridRenderCellParams<T>) => ReactNode;
|
|
41
|
+
/** Value formatter */
|
|
42
|
+
valueFormatter?: (value: unknown, row: T) => string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Explicit editable cell (row + field pair) */
|
|
46
|
+
export declare interface TdDataGridEditableCell<T extends TdDataGridRow = TdDataGridRow> {
|
|
47
|
+
rowId: string | number;
|
|
48
|
+
field: keyof T & string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export declare type TdDataGridEditTrigger = "singleClick" | "doubleClick";
|
|
52
|
+
|
|
53
|
+
export declare interface TdDataGridExportConfig {
|
|
54
|
+
/** Enable export capability */
|
|
55
|
+
enabled?: boolean;
|
|
56
|
+
/** Export formats */
|
|
57
|
+
formats?: TdDataGridExportFormat[];
|
|
58
|
+
/** Default export file name (without extension) */
|
|
59
|
+
fileName?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export declare type TdDataGridExportFormat = "csv" | "xlsx";
|
|
63
|
+
|
|
64
|
+
export declare interface TdDataGridFilterModel {
|
|
65
|
+
field: string;
|
|
66
|
+
operator: TdDataGridFilterOperator;
|
|
67
|
+
value: unknown;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export declare type TdDataGridFilterOperator = "equals" | "contains" | "startsWith" | "endsWith" | "greaterThan" | "lessThan";
|
|
71
|
+
|
|
72
|
+
declare function TdDataGridInner<T extends TdDataGridRow>({ columns, rows, loading, height, selectable, checkboxSelection, selectedRowIds, onSelectionChange, onRowSelect, onRowClick, pagination, pageSize, onPaginationChange, rowCount: _rowCount, serverSidePagination: _serverSidePagination, sortModel, onSortChange, filterModel: _filterModel, onFilterChange: _onFilterChange, search: _search, export: exportConfig, persistence, permissions, rowActions, editable, editableRowIds, isRowEditable, editableCells, isCellEditable, editTrigger, onCellValueChanged, themeClassName, className, style, emptyMessage, error, errorMessage, "aria-label": ariaLabel, }: TdDataGridProps<T>): JSX.Element;
|
|
73
|
+
|
|
74
|
+
export declare interface TdDataGridPaginationModel {
|
|
75
|
+
page: number;
|
|
76
|
+
pageSize: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export declare interface TdDataGridPermissionsConfig {
|
|
80
|
+
/** Can user edit rows */
|
|
81
|
+
canEdit?: boolean;
|
|
82
|
+
/** Can user delete rows */
|
|
83
|
+
canDelete?: boolean;
|
|
84
|
+
/** Can user export data */
|
|
85
|
+
canExport?: boolean;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export declare interface TdDataGridPersistenceConfig {
|
|
89
|
+
/** Storage key for column state persistence */
|
|
90
|
+
storageKey?: string;
|
|
91
|
+
/** Enable state persistence */
|
|
92
|
+
enabled?: boolean;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export declare interface TdDataGridProps<T extends TdDataGridRow = TdDataGridRow> {
|
|
96
|
+
/** Column definitions */
|
|
97
|
+
columns: TdDataGridColumn<T>[];
|
|
98
|
+
/** Row data */
|
|
99
|
+
rows: T[];
|
|
100
|
+
/** Loading state */
|
|
101
|
+
loading?: boolean;
|
|
102
|
+
/** Grid height */
|
|
103
|
+
height?: number | string;
|
|
104
|
+
/** Enable row selection (alias: checkboxSelection) */
|
|
105
|
+
selectable?: boolean;
|
|
106
|
+
/** @deprecated Use selectable */
|
|
107
|
+
checkboxSelection?: boolean;
|
|
108
|
+
/** Selected row IDs */
|
|
109
|
+
selectedRowIds?: (string | number)[];
|
|
110
|
+
/** Selection change handler (returns selected IDs) */
|
|
111
|
+
onSelectionChange?: (selectedIds: (string | number)[]) => void;
|
|
112
|
+
/** Row selection handler (returns selected row objects) */
|
|
113
|
+
onRowSelect?: (selectedRows: T[]) => void;
|
|
114
|
+
/** Row click handler */
|
|
115
|
+
onRowClick?: (row: T) => void;
|
|
116
|
+
/** Enable pagination or provide controlled pagination model */
|
|
117
|
+
pagination?: boolean | TdDataGridPaginationModel;
|
|
118
|
+
/** Default or controlled page size when pagination is enabled */
|
|
119
|
+
pageSize?: number;
|
|
120
|
+
/** Pagination change handler */
|
|
121
|
+
onPaginationChange?: (model: TdDataGridPaginationModel) => void;
|
|
122
|
+
/** Total row count for server-side pagination */
|
|
123
|
+
rowCount?: number;
|
|
124
|
+
/** Server-side pagination mode */
|
|
125
|
+
serverSidePagination?: boolean;
|
|
126
|
+
/** Server-side mode flags (future-ready) */
|
|
127
|
+
serverSideMode?: TdDataGridServerSideMode[];
|
|
128
|
+
/** Sort model */
|
|
129
|
+
sortModel?: TdDataGridSortModel[];
|
|
130
|
+
/** Sort change handler */
|
|
131
|
+
onSortChange?: (model: TdDataGridSortModel[]) => void;
|
|
132
|
+
/** Filter model */
|
|
133
|
+
filterModel?: TdDataGridFilterModel[];
|
|
134
|
+
/** Filter change handler */
|
|
135
|
+
onFilterChange?: (model: TdDataGridFilterModel[]) => void;
|
|
136
|
+
/** Global search configuration */
|
|
137
|
+
search?: TdDataGridSearchConfig;
|
|
138
|
+
/** Export configuration */
|
|
139
|
+
export?: TdDataGridExportConfig;
|
|
140
|
+
/** State persistence configuration */
|
|
141
|
+
persistence?: TdDataGridPersistenceConfig;
|
|
142
|
+
/** Permission configuration */
|
|
143
|
+
permissions?: TdDataGridPermissionsConfig;
|
|
144
|
+
/** Row-level actions */
|
|
145
|
+
rowActions?: TdDataGridRowAction<T>[];
|
|
146
|
+
/** Enable inline cell editing (can be overridden per column, row, or cell) */
|
|
147
|
+
editable?: boolean;
|
|
148
|
+
/** Only these row IDs are editable */
|
|
149
|
+
editableRowIds?: (string | number)[];
|
|
150
|
+
/** Dynamic row editability check */
|
|
151
|
+
isRowEditable?: (row: T) => boolean;
|
|
152
|
+
/** Whitelist of editable cells (row + field pairs) */
|
|
153
|
+
editableCells?: TdDataGridEditableCell<T>[];
|
|
154
|
+
/** Dynamic per-cell editability check (highest priority) */
|
|
155
|
+
isCellEditable?: (params: TdDataGridCellContext<T>) => boolean;
|
|
156
|
+
/** How editing is triggered */
|
|
157
|
+
editTrigger?: TdDataGridEditTrigger;
|
|
158
|
+
/** Cell value change handler */
|
|
159
|
+
onCellValueChanged?: (event: TdDataGridCellEditEvent<T>) => void;
|
|
160
|
+
/** AG Grid theme class (default: ag-theme-alpine) */
|
|
161
|
+
themeClassName?: TdDataGridThemeClassName | (string & {});
|
|
162
|
+
/** Additional CSS class for the grid container */
|
|
163
|
+
className?: string;
|
|
164
|
+
/** Inline styles for the grid container */
|
|
165
|
+
style?: React.CSSProperties;
|
|
166
|
+
/** Empty state message */
|
|
167
|
+
emptyMessage?: string;
|
|
168
|
+
/** Error state */
|
|
169
|
+
error?: boolean;
|
|
170
|
+
/** Error message */
|
|
171
|
+
errorMessage?: string;
|
|
172
|
+
/** Accessible label */
|
|
173
|
+
"aria-label"?: string;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export declare interface TdDataGridRenderCellParams<T extends TdDataGridRow> {
|
|
177
|
+
row: T;
|
|
178
|
+
value: unknown;
|
|
179
|
+
field: keyof T & string;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export declare interface TdDataGridRow {
|
|
183
|
+
id: string | number;
|
|
184
|
+
[key: string]: unknown;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export declare interface TdDataGridRowAction<T extends TdDataGridRow> {
|
|
188
|
+
id: string;
|
|
189
|
+
label: string;
|
|
190
|
+
icon?: ReactNode;
|
|
191
|
+
onClick: (row: T) => void;
|
|
192
|
+
disabled?: (row: T) => boolean;
|
|
193
|
+
hidden?: (row: T) => boolean;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export declare interface TdDataGridSearchConfig {
|
|
197
|
+
/** Enable global search */
|
|
198
|
+
enabled?: boolean;
|
|
199
|
+
/** Search placeholder */
|
|
200
|
+
placeholder?: string;
|
|
201
|
+
/** Controlled search value */
|
|
202
|
+
value?: string;
|
|
203
|
+
/** Search change handler */
|
|
204
|
+
onChange?: (value: string) => void;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** Server-side data fetching mode (future-ready abstraction) */
|
|
208
|
+
export declare type TdDataGridServerSideMode = "pagination" | "sort" | "filter" | "full";
|
|
209
|
+
|
|
210
|
+
export declare interface TdDataGridSortModel {
|
|
211
|
+
field: string;
|
|
212
|
+
sort: "asc" | "desc";
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Built-in AG Grid theme class names */
|
|
216
|
+
export declare type TdDataGridThemeClassName = "ag-theme-alpine" | "ag-theme-balham" | "ag-theme-quartz" | "ag-theme-material";
|
|
217
|
+
|
|
218
|
+
export { }
|