@gravionlabs/helix-ag-grid 22.0.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/LICENSE.md +21 -0
- package/README.md +62 -0
- package/fesm2022/gravionlabs-helix-ag-grid.mjs +249 -0
- package/fesm2022/gravionlabs-helix-ag-grid.mjs.map +1 -0
- package/package.json +43 -0
- package/styles.css +81 -0
- package/types/gravionlabs-helix-ag-grid.d.ts +158 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GravionLabs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @gravionlabs/helix-ag-grid
|
|
2
|
+
|
|
3
|
+
AG Grid helpers for Helix applications: locale-aware value formatters, robust
|
|
4
|
+
number parsing for editable cells, and shared cell styles.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @gravionlabs/helix-ag-grid
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Peer dependencies: `@angular/core >=22`, `ag-grid-angular >=33`, `ag-grid-community >=33`.
|
|
13
|
+
|
|
14
|
+
The package ships a prebuilt stylesheet; add it to your global styles:
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
// angular.json
|
|
18
|
+
"styles": ["node_modules/@gravionlabs/helix-ag-grid/styles.css", "src/styles.scss"]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Formatters
|
|
22
|
+
|
|
23
|
+
`Intl`-based value formatters for column definitions:
|
|
24
|
+
|
|
25
|
+
| Export | Formats |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| `numberFormatter` / `rawNumberFormatter` / `intlNumberFormatter` | Numbers (grouped, raw, or custom `Intl.NumberFormat` options) |
|
|
28
|
+
| `currencyFormatter` | Currency values |
|
|
29
|
+
| `cetDateFormatter` / `cetTimeFormatter` / `cetDateTimeFormatter` | Dates/times in CET |
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { currencyFormatter } from '@gravionlabs/helix-ag-grid';
|
|
33
|
+
|
|
34
|
+
const columnDefs: ColDef[] = [
|
|
35
|
+
{ field: 'price', valueFormatter: currencyFormatter('EUR') },
|
|
36
|
+
];
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
See `AgGridFormatterParams` for the accepted parameter shape.
|
|
40
|
+
|
|
41
|
+
## Parsers
|
|
42
|
+
|
|
43
|
+
Number parsing for cell editing:
|
|
44
|
+
|
|
45
|
+
- `parseNumber(value, options?)` / `parseNumberValue` — parse localized number strings (`ParseNumberOptions` controls locale/precision behavior).
|
|
46
|
+
- `numberValueParser` — drop-in `valueParser` for numeric columns.
|
|
47
|
+
- `coerceValue` — general value coercion helper.
|
|
48
|
+
|
|
49
|
+
## Cell Styles
|
|
50
|
+
|
|
51
|
+
- `numberCellStyle` — right-aligned tabular style for numeric columns.
|
|
52
|
+
|
|
53
|
+
## Development
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
ng build ag-grid
|
|
57
|
+
ng test ag-grid
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AG Grid `cellStyle` callback that right-aligns numeric cells and colours
|
|
3
|
+
* truthy (non-zero, non-null, non-undefined) values with the helix success
|
|
4
|
+
* colour (`--h-green-500`).
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* columnDefs = [{ field: 'amount', cellStyle: numberCellStyle }];
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
function numberCellStyle(params) {
|
|
12
|
+
return params.value
|
|
13
|
+
? { textAlign: 'right', color: 'var(--h-green-500)' }
|
|
14
|
+
: { textAlign: 'right' };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ── Number formatters ──────────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Formats a numeric cell value using the system locale (`toLocaleString`).
|
|
20
|
+
* Returns `''` for `null`, `undefined`, or `NaN`.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* { field: 'amount', valueFormatter: numberFormatter }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function numberFormatter(params) {
|
|
28
|
+
const v = params.value;
|
|
29
|
+
if (v == null || Number.isNaN(v))
|
|
30
|
+
return '';
|
|
31
|
+
return v.toLocaleString();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns the raw string representation of a number without any locale
|
|
35
|
+
* formatting. Returns `''` for `null` or `undefined`.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* { field: 'id', valueFormatter: rawNumberFormatter }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
function rawNumberFormatter(params) {
|
|
43
|
+
const v = params.value;
|
|
44
|
+
if (v == null)
|
|
45
|
+
return '';
|
|
46
|
+
return v.toString();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Formats a number using a caller-supplied `Intl.NumberFormat` instance,
|
|
50
|
+
* allowing full control over locale, currency, fraction digits, etc.
|
|
51
|
+
* Returns `''` for `null` or `undefined`.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const fmt = new Intl.NumberFormat('de-DE', { minimumFractionDigits: 2 });
|
|
56
|
+
* { field: 'price', valueFormatter: (p) => intlNumberFormatter(p, fmt) }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
function intlNumberFormatter(params, numberFormat) {
|
|
60
|
+
const v = params.value;
|
|
61
|
+
if (v == null || Number.isNaN(v))
|
|
62
|
+
return '';
|
|
63
|
+
return numberFormat.format(v);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Factory that returns a currency formatter closure using `Intl.NumberFormat`
|
|
67
|
+
* with `style: 'currency'`. Defaults to EUR / de-DE.
|
|
68
|
+
* Returns `''` for `null`, `undefined`, or `NaN`.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* { field: 'revenue', valueFormatter: currencyFormatter() } // '1.234,50 €'
|
|
73
|
+
* { field: 'price', valueFormatter: currencyFormatter('USD','en-US') } // '$99.90'
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
function currencyFormatter(currencyCode = 'EUR', locale = 'de-DE') {
|
|
77
|
+
const fmt = new Intl.NumberFormat(locale, { style: 'currency', currency: currencyCode });
|
|
78
|
+
return (params) => {
|
|
79
|
+
const v = params.value;
|
|
80
|
+
if (v == null || Number.isNaN(v))
|
|
81
|
+
return '';
|
|
82
|
+
return fmt.format(v);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function toDate(value) {
|
|
86
|
+
if (value == null)
|
|
87
|
+
return null;
|
|
88
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
89
|
+
return Number.isNaN(d.getTime()) ? null : d;
|
|
90
|
+
}
|
|
91
|
+
const cetDateFormat = new Intl.DateTimeFormat('de-DE', {
|
|
92
|
+
timeZone: 'Europe/Berlin',
|
|
93
|
+
day: '2-digit',
|
|
94
|
+
month: '2-digit',
|
|
95
|
+
year: 'numeric',
|
|
96
|
+
});
|
|
97
|
+
const cetDateTimeFormat = new Intl.DateTimeFormat('de-DE', {
|
|
98
|
+
timeZone: 'Europe/Berlin',
|
|
99
|
+
day: '2-digit',
|
|
100
|
+
month: '2-digit',
|
|
101
|
+
year: 'numeric',
|
|
102
|
+
hour: '2-digit',
|
|
103
|
+
minute: '2-digit',
|
|
104
|
+
second: '2-digit',
|
|
105
|
+
hour12: false,
|
|
106
|
+
});
|
|
107
|
+
const cetTimeFormat = new Intl.DateTimeFormat('de-DE', {
|
|
108
|
+
timeZone: 'Europe/Berlin',
|
|
109
|
+
hour: '2-digit',
|
|
110
|
+
minute: '2-digit',
|
|
111
|
+
hour12: false,
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* Formats a `Date` or ISO string as a CET date: `'15.06.2024'`.
|
|
115
|
+
* Returns `''` for `null`, `undefined`, or invalid dates.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* { field: 'date', valueFormatter: cetDateFormatter }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
function cetDateFormatter(params) {
|
|
123
|
+
const d = toDate(params.value);
|
|
124
|
+
return d ? cetDateFormat.format(d) : '';
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Formats a `Date` or ISO string as a CET date-time: `'15.06.2024 12:30:00'`.
|
|
128
|
+
* Returns `''` for `null`, `undefined`, or invalid dates.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* { field: 'updatedAt', valueFormatter: cetDateTimeFormatter }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
function cetDateTimeFormatter(params) {
|
|
136
|
+
const d = toDate(params.value);
|
|
137
|
+
if (!d)
|
|
138
|
+
return '';
|
|
139
|
+
// Intl formats date and time parts separated by ', ' in de-DE — replace with ' '
|
|
140
|
+
return cetDateTimeFormat.format(d).replace(', ', ' ');
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Formats a `Date` or ISO string as a CET time: `'12:30'`.
|
|
144
|
+
* Returns `''` for `null`, `undefined`, or invalid dates.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* { field: 'startTime', valueFormatter: cetTimeFormatter }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
function cetTimeFormatter(params) {
|
|
152
|
+
const d = toDate(params.value);
|
|
153
|
+
return d ? cetTimeFormat.format(d) : '';
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Validates a number against optional `min`/`max` bounds.
|
|
158
|
+
* Returns `null` if the value is `null`, `undefined`, `NaN`, or out of bounds.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* coerceValue(5, { min: 0, max: 10 }) // → 5
|
|
163
|
+
* coerceValue(15, { max: 10 }) // → null
|
|
164
|
+
* coerceValue(null) // → null
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
function coerceValue(value, options) {
|
|
168
|
+
if (value == null || Number.isNaN(value))
|
|
169
|
+
return null;
|
|
170
|
+
if (options?.min != null && value < options.min)
|
|
171
|
+
return null;
|
|
172
|
+
if (options?.max != null && value > options.max)
|
|
173
|
+
return null;
|
|
174
|
+
return value;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Locale-aware string-to-number parser.
|
|
178
|
+
* Handles thousand separators and decimal commas for the given locale.
|
|
179
|
+
* Returns `null` for empty, `null`, or `undefined` input.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* parseNumber('1.234,56', 'de-DE') // → 1234.56
|
|
184
|
+
* parseNumber('1,234.56', 'en-US') // → 1234.56
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
function parseNumber(value, locale, options) {
|
|
188
|
+
if (value == null || value.trim() === '')
|
|
189
|
+
return null;
|
|
190
|
+
// Derive separators from the locale
|
|
191
|
+
const parts = new Intl.NumberFormat(locale).formatToParts(1234.5);
|
|
192
|
+
const group = parts.find((p) => p.type === 'group')?.value ?? '';
|
|
193
|
+
const decimal = parts.find((p) => p.type === 'decimal')?.value ?? '.';
|
|
194
|
+
const normalised = value.trim().replaceAll(group, '').replace(decimal, '.');
|
|
195
|
+
const n = Number.parseFloat(normalised);
|
|
196
|
+
return coerceValue(n, options);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Smart string-to-number parser that detects the decimal separator
|
|
200
|
+
* automatically:
|
|
201
|
+
* - Strings containing a comma (e.g. `'1.234,56'` from spreadsheet paste)
|
|
202
|
+
* are parsed as German locale (`de-DE`).
|
|
203
|
+
* - All other strings (e.g. `'3.14'` from keyboard input) are parsed with
|
|
204
|
+
* `parseFloat`.
|
|
205
|
+
*
|
|
206
|
+
* Returns `null` for empty, `null`, or `undefined` input.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* parseNumberValue('42') // → 42
|
|
211
|
+
* parseNumberValue('3.14') // → 3.14
|
|
212
|
+
* parseNumberValue('1.234,56') // → 1234.56 (German paste)
|
|
213
|
+
* parseNumberValue(null) // → null
|
|
214
|
+
* parseNumberValue('5', { min: 10 }) // → null (out of bounds)
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
function parseNumberValue(value, options) {
|
|
218
|
+
if (value == null || value.trim() === '')
|
|
219
|
+
return null;
|
|
220
|
+
const hasComma = value.includes(',');
|
|
221
|
+
if (hasComma) {
|
|
222
|
+
return parseNumber(value, 'de-DE', options);
|
|
223
|
+
}
|
|
224
|
+
const n = Number.parseFloat(value.trim());
|
|
225
|
+
return coerceValue(n, options);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* AG Grid `valueParser` adapter — wraps `parseNumberValue` to read
|
|
229
|
+
* `params.newValue`. Drop-in for any editable numeric column.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```ts
|
|
233
|
+
* { field: 'quantity', editable: true, valueParser: numberValueParser }
|
|
234
|
+
* // or with bounds:
|
|
235
|
+
* { field: 'pct', editable: true, valueParser: (p) => numberValueParser(p, { min: 0, max: 100 }) }
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
function numberValueParser(params, options) {
|
|
239
|
+
return parseNumberValue(params.newValue, options);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const HELIX_AG_GRID_VERSION = '0.1.0';
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Generated bundle index. Do not edit.
|
|
246
|
+
*/
|
|
247
|
+
|
|
248
|
+
export { HELIX_AG_GRID_VERSION, cetDateFormatter, cetDateTimeFormatter, cetTimeFormatter, coerceValue, currencyFormatter, intlNumberFormatter, numberCellStyle, numberFormatter, numberValueParser, parseNumber, parseNumberValue, rawNumberFormatter };
|
|
249
|
+
//# sourceMappingURL=gravionlabs-helix-ag-grid.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gravionlabs-helix-ag-grid.mjs","sources":["../../../projects/ag-grid/src/lib/cell-styles/cell-styles.ts","../../../projects/ag-grid/src/lib/formatters/ag-grid-formatters.ts","../../../projects/ag-grid/src/lib/parsers/number-parsers.ts","../../../projects/ag-grid/src/public-api.ts","../../../projects/ag-grid/src/gravionlabs-helix-ag-grid.ts"],"sourcesContent":["import type { CellClassParams, CellStyle } from 'ag-grid-community';\n\n/**\n * AG Grid `cellStyle` callback that right-aligns numeric cells and colours\n * truthy (non-zero, non-null, non-undefined) values with the helix success\n * colour (`--h-green-500`).\n *\n * @example\n * ```ts\n * columnDefs = [{ field: 'amount', cellStyle: numberCellStyle }];\n * ```\n */\nexport function numberCellStyle(params: CellClassParams): CellStyle {\n return params.value\n ? { textAlign: 'right', color: 'var(--h-green-500)' }\n : { textAlign: 'right' };\n}\n","import type { ValueFormatterParams } from 'ag-grid-community';\n\n/** Type alias for AG Grid's `ValueFormatterParams`, used by all formatter functions. */\nexport type AgGridFormatterParams<TData = unknown, TValue = unknown> = ValueFormatterParams<\n TData,\n TValue\n>;\n\n// ── Number formatters ──────────────────────────────────────────────────────\n\n/**\n * Formats a numeric cell value using the system locale (`toLocaleString`).\n * Returns `''` for `null`, `undefined`, or `NaN`.\n *\n * @example\n * ```ts\n * { field: 'amount', valueFormatter: numberFormatter }\n * ```\n */\nexport function numberFormatter(\n params: AgGridFormatterParams<unknown, number | null | undefined>,\n): string {\n const v = params.value;\n if (v == null || Number.isNaN(v)) return '';\n return v.toLocaleString();\n}\n\n/**\n * Returns the raw string representation of a number without any locale\n * formatting. Returns `''` for `null` or `undefined`.\n *\n * @example\n * ```ts\n * { field: 'id', valueFormatter: rawNumberFormatter }\n * ```\n */\nexport function rawNumberFormatter(\n params: AgGridFormatterParams<unknown, number | null | undefined>,\n): string {\n const v = params.value;\n if (v == null) return '';\n return v.toString();\n}\n\n/**\n * Formats a number using a caller-supplied `Intl.NumberFormat` instance,\n * allowing full control over locale, currency, fraction digits, etc.\n * Returns `''` for `null` or `undefined`.\n *\n * @example\n * ```ts\n * const fmt = new Intl.NumberFormat('de-DE', { minimumFractionDigits: 2 });\n * { field: 'price', valueFormatter: (p) => intlNumberFormatter(p, fmt) }\n * ```\n */\nexport function intlNumberFormatter(\n params: AgGridFormatterParams<unknown, number | null | undefined>,\n numberFormat: Intl.NumberFormat,\n): string {\n const v = params.value;\n if (v == null || Number.isNaN(v)) return '';\n return numberFormat.format(v);\n}\n\n/**\n * Factory that returns a currency formatter closure using `Intl.NumberFormat`\n * with `style: 'currency'`. Defaults to EUR / de-DE.\n * Returns `''` for `null`, `undefined`, or `NaN`.\n *\n * @example\n * ```ts\n * { field: 'revenue', valueFormatter: currencyFormatter() } // '1.234,50 €'\n * { field: 'price', valueFormatter: currencyFormatter('USD','en-US') } // '$99.90'\n * ```\n */\nexport function currencyFormatter(\n currencyCode = 'EUR',\n locale = 'de-DE',\n): (params: AgGridFormatterParams<unknown, number | null | undefined>) => string {\n const fmt = new Intl.NumberFormat(locale, { style: 'currency', currency: currencyCode });\n return (params) => {\n const v = params.value;\n if (v == null || Number.isNaN(v)) return '';\n return fmt.format(v);\n };\n}\n\n// ── CET date formatters ────────────────────────────────────────────────────\n\ntype DateInput = Date | string | null | undefined;\n\nfunction toDate(value: DateInput): Date | null {\n if (value == null) return null;\n const d = value instanceof Date ? value : new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\nconst cetDateFormat = new Intl.DateTimeFormat('de-DE', {\n timeZone: 'Europe/Berlin',\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n});\n\nconst cetDateTimeFormat = new Intl.DateTimeFormat('de-DE', {\n timeZone: 'Europe/Berlin',\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n});\n\nconst cetTimeFormat = new Intl.DateTimeFormat('de-DE', {\n timeZone: 'Europe/Berlin',\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n});\n\n/**\n * Formats a `Date` or ISO string as a CET date: `'15.06.2024'`.\n * Returns `''` for `null`, `undefined`, or invalid dates.\n *\n * @example\n * ```ts\n * { field: 'date', valueFormatter: cetDateFormatter }\n * ```\n */\nexport function cetDateFormatter(params: AgGridFormatterParams<unknown, DateInput>): string {\n const d = toDate(params.value);\n return d ? cetDateFormat.format(d) : '';\n}\n\n/**\n * Formats a `Date` or ISO string as a CET date-time: `'15.06.2024 12:30:00'`.\n * Returns `''` for `null`, `undefined`, or invalid dates.\n *\n * @example\n * ```ts\n * { field: 'updatedAt', valueFormatter: cetDateTimeFormatter }\n * ```\n */\nexport function cetDateTimeFormatter(params: AgGridFormatterParams<unknown, DateInput>): string {\n const d = toDate(params.value);\n if (!d) return '';\n // Intl formats date and time parts separated by ', ' in de-DE — replace with ' '\n return cetDateTimeFormat.format(d).replace(', ', ' ');\n}\n\n/**\n * Formats a `Date` or ISO string as a CET time: `'12:30'`.\n * Returns `''` for `null`, `undefined`, or invalid dates.\n *\n * @example\n * ```ts\n * { field: 'startTime', valueFormatter: cetTimeFormatter }\n * ```\n */\nexport function cetTimeFormatter(params: AgGridFormatterParams<unknown, DateInput>): string {\n const d = toDate(params.value);\n return d ? cetTimeFormat.format(d) : '';\n}\n","import type { ValueParserParams } from 'ag-grid-community';\n\n/** Bounds for number validation. */\nexport interface ParseNumberOptions {\n min?: number;\n max?: number;\n}\n\n/**\n * Validates a number against optional `min`/`max` bounds.\n * Returns `null` if the value is `null`, `undefined`, `NaN`, or out of bounds.\n *\n * @example\n * ```ts\n * coerceValue(5, { min: 0, max: 10 }) // → 5\n * coerceValue(15, { max: 10 }) // → null\n * coerceValue(null) // → null\n * ```\n */\nexport function coerceValue(\n value: number | null | undefined,\n options?: ParseNumberOptions,\n): number | null {\n if (value == null || Number.isNaN(value)) return null;\n if (options?.min != null && value < options.min) return null;\n if (options?.max != null && value > options.max) return null;\n return value;\n}\n\n/**\n * Locale-aware string-to-number parser.\n * Handles thousand separators and decimal commas for the given locale.\n * Returns `null` for empty, `null`, or `undefined` input.\n *\n * @example\n * ```ts\n * parseNumber('1.234,56', 'de-DE') // → 1234.56\n * parseNumber('1,234.56', 'en-US') // → 1234.56\n * ```\n */\nexport function parseNumber(\n value: string | null | undefined,\n locale: string,\n options?: ParseNumberOptions,\n): number | null {\n if (value == null || value.trim() === '') return null;\n\n // Derive separators from the locale\n const parts = new Intl.NumberFormat(locale).formatToParts(1234.5);\n const group = parts.find((p) => p.type === 'group')?.value ?? '';\n const decimal = parts.find((p) => p.type === 'decimal')?.value ?? '.';\n\n const normalised = value.trim().replaceAll(group, '').replace(decimal, '.');\n\n const n = Number.parseFloat(normalised);\n return coerceValue(n, options);\n}\n\n/**\n * Smart string-to-number parser that detects the decimal separator\n * automatically:\n * - Strings containing a comma (e.g. `'1.234,56'` from spreadsheet paste)\n * are parsed as German locale (`de-DE`).\n * - All other strings (e.g. `'3.14'` from keyboard input) are parsed with\n * `parseFloat`.\n *\n * Returns `null` for empty, `null`, or `undefined` input.\n *\n * @example\n * ```ts\n * parseNumberValue('42') // → 42\n * parseNumberValue('3.14') // → 3.14\n * parseNumberValue('1.234,56') // → 1234.56 (German paste)\n * parseNumberValue(null) // → null\n * parseNumberValue('5', { min: 10 }) // → null (out of bounds)\n * ```\n */\nexport function parseNumberValue(\n value: string | null | undefined,\n options?: ParseNumberOptions,\n): number | null {\n if (value == null || value.trim() === '') return null;\n\n const hasComma = value.includes(',');\n if (hasComma) {\n return parseNumber(value, 'de-DE', options);\n }\n\n const n = Number.parseFloat(value.trim());\n return coerceValue(n, options);\n}\n\n/**\n * AG Grid `valueParser` adapter — wraps `parseNumberValue` to read\n * `params.newValue`. Drop-in for any editable numeric column.\n *\n * @example\n * ```ts\n * { field: 'quantity', editable: true, valueParser: numberValueParser }\n * // or with bounds:\n * { field: 'pct', editable: true, valueParser: (p) => numberValueParser(p, { min: 0, max: 100 }) }\n * ```\n */\nexport function numberValueParser(\n params: ValueParserParams,\n options?: ParseNumberOptions,\n): number | null {\n return parseNumberValue(params.newValue as string | null | undefined, options);\n}\n","export const HELIX_AG_GRID_VERSION = '0.1.0';\n\nexport { numberCellStyle } from './lib/cell-styles/cell-styles';\n\nexport type { AgGridFormatterParams } from './lib/formatters/ag-grid-formatters';\nexport {\n cetDateFormatter,\n cetDateTimeFormatter,\n cetTimeFormatter,\n currencyFormatter,\n intlNumberFormatter,\n numberFormatter,\n rawNumberFormatter,\n} from './lib/formatters/ag-grid-formatters';\n\nexport type { ParseNumberOptions } from './lib/parsers/number-parsers';\nexport {\n coerceValue,\n numberValueParser,\n parseNumber,\n parseNumberValue,\n} from './lib/parsers/number-parsers';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gravionlabs/helix-ag-grid",
|
|
3
|
+
"version": "22.0.0",
|
|
4
|
+
"description": "Helix AG Grid helpers for Angular — value formatters, number parsers, and cell styles.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"helix",
|
|
8
|
+
"angular",
|
|
9
|
+
"ag-grid"
|
|
10
|
+
],
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/GravionLabs/helix.git",
|
|
14
|
+
"directory": "projects/ag-grid"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@angular/core": ">=22",
|
|
21
|
+
"ag-grid-angular": ">=33",
|
|
22
|
+
"ag-grid-community": ">=33"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"tslib": "^2.3.0"
|
|
26
|
+
},
|
|
27
|
+
"sideEffects": [
|
|
28
|
+
"**/*.css"
|
|
29
|
+
],
|
|
30
|
+
"module": "fesm2022/gravionlabs-helix-ag-grid.mjs",
|
|
31
|
+
"typings": "types/gravionlabs-helix-ag-grid.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
"./package.json": {
|
|
34
|
+
"default": "./package.json"
|
|
35
|
+
},
|
|
36
|
+
".": {
|
|
37
|
+
"types": "./types/gravionlabs-helix-ag-grid.d.ts",
|
|
38
|
+
"default": "./fesm2022/gravionlabs-helix-ag-grid.mjs"
|
|
39
|
+
},
|
|
40
|
+
"./styles.css": "./styles.css"
|
|
41
|
+
},
|
|
42
|
+
"type": "module"
|
|
43
|
+
}
|
package/styles.css
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* AG Grid Theme — Helix
|
|
3
|
+
*
|
|
4
|
+
* Apply the `.helix-ag-grid` class to the ag-grid host element to get a
|
|
5
|
+
* look and feel consistent with the Helix / PrimeNG design system.
|
|
6
|
+
*
|
|
7
|
+
* Token reference:
|
|
8
|
+
* --helix-* design tokens defined in @gravionlabs/helix styles.css
|
|
9
|
+
* --p-* PrimeNG Aura tokens injected at runtime by ThemeService
|
|
10
|
+
*
|
|
11
|
+
* Approach: https://www.ag-grid.com/javascript-data-grid/theming-css/#overriding-theme-parameters-with-custom-properties
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
.helix-ag-grid {
|
|
15
|
+
/* ── Colours ──────────────────────────────────────────────────────────── */
|
|
16
|
+
--ag-background-color: var(--helix-surface-card);
|
|
17
|
+
--ag-foreground-color: var(--h-text-color);
|
|
18
|
+
--ag-text-color: var(--ag-foreground-color);
|
|
19
|
+
--ag-accent-color: var(--h-primary-color);
|
|
20
|
+
--ag-invalid-color: var(--h-form-field-invalid-border-color);
|
|
21
|
+
--ag-border-color: var(--helix-border);
|
|
22
|
+
--ag-wrapper-border: none;
|
|
23
|
+
--ag-row-border: solid 1px var(--helix-border);
|
|
24
|
+
--ag-odd-row-background-color: color-mix(
|
|
25
|
+
in srgb,
|
|
26
|
+
transparent,
|
|
27
|
+
var(--helix-border) 10%
|
|
28
|
+
);
|
|
29
|
+
--ag-row-hover-color: var(--helix-surface-hover);
|
|
30
|
+
|
|
31
|
+
/* ── Typography ───────────────────────────────────────────────────────── */
|
|
32
|
+
--ag-font-family: "Lato", sans-serif;
|
|
33
|
+
--ag-font-size: 0.75rem;
|
|
34
|
+
|
|
35
|
+
/* ── Header ───────────────────────────────────────────────────────────── */
|
|
36
|
+
--ag-header-background-color: var(--helix-surface-card);
|
|
37
|
+
--ag-header-font-family: "Lato", sans-serif;
|
|
38
|
+
--ag-header-font-weight: 500;
|
|
39
|
+
--ag-header-font-size: 0.75rem;
|
|
40
|
+
--ag-header-text-color: var(--h-primary-color);
|
|
41
|
+
|
|
42
|
+
/* ── Cells ────────────────────────────────────────────────────────────── */
|
|
43
|
+
--ag-cell-text-color: var(--h-text-color);
|
|
44
|
+
--ag-cell-horizontal-padding: 1ch;
|
|
45
|
+
|
|
46
|
+
/* ── Input ────────────────────────────────────────────────────────────── */
|
|
47
|
+
--ag-input-background-color: var(--ag-background-color);
|
|
48
|
+
--ag-input-border: solid 1px var(--ag-border-color);
|
|
49
|
+
|
|
50
|
+
/* ── Drag & drop ──────────────────────────────────────────────────────── */
|
|
51
|
+
--ag-column-drop-cell-background-color: color-mix(
|
|
52
|
+
in srgb,
|
|
53
|
+
transparent,
|
|
54
|
+
var(--ag-foreground-color) 7%
|
|
55
|
+
);
|
|
56
|
+
--ag-column-drop-cell-border: solid 1px
|
|
57
|
+
color-mix(in srgb, transparent, var(--ag-foreground-color) 13%);
|
|
58
|
+
|
|
59
|
+
/* ── Inner element overrides ──────────────────────────────────────────── */
|
|
60
|
+
.ag-root-wrapper,
|
|
61
|
+
.ag-measurement-container,
|
|
62
|
+
.ag-apply-theme-variables {
|
|
63
|
+
--ag-row-height: 2rem;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.ag-cell {
|
|
67
|
+
line-height: 1.85rem;
|
|
68
|
+
-webkit-font-smoothing: antialiased;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.ag-dnd-ghost {
|
|
72
|
+
font-family: "Lato", sans-serif;
|
|
73
|
+
font-size: 0.75rem;
|
|
74
|
+
font-weight: 500;
|
|
75
|
+
color: var(--h-primary-color);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.ag-paging-panel {
|
|
79
|
+
block-size: 3em;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { CellClassParams, CellStyle, ValueFormatterParams, ValueParserParams } from 'ag-grid-community';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AG Grid `cellStyle` callback that right-aligns numeric cells and colours
|
|
5
|
+
* truthy (non-zero, non-null, non-undefined) values with the helix success
|
|
6
|
+
* colour (`--h-green-500`).
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* columnDefs = [{ field: 'amount', cellStyle: numberCellStyle }];
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
declare function numberCellStyle(params: CellClassParams): CellStyle;
|
|
14
|
+
|
|
15
|
+
/** Type alias for AG Grid's `ValueFormatterParams`, used by all formatter functions. */
|
|
16
|
+
type AgGridFormatterParams<TData = unknown, TValue = unknown> = ValueFormatterParams<TData, TValue>;
|
|
17
|
+
/**
|
|
18
|
+
* Formats a numeric cell value using the system locale (`toLocaleString`).
|
|
19
|
+
* Returns `''` for `null`, `undefined`, or `NaN`.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* { field: 'amount', valueFormatter: numberFormatter }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare function numberFormatter(params: AgGridFormatterParams<unknown, number | null | undefined>): string;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the raw string representation of a number without any locale
|
|
29
|
+
* formatting. Returns `''` for `null` or `undefined`.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* { field: 'id', valueFormatter: rawNumberFormatter }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
declare function rawNumberFormatter(params: AgGridFormatterParams<unknown, number | null | undefined>): string;
|
|
37
|
+
/**
|
|
38
|
+
* Formats a number using a caller-supplied `Intl.NumberFormat` instance,
|
|
39
|
+
* allowing full control over locale, currency, fraction digits, etc.
|
|
40
|
+
* Returns `''` for `null` or `undefined`.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const fmt = new Intl.NumberFormat('de-DE', { minimumFractionDigits: 2 });
|
|
45
|
+
* { field: 'price', valueFormatter: (p) => intlNumberFormatter(p, fmt) }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
declare function intlNumberFormatter(params: AgGridFormatterParams<unknown, number | null | undefined>, numberFormat: Intl.NumberFormat): string;
|
|
49
|
+
/**
|
|
50
|
+
* Factory that returns a currency formatter closure using `Intl.NumberFormat`
|
|
51
|
+
* with `style: 'currency'`. Defaults to EUR / de-DE.
|
|
52
|
+
* Returns `''` for `null`, `undefined`, or `NaN`.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* { field: 'revenue', valueFormatter: currencyFormatter() } // '1.234,50 €'
|
|
57
|
+
* { field: 'price', valueFormatter: currencyFormatter('USD','en-US') } // '$99.90'
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
declare function currencyFormatter(currencyCode?: string, locale?: string): (params: AgGridFormatterParams<unknown, number | null | undefined>) => string;
|
|
61
|
+
type DateInput = Date | string | null | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Formats a `Date` or ISO string as a CET date: `'15.06.2024'`.
|
|
64
|
+
* Returns `''` for `null`, `undefined`, or invalid dates.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* { field: 'date', valueFormatter: cetDateFormatter }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
declare function cetDateFormatter(params: AgGridFormatterParams<unknown, DateInput>): string;
|
|
72
|
+
/**
|
|
73
|
+
* Formats a `Date` or ISO string as a CET date-time: `'15.06.2024 12:30:00'`.
|
|
74
|
+
* Returns `''` for `null`, `undefined`, or invalid dates.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* { field: 'updatedAt', valueFormatter: cetDateTimeFormatter }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
declare function cetDateTimeFormatter(params: AgGridFormatterParams<unknown, DateInput>): string;
|
|
82
|
+
/**
|
|
83
|
+
* Formats a `Date` or ISO string as a CET time: `'12:30'`.
|
|
84
|
+
* Returns `''` for `null`, `undefined`, or invalid dates.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* { field: 'startTime', valueFormatter: cetTimeFormatter }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
declare function cetTimeFormatter(params: AgGridFormatterParams<unknown, DateInput>): string;
|
|
92
|
+
|
|
93
|
+
/** Bounds for number validation. */
|
|
94
|
+
interface ParseNumberOptions {
|
|
95
|
+
min?: number;
|
|
96
|
+
max?: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Validates a number against optional `min`/`max` bounds.
|
|
100
|
+
* Returns `null` if the value is `null`, `undefined`, `NaN`, or out of bounds.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* coerceValue(5, { min: 0, max: 10 }) // → 5
|
|
105
|
+
* coerceValue(15, { max: 10 }) // → null
|
|
106
|
+
* coerceValue(null) // → null
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
declare function coerceValue(value: number | null | undefined, options?: ParseNumberOptions): number | null;
|
|
110
|
+
/**
|
|
111
|
+
* Locale-aware string-to-number parser.
|
|
112
|
+
* Handles thousand separators and decimal commas for the given locale.
|
|
113
|
+
* Returns `null` for empty, `null`, or `undefined` input.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* parseNumber('1.234,56', 'de-DE') // → 1234.56
|
|
118
|
+
* parseNumber('1,234.56', 'en-US') // → 1234.56
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
declare function parseNumber(value: string | null | undefined, locale: string, options?: ParseNumberOptions): number | null;
|
|
122
|
+
/**
|
|
123
|
+
* Smart string-to-number parser that detects the decimal separator
|
|
124
|
+
* automatically:
|
|
125
|
+
* - Strings containing a comma (e.g. `'1.234,56'` from spreadsheet paste)
|
|
126
|
+
* are parsed as German locale (`de-DE`).
|
|
127
|
+
* - All other strings (e.g. `'3.14'` from keyboard input) are parsed with
|
|
128
|
+
* `parseFloat`.
|
|
129
|
+
*
|
|
130
|
+
* Returns `null` for empty, `null`, or `undefined` input.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* parseNumberValue('42') // → 42
|
|
135
|
+
* parseNumberValue('3.14') // → 3.14
|
|
136
|
+
* parseNumberValue('1.234,56') // → 1234.56 (German paste)
|
|
137
|
+
* parseNumberValue(null) // → null
|
|
138
|
+
* parseNumberValue('5', { min: 10 }) // → null (out of bounds)
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
declare function parseNumberValue(value: string | null | undefined, options?: ParseNumberOptions): number | null;
|
|
142
|
+
/**
|
|
143
|
+
* AG Grid `valueParser` adapter — wraps `parseNumberValue` to read
|
|
144
|
+
* `params.newValue`. Drop-in for any editable numeric column.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* { field: 'quantity', editable: true, valueParser: numberValueParser }
|
|
149
|
+
* // or with bounds:
|
|
150
|
+
* { field: 'pct', editable: true, valueParser: (p) => numberValueParser(p, { min: 0, max: 100 }) }
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
declare function numberValueParser(params: ValueParserParams, options?: ParseNumberOptions): number | null;
|
|
154
|
+
|
|
155
|
+
declare const HELIX_AG_GRID_VERSION = "0.1.0";
|
|
156
|
+
|
|
157
|
+
export { HELIX_AG_GRID_VERSION, cetDateFormatter, cetDateTimeFormatter, cetTimeFormatter, coerceValue, currencyFormatter, intlNumberFormatter, numberCellStyle, numberFormatter, numberValueParser, parseNumber, parseNumberValue, rawNumberFormatter };
|
|
158
|
+
export type { AgGridFormatterParams, ParseNumberOptions };
|