-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic addon decorators #3555
Generic addon decorators #3555
Changes from all commits
f330011
3861711
6f78c12
0ecf66e
f9e946e
09225c2
7cbadb1
bb5c62f
2e30aeb
f779598
b94155e
c15b9da
2889076
56f30e7
24fe256
34f0c53
2557bc6
06101ef
7b19079
a36f35d
ef03d22
da9990e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,37 @@ | ||
import { document } from 'global'; | ||
import axe from 'axe-core'; | ||
import addons from '@storybook/addons'; | ||
import Events from '@storybook/core-events'; | ||
import { logger } from '@storybook/client-logger'; | ||
|
||
import A11yManager from './A11yManager'; | ||
import * as shared from './shared'; | ||
import { CHECK_EVENT_ID, RERUN_EVENT_ID } from './shared'; | ||
|
||
const manager = new A11yManager(); | ||
let axeOptions = {}; | ||
|
||
function checkA11y(storyFn, context) { | ||
export const configureA11y = (options = {}) => { | ||
axeOptions = options; | ||
}; | ||
|
||
const runA11yCheck = () => { | ||
const channel = addons.getChannel(); | ||
return manager.wrapStory(channel, storyFn, context, axeOptions); | ||
} | ||
const wrapper = document.getElementById('root'); | ||
|
||
function configureA11y(options = {}) { | ||
axeOptions = options; | ||
} | ||
axe.reset(); | ||
axe.configure(axeOptions); | ||
axe.run(wrapper).then(results => channel.emit(CHECK_EVENT_ID, results), logger.error); | ||
}; | ||
|
||
const a11ySubscription = () => { | ||
const channel = addons.getChannel(); | ||
channel.on(Events.STORY_RENDERED, runA11yCheck); | ||
channel.on(RERUN_EVENT_ID, runA11yCheck); | ||
return () => { | ||
channel.removeListener(Events.STORY_RENDERED, runA11yCheck); | ||
channel.removeListener(RERUN_EVENT_ID, runA11yCheck); | ||
}; | ||
}; | ||
|
||
export { checkA11y, shared, configureA11y }; | ||
export const checkA11y = story => { | ||
addons.getChannel().emit(Events.REGISTER_SUBSCRIPTION, a11ySubscription); | ||
return story(); | ||
}; |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
module.exports = require('./dist/mithril'); | ||
module.exports = require('./dist/deprecated'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can keep those files for one alpha release |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import deprecate from 'util-deprecate'; | ||
|
||
import backgrounds from '.'; | ||
|
||
export default deprecate( | ||
backgrounds, | ||
"addon-backgrounds: framework-specific imports are deprecated, just use `import backgrounds from '@storybook/addon-backgrounds`" | ||
); |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the pattern we want to encourage?
I feel like it is more inflexible than we might like, i.e it means stories can only ever be rendered in
#root
, whereas there are other conceivable ways you might want to render a story.Could we instead do something like:
Not sure if that's the best API, but does the idea make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, will try something like
STORY_RENDERED
eventNot sure that I get what you mean by other ways to render a story though. The current setup with
showMain
etc expects that everything you render is inside#root
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess what I mean is that at the moment you can call
const story = getStory()
on the story store and then execute that function to get something renderable (how you render that depends on the view layer of course). At the moment that function is also wrapped in the relevant decorators and those decorators will work however the story is rendered.At the moment the only place a story is rendered is to the
#root
via therenderMain
function, but other ways you might want to render a story is e.g. inside some<Story/>
element in a documentation site.Maybe I'm overthinking it, we would need to think about how decorators/addons make sense in that context a bit anyway, but it's something I think we will want to do in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a pattern we could support in SBNext
CC @ndelangen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added
STORY_RENDERED
event to avoidsetTimeout(fn, 0)
, but I decided to keep#root
part for now. Most of the addons, including a11y, have manager part, so they are unusable outside of storybook context. So I think that gettingrootEl
dynamically would bring more complexity than value right nowThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WFM, thanks for talking through it with me.