Skip to content
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

feat: add annotations support for addons #612

Merged
merged 17 commits into from
Nov 1, 2024
Merged
1 change: 1 addition & 0 deletions examples/expo-example/.storybook-web/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const main: ServerStorybookConfig = {
'@storybook/addon-react-native-web',
// note why does this break with get absolute?
'@storybook/addon-react-native-server',
'storybook-addon-deep-controls',
],
// logLevel: 'debug',
framework: getAbsolutePath('@storybook/react-webpack5'),
Expand Down
1 change: 1 addition & 0 deletions examples/expo-example/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const main: StorybookConfig = {
'@storybook/addon-ondevice-backgrounds',
'@storybook/addon-ondevice-actions',
'@storybook/addon-ondevice-notes',
'storybook-addon-deep-controls',
],
reactNative: {
playFn: false,
Expand Down
4 changes: 3 additions & 1 deletion examples/expo-example/.storybook/storybook.requires.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "@storybook/addon-ondevice-controls/register";
import "@storybook/addon-ondevice-backgrounds/register";
import "@storybook/addon-ondevice-actions/register";
import "@storybook/addon-ondevice-notes/register";
import "storybook-addon-deep-controls/register";

const normalizedStories = [
{
Expand Down Expand Up @@ -57,7 +58,8 @@ declare global {
const annotations = [
require("./preview"),
require("@storybook/react-native/preview"),
require("@storybook/addon-actions/preview"),
require("@storybook/addon-ondevice-actions/preview"),
require("storybook-addon-deep-controls/preview"),
];

global.STORIES = normalizedStories;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Meta, StoryObj } from '@storybook/react';
import { Text, View } from 'react-native';

const DeepControls = ({
objectArg,
}: {
objectArg: {
string: string;
number: number;
boolean: boolean;
enumString: string;
nested: { number: number; boolean: boolean };
};
}) => {
return (
<View style={{ gap: 10 }}>
<Text>Testing story with deep controls (storybook-addon-deep-controls)</Text>
<Text>{JSON.stringify(objectArg, null, 2)}</Text>
</View>
);
};

export default {
title: 'DeepControls',
component: DeepControls,
} satisfies Meta<typeof DeepControls>;

export const Basic: StoryObj<typeof DeepControls> = {
parameters: {
deepControls: { enabled: true },
},
args: {
objectArg: {
string: 'foo',
number: 42,
boolean: true,
enumString: 'value2', // we only want specific values for this
nested: {
number: 222,
boolean: false,
},
},
},
argTypes: {
// so we define an argType for the property to use a radio control with specific values
// @ts-expect-error
'objectArg.enumString': {
control: 'radio',
options: ['value1', 'value2', 'value3'],
},

'objectArg.boolean': {
control: 'boolean',
},

'objectArg.number': {
control: 'number',
},

'objectArg.string': {
control: 'text',
},

'objectArg.nested.boolean': {
control: 'boolean',
},

'objectArg.nested.number': {
control: 'number',
},
},
};
1 change: 1 addition & 0 deletions examples/expo-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"react-native-web": "~0.19.13",
"react-router": "^6.26.2",
"storybook": "^8.4.0",
"storybook-addon-deep-controls": "^0.9.2",
"ws": "^8.18.0"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions packages/ondevice-actions/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '@storybook/addon-actions/preview';
1 change: 1 addition & 0 deletions packages/ondevice-actions/src/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '@storybook/addon-actions/preview';
3 changes: 2 additions & 1 deletion packages/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"dev": "npx --yes tsx buildscripts/gendtsdev.ts && tsup --watch",
"prepare": "rm -rf dist/ && tsup",
"test": "jest",
"test:ci": "jest"
"test:ci": "jest",
"test:update": "jest --updateSnapshot"
},
"dependencies": {
"@storybook/core": "^8.4.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import "@storybook/addon-ondevice-controls/register";
import "@storybook/addon-ondevice-backgrounds/register";
import "@storybook/addon-ondevice-actions/register";


const normalizedStories = [{
titlePrefix: "",
directory: "./scripts/mocks/file-extensions",
Expand All @@ -27,7 +28,7 @@ import "@storybook/addon-ondevice-actions/register";
}


const annotations = [require('./preview'),require("@storybook/react-native/preview"), require('@storybook/addon-actions/preview')];
const annotations = [require('./preview'), require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];

global.STORIES = normalizedStories;

Expand Down Expand Up @@ -61,6 +62,7 @@ import "@storybook/addon-ondevice-controls/register";
import "@storybook/addon-ondevice-backgrounds/register";
import "@storybook/addon-ondevice-actions/register";


const normalizedStories = [{
titlePrefix: "ComponentsPrefix",
directory: "./scripts/mocks/configuration-objects/components",
Expand All @@ -77,7 +79,7 @@ import "@storybook/addon-ondevice-actions/register";
}


const annotations = [require('./preview'),require("@storybook/react-native/preview"), require('@storybook/addon-actions/preview')];
const annotations = [require('./preview'), require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];

global.STORIES = normalizedStories;

Expand Down Expand Up @@ -111,6 +113,7 @@ import "@storybook/addon-ondevice-controls/register";
import "@storybook/addon-ondevice-backgrounds/register";
import "@storybook/addon-ondevice-actions/register";


const normalizedStories = [{
titlePrefix: "",
directory: "./scripts/mocks/all-config-files",
Expand All @@ -127,7 +130,7 @@ import "@storybook/addon-ondevice-actions/register";
}


const annotations = [require('./preview'),require("@storybook/react-native/preview"), require('@storybook/addon-actions/preview')];
const annotations = [require('./preview'), require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];

global.STORIES = normalizedStories;

Expand Down Expand Up @@ -161,6 +164,7 @@ import "@storybook/addon-ondevice-controls/register";
import "@storybook/addon-ondevice-backgrounds/register";
import "@storybook/addon-ondevice-actions/register";


const normalizedStories = [{
titlePrefix: "",
directory: "./scripts/mocks/no-preview",
Expand All @@ -177,7 +181,7 @@ import "@storybook/addon-ondevice-actions/register";
}


const annotations = [require("@storybook/react-native/preview"), require('@storybook/addon-actions/preview')];
const annotations = [require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];

global.STORIES = normalizedStories;

Expand Down Expand Up @@ -211,6 +215,7 @@ import "@storybook/addon-ondevice-controls/register";
import "@storybook/addon-ondevice-backgrounds/register";
import "@storybook/addon-ondevice-actions/register";


const normalizedStories = [{
titlePrefix: "",
directory: "./scripts/mocks/all-config-files",
Expand All @@ -222,7 +227,7 @@ import "@storybook/addon-ondevice-actions/register";



const annotations = [require('./preview'),require("@storybook/react-native/preview"), require('@storybook/addon-actions/preview')];
const annotations = [require('./preview'), require("@storybook/react-native/preview"), require('@storybook/addon-ondevice-actions/preview')];

global.STORIES = normalizedStories;

Expand Down
23 changes: 23 additions & 0 deletions packages/react-native/scripts/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,34 @@ function getPreviewExists({ configPath }) {
return !!getFilePathExtension({ configPath }, 'preview');
}

function resolveAddonFile(addon, file, extensions = ['js', 'mjs', 'ts']) {
try {
const basePath = path.join(addon, file);

require.resolve(basePath);

return basePath;
} catch (error) {}

for (const ext of extensions) {
try {
const filePath = path.join(addon, `${file}.${ext}`);

require.resolve(filePath);

return filePath;
} catch (error) {}
}

return null;
}

module.exports = {
toRequireContext,
requireUncached,
getFilePathExtension,
getMain,
ensureRelativePathHasDot,
getPreviewExists,
resolveAddonFile,
};
33 changes: 26 additions & 7 deletions packages/react-native/scripts/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const {
ensureRelativePathHasDot,
getMain,
getPreviewExists,
resolveAddonFile,
} = require('./common');
const { normalizeStories, globToRegexp } = require('@storybook/core/common');
const fs = require('fs');
Expand Down Expand Up @@ -46,14 +47,28 @@ function generate({ configPath, absolute = false, useJs = false }) {
}`;
});

const registerAddons = main.addons?.map((addon) => `import "${addon}/register";`).join('\n');
let registerAddons = '';

const doctools = 'require("@storybook/react-native/preview")';
for (const addon of main.addons) {
const registerPath = resolveAddonFile(addon, 'register', ['js', 'mjs', 'jsx', 'ts', 'tsx']);

// TODO: implement presets or something similar
const enhancer = main.addons?.includes('@storybook/addon-ondevice-actions')
? "require('@storybook/addon-actions/preview')"
: '';
if (registerPath) {
registerAddons += `import "${registerPath}";\n`;
}
}

const docTools = 'require("@storybook/react-native/preview")';

const enhancers = [docTools];

for (const addon of main.addons) {
const previewPath = resolveAddonFile(addon, 'preview', ['js', 'mjs', 'jsx', 'ts', 'tsx']);

if (previewPath) {
enhancers.push(`require('${previewPath}')`);
continue;
}
}

let options = '';
let optionsVar = '';
Expand All @@ -66,7 +81,11 @@ function generate({ configPath, absolute = false, useJs = false }) {

const previewExists = getPreviewExists({ configPath });

const annotations = `[${previewExists ? "require('./preview')," : ''}${doctools}, ${enhancer}]`;
if (previewExists) {
enhancers.unshift("require('./preview')");
}

const annotations = `[${enhancers.join(', ')}]`;

const globalTypes = `
declare global {
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9949,6 +9949,7 @@ __metadata:
react-native-web: "npm:~0.19.13"
react-router: "npm:^6.26.2"
storybook: "npm:^8.4.0"
storybook-addon-deep-controls: "npm:^0.9.2"
typescript: "npm:^5.3.3"
ws: "npm:^8.18.0"
languageName: unknown
Expand Down Expand Up @@ -17498,6 +17499,17 @@ __metadata:
languageName: node
linkType: hard

"storybook-addon-deep-controls@npm:^0.9.2":
version: 0.9.2
resolution: "storybook-addon-deep-controls@npm:0.9.2"
peerDependencies:
"@storybook/addon-controls": 7.x.x || 8.x.x
"@storybook/types": 7.x.x || 8.x.x
storybook: 7.x.x || 8.x.x
checksum: 10/458c401195d34559afd637fdd2fbe5bfe447d5400b80abdd0a600a34a51671d27762c2476b654be45878590eb5124fcf809bafb3cd591abcd92f922fe287db5a
languageName: node
linkType: hard

"storybook@npm:^8.4.0":
version: 8.4.0
resolution: "storybook@npm:8.4.0"
Expand Down