Property Report Widget

3432
22
12-10-2025 03:48 PM
Brian_McLeer
MVP Regular Contributor
8 22 3,432

Property Report Widget for ArcGIS Experience Builder

Overview

https://github.com/brianmcleer/property-report-widget 

This custom widget provides comprehensive property lookup and reporting capabilities for ArcGIS Experience Builder applications. The widget was built on ArcGIS Experience Builder Developer Edition 1.19. The widget supports multiple search methods, configurable data sections with tables and charts, related table queries, nearby feature analysis, and PDF export functionality with WCAG 2.1 AA accessibility compliance.

The reporting tool on PortlandMaps.com served as a major reference for the design and functionality of this widget. While PortlandMaps.com is not an Experience Builder application, its approach to property information display, section organization, and user interaction patterns informed many of the design decisions implemented here.

This widget enables users to search for properties by address, parcel number, or other attributes, then view detailed information from multiple data sources in a unified report format. Results can be exported to PDF for offline use or distribution.

(view in My Videos)

Optional Required Dependencies - updated on 6/3/2026 to not require installing dependencies 

Before implementing this widget, install the following npm packages:

npm install recharts @tanstack/react-table

npm install @mantine/dates dayjs

npm install @mantine/charts

npm install @mantine/notifications

npm install html2canvas

npm install jspdf

These dependencies provide chart visualization (recharts), table functionality with sorting, filtering, and pagination (@tanstack/react-table), date handling (@mantine/dates, dayjs), additional chart utilities (@mantine/charts), toast notifications (@mantine/notifications), HTML-to-canvas conversion for PDF chart rendering (html2canvas), and PDF generation (jspdf).

Developer Configuration (setting.tsx)

The setting.tsx file provides developers with a comprehensive configuration interface within Experience Builder. The configuration is organized into multiple collapsible sections that control widget behavior and appearance.

Map Connection

Developers select which map widget the property report widget will interact with using the MapWidgetSelector component. This establishes the connection to the map view where property locations will be displayed and highlighted.

Search Sources Configuration

The widget supports three search source types that can be combined for flexible property lookup.

Geocoder Sources connect to ArcGIS geocoding services for address-based searches. Developers configure the geocoder service URL, source name for display in suggestions, suggestion count limit, and outfields for returned attributes.

Layer Sources query feature layers directly for attribute-based searches. Configuration includes data source selection from map layers or direct URL, search and display field selection, suggestion count limit, where clause filtering, and source name customization.

URL Parameter Sources accept search values from URL query parameters for direct linking to specific properties. Developers specify the parameter name, layer URL, search field, and outfields.

Global search settings include combined maximum suggestions across all sources, source label visibility in dropdowns, and priority ordering via drag-and-drop.

Header Info Configuration

An optional header section displays key property information at the top of results. Developers configure a data source with search field and display fields, where each field supports custom aliases, visibility controls, PDF exclusion, and formatting options. An optional geocoder URL enables reverse geocoding to display addresses in the header title regardless of search method used.

Property Preview Configuration

An optional property preview section displays a static map image centered on the property location. Developers configure image dimensions, basemap selection, and zoom level. Action buttons include zoom to property, copy address, and custom buttons with configurable URLs that support field value tokens like {parcelid}. An optional logo can be displayed with configurable dimensions and position.

Sections Configuration

Sections organize query results from different data sources, with each section containing one or more layers and displaying data as tables, charts, or both.

Section-level settings include section title, PDF exclusion toggle, display options for table and chart visibility, default expanded or collapsed state, and display pane selection for inline or separate pane rendering with configurable threshold.

Rich text configuration allows HTML content with links, phone numbers, and email addresses. Rich text can appear before or after data, include action buttons with customizable labels and URLs, and be excluded from PDF exports.

Chart configuration includes chart type selection (bar, pie, donut, line, area, column), category field for grouping, value field with aggregation method (count, sum, average, min, max), color palette customization, legend options, and PDF exclusion.

Table configuration includes sticky headers, row striping, compact mode, maximum rows, pagination settings, and column resizing and sorting options.

