Skip to content

Commit 922f732

Browse files
jordangarsideclaude
andcommitted
[feat][grafana-react] add value mappings, defaults system, and type improvements
__Changes__ *Types* - Add color type improvements (FixedColorMode, ContinuousColorMode, PaletteColorMode, ColorSeriesBy) - Add OverrideConfig as discriminated union based on color mode - Add value mapping types (ValueMappingValue, Range, Regex, Special) - Add FieldConfigProps shared interface for common field configuration - Add TableDataLink and enhanced TableColumnOverride types - Add BasePanelProps.extend and marginLeft props - Add PanelDefaults and ExtendedPanelDefaults types *Components* - Add Container component for nested grid layouts within rows - Add Defaults component for scoped panel defaults - Add defaults prop to Dashboard component - Refactor Stat, Gauge, BarGauge, Table, Timeseries to use FieldConfigProps - Add min/max props to Stat for sparkline Y-axis *Renderer* - Implement value mappings support (normalizeValueMappings) - Implement defaults stack with per-panel-type overrides - Implement Container layout algorithm - Implement extend prop deep-merge for escape hatch - Add deepMerge utility *CLI* - Add --defaults flag to load panel defaults from JSON file *Tests* - Add comprehensive tests for value mappings - Add tests for defaults system - Add tests for Container layout - Add tests for deepMerge utility __Why__ - Value mappings allow transforming values to text/colors (e.g., 0 → "Offline") - Defaults system reduces boilerplate when many panels share configuration - FieldConfigProps consolidates duplicated props across panel types - Container enables complex nested layouts within rows - Discriminated union for OverrideConfig provides better type safety Co-Authored-By: Claude <noreply@anthropic.com>
1 parent dc4bd89 commit 922f732

File tree

24 files changed

+2693
-325
lines changed

24 files changed

+2693
-325
lines changed

docs/scripts/generate-docs.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@
88
* - Type references and defaults
99
*/
1010

11-
import {
12-
Project,
13-
SourceFile,
14-
InterfaceDeclaration,
15-
SyntaxKind,
16-
} from 'ts-morph';
11+
import { Project, SourceFile, InterfaceDeclaration } from 'ts-morph';
1712
import * as fs from 'fs';
1813
import * as path from 'path';
1914

@@ -60,6 +55,11 @@ const COMPONENT_MAPPINGS: ComponentMapping[] = [
6055
output: 'components/_generated/structure/link.mdx',
6156
category: 'structure',
6257
},
58+
{
59+
source: 'components/defaults/defaults.ts',
60+
output: 'components/_generated/structure/defaults.mdx',
61+
category: 'structure',
62+
},
6363

