Skip to content

Commit

Permalink
feat: added props table panel
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Apr 23, 2020
1 parent cf6d001 commit f051248
Show file tree
Hide file tree
Showing 20 changed files with 286 additions and 133 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- [Roadmap](#roadmap)
- [Integrations](#integrations)
- [@component-controls/storybook](#component-controlsstorybook)
- [storybook integration of component-controls.](#storybook-integration-of-component-controls)
- [Motivation](#motivation-1)
- [Limitations](#limitations)
- [Core packages](#core-packages)
Expand Down Expand Up @@ -74,7 +75,11 @@ There are many developments that have contributed to the creation of `component-

Storybook Addon For live editing of component controls

The Storybook](<https://storybook.js.org>) integration of component-controls.
### [storybook](https://storybook.js.org) integration of component-controls.

<p align="center">
<img src="./images/component-controls.gif" alt="introduction to using component-controls" width="738">
</p>

### Motivation

Expand Down
37 changes: 19 additions & 18 deletions core/store/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,25 @@ $ npm install @component-controls/store --save-dev

Store class used to query the stories and exchange information between processes

_defined in [@component-controls/store/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/store/src/index.ts#L29)_
_defined in [@component-controls/store/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/store/src/index.ts#L33)_



### properties

| Name | Type | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `constructor*` | **function** constructor | create a store with options |
| `addObserver*` | **function** addObserver(`observer`\*: [StoreObserver](#storeobserver)): number; | add observer callback function |
| `getStore*` | **function** getStore(): [StoriesStore](#storiesstore); | returns an instance of the store |
| `getStory*` | **function** getStory(`storyId`\*: string): [Story](#story); | given a story id return a story from the store |
| `removeObserver*` | **function** removeObserver(`observer`\*: [StoreObserver](#storeobserver)): **function** (`storyId`: string): void;\[]; | remove installed observer callback function |
| `setStore*` | **function** setStore(`store`: [StoriesStore](#storiesstore)): void; | internal set store, use for testing with mockup store. |
| `updateStoryProp*` | **function** updateStoryProp(`storyId`\*: string, `propName`\*: string, `newVal`\*: any): [StoriesStore](#storiesstore) \| undefined; | modify story properties, for example controls values. will notify all installed store observers of the changed story. |
| Name | Type | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `constructor*` | **function** constructor | create a store with options |
| `addObserver*` | **function** addObserver(`observer`\*: [StoreObserver](#storeobserver)): number; | add observer callback function |
| `getStore*` | **function** getStore(): [StoriesStore](#storiesstore); | returns an instance of the store |
| `getStory*` | **function** getStory(`storyId`\*: string): [Story](#story); | given a story id return a story from the store |
| `removeObserver*` | **function** removeObserver(`observer`\*: [StoreObserver](#storeobserver)): **function** (`storyId`: string, `propName`: string): void;\[]; | remove installed observer callback function |
| `setStore*` | **function** setStore(`store`: [StoriesStore](#storiesstore)): void; | internal set store, use for testing with mockup store. |
| `updateStoryProp*` | **function** updateStoryProp(`storyId`\*: string, `propName`\*: string, `newValue`\*: any): [StoriesStore](#storiesstore) \| undefined; | modify story properties, for example controls values. will notify all installed store observers of the changed story. |

## StoreOptions

_defined in [@component-controls/store/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/store/src/index.ts#L16)_
_defined in [@component-controls/store/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/store/src/index.ts#L20)_



Expand All @@ -64,13 +64,13 @@ _defined in [@component-controls/store/src/index.ts](https://github.com/ccontrol

store variable, automatically filled with stories.

_defined in [@component-controls/store/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/store/src/index.ts#L148)_
_defined in [@component-controls/store/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/store/src/index.ts#L142)_



## stores

_defined in [@component-controls/store/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/store/src/index.ts#L150)_
_defined in [@component-controls/store/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/store/src/index.ts#L144)_



Expand All @@ -82,13 +82,14 @@ so they can re-load the stories

_defined in [@component-controls/store/src/types.ts](https://github.com/ccontrols/component-controls/tree/master/core/store/src/types.ts#L8)_

**function** (`storyId`: string): void;
**function** (`storyId`: string, `propName`: string): void;

### parameters

| Name | Type | Description |
| --------- | ------ | ----------- |
| `storyId` | string | |
| `returns` | void | |
| Name | Type | Description |
| ---------- | ------ | ----------- |
| `storyId` | string | |
| `propName` | string | |
| `returns` | void | |

<!-- END-TSDOC-TYPESCRIPT -->
67 changes: 28 additions & 39 deletions core/store/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import {
StoryStore,
MessageType,
UPDATE_STORY_MSG,
COMPONENT_CONTROLS_STORAGE,
} from './types';
import {
saveStore,
readStore,
updateStory,
} from './serialization/StoreStorage';

export { StoreObserver, StoryStore };

Expand Down Expand Up @@ -45,11 +49,11 @@ export class Store implements StoryStore {
type: 'localstorage',
});
this.observers = [];
this.channel.onmessage = ({ storyId, moduleId }: MessageType) => {
this.channel.onmessage = ({ storyId, moduleId, propName }: MessageType) => {
if (storyId && moduleId) {
if (this.moduleId !== moduleId) {
this.readData(storyId);
this.notifyObservers(storyId);
this.readData(storyId, propName);
this.notifyObservers(storyId, propName);
}
}
};
Expand All @@ -65,9 +69,9 @@ export class Store implements StoryStore {
removeObserver = (observer: StoreObserver) =>
(this.observers = this.observers.filter(o => o !== observer));

private notifyObservers = (storyId?: string) => {
private notifyObservers = (storyId?: string, propName?: string) => {
if (this.observers.length > 0) {
this.observers.forEach(observer => observer(storyId));
this.observers.forEach(observer => observer(storyId, propName));
}
};

Expand All @@ -78,23 +82,10 @@ export class Store implements StoryStore {
this.loadedStore = store;
this.notifyObservers();
};
private readData = (storyId?: string) => {
const data = localStorage.getItem(COMPONENT_CONTROLS_STORAGE);
if (data) {
try {
const newStore = JSON.parse(data) as StoriesStore;

if (this.loadedStore && storyId) {
this.loadedStore.stories[storyId] = {
...this.loadedStore.stories[storyId],
controls: { ...newStore.stories[storyId].controls },
};
} else {
this.loadedStore = newStore;
}
} catch (e) {}
}
private readData = (storyId?: string, propName?: string) => {
this.loadedStore = readStore(this.loadedStore, storyId, propName);
};

/**
* returns an instance of the store
*/
Expand Down Expand Up @@ -122,22 +113,25 @@ export class Store implements StoryStore {
updateStoryProp = (
storyId: string,
propName: string,
newVal: any,
newValue: any,
): StoriesStore | undefined => {
this.loadedStore = updateStory(
this.loadedStore,
storyId,
propName,
newValue,
this.updateLocalStorage,
);
if (this.loadedStore) {
this.loadedStore.stories[storyId] = {
...this.loadedStore.stories[storyId],
[propName]: newVal,
};
if (this.updateLocalStorage) {
localStorage.setItem(
COMPONENT_CONTROLS_STORAGE,
JSON.stringify(this.loadedStore),
);
const message: MessageType = { storyId, moduleId: this.moduleId };
const message: MessageType = {
storyId,
moduleId: this.moduleId,
propName,
};
this.channel.postMessage(message);
}
this.notifyObservers(storyId);
this.notifyObservers(storyId, propName);
}
return this.loadedStore;
};
Expand All @@ -150,10 +144,5 @@ export const store = new Store();
const stores = loadStoryStore();
if (stores) {
store.setStore(stores);
for (var key in localStorage) {
if (key.indexOf(COMPONENT_CONTROLS_STORAGE) == 0) {
localStorage.removeItem(key);
}
}
localStorage.setItem(COMPONENT_CONTROLS_STORAGE, JSON.stringify(stores));
saveStore(stores);
}
78 changes: 78 additions & 0 deletions core/store/src/serialization/StoreStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
StoriesStore,
getComponentName,
} from '@component-controls/specification';

import { COMPONENT_CONTROLS_STORAGE } from '../types';

const encodeFn = (name: string, val: any) => {
// convert RegExp to string
if (val && val.constructor === RegExp) {
return val.toString();
} else if (name === 'component') {
//serialize components as string of their name
const component = getComponentName(val);
return component ? component : val;
}
return val;
};
export const saveStore = (store: StoriesStore) => {
for (var key in localStorage) {
if (key.indexOf(COMPONENT_CONTROLS_STORAGE) == 0) {
localStorage.removeItem(key);
}
}
localStorage.setItem(
COMPONENT_CONTROLS_STORAGE,
JSON.stringify(store, encodeFn),
);
};

export const readStore = (
store?: StoriesStore,
storyId?: string,
propName?: string,
): StoriesStore | undefined => {
const data = localStorage.getItem(COMPONENT_CONTROLS_STORAGE);
if (data) {
const newStore = JSON.parse(data) as StoriesStore;
if (store && storyId && propName) {
const newValue = (newStore.stories[storyId] as any)[propName];
store.stories = {
...store.stories,
[storyId]: {
...store.stories[storyId],
[propName]: newValue,
},
};
return store;
}
return newStore;
}
return store;
};

export const updateStory = (
store: StoriesStore | undefined,
storyId: string,
propName: string,
newValue: any,
updateLocalStorage?: boolean,
): StoriesStore | undefined => {
if (store) {
store.stories = {
...store.stories,
[storyId]: {
...store.stories[storyId],
[propName]: newValue,
},
};
if (updateLocalStorage) {
localStorage.setItem(
COMPONENT_CONTROLS_STORAGE,
JSON.stringify(store, encodeFn),
);
}
}
return store;
};
3 changes: 2 additions & 1 deletion core/store/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { StoriesStore, Story } from '@component-controls/specification';
* when updateStoryProp is called on the store, the store observers will be notified
* so they can re-load the stories
*/
export type StoreObserver = (storyId?: string) => void;
export type StoreObserver = (storyId?: string, propName?: string) => void;

export interface StoryStore {
getStore: () => StoriesStore | undefined;
Expand All @@ -25,4 +25,5 @@ export const COMPONENT_CONTROLS_STORAGE = 'component-controls-store-data';
export interface MessageType {
storyId: string;
moduleId: number;
propName: string;
}
22 changes: 18 additions & 4 deletions core/webpack-rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [getRules](#getrules)
- [ruleMerge](#rulemerge)
- [rulesFactory](#rulesfactory)
- [RuleOptions](#ruleoptions)
- [RuleType](#ruletype)
- [RuleTypes](#ruletypes)
- [WebpackRule](#webpackrule)
Expand Down Expand Up @@ -55,7 +56,7 @@ _defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/

expands the rules into webpack rules

_defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/index.ts#L31)_
_defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/index.ts#L33)_

**function** getRules(`rules`\*: [RuleType](#ruletype)\[]): [WebpackRules](#webpackrules);

Expand Down Expand Up @@ -94,15 +95,28 @@ _defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/
| `react-docgen*` | [RuleSetRule](#rulesetrule)\[] | |
| `react-docgen-typescript*` | [RuleSetRule](#rulesetrule)\[] | |

## RuleType
## RuleOptions

_defined in [@component-controls/webpack-rules/src/types.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/types.ts#L6)_

[WebpackRule](#webpackrule) | string | **options**: [WebpackRules](#webpackrules)**rules**: [RuleTypes](#ruletypes)


### properties

| Name | Type | Description |
| -------- | ----------------------------- | ----------- |
| `name*` | string | |
| `rules*` | [WebpackRules](#webpackrules) | |

## RuleType

_defined in [@component-controls/webpack-rules/src/types.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/types.ts#L10)_

[WebpackRule](#webpackrule) | string | [RuleOptions](#ruleoptions)

## RuleTypes

_defined in [@component-controls/webpack-rules/src/types.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/types.ts#L14)_
_defined in [@component-controls/webpack-rules/src/types.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/types.ts#L12)_

[RuleType](#ruletype)\[]

Expand Down
8 changes: 7 additions & 1 deletion examples/storybook-6/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ module.exports = {
configureJSX: true,
},
},
'@component-controls/storybook',
{
name: '@component-controls/storybook',
options: {
controlsPanel: true,
propsPanel: true,
}
}
],
};
Loading

0 comments on commit f051248

Please sign in to comment.