Layer Configuration

Each layer within a section has extensive configuration options.

Data source settings include layer selection from map or direct URL, custom layer title, and query configuration with spatial relationship and where clause options.

Buffer configuration enables buffer queries with configurable distance and units (feet, meters, miles, kilometers) and optional buffer display on the map.

Field configuration includes field selection and ordering, custom aliases, visibility toggles, PDF exclusion per field, and formatting options for numbers (decimal places, thousands separator) and dates.

Row interaction settings configure click behavior (none, zoom, highlight, popup, or combinations), hover highlighting, and zoom scale.

Related tables configuration enables queries against relationship classes. Developers configure the relationship ID, table name, display mode (inline collapsed, inline expanded, or separate pane), field configuration, chart display, sort options, maximum records, and PDF exclusion.

Nearby features configuration enables distance-based feature analysis. Settings include search distance and units, title and subtitle fields, distance format, sort order (nearest or farthest first), maximum features, zoom-on-click behavior, and PDF exclusion.

Highlight Layer Configuration

Highlight layer settings control how selected features appear on the map. Developers configure point symbols (color, size, outline), line symbols (color, width, style), and polygon symbols (fill color, outline). Behavior settings include enable/disable toggle and auto-clear timeout.

PDF Export Configuration

PDF export settings are organized into multiple subsections for comprehensive customization.

Header configuration includes enable/disable toggle, title and subtitle text with field token support, logo image with dimensions and position, and background and text colors.

Footer configuration includes enable/disable toggle, left/center/right text areas, page numbering format, date/time display, colors, and disclaimer text.

Style configuration includes page size (Letter, Legal, A4, Tabloid), orientation, margins, section and table header colors, alternating row colors, font settings, large text mode for accessibility, and section numbering.

Table of contents settings include enable/disable toggle, title customization, layer inclusion, and page break options.

Content options toggle inclusion of tables, charts, related tables, and related table charts, with configurable chart dimensions and maximum table rows.

Accessibility settings include document language, title metadata, and alt text templates for map images, logos, and charts, plus table summary templates.

Default Configurations

Global defaults for chart configuration (type, colors, animation, legend) and table configuration (styling, pagination) apply across all sections unless overridden at the section or layer level.

Coordinate Display Settings

Developers configure coordinate system (map native, WGS84, or Web Mercator), format (decimal degrees or degrees-minutes-seconds), decimal precision, and visibility toggle.

Import/Export Configuration

Settings can be exported to XML format for backup or transfer between Experience Builder applications. Import functionality allows loading previously exported configurations, enabling easy replication of widget setup across multiple applications.

End User Functionality (widget.tsx)

The widget.tsx file implements the runtime functionality that end users interact with in published Experience Builder applications.

Search Interface

Users search for properties through a unified search interface with multiple input methods.

Text search displays type-ahead suggestions as users type, grouped by source with optional labels. Keyboard navigation supports arrow keys to browse suggestions and Enter to select. A clear button resets the search field.

Map selection activates when clicking the map location icon. Users click any map location to search at that point, with visual feedback indicating selection mode is active.

URL parameters allow applications to pre-populate searches via query strings, enabling direct linking to specific properties with automatic search execution on page load.

Search Validation

The widget validates search input before executing queries. Invalid or unrecognized text displays an "Address not found" message. Changed search text forces new geocoding rather than reusing cached results, with case-insensitive comparison to prevent duplicate queries.

Results Display

Search results appear in an organized, hierarchical format.

Header section displays the property address as main title with configurable fields from the header info layer, coordinate display, clear results button, and export to PDF button with loading state.

Property preview (when enabled) shows a static map image with location marker, zoom and copy address buttons, and custom action buttons linking to external resources.

Data sections are collapsible with headers showing title and feature count badge. Users click headers or use keyboard (Enter/Space) to expand or collapse sections.

Table Display

Data tables support column sorting by clicking headers, column resizing by dragging borders, per-column text filtering, sticky headers, alternating row colors, and pagination with configurable page sizes. Row interactions include click actions (zoom, highlight, popup) and hover highlighting on the map.

