Open bmayen opened 5 years ago
@bmayen what framework are you using? I'm assuming it isn't react?
If that's correct, see here (particularly read the documentation added in the PR about inline rendering): https://github.com/storybookjs/storybook/pull/7929
Correct, I'm using Angular. So, sounds like while you've done some amazing work for Vue, Angular is still stuck with fixed size iframes for now.
Agreed that wrapping Angular components in Angular Elements seems like the logical next step for prepareForInline
. I have some experience with that so I may be able to contribute here if I can find some time. Thanks for pointing me in the right direction.
@shilman, once prepareForInline
functionality is merged, do you have any thoughts on where support for angular should live? I could open a PR to add an Angular Elements wrapper for this.
@bmayen it's possible that @shilman may have different ideas, but based on the current PR it would logically exist in the addon-docs/preset/angular
folder.
Going to close this and open a new issue to track Angular prepareForInline
support.
I think there are two separate issues. Apparently there are libraries to automatically resize iframes on based on content, and we should support that IN ADDITION TO supporting inline rendering support for angular. Reopening! 😄
Is there a PR open for the automatic resize of iframes for angular? Happy to help contribute.
@herman-rogers that would be awesome! it would need to happen in the storybook UI, which is written in React. Are you ok with that?
@shilman yea that works for me, I've used react pretty extensively.
Since Angular is not mentioned in the title of this issue, I'm not going to open another one.
I've just tried a basic, pristine installation of storybook for HTML and storybook docs. It's extremely annoying to have 500px height on each component preview iframe.
Not sure how much of work is this, but I think it should also support a plain HTML templates.
Screenshot:
@dawidurbanski yeah, this is not angular specific. it's about automatically detecting the size of the contents of an iframe, no matter what its contents are. any interest in taking this on?
@shilman Yes, I'll play around with it and share my thoughts and eventually raise a PR with POC. No promises though.
Any updates? I would say that it is really important feature..
@victorward any interest in contributing it?
@victorward @shilman
I made a simple POC to add this feature but it's not ideal.
First of all, it allows now to set iframeHeight
to auto
in storybook preview.js
parameters. If specified otherwise or not set at all it works as before (defaults to 500px) so it's backwards compatible.
Screen from the html-kitchen-sink
:
There are two problems though:
Addons/Centered
feature (but imho it's the addon fault):It's because it uses fixed positioning and therefore messing with the computed contents height:
I'm looking into fixing the first one, the second one is in my opinion just a matter of documenting this behaviour (saying autoHeight is not compatible with centered addon) or fixing this addon separately.
I'm gonna push the PR as soon as I'm done with it.
@dawidurbanski That's awesome!!! I agree that the centered addon isn't a problem: we're deprecating it in 6.0: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#removed-addon-centered
As for the delayed rendering, there is probably a Storybook event like Events.STORY_RENDERED
you can listen to in order to trigger the code. This will be even more important in 6.1 when we introduce proper asynchronous stories. https://github.com/storybookjs/storybook/pull/11012
@shamin Well, using any api related events would be very difficult in this case I think (but I might be wrong).
First of all I don't think STORY_RENDERED
is aware of async code execution inside stories. It just fires on simple story render regardless of async execution status.
Second problem is that currently docs
addon is not using any component in the render method so I don't have any way to pass api down:
addons.register(ADDON_ID, api => {
addons.add(PANEL_ID, {
type: types.TAB,
title: 'Docs',
route: ({ storyId }) => `/docs/${storyId}`,
match: ({ viewMode }) => viewMode === 'docs',
render: () => null,
});
});
Adding such component is beyond my understanding of how storybook internals work unfortunately. Also I don't think it would help.
I also believe that the only way to make it work is so the story itself is sending an info about the asnyc code completion status.
The solution in my opinion is to force stories using async code (and still wanting to get autoHeight feature) to inform parent renderer window about async code completion by emitting native CustomEvent
that can be handled in the Iframe.tsx
.
So it could look like this (on an example of delayed render story from html-kitchen-sink
):
import { document, parent, setTimeout, CustomEvent } from 'global';
...
export const Story = () => {
const div = document.createElement('div');
setTimeout(() => {
div.innerHTML = `<button>This button has a delayed render of 1s</button>`;
parent.document.dispatchEvent(new CustomEvent('iframeUpdated'));
}, 1000);
return div;
};
Story.story = { name: 'Delayed render' };
This way I can handle updating iframe height in the right moment
Let me know if it's a viable solution, or should I dig deeper into it. Thanks.
One that this possible touches on & that I am currently trying to figure out is a case when you render modals in docs tab. When it's in inline mode, all tabs seem to have all modals rendered at the same time. When I disable the inline mode to render components in iframes, it does render them, but doesn't update when changing args & the modals are too small (ideally I'd like to set a minHeight for the modal on a per-story basis.
@kubijo we'll hopefully get a fix for the iframe args updating here https://github.com/storybookjs/storybook/issues/11908
Automention: Hey @patricklafrance, you've been tagged! Can you give a hand here?
Hey @shilman , @ghengeveld , do we have any news on this? I'm really confused, as the docs suggest this is already possible, I just don't understand how!
I'm happy to lend a hand on the PR to be able to set the height of the iframe in the docsPage, like this:
parameters: {
docs: {
inlineStories: false,
iframe: {
height: '750px'
}
},
@guaiamum you can set the height already using the docs.iframeHeight
parameter. This issue is about making the iframes AUTOMATICALLY resize to fit the content, which is unimplemented.
For context: I've recently been working on dynamically changing an iframe's height based on the story canvas height for the purpose of embedding, by implementing Provider Height Resizing. This can serve as the basis for dynamic canvas height in Docs as we well.
@guaiamum you can set the height already using the
docs.iframeHeight
parameter. This issue is about making the iframes AUTOMATICALLY resize to fit the content, which is unimplemented.
Thanks! I did not find that in the docs, did I miss it or would be a good idea to add it right next to the line I highlighted?
I would really appreciate if you add docs.iframeHeight
to the docs.
On the documentation for DocsPage it says
But using an iframe has disadvantages. For example, you have to set the height of iframe stories explicitly,
But then it does not say how and the only way to find out is too find a semi related github issue which mentions it.
Still not fixed, bump
update on this? @shilman
cc @jreinhold
So in summary there are two issues being discussed here:
parameters.docs.iframeHeight
is undocumented, which is a shame.Anyone is free to pick this up and do a PR for it. @guaiamum's suggestion of where to add it to the docs seems good to me. The gist is:
parameters.docs.iframeHeight
can be a number that defines the min height in pixels - so not "200px"
but just 200
. It defaults to 100
.
I agree that this would improve the DX of iframes in docs. It's non-trivial, because only content within the iframe can know its size, but we want to set it from the outside. I imagine we can inject a script in the iframe that measures the root element and then does a postMessage
to let the docs UI know it's preferred size, after witch the iframe element is resized.
caveats:
For what its worth, I've found issues forcing a height on a story. When adding a height:
<Canvas>
<Story story={stories.Default} height="70px" />
</Canvas>
Storybook is generating this CSS:
#story--components-textarea--default {
min-height: 70px;
transform: translateZ(0);
overflow: auto;
}
That overflow: auto;
is breaking my focus outlines:
Is your feature request related to a problem? Please describe. Sometimes the component being displayed in Docs is only a few px tall, yet the iframe defaults to 500px. When you have a lot of these stories stacked, there is a lot of empty space.
Describe the solution you'd like After iframe loads, have it resize to fit the content
Describe alternatives you've considered Can set styles to manually override the iframe height per-story, but this is difficult/tedious to maintain