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
WIP: feat(addon-docs): Angular inline rendering support #11339
Conversation
Awesome start!! Re: dependency management. I’m planning on adjusting the vue dependencies such that vue-to-React is a dependency of |
Thank you! 😄
Sounds like a smart move, thanks for the input! ❓ Otherwise, some questions about addon-docs logic, since I dunno how it works :
💡 The whole point is that I suspect we'll need to have some kind of BeforeAll or AfterAll mechanism to instantiate Angular stories in a statefull way, since we'll need to bootstrap a single Angular app that'll be used to construct every component (not proven yet, but it's one potential way). |
Agree with the idea of keeping it dirty during prototyping, then moving any angular-specific dependencies out later. Re: beforeAll / afterAll, we should be able to add that for angular. There are two relevant story parameters: WDYT? Something like: import React, { useEffect } from 'react';
import { DocsContainer, DocsContainerProps } from '../blocks';
const beforeRender = () => {
console.log('before');
}
const afterRender = () => {
console.log('after');
}
const AngularDocsContainer: FC<DocsContainerProps> = (props) => {
useEffect(() => {
beforeRender();
return afterRender;
});
return <DocsContainer {...props}>;
} |
"@angular/platform-browser-dynamic": "8.2.14", | ||
"reflect-metadata": "0.1.13", | ||
"zone.js": "^0.10.2", | ||
"@angular/core": "^9.1.0" |
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.
Consider using the same version for all @angular
-namespaced packages. I noticed @angular/core is 9, and the rest are 8
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.
Good call, will do soon!
node: HTMLElement, | ||
AppComponentInstance: any | ||
): Promise<NgModuleRef<any>> => { | ||
node.appendChild(document.createElement(SELECTOR)); |
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.
Consider allowing users to pass in their own value for SELECTOR
. When defining angular components, the decorator accepts a selector value. Users may wish to use their own selector value.
import { Component } from '@angular/core';
@Component({
selector: 'app-hero-list', // <-- current code assumes this value === 'app-root'
templateUrl: './hero-list.component.html',
})
export class HeroListComponent {
}
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.
Thanks, that's a good point.
I started integrating your solution directly in Storybook, hoping for some magic to happen.. 🧙
Still permits to talk about how & where to add this logic, but not good enough for testing.
I ended up making a React side-project and successfully applied your solution there.
Currently looking into injecting metadata, then I'll get into selectors.
I'll let you know once I have news about that, gonna focus on this task for the days to come. 😉
schemas: [CUSTOM_ELEMENTS_SCHEMA], | ||
})(class {}); | ||
return platformBrowserDynamic().bootstrapModule(AppModule); | ||
}; |
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.
It's possible users may need to pass in multiple components, in scenarios where a parent Angular component renders a child Angular component. In that case, declarations would need to accept an array of components.
(IIRC) Only the root component should be listed in the bootstrap
array.
Example: Suppose I need to render three components, A
, B
, and C
, and A
is the root component.
AppModule should look like this:
const AppModule = NgModule({
declarations: [A, B, C],
imports: [BrowserModule],
bootstrap: [A],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})(class {});
It could be beneficial to update the bootstrapAngularApp
contract to be more flexible. Example:
const bootstrapAngularApp = (
node: HTMLElement,
- AppComponentInstance: any
+ AppComponentInstance: any,
+ moduleOverrides?: object = {}
): Promise<NgModuleRef<any>> => {
node.appendChild(document.createElement(SELECTOR));
const AppModule = NgModule({
declarations: [AppComponentInstance],
imports: [BrowserModule],
bootstrap: [AppComponentInstance],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
+ ...moduleOverrides
})(class {});
This allows users to completely configure the object passed to the NgModule function.
My original comment (#3889 (comment)) only scratched the surface of what users could possibly need, and my code there represented my individual use case at the time. I ended up needing more, like adding more items to the imports
array.
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.
So glad to see you there @petermikitsh! Was hoping to get some insights from you to achieve this task. 😄
Thanks for coming and for reviewing!
It could be beneficial to update the bootstrapAngularApp contract to be more flexible.
You'r absolutely right! After thinking about it, we simply need to pass anything declared in the story's moduleMetada : All declarations, imports & providers are already there. I'll have to dig into where & how it is used, so that I adapt this logic.
My original comment (#3889 (comment)) only scratched the surface of what users could possibly need
It's already a lot, you know. Even if it's not the complete solution, it's enough to give a direction.. and honestly, without it, I wouldn't dare trying to resolve this.
@shilman Thanks for the hints on implementing a BeforeAll / AfterAll (example greatly appreciated!) Sounds good to me, I'll look further into it when/if the implementation needs to go that way. 😄 |
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! |
How can I help with this? |
Indeed!! Thanks |
Issue: #8153
🚀 This is a first attempt to allow inlining Angular stories in addon-docs.
⚠️ While this is not working yet, it might give birth to discussions permitting to reach that goal.
What I did
What I miss
How to test
Go into the angular-cli storybook, then take any story and display the DocPage.
⚠️ Currently, this results in the following error :
Error: A platform with a different configuration has been created. Please destroy it first. zone-error.js:97
If your answer is yes to any of these, please make sure to include it in your PR.