Chart Display

Charts visualize aggregated data with support for bar, column, pie, donut, line, and area types. Features include interactive legends, hover tooltips, responsive sizing, and smooth animations. Screen reader accessible data tables provide alternative access to chart data.

Related Tables

Related records display within their parent layer in three modes: inline collapsed (accordion-style), inline expanded (always visible), or separate pane (slide-out panel). Each mode shows record counts and supports field formatting, optional charts, and sorting.

Nearby Features

Proximity-based display shows features near the searched location sorted by distance. Each item displays title, subtitle, and formatted distance, with optional click-to-zoom functionality.

Separate Pane View

A dedicated slide-out panel provides expanded viewing for sections configured for separate display, related tables with many records, or when record thresholds are exceeded. The pane includes full table display with pagination, sorting, filtering, zoom controls, and keyboard-accessible close functionality.

PDF Export

Users export results by clicking the Export to PDF button, which shows loading state during client-side generation. The resulting PDF includes header with logo and title, property summary, data tables, charts as images, related data, table of contents (when enabled), page numbers, and footer. Accessibility features include tagged structure, document language, alt text, and marked table headers.

Coordinate Display

Coordinates display in the results header in decimal degrees or degrees-minutes-seconds format, with support for map native, WGS84, or Web Mercator coordinate systems and configurable precision.

Map Integration

The widget highlights query results on the connected map using configured symbols for points, lines, and polygons. Features include zoom to searched location, zoom to individual features, buffer display, and automatic highlight cleanup with configurable timeout.

Error Handling

The widget displays clear error messages for search failures, query errors, and export issues. Error banners are dismissible and announced to screen readers via ARIA live regions.

Keyboard and Screen Reader Support

Full keyboard navigation supports tab movement, Enter/Space activation, arrow key navigation in dropdowns and tables, and Escape to close menus and panes. Screen reader support includes ARIA labels, role attributes, live regions for dynamic updates, and proper heading hierarchy.

Accessibility Compliance (WCAG 2.1 AA)

The widget implements comprehensive accessibility features meeting WCAG 2.1 Level AA requirements. All interactive elements support full keyboard navigation with visible focus indicators. Screen reader users benefit from proper ARIA labels, roles, and live regions that announce dynamic content changes. Text meets minimum contrast ratios, and font sizes use relative units (rem) to support browser zoom and user font preferences. Charts include screen reader accessible data tables as alternatives. The widget respects the prefers-reduced-motion setting for users sensitive to animation. PDF exports include tagged structure, document language declaration, and alt text for images to maintain accessibility in exported documents.

Feedback

Please use the comments section of this blog post to provide feedback on bugs, ideas, questions, or enhancement requests.

Changelog:

6/03/26: Added package.json and package-lock.json to the widget. You no longer need to run the manual npm install commands listed at the top of this post. Since the widget lives in your-extensions, Experience Builder installs its dependencies automatically when you run npm install in your client folder, so it is just the standard setup you are already doing. Thanks to @SunshineLuke90  for the suggestion and for walking through the packaging approach.

3/27/26: Resolved issue for 1.20. Version 1.19 and 1.20 available for download. Please report any issues on this blog post. 

3/25/26: DE 1.20 broke something in this widget, need to troubleshoot

2/23/26: Allow manual sorting of fields in sections if needed in settings. 

2/17/26: No update to code on this log, but Right Click widget has been updated to launch this widget. 

(view in My Videos)

2/9/26: Added an option to interact with search widget and other widgets for actions (see video below). Fixed UI bug where word "Nearby" would overrun in some PDF reports. 

(view in My Videos)

 

 

 

22 Comments
KeyHunter
Occasional Contributor

Great stuff and thank you! We are currently updating our external and internal apps with this tool. I sent a private email, but maybe this will be helpful to someone.

We were updating a Basic property Info card to a one-pager, and a more advanced one for planning and flood plain work. There was a bit  of initial orientation to all the configurations there are to choose from (love it!)  but I lost site of the trees because of the forest.

