Is your feature request related to a problem? Please describe.
I had originally filed this as a bug report, but belatedly decided that it's technically a feature request.
Basically, though, when I am building a WebComponent which generates a CustomEvent, I want to be sure that the CustomEvent is being generated properly.
Describe the solution you'd like
withActions (from @storybook/addon-actions) should include in the log the detail property of an event it receives if the event is a CustomEvent (or there should be some other documented way for stories to listen for a CustomEvent and see its detail property in the log).
Describe alternatives you've considered
(using html from lit element and render from lit html), I render:
<button type="button" @click="${this.publishtest}">publish</button>
And, I add a publish method on that class:
publishtest() {
this.dispatchEvent(new CustomEvent('pubexample', {detail: {a: 1, b: 2}, bubbles: true}));
}
And, in my stories I include:
.addDecorator(withActions('pubexample'))
I click the button, and something representing my example event shows up in the console log, but the detail property appears to be missing (or at least is not accessible from the console.log in chrome).
Are you able to assist bring the feature to reality?
I don't know - I'll try implementing this tomorrow and submit a pull request if I can make this work.
Additional context
Possibly relevant is that the logged message has a data property which has an args property which is an array of one element which is seems to be my CustomEvent but the only visible property of that item is {isTrusted: false}. Meanwhile, if I save that CustomEvent globally, and display it in the log, I see something completely different (with about 16 properties, but Object.keys() on that object only gets me isTrusted and _constructor-name_ -- so a part of the issue here is simply that chrome doesn't let me see inherited properties in the context of the logged message, perhaps because the CustomEvent is deeply nested in the message).
Just curious - on this line:
<button type="button" @click="${this.publishtest}">publish</button>
Did you mean onClick instead of @click? Or is this @click something that I don't know about?
The @click mechanism is slightly different from onClick -- see, for example https://lit-element.polymer-project.org/guide/events
[And, on the positive side, despite a sordid history of CustomEvent problems with detail, in this context detail is not being lost -- it's just not visible as it's logged here. (But I haven't come up with a better alternative for logging, yet, either.)]
Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!
Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!
I have also this issue, can you reopen ?
Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!
Given the current state of things, this is likely to take much longer than 30 days to address.
@rdm would you like to take a crack at it?
@shilman there are still too many issues which I do not comprehend, here. I think I'd botch the job.
Still... maybe I should try -- a botched job might at least be a step in the right direction...
Edit: currently, storybook tests do not succeed for me, on master because of some insufficient color contrast issues. That's from the puppeteer report -- I'm getting a variety of additional require "package not installed as a dependency" failures when I try testing locally...
Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!
Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!
cc @jonspalmer
Seems like this issue is coming from react-inspector.
I managed to reproduce it there as follow:
window.eval = () => new CustomEvent('test', {detail: 123})isTrusted property, and no mention of the details property, similar to what happens in storybook:
At the same time, running console.log(new CustomEvent('test', {detail: 123})) in chrome devtools shows a bunch of properties, including detail:

I hope that this is helpful!
After doing a few tries, I discovered that almost all the "properties" of the CustomEvent are actually class getters, the only property is isTrusted.
It means, that if you try to duplicate or serialize a CustomEvent, you will only get the property isTrusted since class getters are not considered as properties.
Examples:
Object.assign({}, new CustomEvent('test', {detail: 123})) // => { isTrusted: false }JSON.stringify(new CustomEvent('test', {detail: 123})) // => {"isTrusted":false}I assume that react-inspector is doing a serialization or a copy of the original event somewhere before to render it. Resulting in the loss of the other "properties".
I managed to workaround that issue by adding a custom decorator to the addons-actions like this:
// .storybook/helpers/actions.js
import { decorate } from '@storybook/addon-actions';
const eventProperties = [
'bubbles',
'cancelBubble',
'cancelable',
'composed',
'currentTarget',
'defaultPrevented',
'detail',
'eventPhase',
'isTrusted',
'path',
'returnValue',
'srcElement',
'target',
'timeStamp',
'type',
];
const cloneEventObj = (eventObj, overrideObj = {}) => {
class EventCloneFactory {
constructor (override){
for(const prop of eventProperties){
this[prop] = eventObj[prop];
}
for(const prop in override){
this[prop] = override[prop];
}
}
}
EventCloneFactory.prototype.constructor = eventObj.constructor;
return new EventCloneFactory(overrideObj);
}
const uniqueId = (eventName) => `${eventName}-${(new Date()).getTime()}`;
export const customEvent = decorate([args => {
const originalEvent = args[0];
const ev = cloneEventObj(originalEvent, {
id: uniqueId(originalEvent.type),
});
return [ev];
}]);
// story/test.stories.js
import { customEvent } from '../.storybook/helpers/actions';
export default {
title: 'Test',
decorators: [
customEvent.withActions('test'),
],
};
...
There's probably a better way to do that, but at least it works 🤷♂️
thanks @jeremiej-q , it works very well 👏
Here is a solution to this problem: https://stackoverflow.com/questions/13333683/javascript-customevent-detail-not-getting-passed
@shilman @ndelangen the problem in here is the communication between manager and preview:
https://github.com/storybookjs/storybook/blob/next/lib/channel-postmessage/src/index.ts#L77
look at the console screenshot:

and the result in the action console is:

the telejson package get the _constructor_name_ and JSON.stringify did the rest and only return "isTrusted"
https://github.com/storybookjs/telejson/blob/master/src/index.ts#L209
as you can see at @jeremiej-q posts.
i think we can reopen this issue!
edit:
@jeremiej-q your fix didn't work in storybook 6
for telesync i found a solution to get all getter values from event into actions:
https://github.com/storybookjs/telejson/blob/master/src/index.ts#L209
Object.assign(value, {
'_constructor-name_': value.constructor.name,
eventData: JSON.parse(JSON.stringify(value, Object.keys(value.constructor.prototype))),
details: value.detail,
});
will show like this:

cheers
@dutscher what are you recommending here? ☝️
Most helpful comment
After doing a few tries, I discovered that almost all the "properties" of the CustomEvent are actually class getters, the only property is
isTrusted.It means, that if you try to duplicate or serialize a CustomEvent, you will only get the property
isTrustedsince class getters are not considered as properties.Examples:
Object.assign({}, new CustomEvent('test', {detail: 123})) // => { isTrusted: false }JSON.stringify(new CustomEvent('test', {detail: 123})) // => {"isTrusted":false}I assume that react-inspector is doing a serialization or a copy of the original event somewhere before to render it. Resulting in the loss of the other "properties".
I managed to workaround that issue by adding a custom decorator to the addons-actions like this:
There's probably a better way to do that, but at least it works 🤷♂️