@lightdash/cli 2.255.3 → 2.256.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.
@@ -36,7 +36,15 @@ The scaffold ships a `viz-fixture.json` at the folder root. To use it:
36
36
 
37
37
  1. `lightdash apps preview` (or `npm run dev`) to start the dev server.
38
38
  2. Open the dev URL with the param, e.g. `http://localhost:5173/?vizFixture=/viz-fixture.json`. The chart renders from the fixture.
39
- 3. Edit `viz-fixture.json` to match your declared `vizSchema` — `fieldMapping` (declared field name → any string id), `rows` (each cell is `{ "value": { "raw": ..., "formatted": "..." } }`, keyed by those ids), `options` (declared option name → value), `colorPalette`, and `pivotDetails` (`null` unless you map a `series` field). Reload to see changes.
39
+ 3. Edit `viz-fixture.json` to match your declared `vizSchema` — `fieldMapping` (input name → string id, or an ordered array of ids for multiple-field inputs), `rows` (each cell is `{ "value": { "raw": ..., "formatted": "..." } }`, keyed by those ids), `options` (declared option name → value), `colorPalette`, and `pivotDetails` (`null` unless you map a `series` field). Reload to see changes.
40
+
41
+ For multiple-field inputs, set `multiple: true` on the `vizSchema.fields` entry and iterate
42
+ the array at `useVizContext().fieldMapping[name]` in its existing order, narrowing with
43
+ `Array.isArray` first. Single-field
44
+ inputs continue to read a string from `fieldMapping[name]`. Test three
45
+ metrics and multiple dimensions, remove and re-add one, then save and reopen the chart
46
+ in the explorer. Verify fields follow the order they were added, with re-added fields at the end. Keep the input names stable across upgrades. Single-field inputs
47
+ retain string bindings; details and examples live in the reusable-visualization skill.
40
48
 
41
49
  This is for **layout and option iteration only**, and never fires in production (an embedded viz has a real host whose context always wins, and the param must be explicitly present). The fixture is fake data you hand-maintain: colors fall back to the palette (no model or shared-dashboard colors), `pivotDetails` must be shaped by hand, and formatting is whatever you type. **The explorer with real data remains the source of truth for correctness** — still run the upload → verify loop above before finishing, and verify every declared option actually changes the chart there.
42
50
 
@@ -40,9 +40,10 @@ const {
40
40
  } = context;