In adding and removing, and then returning to learn that I could format currency and other such nuances one discovers when acclimating to a new widget, I could not figure out how to manage the order of my fields on the report. I could not figure our how they had gotten in the order they were. They were not linear and I thought at one point they were moving. 

** THE DISCOVERY was that they were located in the order I was editing. So if I wanted PIN first, then Owner, then Full Address. I needed to get PIN exactly how I wanted it then move to Owner and set it to text, and proper address, and prefix before moving on to Full Address. If I saved and published and went back and added new fields because there was more space, they were not in the order of FC structure but in order of being saved. 

Long winded Thank you ! with a side note of how to manage the order they are displayed on your report. 

Brian_McLeer
MVP Regular Contributor

Hi @KeyHunter ,

Thank you for feedback. I replied to the PM, and can update this post once we correspond there. At this point, changing field orders in the settings should not be possible within the settings. I have my field order configured at the published service level from Pro to Enterprise. 

Brian_McLeer
MVP Regular Contributor

After very helpful feedback from @PiotrCienin and @KeyHunter through direct messages, V1 of the widget is finished and ZIP is current as of 1/22/26. Please report any BUGS or enhancement requests on this page. 

Brian_McLeer
MVP Regular Contributor

2/9/26: Added an option to interact with search widget and other widgets for actions (see video below). Fixed UI bug where word "Nearby" would overrun in some PDF reports. 

(view in My Videos)

Brian_McLeer
MVP Regular Contributor

2/17/26: No update to code on this log, but Right Click widget has been updated to launch this widget. 

(view in My Videos)

Brian_McLeer
MVP Regular Contributor

2/23/26: Allow manual sorting of fields in sections if needed in settings. 

KeyHunter
Occasional Contributor

Hey I was doing a fresh install for EB 1.19 and am getting an error relating to recharts

ERROR in ./node_modules/recharts/es6util/ReactUtil.js 3:0-38
 
The thread I am pulling on is leading me to ReactUtil.js was removed as a deeper internal rewrite. I have a backup, but am turning to a rollback install to see what behaviour is there and how I mucked it up
SunshineLuke90
Occasional Contributor

Hey Brian,

This widget is fantastic! I do have a recommendation for using external dependencies though. When you're using external dependencies within your widget, right now every user has to keep up with all of the dependencies you're adding, and might installing the wrong version, or a dependency could get updated and then become incompatible. To prevent this, if you could run 

npm init

while within your widget directory, an interactive tool will come up, walking you through setting up your widget as an NPM package. The process is fairly straightforward, and your manifest.json has most of the information already. This will create a package.json file in your widget, which is used for a lot of things, one of them being managing dependencies. Once you have the package.json file, re-install all of your dependencies, using 

npm install <dependencyname>

 You'll end up with a package.json file that will look something like this:

{
  "name": "exb-property-report",
  "version": "1.0.0",
  "description": "A comprehensive property report widget.",
  "keywords": [
    "exb-widget"
  ],
  "license": "Apache-2.0",
  "author": "Brian McLeer",
  "dependencies": {
    "@mantine/charts": "^8.3.16",
    "@mantine/dates": "^8.3.16",
    "@mantine/notifications": "^8.3.16",
    "@tanstack/react-table": "^8.21.3",
    "dayjs": "^1.11.19",
    "html2canvas": "^1.4.1",
    "jspdf": "^4.2.0",
    "recharts": "^3.7.0"
  }
}

As you can see, the dependencies all get stored in the package.json file, with the version numbers you installed them with. If you distribute your widget with these dependencies (But without the node_modules folder), all someone needs to do to get your widget up and running is download it, place it in their custom widgets folder, and run npm ci in their client directory, and the command will install the dependencies directly within the widget's folder. 

I highly recommend doing this, as it will make it easier for others to use your widgets, and it will also make it more clear what dependencies are being used, at what version.

Brian_McLeer
MVP Regular Contributor

Thank you for the idea @SunshineLuke90, I think as I release future widget updates I will try to include this.  