6464
// Query components
6565
{
@@ -230,17 +230,16 @@ interface TypeMapping {
230230
const TYPE_MAPPINGS: TypeMapping[] = [
231231
{
232232
source: 'types/panel-base.ts',
233-
interfaces: [
234-
'BasePanelProps',
235-
'OverrideConfig',
236-
'TableColumnOverride',
237-
'Transformation',
238-
],
233+
interfaces: ['BasePanelProps', 'TableColumnOverride', 'Transformation'],
239234
},
240235
{
241236
source: 'types/display.ts',
242237
interfaces: ['LegendConfig'],
243238
},
239+
{
240+
source: 'types/defaults.ts',
241+
interfaces: ['FieldDefaults', 'PanelOptionDefaults', 'PanelDefaults'],
242+
},
244243
{
245244
source: 'types/common/axis.ts',
246245
interfaces: ['ScaleDistributionConfig', 'AxisConfig'],
@@ -426,7 +425,7 @@ function escapeForMdx(text: string): string {
426425
*/
427426
function parseInterfaceProps(
428427
interfaceDecl: InterfaceDeclaration,
429-
project: Project,
428+
_project: Project,
430429
): { props: ParsedProp[]; extendsType?: string } {
431430
const props: ParsedProp[] = [];
432431
let extendsType: string | undefined;

docs/src/content/docs/api/types.mdx

Lines changed: 80 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ This page documents the TypeScript types used by grafana-react components.
1010
## Quick Reference
1111

1212
- [BasePanelProps](#basepanelprops) - Type definition
13-
- [OverrideConfig](#overrideconfig) - Override configuration for field-specific styling
1413
- [TableColumnOverride](#tablecolumnoverride) - Table column override configuration
1514
- [Transformation](#transformation) - Transformation configuration
1615
- [LegendConfig](#legendconfig) - Legend configuration
16+
- [FieldDefaults](#fielddefaults) - Default field configuration options.
17+
- [PanelOptionDefaults](#paneloptiondefaults) - Default panel options.
18+
- [PanelDefaults](#paneldefaults) - Combined defaults for panels.
1719
- [ScaleDistributionConfig](#scaledistributionconfig) - Scale distribution configuration
1820
- [AxisConfig](#axisconfig) - Axis configuration
1921
- [VizTooltipOptions](#viztooltipoptions) - Tooltip configuration
@@ -29,46 +31,41 @@ This page documents the TypeScript types used by grafana-react components.
2931

3032
_Source: `types/panel-base.ts`_
3133

32-
| Property | Type | Required | Description |
33-
| ----------------- | ------------ | -------- | --------------------------------------------------------------------- |
34-
| `title` | `string` | Yes | Panel title |
35-
| `description` | `string` | No | Panel description |
36-
| `datasource` | `string` | No | Override datasource for this panel (defaults to dashboard datasource) |
37-
| `width` | `number` | No | Panel width in grid units (1-24) |
38-
| `height` | `number` | No | Panel height in grid units |
39-
| `x` | `number` | No | X position (0-23) |
40-
| `y` | `number` | No | Y position |
41-
| `repeat` | `string` | No | Variable to repeat panel for |
42-
| `repeatDirection` | `'v' \| 'h'` | No | Repeat direction |
43-
| `children` | `ReactNode` | No | Panel children (queries or query strings) |
44-
45-
## OverrideConfig
46-
47-
Override configuration for field-specific styling
48-
49-
_Source: `types/panel-base.ts`_
50-
51-
| Property | Type | Required | Description |
52-
| ------------- | --------------------- | -------- | -------------------------- |
53-
| `refId` | `string` | No | Match by query refId |
54-
| `fieldName` | `string` | No | Match by exact field name |
55-
| `fieldRegex` | `string` | No | Match by field name regex |
56-
| `color` | `string` | No | Fixed color |
57-
| `colorMode` | `'shades' \| 'fixed'` | No | Color mode (shades, fixed) |
58-
| `displayName` | `string` | No | Override display name |
59-
| `thresholds` | `ThresholdSpec` | No | Override thresholds |
34+
| Property | Type | Required | Description |
35+
| ----------------- | ------------------------- | -------- | --------------------------------------------------------------------- |
36+
| `title` | `string` | Yes | Panel title |
37+
| `description` | `string` | No | Panel description |
38+
| `datasource` | `string` | No | Override datasource for this panel (defaults to dashboard datasource) |
39+
| `width` | `number` | No | Panel width in grid units (1-24) |
40+
| `height` | `number` | No | Panel height in grid units |
41+
| `marginLeft` | `number` | No | Left margin in grid units - adds empty space before the panel |
42+
| `repeat` | `string` | No | Variable to repeat panel for |
43+
| `repeatDirection` | `'v' \| 'h'` | No | Repeat direction |
44+
| `children` | `ReactNode` | No | Panel children (queries or query strings) |
45+
| `extend` | `Record<string, unknown>` | No | Raw JSON to deep-merge into the panel output. |
46+
47+
Use this escape hatch for Grafana features not yet supported by typed props,
48+
or for custom Grafana fork extensions. |
6049

6150
## TableColumnOverride
6251

6352
Table column override configuration
6453

6554
_Source: `types/panel-base.ts`_
6655

67-
| Property | Type | Required | Description |
68-
| -------- | -------- | -------- | ---------------------- |
69-
| `name` | `string` | Yes | Column name to match |
70-
| `unit` | `string` | No | Display unit |
71-
| `width` | `number` | No | Column width in pixels |
56+
| Property | Type | Required | Description |
57+
| ------------- | ----------------------------------- | -------- | ------------------------------------------------------------------------------------------------ |
58+
| `name` | `string` | Yes | Column name to match |
59+
| `unit` | `string` | No | Display unit |
60+
| `width` | `number` | No | Column width in pixels |
61+
| `displayName` | `string` | No | Override display name for column header |
62+
| `link` | `TableDataLink` | No | Data link for cell values |
63+
| `decimals` | `number` | No | Number of decimal places |
64+
| `cellMode` | ` \| 'auto' \| 'color-text' \| ...` | No | Cell display mode |
65+
| `gaugeMode` | `'basic' \| 'gradient' \| 'lcd'` | No | For gauge cellMode: display mode (basic=solid color, gradient=threshold gradient, lcd=segmented) |
66+
| `min` | `number` | No | For gauge mode: minimum value |
67+
| `max` | `number` | No | For gauge mode: maximum value |
68+
| `thresholds` | `ThresholdSpec` | No | Per-column thresholds (overrides table-level thresholds) |
7269

7370
## Transformation
7471

@@ -87,13 +84,55 @@ Legend configuration
8784

8885
_Source: `types/display.ts`_
8986

90-
| Property | Type | Required | Description |
91-
| ------------- | ------------------- | -------- | ----------- |
92-
| `placement` | `LegendPlacement` | No | |
93-
| `displayMode` | `LegendDisplayMode` | No | |
94-
| `calcs` | `LegendCalc[]` | No | |
95-
| `sortBy` | `string` | No | |
96-
| `sortDesc` | `boolean` | No | |
87+
| Property | Type | Required | Description |
88+
| ------------- | ------------------- | -------- | ------------------------------------------------------------------ |
89+
| `placement` | `LegendPlacement` | No | |
90+
| `displayMode` | `LegendDisplayMode` | No | |
91+
| `calcs` | `LegendCalc[]` | No | |
92+
| `sortBy` | `string` | No | |
93+
| `sortDesc` | `boolean` | No | |
94+
| `width` | `number` | No | Width of legend in pixels (only applies when placement is 'right') |
95+
96+
## FieldDefaults
97+
98+
Default field configuration options.
99+
100+
_Source: `types/defaults.ts`_
101+
102+
| Property | Type | Required | Description |
103+
| ---------------- | ------------------------------------------ | -------- | ---------------------------------------------------------------------- |
104+
| `colorMode` | `ColorMode` | No | Default color mode for panels |
105+
| `axisBorderShow` | `boolean` | No | Default axis border visibility |
106+
| `axisColorMode` | `'text' \| 'series'` | No | Default axis color mode |
107+
| `axisPlacement` | `'auto' \| 'left' \| 'right' \| 'hidden'` | No | Default axis placement |
108+
| `axisGridShow` | `boolean` | No | Default axis grid visibility |
109+
| `lineWidth` | `number` | No | Default line width |
110+
| `fill` | `number` | No | Default fill opacity (0-100) |
111+
| `gradientMode` | `'none' \| 'opacity' \| 'hue' \| 'scheme'` | No | Default gradient mode |
112+
| `pointSize` | `number` | No | Default point size |
113+
| `showPoints` | `'auto' \| 'always' \| 'never'` | No | Default show points mode |
114+
| `thresholdStyle` | `ThresholdStyle` | No | Default threshold display style |
115+
| `seriesBy` | `ColorSeriesBy` | No | For continuous color modes, default value to use for color calculation |
116+
117+
## PanelOptionDefaults
118+
119+
Default panel options.
120+
121+
_Source: `types/defaults.ts`_
122+
123+
| Property | Type | Required | Description |
124+
| ------------- | ------------------------------- | -------- | ---------------------------- |
125+
| `legend` | `LegendConfig \| false` | No | Default legend configuration |
126+
| `tooltipMode` | `'single' \| 'multi' \| 'none'` | No | Default tooltip mode |
127+
| `tooltipSort` | `'none' \| 'asc' \| 'desc'` | No | Default tooltip sort order |
128+
129+
## PanelDefaults
130+
131+
Combined defaults for panels.
132+
133+
_Source: `types/defaults.ts`_
134+
135+
_Extends [FieldDefaults](#fielddefaults)_
97136

98137
## ScaleDistributionConfig
99138

notes/value-mappings.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Value Mappings
2+
3+
## Current Implementation
4+
5+
Value mappings are implemented via the `valueMappings` prop on panels that extend `FieldConfigProps`.
6+
7+
### Supported Panels
8+
9+
The following panels support `valueMappings` through `FieldConfigProps`:
10+
11+
- Stat
12+
- Gauge
13+
- Bar Gauge
14+
- Table
15+
- Timeseries
16+
17+
### FieldConfigProps
18+
19+
We created a shared `FieldConfigProps` interface in `types/panel-base.ts` that panels extend:
20+
21+
```typescript
22+
interface FieldConfigProps {
23+
unit?: Unit;
24+
decimals?: number;
25+
thresholds?: ThresholdSpec;
26+
baseColor?: 'green' | 'transparent' | 'text' | string;
27+
valueMappings?: ValueMapping[];
28+
noValue?: string;
29+
}
30+
31+
interface StatProps extends BasePanelProps, FieldConfigProps {
32+
// Stat-specific props
33+
}
34+
```
35+
36+
This consolidates common field configuration props that were previously duplicated across panels.
37+
38+
### Prop Name
39+
40+
We use `valueMappings` (not `mappings`) because:
41+
42+
- Grafana's UI calls this feature "Value mappings"
43+
- More descriptive than just `mappings`
44+
- Distinguishes from other mapping concepts
45+
46+
### JSON Output
47+
48+
The prop maps to `fieldConfig.defaults.mappings` in Grafana's JSON format.
49+
50+
### Types
51+
52+
```typescript
53+
// In types/display.ts
54+
type ValueMapping =
55+
| ValueMappingValue // Exact value match
56+
| ValueMappingRange // Range of values
57+
| ValueMappingRegex // Regex pattern match
58+
| ValueMappingSpecial; // Special values (null, NaN, etc)
59+
```
60+
61+
## Future Considerations
62+
63+
### Additional Panels
64+
65+
The following panels have `mappings: []` in their fieldConfig and could be updated to extend `FieldConfigProps`:
66+
67+
- State Timeline
68+
- Status History
69+
- Pie Chart
70+
- Bar Chart
71+
- Histogram
72+
- Candlestick
73+
- Trend
74+
- XY Chart
75+
- Logs
76+
- Datagrid
77+
78+
### Partial Field Config
79+
80+
Some panels may only need a subset of `FieldConfigProps`. If needed, use `Pick<>`:
81+
82+
```typescript
83+
interface SomeProps
84+
extends BasePanelProps, Pick<FieldConfigProps, 'unit' | 'valueMappings'> {
85+
// Panel-specific props
86+
}
87+
```

0 commit comments

Comments
 (0)