Skip to content

Commit

Permalink
Merge pull request #2017 from hashicorp/02-popover-register-event-mod…
Browse files Browse the repository at this point in the history
…ifier

`RichTooltip/Popover` component - `hds-register-event` modifier [02]
  • Loading branch information
didoo authored Apr 30, 2024
2 parents 7a0bd87 + 1131bc6 commit 9fe9fcf
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/afraid-beds-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hashicorp/design-system-components": minor
---

Added `hds-register-event` modifier (for internal use)
1 change: 1 addition & 0 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
"./helpers/hds-link-to-query.js": "./dist/_app_/helpers/hds-link-to-query.js",
"./modifiers/hds-anchored-position.js": "./dist/_app_/modifiers/hds-anchored-position.js",
"./modifiers/hds-clipboard.js": "./dist/_app_/modifiers/hds-clipboard.js",
"./modifiers/hds-register-event.js": "./dist/_app_/modifiers/hds-register-event.js",
"./modifiers/hds-tooltip.js": "./dist/_app_/modifiers/hds-tooltip.js"
}
},
Expand Down
30 changes: 30 additions & 0 deletions packages/components/src/modifiers/hds-register-event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { modifier } from 'ember-modifier';

// Notice: we use a function-based modifier here instead of a class-based one
// because it's quite simple in its logic, and doesn't require injecting services
// see: https://github.com/ember-modifier/ember-modifier#function-based-modifiers

// this modifier is a "replacement" of the standard `{{on 'event' myFunction}}`
// it's needed because the {{on}} modifier can't be applied conditionally, apparently
// see: https://github.com/emberjs/ember.js/issues/19869#issuecomment-1909118910
// see: https://github.com/emberjs/ember.js/pull/20629
// see also: https://github.com/emberjs/ember.js/blob/main/packages/%40ember/-internals/glimmer/lib/modifiers/on.ts#L30
export default modifier((element, positional, named = {}) => {
// the "target" element the listeners are added to
// notice: this is the element the Ember modifier is attached to
const targetElement = element;
// the event name and handler to apply to the element
// notice: it's expressed as "positional" argument (array) for the modifier
const [event, eventHandler] = positional;
// the options for the `addEventListener()` method
// see: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
// notice: it's expressed as "named" argument (object) for the modifier
const { useCapture = false } = named;

targetElement.addEventListener(event, eventHandler, useCapture);

// this (teardown) function is run when the element is removed from the DOM
return () => {
targetElement.removeEventListener(event, eventHandler, useCapture);
};
});
45 changes: 45 additions & 0 deletions showcase/tests/integration/modifiers/hds-register-event-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/

import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { click, render, triggerEvent } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';

module('Integration | Modifier | hds-register-event', function (hooks) {
setupRenderingTest(hooks);

test('it adds an event listener to the element', async function (assert) {
assert.expect(1);

this.set('eventHandler', () => {
assert.ok(true, 'event handler was called');
});

await render(
hbs`<button id="test-button" {{hds-register-event 'click' this.eventHandler}}>Test</button>`
);

await click('button');
});

test('it passes the `useCapture` option to the event listener', async function (assert) {
assert.expect(1);

this.set('eventHandler', (event) => {
assert.strictEqual(
event.eventPhase,
Event.CAPTURING_PHASE,
'event was captured'
);
});

await render(
hbs`<button id="test-button" {{hds-register-event 'click' this.eventHandler useCapture=true}}><span>Test</span></button>`
);

await triggerEvent('span', 'click', { bubbles: true });
});
});

0 comments on commit 9fe9fcf

Please sign in to comment.