@KeyHunter your issue may be related to this. 

JesseJoe
Occasional Contributor

Thank you Brian - What you have here is impressive and something I am looking to make available. I agree, PortlandMaps provides a comprehensive offering of what's possible, excellent web map.

Brian_McLeer
MVP Regular Contributor

Thank you @JesseJoe! If you end up using it in any public-facing apps please send them my way! 

JesseJoe
Occasional Contributor

Hi @Brian - I am looking to replicate this report for my local government.

Question - Do you have any plans to incorporate a map window section to this Property Report Widget? This way, you can show underground utility tabular data along with a map showing where they are, relative to the property selected.

Sidney - SCR.png

 

 

Brian_McLeer
MVP Regular Contributor

Hi @JesseJoe no plans at the moment, but if you could provide more detail about what you would expect the inputs and outputs to be I could look at it. 

JesseJoe
Occasional Contributor

Hi Brian, thanks for the prompt response and glad to hear from you. It's nice to brainstorm with GIS colleagues. 

Inputs are underground infrastructure assets - sewer, storm, water with asset types being mains, lateral mains and lateral dimensions.

This tabular data comes by relating to the property layer via GISLINK#

I look forward to seeing what you can create.

Jesse

Brian_McLeer
MVP Regular Contributor

3/25/26: DE 1.20 broke something in this widget, need to troubleshoot

Brian_McLeer
MVP Regular Contributor

3/27/26: Resolved issue for 1.20. Version 1.19 and 1.20 available for download. Please report any issues on this blog post. 

KeyHunter
Occasional Contributor

Hey @Brian_McLeer 

Thanks for this report, it works great, and we just released a 2.0 site for our internal and external apps with the report in a sidebar panel straight from the initial search tool. Now that everything is stable, sized and in effect migrated from web app builder to Experience Builder for our sites, I am going back to do an npm audit fix and testing before downloading and testing 1.20.

I did a copy of my EB 1.19 folder to an EB 1.19 v2 folder and ran an audit fix and came back with one error in recharts/es6/util/Rcharts.js 3:0-38 

The dependency packages is still something I am trying to get my head around. I am not sure I follow @SunshineLuke90 instructions. Is he suggesting you run npm inuit in your build? Or users run it when they download your tool.

Basic question is:

How does an EB hack relying on the wonderful tools of developers like yourself keep up with the dependencies? 

Or if I redownload the new EB 1.19 report widget from 3/27 and reinstall it will it resolve the error. 

 

Brian_McLeer
MVP Regular Contributor

Thank you @KeyHunter, I think your question still needs research and further discussion. From our private messages earlier this week I'm glad you were able to get the dependencies resolved. 

SunshineLuke90
Occasional Contributor

@KeyHunter, I think what I was intending would be that the widget that is provided would include a package.json and package-lock.json file with the widget, to reduce the issues with manually installing npm modules within the widget. My instructions above would be completed by Brian, prior to sharing the widget code. Then, when the widget is being downloaded and used, the user would only need to run npm ci, and Experience Builder will automatically install the dependencies that the widget requires, hopefully with less dependency clashing.

I would love to attach a version of Brian's widget with the package.json file included, but it looks like esri community doesn't support it. Instead I'll leave a google drive link to a zip file (1.20 version), which is just an example of how the widget could be packaged, and you would only need to place it in your widgets folder, and then run npm ci in the client directory. You won't have to run any of the npm install commands that Brian mentioned at the top of the blog post. However, I want it to be clear that this is Brian's widget, and I have not actually used this widget in any of my own applications, so I can't verify that this works perfectly within this widget specifically.

KeyHunter
Occasional Contributor

@Brian_McLeer  &  @SunshineLuke90 

