Skip to content

Commit

Permalink
feat: broadcast messages for controls values to manager
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Apr 2, 2020
1 parent 57bf0c1 commit 7b31a84
Show file tree
Hide file tree
Showing 13 changed files with 131 additions and 13 deletions.
3 changes: 1 addition & 2 deletions examples/storybook-6/.storybook/preview.js
@@ -1,12 +1,11 @@
import React from 'react'
import { addDecorator, addParameters } from '@storybook/react';
import { ThemeProvider, BlockContextProvider } from '@component-controls/storybook';
import { ControlsTable, Title, Subtitle, Story, Playground, Stories, Description, StorySource, ComponentSource, PropsTable } from '@component-controls/blocks';
import { ControlsTable, Title, Subtitle, Story, Playground, Stories, Description, ComponentSource, PropsTable } from '@component-controls/blocks';

addDecorator((story, ctx ) => {
return (
<ThemeProvider>
{console.log(ctx)}
{story(ctx)}
</ThemeProvider>
);
Expand Down
1 change: 1 addition & 0 deletions integrations/storybook/package.json
Expand Up @@ -38,6 +38,7 @@
"@component-controls/editors": "^0.6.0",
"@component-controls/loader": "^0.6.0",
"@component-controls/specification": "^0.6.0",
"broadcast-channel": "^3.1.0",
"core-js": "^3.0.1",
"global": "^4.3.2",
"polished": "^3.4.4",
Expand Down
8 changes: 6 additions & 2 deletions integrations/storybook/src/config.ts
@@ -1,12 +1,16 @@
import { addDecorator } from '@storybook/client-api';
import { makeDecorator } from '@storybook/addons';
import { controlsMessages } from './context/BroadcastMessage';

addDecorator(
makeDecorator({
name: 'legacyControls',
name: 'componnet-controls',
parameterName: 'controls',
wrapper: (storyFn, context) => {
return storyFn(context);
console.log(controlsMessages);
const values = controlsMessages && controlsMessages[context.id];
//@ts-ignore
return values ? storyFn(values, context) : storyFn(context);
},
}),
);
14 changes: 13 additions & 1 deletion integrations/storybook/src/context/BlockContext.tsx
@@ -1,11 +1,23 @@
import React from 'react';
import addons from '@storybook/addons';
import { FORCE_RE_RENDER } from '@storybook/core-events';
import { BlockContextProvider as BlocksContextProvider } from '@component-controls/blocks';
import { DocsContext } from '@storybook/addon-docs/blocks';

export const BlockContextProvider: React.FC = ({ children }) => {
const context = React.useContext(DocsContext);
const channel = React.useMemo(() => addons.getChannel(), []);
const { id } = context as any;
const onRefresh = () => channel.emit(FORCE_RE_RENDER);

// this._channel.emit(Events.FORCE_RE_RENDER);
return (
<BlocksContextProvider currentId={id}>{children}</BlocksContextProvider>
<BlocksContextProvider
currentId={id}
onRefresh={onRefresh}
postMessage={true}
>
{children}
</BlocksContextProvider>
);
};
12 changes: 12 additions & 0 deletions integrations/storybook/src/context/BroadcastMessage.ts
@@ -0,0 +1,12 @@
import { BroadcastChannel } from 'broadcast-channel';
import { UPDATE_CONTROLS_MESSAGE } from '@component-controls/blocks';

const channel = new BroadcastChannel(UPDATE_CONTROLS_MESSAGE);

interface ControlsMessages {
[id: string]: any;
}
export const controlsMessages: ControlsMessages = {};
channel.onmessage = (message: { id: string; values: any }) => {
controlsMessages[message.id] = message.values;
};
2 changes: 2 additions & 0 deletions integrations/storybook/src/context/index.ts
@@ -0,0 +1,2 @@
export * from './BlockContext';
export * from './ThemeProvider';
3 changes: 1 addition & 2 deletions integrations/storybook/src/index.ts
@@ -1,3 +1,2 @@
export { ThemeProvider } from './context/ThemeProvider';
export * from './context/BlockContext';
export * from './context';
export * from './blocks';
1 change: 1 addition & 0 deletions ui/blocks/package.json
Expand Up @@ -35,6 +35,7 @@
"@component-controls/editors": "^0.6.0",
"@component-controls/specification": "^0.6.0",
"@storybook/csf": "^0.0.1",
"broadcast-channel": "^3.1.0",
"copy-to-clipboard": "^3.2.1",
"global": "^4.3.2",
"js-string-escape": "^1.0.1",
Expand Down
36 changes: 32 additions & 4 deletions ui/blocks/src/context/block/BlockContext.tsx
@@ -1,4 +1,5 @@
import React from 'react';
import React, { useEffect, useState } from 'react';

import storyFn from '@component-controls/loader/story-store-data';
import {
StoriesStore,
Expand All @@ -7,6 +8,7 @@ import {
ComponentControlButton,
} from '@component-controls/specification';
import { mergeControlValues } from '@component-controls/core';
import { postControlsMsg } from './channel';

export interface BlockContextInputProps {
/**
Expand All @@ -17,6 +19,15 @@ export interface BlockContextInputProps {
* store mockup when running tests
*/
mockStore?: StoriesStore;
/**
* optional cllabel to invoke when the story data are changed
* for example when controls values are updated
*/
onRefresh: () => void;
/**
* when set to true, the BlockCOntext will broadcast a message for changed controls values
*/
postMessage?: boolean;
}

export interface BlockContextProps {
Expand Down Expand Up @@ -45,17 +56,28 @@ export const BlockContextProvider: React.FC<BlockContextInputProps> = ({
children,
currentId,
mockStore,
onRefresh,
postMessage,
}) => {
const [store, setStore] = React.useState<StoriesStore>(
const [store, setStore] = useState<StoriesStore>(
mockStore || {
components: {},
stories: {},
kinds: {},
},
);
React.useEffect(() => {
useEffect(() => {
if (mockStore === undefined) {
setStore(storyFn());
const store = storyFn();
if (postMessage) {
Object.keys(store.stories).forEach(id => {
postControlsMsg({ id, controls: store.stories[id].controls });
});
if (onRefresh) {
onRefresh();
}
}
setStore(store);
}
}, []);
const setControlValue: SetControlValueFn = (
Expand All @@ -67,13 +89,19 @@ export const BlockContextProvider: React.FC<BlockContextInputProps> = ({
store && store.stories[storyId] && store.stories[storyId].controls;
if (controls) {
const newValues = mergeControlValues(controls, propName, propValue);
if (postMessage) {
postControlsMsg({ id: storyId, controls: newValues });
}
setStore({
...store,
stories: {
...store.stories,
[storyId]: { ...store.stories[storyId], controls: newValues },
},
});
if (onRefresh) {
onRefresh();
}
}
};
const clickControl: ClickControlFn = (storyId: string, propName: string) => {
Expand Down
15 changes: 15 additions & 0 deletions ui/blocks/src/context/block/channel.ts
@@ -0,0 +1,15 @@
import { BroadcastChannel } from 'broadcast-channel';
import {
LoadedComponentControls,
getControlValues,
} from '@component-controls/core';
import { UPDATE_CONTROLS_MESSAGE } from './consts';

const channel = new BroadcastChannel(UPDATE_CONTROLS_MESSAGE);

interface ControlsMessage {
id: string;
controls: LoadedComponentControls;
}
export const postControlsMsg = ({ id, controls }: ControlsMessage) =>
controls && channel.postMessage({ id, values: getControlValues(controls) });
1 change: 1 addition & 0 deletions ui/blocks/src/context/block/consts.ts
@@ -0,0 +1 @@
export const UPDATE_CONTROLS_MESSAGE = 'component-controls-channel';
1 change: 1 addition & 0 deletions ui/blocks/src/context/block/index.ts
@@ -1 +1,2 @@
export * from './BlockContext';
export * from './consts';
47 changes: 45 additions & 2 deletions yarn.lock
Expand Up @@ -1371,7 +1371,7 @@
dependencies:
regenerator-runtime "^0.13.4"

"@babel/runtime@^7.8.4":
"@babel/runtime@^7.6.2", "@babel/runtime@^7.8.4":
version "7.9.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06"
integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==
Expand Down Expand Up @@ -5428,6 +5428,11 @@ before-after-hook@^2.0.0:
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==

big-integer@^1.6.16:
version "1.6.48"
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e"
integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==

big.js@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
Expand Down Expand Up @@ -5540,6 +5545,19 @@ braces@^3.0.1, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"

broadcast-channel@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.1.0.tgz#b4a6970fc72c4d68fc859321a6af850e66cb2dfa"
integrity sha512-zrjTunJRva1aFW9UlLtoMnB05tu8hbb7qbv3PxXXGnxp3t9VA/KcTIwcC0+u7oLBdlXSnv0yy7pB+UemLjANyQ==
dependencies:
"@babel/runtime" "^7.7.2"
detect-node "^2.0.4"
js-sha3 "0.8.0"
microseconds "0.2.0"
nano-time "1.0.0"
rimraf "3.0.2"
unload "2.2.0"

brorand@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
Expand Down Expand Up @@ -10780,6 +10798,11 @@ jquery@^3.4.1:
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2"
integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==

js-sha3@0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==

js-string-escape@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef"
Expand Down Expand Up @@ -11838,6 +11861,11 @@ micromatch@^4.0.2:
braces "^3.0.1"
picomatch "^2.0.5"

microseconds@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39"
integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==

miller-rabin@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
Expand Down Expand Up @@ -12114,6 +12142,13 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==

nano-time@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef"
integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=
dependencies:
big-integer "^1.6.16"

nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
Expand Down Expand Up @@ -15123,7 +15158,7 @@ rimraf@2.6.3, rimraf@~2.6.2:
dependencies:
glob "^7.1.3"

rimraf@^3.0.0:
rimraf@3.0.2, rimraf@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
Expand Down Expand Up @@ -17001,6 +17036,14 @@ universalify@^0.1.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==

unload@2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7"
integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==
dependencies:
"@babel/runtime" "^7.6.2"
detect-node "^2.0.4"

unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
Expand Down

0 comments on commit 7b31a84

Please sign in to comment.