Closed toddpi314 closed 1 year ago
Cc @dannyhw
@toddpi314 Hey this sounds really cool! Could you maybe demo this or provide a video/images? Would love to see what it looks like.
Just a note in the 6.0 alpha we've added support for CSF and the new config style used in web so the integration here might become quite different. Also with 6.0 there is a command for getting all the stories based on the main.js config so the loader won't be necessary.
That being said I'd love to bring this functionality directly into the react native package. Or at least facilitate this. Maybe we can collaborate to make this happen, what do you think?
@toddpi314 Do you think this could fully replace the server? Currently the server is outdated and not working with 6.0 alpha. I've been thinking a lot about a new way of doing the server and this seems like it could have potential. I'm not sure exactly how the native package works though so I'm interested in knowing more about this.
@dannyhw While I am not sure what the full range of use-cases are for server, I personally believe storybook/native
is going to be a game changer. I have used server to speed up story dev, even to drive screenshots with cypress (over detox scaffolding); aside being an accelerator, it didn't ever make it to design system artifacts.
The major advantage I see of storybook/native
is the web-first funnel. The idea that a legacy storybook web team, which is a majority of setup's i've encountered professionally, can drop in React components to interop with connected devices and appetize.io makes this huge. This also would avoid native-only silo'd design systems, when they can just extend web-based.
There are gaps:
storybook/native
's native MVC-style component glue is a nightmare for web teams, even react-native devsUnimoduleStoryRenderer
facade above)Here's what I expect to see as a consumer:
storybook/react-native
OnDeviceUI docs updated to showcase how to automate via a Deep-Linkstorybook/native
examples to use storybook/react-native
as the Device rendererstorybook
(main project) doc updates to help web folks connect the dots on how to opt-in easily to the combined solutionA combined story facade would be a huge commitment on the storybook/react-native
team to keep compatible with core-web add-ons, and to support a deep-link format across. That seems like a huge risk. Basically, the expectations for add-ons so far (ex. @storybook/addon-ondevice-actions
) are probably lower, since those storybook instances are silo'd. Add this to web project, start combining the story facade, and the native add-ons offerings will really be limiting compared to the web ecosystem.
If this general plan sounds ballpark, I can just submit PRs to the respective repositories after getting caught up on the v6.0 setup.
I think that a lot of the pain with "glue" could be solved by using CSF to do things behind the scenes.
I think with web support that could be easier than it seems considering the new addon I've been working on (addon-react-native-web) in which I've had success in using react-native-web with the modern storybook features. Though I'm not sure how much overlap there would be here.
Also big part of 6.0 for stoybook/react-native is the support for the main features like controls, args and CSF which helps to bring things closer to the web.
I'm not sure I understand fully about the combined story facade that you mention, the thing with the react-native addons is that it's always been limited by having to reimplement addons. I'm not sure if its viable to suggest that all addons would be supported however similar to the current solution probably the core ones can be supported.
I think I'd like to see a gradual introduction of these features/documentation and see if people like the idea. From what I can tell nothing with this approach would be breaking right? For example exporting the preview could be a change made to the stable version to make it available already without much fuss.
Probably providing content around this approach would also be good to get some feedback on the idea. Have you written about this somewhere?
Same experience with web-native-web mounted in custom webconfig for storybook-web historically. Works like a charm.
100% agree on the simplicity of CSF being supported on storybook/react-native side. I think the "Story Facade" idea is really just a byproduct of CSF 3.0 no being portable on storybook/react-native@v5.
Since it sounds like a good idea, I'll get a PR up in this repo/examples folder to showcase how it could potentially work on storybook/react-native@v6. Basing it on CSF on both sides (web, native) would simplify it greatly. We can let folks beat up the approach on the PR.
Hey folks! There is an exciting opportunity here to bridge the Storybook/Native solution with the pre-existing OnDeviceUI. I didn't see this publicly documented anywhere, and thought it would be worth sharing so folks can get a picture of how the pieces could potentially fit together.
Native Side
npx -p @storybook/cli sb init --type react_native
DeviceEventManager
import android.content.Intent; import android.net.Uri; import android.os.Bundle; import com.facebook.react.ReactActivity; import com.facebook.react.modules.core.DeviceEventManagerModule;
public class MainActivity extends ReactActivity {
/**
rendering of the component. */ @Override protected String getMainComponentName() { return "storybook"; }
// Support the deep-link @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent);
String link = intent.getStringExtra("component"); Uri data = intent.getData();
// Post the deep-link to the device event manager try { // Note: Also forward the addition args getReactInstanceManager() .getCurrentReactContext() .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("storybookDeepLink", data.getQueryParameter("component")); } catch (Exception e) { // ZARDOZ SPEAKS TO YOU } } }
import {preview} from '@storybook/react-native'; import {DeviceEventEmitter} from 'react-native'; ... const listener = function (deepLink: Event) { preview._selectStoryEvent({storyId: deepLink}); }; DeviceEventEmitter.addListener('storybookDeepLink', listener); ...
Web Side
export default ({ kind, story, component, }: { kind: string, story: string, component: any, }) => { storiesOf(kind, module).add(story, () => UnimoduleStoryRenderer({ component, deepLinkPath: toId(kind, story), }), ); };
// index.native.js // @flow import {Platform} from 'react-native';
export default ({component}: {component: any}) => { return component; };
// index.web.js // @flow import React from 'react'; import {Platform, View} from 'react-native'; import {DeepLinkRenderer} from '@storybook/native-components';
export default ({ extraParams, component, deepLinkPath, }: { deepLinkPath: string, component: any, extraParams: any, }) => { const isOsx = process.platform === 'darwin'; const platforms = ['android']; if (isOsx) { platforms.push('ios'); } return (
); };
UnimoduleStory({ kind: 'Alert', story: 'default', component: (
), });