Skip to content

feat(unity-react-core): modal auto focus and disabled tab to content … - #1768

Open
spaceperson wants to merge 42 commits into
devfrom
uds02-2211
Open

feat(unity-react-core): modal auto focus and disabled tab to content …#1768
spaceperson wants to merge 42 commits into
devfrom
uds02-2211

Conversation

@spaceperson

Copy link
Copy Markdown
Contributor

…outside the modal

Description

Checklist

  • Tests pass for relevant code changes

Important Reminders

Links

@spaceperson
spaceperson requested a review from a team as a code ownerAugust 5, 2026 17:27
@asu-jenkins-devops

Copy link
Copy Markdown
Collaborator

</GaEventWrapper>
<h1>{modalTitle}</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Content should be a prop

* @typedef {Object} ButtonIconOnlyProps
* @property {Array.<string>} icon
* @property {string} [color]
* @property {boolean} [autoFocus]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this always be true?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh the name confused me. is this variable for automatically opening the modal on page load? Can we pick a different variable name? variable name should describe if true the modal will be open when it loads

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an html value for automatically updating the focus to activate the button when the modal opens. I left it as an option, but it didn't work when I tried it. I assumed it was because another element was taking priority. I didn't see the harm in leaving it as an option, but we could remove it.

https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/autofocus
JSX uses camel case instead of the lowercase autofocus value.


useEffect(() => {
if (!openState) return;
if (!openState) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidornelas11 are we mixing our react components with js inside bootstrap-theme (it technically loses react "coolness" but makes the functionality consistant)

If we use react functionality,

  • make sure the bootstrap JS script does not conflict.
  • useRef will be a better solution to target the element.

@@ -1,22 +1,101 @@
import { EventHandler } from "./bootstrap-helper";

function openModal() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the modal close if a user clicks the backdrop? I thought this was a standard behavior?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that feature missing was odd as well but wasn't sure if there was a reason we didn't have that feature. I'll implement that with the next update.

// const mainContentChildren = mainContent.children;
// let mainContentChildrenArray = Array.from(mainContentChildren);
// for (let i = 0; i < mainContentChildrenArray.length; i++) {
// mainContentChildrenArray[i].setAttribute("inert", "");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clean up code we aren't keeping

closeModal();
});

document?.addEventListener("keydown", function (event) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this event when the modal is not open

}