41
41
  ```
42
42
 
43
- - `fieldMapping` — `Record<string, string>`: the field name you declared → the query field
44
- id it is bound to. Read cells with `getFormatted(row, fieldId)` (display text) and
45
- `getRaw(row, fieldId)` (raw value).
43
+ - `fieldMapping` — `Record<string, string | string[]>`: each single-field input maps
44
+ to one query field id; inputs declared with `multiple: true` map to ordered arrays.
45
+ Narrow with `Array.isArray(binding)` before iterating. Read each id with
46
+ `getFormatted(row, fieldId)` (display text) and `getRaw(row, fieldId)` (raw value).
46
47
  - `rows` — the host-fetched result rows, keyed by query field id.
47
48
  - `options` — `Record<string, boolean | number | string>`: the current value of each config
48
49
  option you declared (the viewer's choice, else your declared `default`).
@@ -208,6 +209,11 @@ underlyingData.open({ row: datum.sourceRow, metric: 'value' }).catch(() => {});
208
209
  action menu. It never renders an underlying-data dialog, table, loading state, error
209
210
  state, or download control inside the iframe.
210
211
 
212
+ For a multiple-metric input, also pass `fieldId`, the member of that input's binding
213
+ whose mark was clicked: `underlyingData.open({ row: datum.sourceRow, metric: 'values',
214
+ fieldId })`. Use the same `fieldId` with `drillDown.open`. A mark combining several
215
+ metrics cannot identify one underlying metric and gets no data-point action.
216
+
211
217
  ### Drill into a data point
212
218
 
213
219
  When `drillDown.enabled` is true, the same data-point action menu also offers
@@ -256,13 +262,12 @@ file**. It has four parts: `fields`, `configOptions`, `colorPalette` and optiona
256
262
  the field-mapping UI and the chart config panel from it, so the component is unusable
257
263
  without it.
258
264
 
259
- The correspondence is exact in both directions: **every key read from `fieldMapping` or
260
- `options` is declared, and everything declared is read.** A declared option nothing reads is
261
- a dead control the viewer can move with no effect.
265
+ The correspondence is exact in both directions: **every key read from `fieldMapping` or `options` is declared, and everything declared is read.** A declared
266
+ option nothing reads is a dead control the viewer can move with no effect.
262
267
 
263
268
  ### `fields`
264
269
 
265
- One entry per data column the component reads:
270
+ One entry per input the component reads:
266
271
 
267
272
  - `name` — the key read from `fieldMapping`. Unique, no spaces.
268
273
  - `label` — human label shown in the mapping UI.
@@ -270,6 +275,11 @@ One entry per data column the component reads:
270
275
  `series` (a dimension used to split or colour the chart), or `column` (any result
271
276
  column, whether metric or dimension).
272
277
  - `required` — `false` only when the chart still renders with this field unmapped.
278
+ - `multiple` — optional boolean, default `false`. Set `true` when this input accepts an
279
+ ordered selection of fields of its declared type. Its `fieldMapping` value is a
280
+ `string[]`, including when only one field is selected. A required input needs at least
281
+ one selection; an empty array means the viewer cleared it. Render a placeholder until
282
+ required selections exist.
273
283
  - `description` — optional reusable mapping help, maximum 160 characters. Use one
274
284
  or two short, plain sentences explaining the field's role in the chart. Keep it agnostic
275
285
  to any business, explore, or query; do not imply fixed categories or values.
@@ -277,6 +287,39 @@ One entry per data column the component reads:
277
287
  Do not generate field examples. Viewers supply their own values; describe the field's
278
288
  role and data shape without prescribing categories from a particular business.
279
289
 
290
+ ### Ordered multiple-field inputs
291
+
292
+ Use one multiple input for a variable number of measures or grouping columns instead of
293
+ declaring a fixed number of numbered slots:
294
+
295
+ ```json
296
+ {
297
+ "fields": [
298
+ { "name": "groups", "label": "Grouping fields", "type": "dimension", "required": true, "multiple": true },
299
+ { "name": "values", "label": "Measures", "type": "metric", "required": true, "multiple": true }
300
+ ],
301
+ "configOptions": [],
302
+ "colorPalette": null
303
+ }
304
+ ```
305
+
306
+ ```tsx
307
+ const { fieldMapping, rows } = useVizContext();
308
+ const groups = Array.isArray(fieldMapping.groups) ? fieldMapping.groups : [];
309
+ const values = Array.isArray(fieldMapping.values) ? fieldMapping.values : [];
310
+ const data = rows.map((row) => ({
311
+ label: groups.map((id) => getFormatted(row, id)).join(' / '),
312
+ values: values.map((id) => ({ id, value: getRaw(row, id) })),
313
+ }));
314
+ ```
315
+
316
+ Array order is the viewer's display order: preserve it when building axes, columns,
317
+ legends and series. For pivoted metrics, iterate the selected ids first and then match
318
+ `pivotDetails.valuesColumns` by `referenceField`. The flag also works for `series` and
319
+ `column` inputs. Existing single inputs continue receiving strings in `fieldMapping`;
320
+ leave their declarations unchanged when adding a separate multiple input. Keep field
321
+ names stable across compatible upgrades so saved selections can be reconciled.
322
+
280
323
  ### `inputGuidance`
281
324
 
282
325
  Optional reusable help shown above the mappings, maximum 200 characters. Use at most two
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/cli",
3
- "version": "2.255.3",
3
+ "version": "2.256.0",
4
4
  "description": "Lightdash CLI tool",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,8 +22,8 @@
22
22
  "@actions/core": "1.11.1",
23
23
  "@aws-sdk/credential-providers": "3.995.0",
24
24
  "@casl/ability": "6.8.0",
25
- "@lightdash/common": "2.255.3",
26
- "@lightdash/warehouses": "2.255.3",
25
+ "@lightdash/common": "2.256.0",
26
+ "@lightdash/warehouses": "2.256.0",
27
27
  "@sidvind/better-ajv-errors": "7.0.0",
28
28
  "@types/columnify": "1.5.1",
29
29
  "ajv": "8.18.0",