Skip to content

Replace AppButtonModalTrigger with useToggle hook.#3514

Open
mikaeltomovic wants to merge 2 commits into
developfrom
feature/GOOWOO-45-replace-appbuttonmodaltrigger
Open

Replace AppButtonModalTrigger with useToggle hook.#3514
mikaeltomovic wants to merge 2 commits into
developfrom
feature/GOOWOO-45-replace-appbuttonmodaltrigger

Conversation

@mikaeltomovic

Copy link
Copy Markdown
Collaborator

Changes proposed in this Pull Request:

Closes GOOWOO-56

This PR replaces AppButtonModalTrigger with a new useToggle hook, addressing the hidden coupling issue described in the ticket.

Previously, AppButtonModalTrigger used React.cloneElement to silently inject onRequestClose into whatever modal was passed to it. This made it impossible to understand how a modal's close behaviour worked without tracing all the way back to AppButtonModalTrigger — the dependency was invisible from the modal component's props.

The new useToggle hook returns a [ value, toggle ] tuple (with an optional initial value) and lets each consumer wire up onClick and onRequestClose explicitly. The open state is visible at the call site, removing the hidden coupling.

Note: For the two cases where the modal trigger lives inside a .map() loop (issues-table-data.js, attribute-mapping-table.js), small private components (IssueReadMoreButton, EditRuleButton, DeleteRuleButton) were extracted to keep hooks at the component level, as required by React's rules of hooks.

Screenshots:

N/A — no visual changes. All existing behaviour is preserved.

Detailed test instructions:

  1. Navigate to Marketing > Google Listings & Ads > Shipping and verify the "Edit" and "Add another rate" buttons still open and close their respective modals correctly.
  2. Navigate to the Minimum order value section and verify the "Edit" and "Add another condition" buttons open and close their modals.
  3. Navigate to Dashboard > Programs and verify the "Edit" button opens the edit program prompt modal and closes on dismiss.
  4. Navigate to Product Feed > Issues to resolve and verify the "Read more about this issue" button opens the issue detail modal.
  5. Navigate to Marketing > Attribute Mapping and verify the "Edit", "Delete", and "Create attribute rule" buttons all open and close their modals, and that the analytics events (gla_modal_open / gla_modal_closed) still fire correctly.

Additional details:

Changelog entry

Dev - Replace AppButtonModalTrigger component with a useToggle hook to make modal open/close state explicit at each call site.

@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.94737% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.2%. Comparing base (fcc6319) to head (dc307e6).

Files with missing lines Patch % Lines
...pages/attribute-mapping/attribute-mapping-table.js 63.2% 7 Missing ⚠️
...l-programs-table-card/edit-program-button/index.js 66.7% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##             develop   #3514      +/-   ##
============================================
- Coverage       67.6%   64.2%    -3.5%     
============================================
  Files            518     395     -123     
  Lines          21461    6793   -14668     
  Branches           0    1731    +1731     
============================================
- Hits           14515    4358   -10157     
+ Misses          6946    2174    -4772     
- Partials           0     261     +261     
Flag Coverage Δ
js-unit-tests 64.2% <78.9%> (?)
php-unit-tests ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...n-section/minimum-order-card/minimum-order-card.js 96.4% <100.0%> (ø)
.../minimum-order-card/minimum-order-input-control.js 93.8% <100.0%> (ø)
js/src/hooks/useToggle.js 100.0% <100.0%> (ø)
...roduct-feed/issues-table-card/issues-table-data.js 94.7% <100.0%> (ø)
...l-programs-table-card/edit-program-button/index.js 83.3% <66.7%> (ø)
...pages/attribute-mapping/attribute-mapping-table.js 70.7% <63.2%> (ø)

... and 907 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

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.

Pull request overview

This PR removes the AppButtonModalTrigger component (which relied on cloneElement to inject onRequestClose) and replaces that pattern with an explicit useToggle hook plus local open-state wiring at each modal call site, making modal open/close behavior visible where it’s used.

Changes:

  • Introduces useToggle (with unit tests) to manage boolean open/close state.
  • Refactors multiple modal trigger call sites to render buttons + conditionally render modals with explicit onRequestClose.
  • Extracts small per-row components in table .map() contexts to keep hook usage compliant with React’s rules of hooks.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
js/src/pages/product-feed/issues-table-card/issues-table-data.js Extracts IssueReadMoreButton to manage modal open/close explicitly via useToggle.
js/src/pages/dashboard/all-programs-table-card/edit-program-button/index.js Replaces trigger component with explicit state and conditional EditProgramPromptModal rendering.
js/src/pages/attribute-mapping/attribute-mapping-table.js Replaces trigger component in table actions/footer; extracts per-row buttons using useToggle; preserves modal open/close tracking events.
js/src/hooks/useToggle.js Adds a reusable boolean toggle hook for modal open state.
js/src/hooks/useToggle.test.js Adds unit tests covering default state, custom initial value, toggling behavior, and stable function reference.
js/src/components/shipping-rate-section/estimated-shipping-rates-card/shipping-rate-input-control.js Replaces trigger component with explicit modal open state and passes onRequestClose.
js/src/components/shipping-rate-section/estimated-shipping-rates-card/estimated-shipping-rates-card.js Replaces trigger component for “Add another rate” with explicit useToggle modal state.
js/src/components/order-value-condition-section/minimum-order-card/minimum-order-input-control.js Replaces trigger component for edit modal with explicit useToggle state and onRequestClose.
js/src/components/order-value-condition-section/minimum-order-card/minimum-order-card.js Replaces trigger component for “Add another condition” modal with explicit useToggle state and onRequestClose.
js/src/components/app-button-modal-trigger.js Removes the cloneElement-based trigger component entirely.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +20 to +24
<AppButton
{ ...buttonProps }
isLink
className={ classnames( className ) }
onClick={ toggleModal }

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

EditProgramButton is purpose-specific, not generic. It has one job: open an edit modal. The onClick override is intentional: the component owns its click behavior, not the caller.

Comment thread js/src/hooks/useToggle.js
Comment on lines +12 to +16
const useToggle = ( initialValue = false ) => {
const [ value, setValue ] = useState( initialValue );
const toggle = useCallback( () => setValue( ( prev ) => ! prev ), [] );
return [ value, toggle ];
};

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The name toggle explicitly implicates that the function should be to toggle on/off. I don't think there's a strong case for accepting a boolean as a parameter here.

@mikaeltomovic mikaeltomovic requested a review from asvinb June 17, 2026 12:04
Sign up for free to 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.

2 participants