I should start at the beginning of my 1.20 install and testing.

  1.  Installed 1.20 with the updated tools where applicable
  2. Tested the right-click tool with Property Report and Mailing List, and tested with tools within the accordion tool. Positive result, and opened correctly
  3. Begin testing other 1.20 and found a problem with Basemap Custom; after some troubleshooting, found that Basemap Custom was installed incorrectly in 1.19 but worked.  
    1. Path in 1.19 - \Experience Builder v1 1.19\client\your-extensions\widgets\basemap-gallery-custom\basemap-gallery-custom
    2. Duplicated  nested folder for 1.20 and was tested
  4. Began a new install for 1.20 using  @SunshineLuke90  google drive link above and the What's New Calcite tool
    1. Initial run produced errors in the manifest.json for different names
    2. Did not run the installs and provided errors on the installs
  5. Updated the manifest.json, and the  @SunshineLuke90 Google Drive property report successfully installed nodes, but did not seem to have the right-click elements
  6. Re-Installed 1.20 Property Report, right-click with accordion widget accommodations from email thread. Launched 1.20 again; green light for all widgets. 
  7. When configuring right-click, Property Report and Mailing lists are options.
    1. When scanning the widgets get a Your config is at: server/public/apps/config.json - Search for "property report" to find the widget ID. 

 

Not sure if I got spun around using these embedded "trying" apps from email threads and blog threads, but may have to go back to only what is on the inventory list.

Thanks for your help.

UPATE @Brian_McLeer  @SunshineLuke90 

I downloaded your @Brian_McLeer 6/1/2028 update, and it loads with dependencies. Nice!

Did a npm fund and npm audit fix on start of process

I installed the draw-advanced dependencies manually and fyi there is a "Unkown env config 'save@mapbox/shp-write'. This will stop working in the next major version of npm". On start, I get a "node_modules doesn't exist" error message; the tool does give me "green joy" in the Entrypoint list. 

Started localhost:3001 - I imported an app built in 1.19, and currently the draw-advance tool does not load; I presume due to the mapbox node module. The right-click tool is returning an error message when I hit the scan button of:

Cannot load app config. Please enter the widget id manually

Your config is at: server/public/apps config.json

Search for property report to find the widget id

Second Install Test

Did not run npm fund or npm audit fix, and the draw-advanced tool works on the second install test.

Scan for widget returns the same message as above in the right-click widget. 

Update and Big Dope Moment 

The newly uploaded 1.19 app with the 1.20 right-click widget is returning the error message because it is not published. Now that it is published, the widget id's can be searched in the config.json. 

Duh

Full 1.20 successful install if no fund or audit fix is run.

A  probably could have been funded but not fix as the second test 

 

Brian_McLeer
MVP Regular Contributor

Thanks @SunshineLuke90 . I went ahead and added a package.json and package-lock.json to the widget following your approach, so the dependencies now install automatically when you run the standard npm install in the client folder. No more manual npm install commands needed. I also included the exb-widget keyword and an Apache 2.0 license to line up with the conventions you laid out in your Standardizing Custom Widget Sharing thread. Really appreciate you walking through this, it makes the widget a lot easier for others to pick up and use, and I think the standardization effort is a great direction for the community. 

I am going to go through all of my widgets and standardize more using this approach. 

SunshineLuke90
Occasional Contributor

@Brian_McLeer No problem at all! I'm happy to assist, and the standardization methods that I laid out in that post were just my first attempt at standards, if there's anything that doesn't make sense, or should be changed, I'd be happy to make amendments. Your widgets were an inspiration for me to build and share my own creations, so I really appreciate you being open to the standardization ideas that I came up with.

One last note on the custom widget sharing, if it interests you, you might also consider publishing your widget as a package on the NPM exchange, in addition to posting the zipped files as attachments here. The NPM exchange will handle versioning (So users can still grab old releases), and will ensure that the files live forever. If you add the exb-widget tag, and publish to NPM, the Command Line Interface I developed will be able to search and install it directly into your Experience Builder install. There's some concerns about using NPM for sharing widgets, particularly about how it can be clunky to use if you're not using the Command Line Interface, but there's also some benefits. Might be worth checking out, and you'd be the first user (Outside of myself) to also publish widgets on NPM. 

Contributors
About the Author
GIS Administrator/Developer at City of Grand Junction, CO.