if (e.shiftKey) {
// if shift key pressed for shift + tab combination

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets let the native tab event do its thing. you can create a focus trap

import { EventHandler } from "./bootstrap-helper";
function initModals() {
const modal = document.getElementById("uds-modal");
const openModalButton = document.getElementById("openModalButton");
const closeModalButton = document.getElementById("closeModalButton");
const firstFocusable = modal.querySelector(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
let previousFocus = null;
function focusTrap(e) {
// If relatedTarget is outside, move focus back inside
if (!modal.contains(e.relatedTarget)) {
firstFocusable?.focus();
}
}
function openModal() {
// When opening: save current focus and move into modal
previousFocus = document.activeElement;
modal.classList.add("open");
// attach event listeners to trap focus and close modal
modal.addEventListener("focusout", focusTrap);
modal.addEventListener("click", closeModal, true);
document.addEventListener("keydown", closeModal);
// Focus the first interactive element inside (or body if none)
firstFocusable?.focus();
}
function closeModal({ type, target, key } = {}) {
if (
// escape key pressed
(type === "keydown" && key === "Escape") ||
// click outside modal
(type === "click" && target === modal) ||
// click on close button
(type === "click" && target === closeModalButton)
) {
modal.classList.remove("open");
modal.removeEventListener("focusout", focusTrap);
modal.removeEventListener("click", closeModal, true);
document.removeEventListener("keydown", closeModal);
// When closing: restore original focus
previousFocus?.focus();
}
}
openModalButton.addEventListener("click", openModal);
}
EventHandler.on(window, "load.uds.modals", initModals);
export { initModals };

spacepersonand others added 21 commits August 11, 2026 17:56
The Web Directory profile card rendered the person's work title in an
h4, causing a skipped heading level on consuming sites where the card
name is not a heading (accessibility issue).
- ProfileCard (app-webdir-ui) and PersonProfile (unity-react-core) now
render the title as p.person-profession-title > strong
- unity-bootstrap-theme styles the new class identically to the old h4
(1rem, 700 weight, 1.625rem line-height, 2-line clamp); h4 selectors
kept for backward compatibility with published consumers
- person-profile Storybook template updated to the new markup
# [@asu/app-webdir-ui-v5.0.16](https://github.com/asu/asu-unity-stack/compare/@asu/app-webdir-ui-v5.0.15...@asu/app-webdir-ui-v5.0.16) (2026-07-25)
### Bug Fixes
* **app-webdir-ui:** fix alpha scrolling ([c7c8944](c7c8944))
…eact-dom/server
- Restore the .scroll-control-prev/-next and carousel-control-*-icon
styles into NavControls.styles.js (co-located with the component
instead of unity-bootstrap-theme). PR #1698's TabbedPanels redesign
removed this CSS assuming it was dead code from the old carousel-based
tabs, but NavControls is still used standalone by app-webdir-ui's
Filter component ("Filter by Last Initial"), which regressed to
unstyled buttons as a result.
- Split getBootstrapHTML (react-dom/server, Storybook/dev-tooling only)
out of useBaseSpecificFramework.js into its own file. Every component
imports useBaseSpecificFramework at runtime, so bundling
react-dom/server there was pulling server-rendering internals
(MessageChannel, TextEncoder, etc.) into every consumer's published
dist for no runtime benefit, and broke jsdom-based tests in
app-webdir-ui.
…-react-core dependency ranges
Both were pinned to ^1.x ranges that no longer match the workspace's
current major versions (unity-bootstrap-theme 2.x, unity-react-core 2.x),
causing yarn to resolve a stale published copy from the registry instead
of symlinking the local workspace package.
… range
Was pinned to ^1.0.0, which no longer matches the workspace's current
2.x version, causing yarn to resolve a stale published copy from the
registry instead of symlinking the local workspace package.
…ange
Was pinned to ^1.0.0, which no longer matches the workspace's current
2.x version, causing yarn to resolve a stale published copy from the
registry instead of symlinking the local workspace package.
… range
Was pinned to ^1.20, which no longer matches the workspace's current
2.x version, causing yarn to resolve a stale published copy from the
registry instead of symlinking the local workspace package.
… range
Was pinned to ^1.0.0, which no longer matches the workspace's current
2.x version, causing yarn to resolve a stale published copy from the
registry instead of symlinking the local workspace package.
# [@asu/unity-react-core-v2.1.1](https://github.com/ASU/asu-unity-stack/compare/@asu/unity-react-core-v2.1.0...@asu/unity-react-core-v2.1.1) (2026-07-28)
### Bug Fixes
* **unity-react-core:** restore nav-control styles and stop bundling react-dom/server ([cb41952](cb41952))
# [@asu/app-degree-pages-v3.2.3](https://github.com/asu/asu-unity-stack/compare/@asu/app-degree-pages-v3.2.2...@asu/app-degree-pages-v3.2.3) (2026-07-28)
### Bug Fixes
* **app-degree-pages:** correct stale @asu/unity-react-core dependency range ([81ce102](81ce102))
# [@asu/app-rfi-v3.10.3](https://github.com/asu/asu-unity-stack/compare/@asu/app-rfi-v3.10.2...@asu/app-rfi-v3.10.3) (2026-07-28)
### Bug Fixes
* **app-rfi:** correct stale @asu/unity-bootstrap-theme and @asu/unity-react-core dependency ranges ([7214d47](7214d47))
# [@asu/app-webdir-ui-v5.0.17](https://github.com/asu/asu-unity-stack/compare/@asu/app-webdir-ui-v5.0.16...@asu/app-webdir-ui-v5.0.17) (2026-07-28)
### Bug Fixes
* **app-webdir-ui:** fix nav controls and anon image for webdir ([0e68046](0e68046))
# [@asu/component-events-v3.2.1](https://github.com/asu/asu-unity-stack/compare/@asu/component-events-v3.2.0...@asu/component-events-v3.2.1) (2026-07-28)
### Bug Fixes
* **component-events:** correct stale @asu/unity-react-core dependency range ([8b66069](8b66069))
# [@asu/component-news-v4.2.2](https://github.com/asu/asu-unity-stack/compare/@asu/component-news-v4.2.1...@asu/component-news-v4.2.2) (2026-07-28)
### Bug Fixes
* **component-news:** correct stale @asu/unity-react-core dependency range ([d5f3869](d5f3869))
davidornelas11and others added 20 commits August 18, 2026 10:59
# [@asu/unity-bootstrap-theme-v2.2.0](https://github.com/ASU/asu-unity-stack/compare/@asu/unity-bootstrap-theme-v2.1.1...@asu/unity-bootstrap-theme-v2.2.0) (2026-07-29)
### Bug Fixes
* **unity-bootstrap-theme:** fix modal close button focus style issue ([c288469](c288469))
### Features
* modal accessibility and escape key features for unity react and bootstrap ([04bdeea](04bdeea))
### Performance Improvements
* **unity-react-core:** useEffect update for React js async key listener handling ([b25ab85](b25ab85))
# [@asu/unity-react-core-v2.2.0](https://github.com/ASU/asu-unity-stack/compare/@asu/unity-react-core-v2.1.1...@asu/unity-react-core-v2.2.0) (2026-07-29)
### Features
* modal accessibility and escape key features for unity react and bootstrap ([04bdeea](04bdeea))
* **unity-react-core:** aria-label update ([eeaebef](eeaebef))
### Performance Improvements
* **unity-react-core:** useEffect update for React js async key listener handling ([b25ab85](b25ab85))
# [@asu/unity-bootstrap-theme-v2.2.1](https://github.com/ASU/asu-unity-stack/compare/@asu/unity-bootstrap-theme-v2.2.0...@asu/unity-bootstrap-theme-v2.2.1) (2026-07-30)
### Bug Fixes
* **unity-bootstrap-theme:** allow ordered lists to be reversed ([d33c05e](d33c05e))
# [@asu/component-header-footer-v1.4.6](https://github.com/asu/asu-unity-stack/compare/@asu/component-header-footer-v1.4.5...@asu/component-header-footer-v1.4.6) (2026-07-31)
### Bug Fixes
* **component-header-footer:** fixed large headers not wrapping on smaller screens ([ed046e1](ed046e1))
# [@asu/unity-bootstrap-theme-v2.2.2](https://github.com/ASU/asu-unity-stack/compare/@asu/unity-bootstrap-theme-v2.2.1...@asu/unity-bootstrap-theme-v2.2.2) (2026-08-03)
### Bug Fixes
* **unity-bootstrap-theme:** add unity defgault focus ring to hover card ([441a16a](441a16a))
* **unity-bootstrap-theme:** tabindex update for hover cards ([1bd6834](1bd6834))
Bumps [undici](https://github.com/nodejs/undici) from 6.27.0 to 6.28.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](nodejs/undici@v6.27.0...v6.28.0)
---
updated-dependencies:
- dependency-name: undici
dependency-version: 6.28.0
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com>
# [@asu/unity-bootstrap-theme-v2.2.3](https://github.com/ASU/asu-unity-stack/compare/@asu/unity-bootstrap-theme-v2.2.2...@asu/unity-bootstrap-theme-v2.2.3) (2026-08-06)
### Bug Fixes
* **app-webdir-ui:** render profile card title as bold text instead of h4 ([f7fb027](f7fb027))
# [@asu/unity-react-core-v2.2.1](https://github.com/ASU/asu-unity-stack/compare/@asu/unity-react-core-v2.2.0...@asu/unity-react-core-v2.2.1) (2026-08-06)
### Bug Fixes
* **app-webdir-ui:** render profile card title as bold text instead of h4 ([f7fb027](f7fb027))
# [@asu/app-webdir-ui-v5.0.18](https://github.com/asu/asu-unity-stack/compare/@asu/app-webdir-ui-v5.0.17...@asu/app-webdir-ui-v5.0.18) (2026-08-07)
### Bug Fixes
* **app-webdir-ui:** render profile card title as bold text instead of h4 ([f7fb027](f7fb027))
# [@asu/app-degree-pages-v3.2.4](https://github.com/asu/asu-unity-stack/compare/@asu/app-degree-pages-v3.2.3...@asu/app-degree-pages-v3.2.4) (2026-08-07)
### Bug Fixes
* **app-degree-pages:** delete degree detail page component ([83e8992](83e8992))
* **app-degree-pages:** fix relative path in Breadcrumbs import ([83338bf](83338bf))
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants

@spaceperson@asu-jenkins-devops@scott-williams-az@juanmitriatti@semantic-release-bot@davidornelas11@tbutterf@mlsamuelson@oatkar