<bmx-report-designer>
The report designer: the authoring tool for the reports the report viewer shows. It edits the same JSON definition the viewer reads, in the browser, with no server and nothing to install - so an application can let its own users design their reports, and save the result wherever it keeps data.
14 properties · 3 events · 7 methods · 23 parts
Example
Show markup
<bmx-report-designer id="ex-rd" style="--bmx-report-designer-height: 40rem"></bmx-report-designer>
<div class="row" style="margin-block-start: 1rem">
<span class="note" id="ex-rd-out">
<strong>Everything runs in the browser.</strong> Drag a field onto a band, move and resize what is there, and
edit the selection on the right. The toolbox adds charts, crosstabs, barcodes and QR codes, drawn from the
sample rows as you place them. <strong>Preview</strong> runs the report in a report viewer;
<strong>New report</strong> lays out a list, a grouped report, a summary or a form letter for the data's fields.
</span>
</div>
<script type="module">
await customElements.whenDefined('bmx-report-designer');
const designer = document.getElementById('ex-rd');
const out = document.getElementById('ex-rd-out');
// Sample rows: the designer finds the fields in them for its field list,
// and the preview runs the report over them.
const customers = ['Acme Ltd', 'Bolt & Co', 'Cogworks', 'Delta Supplies', 'Evergreen Farms', 'Fulcrum Tools'];
designer.data = Array.from({ length: 120 }, (_, i) => ({
date: `2026-${String(1 + (i % 9)).padStart(2, '0')}-${String(1 + ((i * 7) % 28)).padStart(2, '0')}`,
region: i % 3 ? 'North' : 'South',
customer: customers[i % customers.length],
quantity: 1 + ((i * 13) % 20),
price: 20 + ((i * 37) % 180),
}));
// Start from a template laid out for those fields - or set `designer.report`
// to a definition you saved earlier.
await designer.newReport('grouped', 'Orders by region');
// Every edit, undo and redo arrives here with the whole new definition.
designer.addEventListener('bmxReportChange', event => {
out.textContent = `bmxReportChange: ${event.detail.action}.`;
});
// Save: keep the JSON yourself instead of letting it download.
designer.addEventListener('bmxReportSave', event => {
event.preventDefault();
out.textContent = `bmxReportSave: ${event.detail.json.length} characters of JSON ready to store.`;
});
</script>
<bmx-report-designer data-url="/api/orders"></bmx-report-designer>
designer.report = savedDefinition; // or leave it empty: the gallery opens
designer.data = sampleRows; // fields for the field list and the preview
designer.addEventListener('bmxReportSave', event => {
event.preventDefault();
api.save(event.detail.json);
});
WHAT THE AUTHOR GETS
The report's bands down the page, drawn to scale with their items. Items are
dragged in from the toolbox and the field list - a field dropped in a header
becomes its caption, in the detail band its value, in a footer its total -
then moved, resized, lined up and spaced, snapping to the grid and to each
other's edges and centres. Bands are made taller or shorter by their lower
edge. The properties panel edits whatever is selected: an item's content,
format and style, a band and its group, or the report's page, parameters,
calculated fields, filter, sort and named styles. Every expression field
completes fields, parameters, variables and functions as it is typed, and
checks itself; the expression builder lists everything with its help and
shows the result on the first row of the data. Excel's functions that work
on values are there as well, by their Excel names (NETWORKDAYS(start, end), PROPER(name), PMT(rate, n, amount)), with _ for a dot
(WORKDAY_INTL). Undo and redo cover every
edit. Preview runs the report in a bmx-report-viewer; JSON shows the
definition and takes one pasted in.
KEYBOARD AND SCREEN READERS
Everything the mouse does has a keyboard route. The outline lists every band and item as buttons; the properties panel sets positions and sizes as numbers. On the design surface, Tab and Shift+Tab step through the items, the arrow keys move the selection a point (Shift: a grid step), Alt with the arrows resizes it, Delete removes it, Ctrl+C, X, V and D copy, cut, paste and duplicate, Ctrl+A selects the band's items, and Escape clears the selection - after which Tab leaves the surface. Each change is announced.
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
data |
data |
readonly Record<string, unknown>[] | string |
[] |
Sample rows: an array of objects, or JSON text. They give the field list and the preview its data. |
dataUrl |
data-url |
string |
— | A URL to fetch the sample rows from, as a JSON array. Takes the place of data. |
fields |
fields |
readonly BmxReportFieldSpec[] | string |
[] |
The fields to offer, when there is no data to find them in: names, or { name, type } with type number, text, date or boolean. JSON text works too. |
fileName |
file-name |
string |
— | The name the JSON is saved under. Defaults to the report's title. |
gallery |
gallery |
boolean |
true |
Offers the template gallery, and opens it when there is no report. |
gridSize |
grid-size |
number |
4 |
The grid spacing in points. Items snap to it. |
label |
label |
string |
— | The designer's accessible name. |
locale |
locale |
string |
— | The locale for sample values and the preview. Defaults to the report's language. |
mode |
mode |
'design' | 'preview' | 'json' |
'design' |
design, preview (the report run in a viewer) or json (the definition as text). |
report |
report |
BmxReport | string | null |
null |
The report being designed: an object, or JSON text. The designer writes each edit back to it. |
requestInit |
property only | RequestInit |
— | Options for the fetch - headers, credentials. Script only. |
showGrid |
show-grid |
boolean |
true |
Draws the grid on the bands. |
snap |
snap |
boolean |
true |
Items snap to the grid and to each other while they are dragged. Hold Alt to place freely. |
zoom |
zoom |
number | string |
'page-width' |
The design surface's scale: page-width fits the page to the surface; 1 is actual size, 1.5 is 150%. |
Events
| Event | Detail | Description |
|---|---|---|
bmxReportChange |
BmxReportChangeDetail |
Every change to the report: an edit, undo or redo, a template, or JSON applied. |
bmxReportSave |
BmxReportSaveDetail |
Save was pressed. Cancel it to store the report yourself; otherwise the JSON downloads. |
bmxSelectionChange |
BmxReportSelectionDetail |
The selection changed. |
Methods
| Method | Signature | Description |
|---|---|---|
downloadJson |
downloadJson(fileName?: string) => Promise<void> |
Saves the report as a JSON file. |
getJson |
getJson() => Promise<string> |
The report as JSON text. |
getReport |
getReport() => Promise<BmxReport> |
The report as it is now. |
newReport |
newReport(template?: string, title?: string) => Promise<BmxReport> |
Replaces the report with one built from a template in the gallery: blank, list, grouped, summary, letter. |
redo |
redo() => Promise<boolean> |
Redoes the last edit undone. |
select |
select(ids: readonly string[]) => Promise<void> |
Selects items by id. |
undo |
undo() => Promise<boolean> |
Undoes the last edit. Resolves to whether there was one. |
Slots
| Slot | Description |
|---|---|
toolbar-end |
extra controls at the end of the toolbar. |
CSS shadow parts
| Part | Description |
|---|---|
builder |
|
button |
|
card |
|
completions |
|
data-field |
|
empty |
|
field |
|
field-error |
|
gallery |
|
insert-panel |
|
json |
|
main |
|
mode |
|
preview |
|
problems |
|
properties-panel |
|
properties-title |
|
status-bar |
|
surface |
|
template |
|
tool |
|
toolbar |
|
zoom |
CSS custom properties
| Property | Description |
|---|---|
--bmx-report-designer-desk |
The area around the page. |
--bmx-report-designer-guide |
The lines drawn while an item snaps. @part toolbar - the row of controls. @part mode - the Design, Preview and JSON buttons. @part button - a button. @part zoom - the zoom list. @part main - the panels and the design surface. @part insert-panel - the toolbox, field list and outline. @part tool - a toolbox entry. @part data-field - a field in the field list. @part surface - the scrolling design surface. @part empty - what the surface shows when the report has no bands. @part properties-panel - the properties of the selection. @part properties-title - its heading. @part field - a labelled property. @part field-error - an expression's error under its field. @part completions - the suggestion list under an expression field. @part card - a group, sort key, field, parameter or condition in the properties. @part status-bar - the problems count, selection and zoom at the foot. @part problems - the list of problems. @part preview - the report viewer in Preview. @part json - the JSON view. @part builder - the expression builder dialog. @part gallery - the template gallery dialog. @part template - a template in it. |
--bmx-report-designer-height |
How tall the designer is. |
--bmx-report-designer-insert-width |
How wide the insert panel is. |
--bmx-report-designer-properties-width |
How wide the properties panel is. |
--bmx-report-designer-selection |
The outline and handles of the selection. |