Skip to content

Commit

Permalink
Basic support for Args and Control (closes #7)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinresol committed Oct 14, 2020
1 parent 96bd47f commit 59c7fb7
Show file tree
Hide file tree
Showing 19 changed files with 2,709 additions and 1,596 deletions.
2 changes: 1 addition & 1 deletion .haxerc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": "4.0.5",
"version": "4.1.4",
"resolveLibs": "scoped"
}
2 changes: 1 addition & 1 deletion .storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
stories: ['../bin/demo.js'],
addons: ['@storybook/addon-actions', '@storybook/addon-links', '@storybook/addon-knobs/register'],
addons: ['@storybook/addon-actions', '@storybook/addon-links', '@storybook/addon-controls', '@storybook/addon-knobs/register'],
};
3 changes: 2 additions & 1 deletion demo.hxml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
-js bin/demo.js

-lib coconut.storybook
-lib coconut.vdom
# -lib coconut.vdom
-lib coconut.react-dom

-D analyzer-optimize
8 changes: 8 additions & 0 deletions haxe_libraries/cix.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# @install: lix --silent download "gh://github.com/back2dos/cix#fe9eab0ee9f430de7b13695bc4f00cfb8450f5fd" into cix/0.1.0/github/fe9eab0ee9f430de7b13695bc4f00cfb8450f5fd
-lib mime
-lib tink_color
-lib tink_csss
-lib tink_domspec
-lib tink_macro
-cp ${HAXE_LIBCACHE}/cix/0.1.0/github/fe9eab0ee9f430de7b13695bc4f00cfb8450f5fd/src
-D cix=0.1.0
7 changes: 3 additions & 4 deletions haxe_libraries/coconut.data.hxml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.data#777a1b617fa1fce831c03f428b4c65e5ceb92345" into coconut.data/0.9.0/github/777a1b617fa1fce831c03f428b4c65e5ceb92345
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.data#cfef6e5752ef73791670545fc2598e1bf31f51c4" into coconut.data/0.10.1/github/cfef6e5752ef73791670545fc2598e1bf31f51c4
-lib tink_anon
-lib tink_lang
-lib tink_pure
-lib tink_state
-cp ${HAXE_LIBCACHE}/coconut.data/0.9.0/github/777a1b617fa1fce831c03f428b4c65e5ceb92345/src
-D coconut.data=0.9.0
-cp ${HAXE_LIBCACHE}/coconut.data/0.10.1/github/cfef6e5752ef73791670545fc2598e1bf31f51c4/src
-D coconut.data=0.10.1
--macro coconut.data.macros.Setup.run()
10 changes: 6 additions & 4 deletions haxe_libraries/coconut.react-core.hxml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.react#a6ea79792947ced43364cd5ecbf2dc4e3c687d6a" into coconut.react-core/0.1.0/github/a6ea79792947ced43364cd5ecbf2dc4e3c687d6a
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.react-core#1fb438f54c7dcd273d44e5fcb5da53cb7af9a3fa" into coconut.react-core/0.2.2/github/1fb438f54c7dcd273d44e5fcb5da53cb7af9a3fa
-lib coconut.ui
-lib react-next
-cp ${HAXE_LIBCACHE}/coconut.react-core/0.1.0/github/a6ea79792947ced43364cd5ecbf2dc4e3c687d6a/src
-D coconut.react-core=0.1.0
--macro coconut.react.macros.Setup.all()
-lib tink_priority
-cp ${HAXE_LIBCACHE}/coconut.react-core/0.2.2/github/1fb438f54c7dcd273d44e5fcb5da53cb7af9a3fa/src
-D coconut.react-core=0.2.2
--macro coconut.react.macros.Setup.all()
-D coconut_react_core
1 change: 1 addition & 0 deletions haxe_libraries/coconut.storybook.hxml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-lib tink_lang
-lib coconut.ui
-cp src
-D coconut.storybook=0.0.0
Expand Down
8 changes: 3 additions & 5 deletions haxe_libraries/coconut.ui.hxml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.ui#a2987279f3b189e5a02d31a46837d765250c7ca5" into coconut.ui/0.11.2/github/a2987279f3b189e5a02d31a46837d765250c7ca5
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.ui#d652ccf82776f31303da6de907549612eea211c9" into coconut.ui/0.11.2/github/d652ccf82776f31303da6de907549612eea211c9
-lib coconut.data
-lib tink_anon
-lib tink_hxx
-lib tink_lang
-cp ${HAXE_LIBCACHE}/coconut.ui/0.11.2/github/a2987279f3b189e5a02d31a46837d765250c7ca5/src
-D coconut.ui=0.11.2
-D coconut_ui
-cp ${HAXE_LIBCACHE}/coconut.ui/0.11.2/github/d652ccf82776f31303da6de907549612eea211c9/src
-D coconut.ui=0.11.2
4 changes: 4 additions & 0 deletions haxe_libraries/mime.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-D mime=0.1.2
# @install: lix --silent download "haxelib:/mime#0.1.2" into mime/0.1.2/haxelib
-cp ${HAXE_LIBCACHE}/mime/0.1.2/haxelib/src
--macro mime.Mime.init()
3 changes: 3 additions & 0 deletions haxe_libraries/tink_color.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-D tink_color=1.0.0
# @install: lix --silent download "haxelib:/tink_color#1.0.0" into tink_color/1.0.0/haxelib
-cp ${HAXE_LIBCACHE}/tink_color/1.0.0/haxelib/src
6 changes: 3 additions & 3 deletions haxe_libraries/tink_core.hxml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# @install: lix --silent download "haxelib:/tink_core#1.26.0" into tink_core/1.26.0/haxelib
-cp ${HAXE_LIBCACHE}/tink_core/1.26.0/haxelib/src
-D tink_core=1.26.0
# @install: lix --silent download "gh://github.com/haxetink/tink_core#2a9484c4d6571dcd09b9c9d47d45333eb1ccc377" into tink_core/2.0.0-rc.1/github/2a9484c4d6571dcd09b9c9d47d45333eb1ccc377
-cp ${HAXE_LIBCACHE}/tink_core/2.0.0-rc.1/github/2a9484c4d6571dcd09b9c9d47d45333eb1ccc377/src
-D tink_core=2.0.0-rc.1
6 changes: 3 additions & 3 deletions haxe_libraries/tink_hxx.hxml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @install: lix --silent download "haxelib:/tink_hxx#0.23.0" into tink_hxx/0.23.0/haxelib
# @install: lix --silent download "gh://github.com/haxetink/tink_hxx#a845da38b916d4cbebb7c5aae097c0e6d6167e5f" into tink_hxx/0.24.4/github/a845da38b916d4cbebb7c5aae097c0e6d6167e5f
-lib html-entities
-lib tink_anon
-lib tink_parse
-cp ${HAXE_LIBCACHE}/tink_hxx/0.23.0/haxelib/src
-D tink_hxx=0.23.0
-cp ${HAXE_LIBCACHE}/tink_hxx/0.24.4/github/a845da38b916d4cbebb7c5aae097c0e6d6167e5f/src
-D tink_hxx=0.24.4
6 changes: 3 additions & 3 deletions haxe_libraries/tink_macro.hxml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# @install: lix --silent download "haxelib:/tink_macro#0.19.1" into tink_macro/0.19.1/haxelib
# @install: lix --silent download "gh://github.com/haxetink/tink_macro#0680220a778d8fabd3ad4ce1f3d28375d6d420f6" into tink_macro/0.21.1/github/0680220a778d8fabd3ad4ce1f3d28375d6d420f6
-lib tink_core
-cp ${HAXE_LIBCACHE}/tink_macro/0.19.1/haxelib/src
-D tink_macro=0.19.1
-cp ${HAXE_LIBCACHE}/tink_macro/0.21.1/github/0680220a778d8fabd3ad4ce1f3d28375d6d420f6/src
-D tink_macro=0.21.1
6 changes: 3 additions & 3 deletions haxe_libraries/tink_state.hxml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-D tink_state=0.11.0
# @install: lix --silent download "gh://github.com/haxetink/tink_state#68829f7c2abdf0469404da3f4d8407bbd287aea5" into tink_state/0.11.0/github/68829f7c2abdf0469404da3f4d8407bbd287aea5
# @install: lix --silent download "gh://github.com/haxetink/tink_state#84c7a2f67ea58367748d2bca795b3a2b45f36d3a" into tink_state/1.0.0-beta.1/github/84c7a2f67ea58367748d2bca795b3a2b45f36d3a
-lib tink_core
-cp ${HAXE_LIBCACHE}/tink_state/0.11.0/github/68829f7c2abdf0469404da3f4d8407bbd287aea5/src
-cp ${HAXE_LIBCACHE}/tink_state/1.0.0-beta.1/github/84c7a2f67ea58367748d2bca795b3a2b45f36d3a/src
-D tink_state=1.0.0-beta.1
4 changes: 2 additions & 2 deletions haxe_libraries/tink_syntaxhub.hxml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-D tink_syntaxhub=0.4.3
# @install: lix --silent download "gh://github.com/haxetink/tink_syntaxhub#8b928af11fb39170dcb7254d02923777cddcc678" into tink_syntaxhub/0.4.3/github/8b928af11fb39170dcb7254d02923777cddcc678
-lib tink_priority
-lib tink_macro
-lib tink_priority
-cp ${HAXE_LIBCACHE}/tink_syntaxhub/0.4.3/github/8b928af11fb39170dcb7254d02923777cddcc678/src
-D tink_syntaxhub=0.4.3
--macro tink.SyntaxHub.use()
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.9.6",
"@storybook/addon-actions": "^5.3.18",
"@storybook/addon-knobs": "^5.3.18",
"@storybook/addon-links": "^5.3.18",
"@storybook/addons": "^5.3.18",
"@babel/core": "^7.11.4",
"@storybook/addon-actions": "^6.0.16",
"@storybook/addon-controls": "^6.0.26",
"@storybook/addon-knobs": "^6.0.16",
"@storybook/addon-links": "^6.0.16",
"@storybook/addons": "^6.0.16",
"@storybook/react": "^6.0.26",
"babel-loader": "^8.1.0",
"dts2hx": "^0.9.1",
"storybook-coconut": "^0.0.6"
"dts2hx": "^0.9.1"
},
"scripts": {
"storybook": "start-storybook -p 6006",
Expand Down
81 changes: 80 additions & 1 deletion src/coconut/storybook/Storybook.macro.hx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,84 @@ class Storybook {
if (decorators.length > 0)
merges.push(macro {decorators: $a{decorators}});

// storybook args: https://storybook.js.org/docs/react/writing-stories/args
(function addArgs(type:Type) {
switch type {
case TFun([], _):
case TFun(v, _):
final argsType = v[0].t; // first argument the storybook-provided "args"
final argsCt = argsType.toComplex();
switch argsType.reduce() {
case TAnonymous(_.get() => anon):
final args = [];
final argTypes = [];
final argsObj = EObjectDecl(args); // type inference
final argTypesObj = EObjectDecl(argTypes); // type inference

for (f in anon.fields) {
inline function addArg(e)
args.push({field: f.name, expr: e});
inline function addArgType(e)
argTypes.push({field: f.name, expr: e});

addArg(switch f.meta.extract(':default') {
case []:
macro null;
case [{params: [e]}]:
e;
case [v]:
v.pos.error('@:default meta should have exactly one parameter');
case m:
m[0].pos.error('Multiple @:default meta is not supported');
});

// TODO: add more argType fields: https://storybook.js.org/docs/react/api/argtypes
switch f.meta.extract(':control') {
case [] | [{params: []}]:
// infer control type from haxe type
switch f.type {
case _.getID() => 'String':
addArgType(macro {control: {type: 'text'}});
case _.getID() => 'Bool':
addArgType(macro {control: {type: 'boolean'}});
case _.getID() => 'Int' | 'Float':
addArgType(macro {control: {type: 'number'}});
case TInst(_.get() => {pack: [], name: 'Array'}, [_.getID() => 'String']):
addArgType(macro {control: {type: 'array'}});
case _:
addArgType(macro {control: {type: 'object'}});
}
case [{params: [e = {expr: EConst(CString(v))}]}]:
// treat string literal as control type
addArgType(macro {control: {type: $e}});
case [{params: [e]}]:
// anything else is passed as-is
addArgType(macro {control: $e});
case [v]:
v.pos.error('@:control meta should have at most one parameter');
case m:
m[0].pos.error('Multiple @:control meta is not supported');
}
}

if (args.length > 0 || argTypes.length > 0) {
merges.push(macro {
__isArgsStory: true,
args: (${argsObj.at(field.pos)} : $argsCt), // type check to make sure correctness of default values
argTypes: ${argTypesObj.at(field.pos)},
});
}
case t:
trace(t);
}

case TLazy(f):
addArgs(f());
case t:
field.pos.error('@:story is only applicable to function but got (${t})');
}
})(field.type);

var args = [name, macro @:privateAccess inst.$fname];
if (merges.length > 0)
args.push(macro(tink.Anon.merge($a{merges}) : Dynamic));
Expand Down Expand Up @@ -111,10 +189,11 @@ class Storybook {

return macro {
var storiesOf = js.Lib.require(coconut.storybook.Storybook.getDefaultFramework()).storiesOf;

$b{ret}
};
}

static function getMetaRecursive(c:ClassType, name:String) {
var decorators = c.meta.extract(name);
switch c.superClass {
Expand Down
25 changes: 25 additions & 0 deletions tests/Demo.hx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,37 @@ class Demo {
Storybook.add([
// @formatter:off
new Button(),
new Controls(),
new foo.Bar(),
// @formatter:on
]);
}
}

typedef Args = {
@:default('Foo') final text:String;
@:default('#f00') @:control('color') final color:String;
@:default(1.2) final number:Float;
@:default(['a', 'b', 'c']) final sarray:Array<String>;
@:default([2.1, 3.2, 4.3]) final narray:Array<Float>;
}

class Controls extends Component {
// @formatter:off
@:story
function assorted(args:Args) '
<div>
<p>Text: ${args.text}</p>
<p>Color: <span style=${{display: 'inline-block', width: '20px', height: '20px', backgroundColor: args.color}}/></p>
<p>Number: ${args.number}</p>
<p>String Array: ${haxe.Json.stringify(args.sarray)}</p>
<p>Number Array: ${haxe.Json.stringify(args.narray)}</p>
</div>
';

// @formatter:on
}

@:parameter({note: 'component note'}, foo = 1)
@:parameter(bar = 2)
@:decorator(Knobs.withKnobs)
Expand Down
Loading

0 comments on commit 59c7fb7

Please sign in to comment.