{"id":2953252,"date":"2026-03-05T08:30:09","date_gmt":"2026-03-05T16:30:09","guid":{"rendered":"https:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=2953252"},"modified":"2026-03-05T11:46:05","modified_gmt":"2026-03-05T19:46:05","slug":"building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components","status":"publish","type":"blog","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components","title":{"rendered":"Building Accessible Custom Widgets in ArcGIS Experience Builder with Jimu UI, Calcite, and JavaScript Maps SDK Components"},"author":309572,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","format":"standard","meta":{"_acf_changed":false,"_searchwp_excluded":""},"categories":[738191],"tags":[28911,780883,759512],"industry":[],"product":[400032,36831],"class_list":["post-2953252","blog","type-blog","status-publish","format-standard","hentry","category-developers","tag-accessibility","tag-arcgis-experience-builder-jimu-ui","tag-calcite-design-system","product-experience-builder","product-js-api-arcgis"],"acf":{"authors":[{"ID":360712,"user_firstname":"Kevin","user_lastname":"Gonzago","nickname":"Kevin Gonzago","user_nicename":"kgonzago","display_name":"Kevin Gonzago","user_email":"kgonzago@esri.com","user_url":"","user_registered":"2024-08-26 20:33:13","user_description":"Kevin Gonzago is a Principal Product Engineer on the Developer Experience team, where he helps developers succeed with Esri\u2019s products, APIs, and SDKs through tools, guidance, and best practices. In his free time, Kevin loves lacing up his running shoes to explore new neighborhoods\u2014chasing scenic routes and local eateries.","user_avatar":"<img data-del=\"avatar\" src='https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2024\/08\/profile-213x200.png' class='avatar pp-user-avatar avatar-96 photo ' height='96' width='96'\/>"},{"ID":309572,"user_firstname":"Kitty","user_lastname":"Hurley","nickname":"Kitty Hurley","user_nicename":"khurley","display_name":"Kitty Hurley","user_email":"khurley@esri.com","user_url":"https:\/\/www.github.com\/geospatialem","user_registered":"2022-05-04 21:30:59","user_description":"Kitty is a Principal Product Engineer with Calcite Design System, passionate about expanding access to the web and maps for broader audiences. She is dedicated to creating inclusive, user-friendly web experiences that connect people and places through innovative design and technology. Outside of work, Kitty enjoys exploring the wilderness of Minnesota and has a goal to visit every major league baseball stadium across America.","user_avatar":"<img data-del=\"avatar\" src='https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2024\/03\/Esri_Day2_PSCC2024_H_0127-e1710789483673-261x261.jpg' class='avatar pp-user-avatar avatar-96 photo ' height='96' width='96'\/>"}],"short_description":"Create accessible ArcGIS Experience Builder widgets with Jimu UI, Calcite, and JavaScript Maps SDK components.","flexible_content":[{"acf_fc_layout":"image","image":{"ID":2958819,"id":2958819,"title":"","filename":"Card_-826px-x-465px.png","filesize":134757,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components\/card_-826px-x-465px-4","alt":"","author":"309572","description":"","caption":"","name":"card_-826px-x-465px-4","status":"inherit","uploaded_to":2953252,"date":"2026-02-27 15:07:44","modified":"2026-02-27 15:07:49","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":826,"height":465,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px-213x200.png","thumbnail-width":213,"thumbnail-height":200,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px.png","medium-width":464,"medium-height":261,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px.png","medium_large-width":768,"medium_large-height":432,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px.png","large-width":826,"large-height":465,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px.png","1536x1536-width":826,"1536x1536-height":465,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px.png","2048x2048-width":826,"2048x2048-height":465,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px.png","card_image-width":826,"card_image-height":465,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px.png","wide_image-width":826,"wide_image-height":465}},"image_position":"center","orientation":"horizontal","hyperlink":""},{"acf_fc_layout":"content","content":"<p>Custom widgets in <a href=\"https:\/\/www.esri.com\/en-us\/arcgis\/products\/arcgis-experience-builder\/overview\">ArcGIS Experience Builder<\/a> provide flexibility over layout, interaction, and data workflows. The flexibility also comes with responsibility. When you build a widget, you define how users move through it, how they discover information, and how they complete tasks.<\/p>\n<p>Accessibility directly shapes that experience. I<span data-teams=\"true\">ndividuals who rely on keyboard and assistive technologies, or who have low vision, depend on clear structure, predictable focus behavior, and operable controls.<\/span> Experience Builder provides accessibility support at the framework level, but custom widgets require deliberate design decisions to maintain those standards.<\/p>\n<p>Explore practical techniques for building accessible custom widgets using <a href=\"https:\/\/developers.arcgis.com\/experience-builder\/api-reference\/jimu-ui\/\">Jimu UI<\/a>, <a href=\"https:\/\/developers.arcgis.com\/calcite-design-system\/core-concepts\/\">Calcite components<\/a>, and <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/components\/\">ArcGIS Maps SDK for JavaScript components<\/a>, which include practical patterns, developer responsibilities, and implementation techniques ensuring accessibility is built into your widget from the start.<\/p>\n"},{"acf_fc_layout":"content","content":"<h2>Why accessibility matters<\/h2>\n<p data-start=\"1413\" data-end=\"1585\">Accessible widgets support individuals who rely on keyboards, assistive technologies, or alternative input devices. Accessibility also improves the overall usability, consistency, and maintainability of the solutions you build, including:<\/p>\n<ul>\n<li data-start=\"1646\" data-end=\"1684\">Alignment with the <a href=\"https:\/\/www.w3.org\/WAI\/standards-guidelines\/wcag\/\">Web Content Accessibility Guidelines (WCAG)<\/a><\/li>\n<li data-start=\"1646\" data-end=\"1684\">Avoiding fragile, input-specific interactions<\/li>\n<li data-start=\"1732\" data-end=\"1765\">Reducing late-stage rework and costly last-minute fixes<\/li>\n<li data-start=\"1768\" data-end=\"1836\">Building widgets that integrate with Experience Builder layouts<\/li>\n<\/ul>\n<p data-start=\"1838\" data-end=\"2082\">Experience Builder applications often combine multiple widgets on a single page, where accessibility constraints in one widget could affect an entire experience. Accessibility must be integrated throughout widget design and development, not treated as a final review step.<\/p>\n"},{"acf_fc_layout":"content","content":"<h2>Accessibility in custom widgets<\/h2>\n<p data-start=\"2119\" data-end=\"2278\">Custom widgets are built using React and integrate with the Experience Builder framework. Accessibility in custom widgets is supported by three component systems:<\/p>\n<ul>\n<li data-start=\"2282\" data-end=\"2317\"><a href=\"https:\/\/developers.arcgis.com\/documentation\/app-builders\/low-code\/arcgis-experience-builder\/accessibility-for-custom-widgets\/#jimu-ui\">Jimu UI<\/a> as the native React toolkit<\/li>\n<li data-start=\"2320\" data-end=\"2373\"><a href=\"https:\/\/developers.arcgis.com\/documentation\/app-builders\/low-code\/arcgis-experience-builder\/accessibility-for-custom-widgets\/#calcite-components\">Calcite components<\/a> as Esri\u2019s design system comprised of web components with accessibility in mind<\/li>\n<li data-start=\"2376\" data-end=\"2437\"><a href=\"https:\/\/developers.arcgis.com\/documentation\/app-builders\/low-code\/arcgis-experience-builder\/accessibility-for-custom-widgets\/#arcgis-maps-sdk-for-javascript-components\">ArcGIS Maps SDK for JavaScript components<\/a> comprised of web components built with Calcite components supporting map interactions<\/li>\n<\/ul>\n<p data-start=\"2439\" data-end=\"2658\">The Experience Builder framework supports custom development with accessibility features. Developers must continue building <a href=\"https:\/\/developers.arcgis.com\/documentation\/app-builders\/low-code\/arcgis-experience-builder\/accessibility-for-custom-widgets\/#best-practices\">accessibility best practices<\/a> into their widgets to support more individuals, including:<\/p>\n<ul>\n<li>Starting with semantic HTML prior to using ARIA attributes<\/li>\n<li>Ensuring interactive functionality is available for keyboard navigation<\/li>\n<li>Providing visible focus indicators on interactive elements<\/li>\n<li>Managing focus and providing context when content changes dynamically<\/li>\n<\/ul>\n"},{"acf_fc_layout":"content","content":"<h2>Understanding the roles of each system<\/h2>\n<p>When building accessible custom widgets in Experience Builder, accessibility responsibilities are distributed across three systems, where each library solves a different problem. The table below outlines offerings and developer responsibilities.<\/p>\n<table style=\"border-collapse: collapse;width: 100%\">\n<thead style=\"background-color: #007ac2;color: white\">\n<tr>\n<th>Library<\/th>\n<th>Primary role<\/th>\n<th>Offerings<\/th>\n<th>Developer responsibility examples<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background-color: #f2f2f2\">\n<td><a href=\"https:\/\/developers.arcgis.com\/documentation\/app-builders\/low-code\/arcgis-experience-builder\/accessibility-for-custom-widgets\/#jimu-ui\"><strong>Jimu UI<\/strong><\/a><\/td>\n<td>React components for Experience Builder<\/td>\n<td>\n<ul style=\"font-size: 0.875rem\">\n<li>Keyboard behavior aligned with Experience Builder layouts and windows<\/li>\n<li>Accessible roles and states in provided components<\/li>\n<li>Consistent integration with theme and layout<\/li>\n<\/ul>\n<\/td>\n<td>\n<ul style=\"font-size: 0.875rem\">\n<li>Consider the appropriate component<\/li>\n<li>Avoid breaking heading hierarchy<\/li>\n<li>Manage focus when widget state changes<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/developers.arcgis.com\/documentation\/app-builders\/low-code\/arcgis-experience-builder\/accessibility-for-custom-widgets\/#calcite-components\"><strong>Calcite components<\/strong><\/a><\/td>\n<td>Part of Esri&#8217;s design system built as standards-based web components, which provide robust accessibility support<\/td>\n<td>\n<ul style=\"font-size: 0.875rem\">\n<li>Built-in keyboard interaction patterns<\/li>\n<li>Focus management inside components<\/li>\n<li>Accessible roles and WCAG-compliant contrast<\/li>\n<\/ul>\n<\/td>\n<td>\n<ul style=\"font-size: 0.875rem\">\n<li>Provide visible labels<\/li>\n<li>Maintain logical DOM order<\/li>\n<li>Handle focus transitions between components<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<tr style=\"background-color: #f2f2f2\">\n<td><a href=\"https:\/\/developers.arcgis.com\/documentation\/app-builders\/low-code\/arcgis-experience-builder\/accessibility-for-custom-widgets\/#arcgis-maps-sdk-for-javascript-components\"><strong>ArcGIS Maps SDK for JavaScript components<\/strong><\/a><\/td>\n<td>Web components focused on mapping solutions, including controls and interaction<\/td>\n<td>\n<ul style=\"font-size: 0.875rem\">\n<li>Keyboard-accessible map widgets such as <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/references\/map-components\/arcgis-zoom\/\">Zoom<\/a>, <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/references\/map-components\/arcgis-search\/\">Search<\/a>, <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/references\/map-components\/arcgis-legend\/\">Legend<\/a>, and <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/references\/map-components\/arcgis-layer-list\/\">LayerList<\/a><\/li>\n<li>Logical focus handling inside map UI<\/li>\n<\/ul>\n<\/td>\n<td>\n<ul style=\"font-size: 0.875rem\">\n<li>Provide accessible alternatives for map data, such as lists or tables<\/li>\n<li>Expose feature information outside of the map canvas<\/li>\n<li>Avoid hover-only interactions<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The key takeaways between these component libraries, include:<\/p>\n<ul style=\"font-size: 0.875rem\">\n<li>Jimu UI manages framework integration<\/li>\n<li>Calcite provides accessible UI building blocks<\/li>\n<li>JavaScript Maps SDK ensures map interaction is operable<\/li>\n<li>The developer composes them into an accessible workflow<\/li>\n<\/ul>\n"},{"acf_fc_layout":"content","content":"<h2 data-start=\"427\" data-end=\"480\">Common accessibility themes<\/h2>\n<p data-start=\"482\" data-end=\"630\">Jimu UI, Calcite components, and JavaScript Maps SDK components serve different purposes, but share foundational accessibility principles, which are applied differently within Experience Builder, including:<\/p>\n<ul>\n<li data-start=\"634\" data-end=\"656\">Keyboard operability<\/li>\n<li data-start=\"659\" data-end=\"699\">Visible and predictable focus behavior<\/li>\n<li data-start=\"702\" data-end=\"731\">Accessible roles and states<\/li>\n<li data-start=\"734\" data-end=\"764\">Logical interaction patterns<\/li>\n<li data-start=\"767\" data-end=\"797\">Alignment with WCAG guidance<\/li>\n<\/ul>\n"},{"acf_fc_layout":"content","content":"<h2>Accessibility and Jimu UI components<\/h2>\n<p data-start=\"359\" data-end=\"407\">When using Jimu UI components in custom widgets:<\/p>\n<ul>\n<li data-start=\"411\" data-end=\"518\">Avoid introducing heading elements unless required, since Experience Builder manages page-level hierarchy<\/li>\n<li>Manage focus when widget state changes dynamically<\/li>\n<li>Prioritize framework components over custom HTML where possible<\/li>\n<\/ul>\n"},{"acf_fc_layout":"content","content":"<h2>Design accessible interfaces with Calcite components<\/h2>\n<p data-start=\"781\" data-end=\"831\">When composing interfaces with Calcite components:<\/p>\n<ul>\n<li data-start=\"835\" data-end=\"879\">Provide visible labels or accessible names<\/li>\n<li data-start=\"882\" data-end=\"921\">Ensure DOM order matches visual order<\/li>\n<li data-start=\"924\" data-end=\"963\">Define required properties explicitly<\/li>\n<li data-start=\"966\" data-end=\"1035\">Return focus to the initiating control when panels or dialogs close<\/li>\n<\/ul>\n"},{"acf_fc_layout":"content","content":"<h2>Build accessible mapping experiences with JavaScript Maps SDK components<\/h2>\n<p data-start=\"1201\" data-end=\"1243\">When using JavaScript Maps SDK components:<\/p>\n<ul>\n<li data-start=\"1247\" data-end=\"1321\"><span data-teams=\"true\">Prioritize<\/span> built-in map controls such as <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/references\/map-components\/arcgis-zoom\/\">Zoom<\/a>, <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/references\/map-components\/arcgis-search\/\">Search<\/a>, <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/references\/map-components\/arcgis-legend\/\">Legend<\/a>, and <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/references\/map-components\/arcgis-layer-list\/\">LayerList<\/a><\/li>\n<li data-start=\"1324\" data-end=\"1399\"><span data-teams=\"true\">Provide alternative formats for map data, such as lists or tables<\/span><\/li>\n<li data-start=\"1402\" data-end=\"1467\">Synchronize map selection with accessible UI outside the canvas<\/li>\n<li data-start=\"1470\" data-end=\"1530\">Avoid hover-only interactions without keyboard equivalents<\/li>\n<\/ul>\n"},{"acf_fc_layout":"content","content":"<h2>Applying accessibility in a custom widget<\/h2>\n<p><span data-teams=\"true\">In this widget, the user interaction workflow of an individual filtering a layer to reveal a map component and obtain the feature details is handled outside the map, so that assistive technologies do not need to interact with the map canvas. This example demonstrates:<\/span><\/p>\n<ul>\n<li>Using Jimu UI and Calcite components when possible and<\/li>\n<li>Managing keyboard navigation and a visible focus, including restoring focus after action<\/li>\n<\/ul>\n<h3 data-start=\"217\" data-end=\"279\">Set an accessible name on the map<\/h3>\n<p data-start=\"280\" data-end=\"458\">Once the map view is ready, add an accessible label via the <code>aria<\/code> property, setting the <code>aria-label<\/code> to the webmap title. The accessible label provides context for assistive technologies:<\/p>\n<pre><code>useEffect(() =&gt; {\r\n  <span style=\"color: #d73a49\">const<\/span> mapEl = mapElRef.current;\r\n  <span style=\"color: #d73a49\">if<\/span> (!mapEl) <span style=\"color: #d73a49\">return<\/span>;\r\n\r\n  (<span style=\"color: #d73a49\">async<\/span> () =&gt; {\r\n    <span style=\"color: #d73a49\">try<\/span> {\r\n      <span style=\"color: #d73a49\">await<\/span> mapEl.viewOnReady();\r\n      <span style=\"color: #d73a49\">const<\/span> { portalItem } = mapEl.map;\r\n      mapEl.aria = {\r\n        label: portalItem.title,\r\n      };\r\n      setStatus(<span style=\"color: #032f62\">\"Map loaded.\"<\/span>);\r\n    } <span style=\"color: #d73a49\">catch<\/span> {\r\n      setStatus(<span style=\"color: #032f62\">\"Map failed to load.\"<\/span>);\r\n    }\r\n  })();\r\n}, []);\r\n<\/code><\/pre>\n<h3 data-start=\"922\" data-end=\"986\">Provide context to dynamic changes<\/h3>\n<p data-start=\"987\" data-end=\"1134\"><span data-teams=\"true\">Next, create a single-line status message and update it for asynchronous actions,<\/span>\u00a0such as &#8220;<strong>Applying<\/strong>\u2026&#8221; or &#8220;<strong>Applied<\/strong>\u2026&#8221;. Use the <code>aria-describedby<\/code> <span data-teams=\"true\">attribute to connect the controls to the status text, and use <code>aria-live<\/code> to announce dynamic changes on demand to assistive technologies.<\/span><\/p>\n<pre><code>&lt;<span style=\"color: #22863a\">p<\/span>\r\n  <span style=\"color: #005cc5\">id<\/span>=<span style=\"color: #032f62\">\"widget-status\"<\/span>\r\n  <span style=\"color: #005cc5\">role<\/span>=<span style=\"color: #032f62\">\"status\"<\/span>\r\n  <span style=\"color: #005cc5\">aria-live<\/span>=<span style=\"color: #032f62\">\"polite\"<\/span>\r\n  <span style=\"color: #005cc5\">aria-atomic<\/span>=<span style=\"color: #032f62\">\"true\"<\/span>\r\n&gt;\r\n  {status}\r\n&lt;\/<span style=\"color: #22863a\">p<\/span>&gt;\r\n<\/code><\/pre>\n<p>Add a button that updates the status text:<\/p>\n<pre><code>&lt;<span style=\"color: #6f42c1\">Button<\/span>\r\n  id=<span style=\"color: #032f62\">\"apply-filters-btn\"<\/span>\r\n  onClick={applyFilter}\r\n  aria-describedby=<span style=\"color: #032f62\">\"widget-status\"<\/span>\r\n&gt;\r\n  <span style=\"color: #6f42c1\">Apply<\/span> filters\r\n&lt;\/<span style=\"color: #6f42c1\">Button<\/span>&gt;\r\n...\r\n<span style=\"color: #6f42c1\">setStatus<\/span>(<span style=\"color: #032f62\">`Applying \"<span style=\"color: #24292e\">${layer}\"<\/span> filter\u2026`<\/span>);<\/code><\/pre>\n<p>Note that the Jimu UI <code>&lt;Button&gt;<\/code> already has an accessible name from its visible text <code>Apply filters<\/code>, and the focus order will follow the DOM order.<\/p>\n<h3>Label form controls with Calcite components<\/h3>\n<p>Use visible labels by wrapping inputs with <code>CalciteLabel<\/code>. The component provides a consistent UI and accessible labeling without the need for <code>aria<\/code>-named attributes:<\/p>\n<pre><code>&lt;<span style=\"color: #6f42c1\">CalciteLabel<\/span>&gt;\r\n  <span style=\"color: #6f42c1\">Select<\/span> layer\r\n  &lt;<span style=\"color: #6f42c1\">CalciteSelect<\/span>\r\n    label=\"Selected layer\"\r\n    value={layer}\r\n    onCalciteSelectChange={(event) =&gt; {\r\n      <span style=\"color: #d73a49\">const<\/span> target = event.target <span style=\"color: #d73a49\">as<\/span> <span style=\"color: #6f42c1\">HTMLSelectElement<\/span>;\r\n      <span style=\"color: #6f42c1\">setLayer<\/span>(target.value <span style=\"color: #d73a49\">as<\/span> <span style=\"color: #6f42c1\">LayerKey<\/span>);\r\n      <span style=\"color: #6f42c1\">setStatus<\/span>(<span style=\"color: #032f62\">`Layer set to \"<span style=\"color: #24292e\">${target.value}<\/span>\". Ready to apply filter.`<\/span>);\r\n    }}\r\n  &gt;\r\n    &lt;<span style=\"color: #22863a\">CalciteOption<\/span> <span style=\"color: #005cc5\">value<\/span>=<span style=\"color: #032f62\">\"parcels\"<\/span>&gt;Parcels&lt;\/<span style=\"color: #22863a\">CalciteOption<\/span>&gt;\r\n    &lt;<span style=\"color: #22863a\">CalciteOption<\/span> <span style=\"color: #005cc5\">value<\/span>=<span style=\"color: #032f62\">\"buildings\"<\/span>&gt;Buildings&lt;\/<span style=\"color: #22863a\">CalciteOption<\/span>&gt;\r\n    &lt;<span style=\"color: #22863a\">CalciteOption<\/span> <span style=\"color: #005cc5\">value<\/span>=<span style=\"color: #032f62\">\"roads\"<\/span>&gt;Roads&lt;\/<span style=\"color: #22863a\">CalciteOption<\/span>&gt;\r\n  &lt;\/<span style=\"color: #6f42c1\">CalciteSelect<\/span>&gt;\r\n&lt;\/<span style=\"color: #6f42c1\">CalciteLabel<\/span>&gt;\r\n<\/code><\/pre>\n<h3>Return focus after applying changes<\/h3>\n<p>After asynchronous updates, return focus to the initiating control to prevent users from losing their place. <span data-teams=\"true\">Returning focus to the triggering element is especially useful when applied filters change content that may not be visible in the current UI, or which affects content that isn&#8217;t in close proximity to the current control.<\/span><\/p>\n<pre><code><span style=\"color: #d73a49\">const<\/span> <span style=\"color: #6f42c1\">restoreApplyFocus<\/span> = () =&gt; {\r\n  <span style=\"color: #d73a49\">if<\/span> (applyBtnRef.current &amp;&amp; <span style=\"color: #032f62\">\"focus\"<\/span> <span style=\"color: #d73a49\">in<\/span> applyBtnRef.current) {\r\n    (applyBtnRef.current <span style=\"color: #d73a49\">as<\/span> <span style=\"color: #6f42c1\">HTMLElement<\/span>).<span style=\"color: #6f42c1\">focus<\/span>();\r\n    <span style=\"color: #d73a49\">return<\/span>;\r\n  }\r\n  <span style=\"color: #d73a49\">document<\/span>.<span style=\"color: #6f42c1\">getElementById<\/span>(<span style=\"color: #032f62\">\"apply-filters-btn\"<\/span>)?.<span style=\"color: #6f42c1\">focus<\/span>();\r\n};\r\n...\r\n<span style=\"color: #d73a49\">const<\/span> <span style=\"color: #6f42c1\">applyFilter<\/span> = <span style=\"color: #d73a49\">async<\/span> () =&gt; {\r\n  <span style=\"color: #6f42c1\">setStatus<\/span>(<span style=\"color: #032f62\">`Applying \"<span style=\"color: #24292e\">${layer}<\/span>\" filter\u2026`<\/span>);\r\n  <span style=\"color: #d73a49\">await<\/span> <span style=\"color: #d73a49\">new<\/span> <span style=\"color: #6f42c1\">Promise<\/span>((r) =&gt; <span style=\"color: #e36209\">setTimeout<\/span>(r, <span style=\"color: #005cc5\">250<\/span>));\r\n\r\n  <span style=\"color: #6f42c1\">setSelectedObjectId<\/span>(<span style=\"color: #005cc5\">101<\/span>);\r\n  <span style=\"color: #6f42c1\">setStatus<\/span>(<span style=\"color: #032f62\">`Filter applied to \"<span style=\"color: #24292e\">${layer}\"<\/span>. Showing selected feature details.`<\/span>);\r\n\r\n  <span style=\"color: #6f42c1\">restoreApplyFocus<\/span>();\r\n};\r\n<\/code><\/pre>\n<p>To view the full code sample, explore the <a href=\"https:\/\/gist.github.com\/kgonzago\/035d502c0e4330a120c417a5d8c9eae0#file-code-example-tsx\">GitHub gist<\/a>.<\/p>\n"},{"acf_fc_layout":"content","content":"<h2>Accessibility testing for custom widgets<\/h2>\n<p data-start=\"7341\" data-end=\"7423\">Automated accessibility tools help identify common issues, however testing cannot guarantee compliance. Some testing techniques include:<\/p>\n<ul>\n<li data-start=\"7503\" data-end=\"7542\"><span data-teams=\"true\">Move focus to the widget and traverse interactive components using only<\/span>\u00a0<a href=\"https:\/\/www.w3.org\/WAI\/people-use-web\/tools-techniques\/input\/\">keyboard navigation<\/a><\/li>\n<li data-start=\"7545\" data-end=\"7596\">Using a screen reader, such as <a href=\"https:\/\/www.freedomscientific.com\/Downloads\/JAWS\">JAWS<\/a>, <a href=\"https:\/\/www.nvaccess.org\/\">NVDA<\/a> , or <a href=\"https:\/\/support.apple.com\/guide\/voiceover\/welcome\/mac\">VoiceOver<\/a><\/li>\n<li data-start=\"7599\" data-end=\"7638\">Verifying focus order and focus visibility<\/li>\n<li data-start=\"7641\" data-end=\"7700\">Confirming all interactive elements contain accessible names<\/li>\n<\/ul>\n<p data-start=\"7901\" data-end=\"7965\">Explore <a href=\"https:\/\/community.esri.com\/t5\/accessibility-blog\/accessibility-resources\/ba-p\/1258042\">recommended testing tools<\/a> including a developer checklist<span data-teams=\"true\"> to further boost custom widget development.<\/span><\/p>\n"},{"acf_fc_layout":"content","content":"<h2>Summary<\/h2>\n<div>\n<p data-start=\"1495\" data-end=\"1688\"><span data-teams=\"true\">Accessible widgets are not automatic. They result from thoughtful design,<\/span>\u00a0semantic markup, keyboard operability, and careful consideration of Jimu UI, Calcite components, and JavaScript Maps SDK components. When accessibility is integrated from the start, custom widgets become more reliable, usable, and inclusive by design. To learn more about accessibility support and how to adapt accessibility into your solution, visit:<\/p>\n<ul>\n<li data-start=\"1495\" data-end=\"1688\"><a href=\"https:\/\/developers.arcgis.com\/experience-builder\/guide\/accessibility\/\">Accessibility support in Jimu UI and Experience Builder widgets<\/a><\/li>\n<li data-start=\"1495\" data-end=\"1688\"><a href=\"https:\/\/developers.arcgis.com\/calcite-design-system\/foundations\/accessibility\/\">How to continue building accessibility into solutions using Calcite components<\/a><\/li>\n<li data-start=\"1495\" data-end=\"1688\"><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/accessibility\/\">JavaScript Maps SDK components accessibility resources<\/a><\/li>\n<\/ul>\n<\/div>\n<p><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:240}\">Stay in the loop with the latest in developer technology by subscribing to the <a href=\"https:\/\/go.esri.com\/subscribe\" target=\"_blank\" rel=\"noopener\">Esri Developer Newsletter.<\/a><\/span><\/p>\n"}],"show_article_image":false,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Card_-826px-x-465px.png","wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Banner_-1920px-x-1080px-1.png","related_articles":[{"ID":2946387,"post_author":"309572","post_date":"2025-11-17 07:00:27","post_date_gmt":"2025-11-17 15:00:27","post_content":"","post_title":"Optimizing Custom Widgets in ArcGIS Experience Builder with Jimu UI, Calcite, and Map Components","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"closed","post_password":"","post_name":"optimizing-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components","to_ping":"","pinged":"","post_modified":"2025-11-17 09:55:41","post_modified_gmt":"2025-11-17 17:55:41","post_content_filtered":"","post_parent":0,"guid":"https:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=2946387","menu_order":0,"post_type":"blog","post_mime_type":"","comment_count":"0","filter":"raw"}]},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.9 (Yoast SEO v25.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Building Accessible Custom Widgets in ArcGIS Experience Builder<\/title>\n<meta name=\"description\" content=\"Learn how to implement accessibility in ArcGIS Experience Builder custom widgets using Jimu UI, Calcite components, and ArcGIS Maps SDK.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building Accessible Custom Widgets in ArcGIS Experience Builder with Jimu UI, Calcite, and JavaScript Maps SDK Components\" \/>\n<meta property=\"og:description\" content=\"Learn how to implement accessibility in ArcGIS Experience Builder custom widgets using Jimu UI, Calcite components, and ArcGIS Maps SDK.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components\" \/>\n<meta property=\"og:site_name\" content=\"ArcGIS Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/esrigis\/\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-05T19:46:05+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@ESRI\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components\"},\"author\":{\"name\":\"Kitty Hurley\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/1d3e2f690ee8951f6625010e5b55aee8\"},\"headline\":\"Building Accessible Custom Widgets in ArcGIS Experience Builder with Jimu UI, Calcite, and JavaScript Maps SDK Components\",\"datePublished\":\"2026-03-05T16:30:09+00:00\",\"dateModified\":\"2026-03-05T19:46:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components\"},\"wordCount\":17,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"keywords\":[\"accessibility\",\"arcgis experience builder jimu ui\",\"Calcite Design System\"],\"articleSection\":[\"Developers\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components\",\"name\":\"Building Accessible Custom Widgets in ArcGIS Experience Builder\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\"},\"datePublished\":\"2026-03-05T16:30:09+00:00\",\"dateModified\":\"2026-03-05T19:46:05+00:00\",\"description\":\"Learn how to implement accessibility in ArcGIS Experience Builder custom widgets using Jimu UI, Calcite components, and ArcGIS Maps SDK.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.esri.com\/arcgis-blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building Accessible Custom Widgets in ArcGIS Experience Builder with Jimu UI, Calcite, and JavaScript Maps SDK Components\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"name\":\"ArcGIS Blog\",\"description\":\"Get insider info from Esri product teams\",\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\",\"name\":\"Esri\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"contentUrl\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"width\":400,\"height\":400,\"caption\":\"Esri\"},\"image\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/esrigis\/\",\"https:\/\/x.com\/ESRI\",\"https:\/\/www.linkedin.com\/company\/5311\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/1d3e2f690ee8951f6625010e5b55aee8\",\"name\":\"Kitty Hurley\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2024\/03\/Esri_Day2_PSCC2024_H_0127-e1710789483673-261x261.jpg\",\"contentUrl\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2024\/03\/Esri_Day2_PSCC2024_H_0127-e1710789483673-261x261.jpg\",\"caption\":\"Kitty Hurley\"},\"description\":\"Kitty is a Principal Product Engineer with Calcite Design System, passionate about expanding access to the web and maps for broader audiences. She is dedicated to creating inclusive, user-friendly web experiences that connect people and places through innovative design and technology. Outside of work, Kitty enjoys exploring the wilderness of Minnesota and has a goal to visit every major league baseball stadium across America.\",\"sameAs\":[\"https:\/\/www.github.com\/geospatialem\",\"https:\/\/www.linkedin.com\/in\/khurley\",\"https:\/\/x.com\/geospatialem\"],\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/author\/khurley\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Building Accessible Custom Widgets in ArcGIS Experience Builder","description":"Learn how to implement accessibility in ArcGIS Experience Builder custom widgets using Jimu UI, Calcite components, and ArcGIS Maps SDK.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components","og_locale":"en_US","og_type":"article","og_title":"Building Accessible Custom Widgets in ArcGIS Experience Builder with Jimu UI, Calcite, and JavaScript Maps SDK Components","og_description":"Learn how to implement accessibility in ArcGIS Experience Builder custom widgets using Jimu UI, Calcite components, and ArcGIS Maps SDK.","og_url":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components","og_site_name":"ArcGIS Blog","article_publisher":"https:\/\/www.facebook.com\/esrigis\/","article_modified_time":"2026-03-05T19:46:05+00:00","twitter_card":"summary_large_image","twitter_site":"@ESRI","twitter_misc":{"Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components#article","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components"},"author":{"name":"Kitty Hurley","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/1d3e2f690ee8951f6625010e5b55aee8"},"headline":"Building Accessible Custom Widgets in ArcGIS Experience Builder with Jimu UI, Calcite, and JavaScript Maps SDK Components","datePublished":"2026-03-05T16:30:09+00:00","dateModified":"2026-03-05T19:46:05+00:00","mainEntityOfPage":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components"},"wordCount":17,"commentCount":0,"publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"keywords":["accessibility","arcgis experience builder jimu ui","Calcite Design System"],"articleSection":["Developers"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components","url":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components","name":"Building Accessible Custom Widgets in ArcGIS Experience Builder","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#website"},"datePublished":"2026-03-05T16:30:09+00:00","dateModified":"2026-03-05T19:46:05+00:00","description":"Learn how to implement accessibility in ArcGIS Experience Builder custom widgets using Jimu UI, Calcite components, and ArcGIS Maps SDK.","breadcrumb":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.esri.com\/arcgis-blog\/"},{"@type":"ListItem","position":2,"name":"Building Accessible Custom Widgets in ArcGIS Experience Builder with Jimu UI, Calcite, and JavaScript Maps SDK Components"}]},{"@type":"WebSite","@id":"https:\/\/www.esri.com\/arcgis-blog\/#website","url":"https:\/\/www.esri.com\/arcgis-blog\/","name":"ArcGIS Blog","description":"Get insider info from Esri product teams","publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization","name":"Esri","url":"https:\/\/www.esri.com\/arcgis-blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","contentUrl":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","width":400,"height":400,"caption":"Esri"},"image":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/esrigis\/","https:\/\/x.com\/ESRI","https:\/\/www.linkedin.com\/company\/5311\/"]},{"@type":"Person","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/1d3e2f690ee8951f6625010e5b55aee8","name":"Kitty Hurley","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/","url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2024\/03\/Esri_Day2_PSCC2024_H_0127-e1710789483673-261x261.jpg","contentUrl":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2024\/03\/Esri_Day2_PSCC2024_H_0127-e1710789483673-261x261.jpg","caption":"Kitty Hurley"},"description":"Kitty is a Principal Product Engineer with Calcite Design System, passionate about expanding access to the web and maps for broader audiences. She is dedicated to creating inclusive, user-friendly web experiences that connect people and places through innovative design and technology. Outside of work, Kitty enjoys exploring the wilderness of Minnesota and has a goal to visit every major league baseball stadium across America.","sameAs":["https:\/\/www.github.com\/geospatialem","https:\/\/www.linkedin.com\/in\/khurley","https:\/\/x.com\/geospatialem"],"url":"https:\/\/www.esri.com\/arcgis-blog\/author\/khurley"}]}},"text_date":"March 5, 2026","author_name":"Multiple Authors","author_page":"https:\/\/www.esri.com\/arcgis-blog\/products\/experience-builder\/developers\/building-accessible-custom-widgets-in-arcgis-experience-builder-with-jimu-ui-calcite-and-map-components","custom_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/01\/Banner_-1920px-x-1080px-1.png","primary_product":"ArcGIS Experience Builder","tag_data":[{"term_id":28911,"name":"accessibility","slug":"accessibility","term_group":0,"term_taxonomy_id":28911,"taxonomy":"post_tag","description":"","parent":0,"count":71,"filter":"raw"},{"term_id":780883,"name":"arcgis experience builder jimu ui","slug":"arcgis-experience-builder-jimu-ui","term_group":0,"term_taxonomy_id":780883,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":759512,"name":"Calcite Design System","slug":"calcite-design-system","term_group":0,"term_taxonomy_id":759512,"taxonomy":"post_tag","description":"","parent":0,"count":15,"filter":"raw"}],"category_data":[{"term_id":738191,"name":"Developers","slug":"developers","term_group":0,"term_taxonomy_id":738191,"taxonomy":"category","description":"","parent":0,"count":420,"filter":"raw"}],"product_data":[{"term_id":400032,"name":"ArcGIS Experience Builder","slug":"experience-builder","term_group":0,"term_taxonomy_id":400032,"taxonomy":"product","description":"","parent":36591,"count":160,"filter":"raw"},{"term_id":36831,"name":"ArcGIS Maps SDK for JavaScript","slug":"js-api-arcgis","term_group":0,"term_taxonomy_id":36831,"taxonomy":"product","description":"","parent":36601,"count":361,"filter":"raw"}],"primary_product_link":"https:\/\/www.esri.com\/arcgis-blog\/?s=#&products=experience-builder","_links":{"self":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/2953252","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/users\/309572"}],"replies":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/comments?post=2953252"}],"version-history":[{"count":0,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/2953252\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/media?parent=2953252"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/categories?post=2953252"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/tags?post=2953252"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/industry?post=2953252"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/product?post=2953252"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}