fable-compiler / fable-react

Fable bindings and helpers for React and React Native
MIT License
273 stars 67 forks source link

Q: Use ReactElement import member for Storybook #230

Closed rastreus closed 2 years ago

rastreus commented 2 years ago

I am trying to follow Storybook's Default export example.

I have a Count.stories.fs file:

module CountStories

open Fable.Core.JsInterop
open Count

let defaultExport =
    createObj [
        "title" ==> "Count"
        "component" ==> Count.CountComponent
    ]

exportDefault defaultExport

which Fable compiles to the following Count.stories.fs.js file:

import { createElement } from "react";
import { Count_CountComponent_39D2159E } from "./Count.fs.js";

export const defaultExport = {
    title: "Count",
    component: () => createElement(Count_CountComponent_39D2159E, {}),
};

export default defaultExport;

What all do I need to change to get the following output for the Count.stories.fs.js file?

import { Count_CountComponent_39D2159E } from "./Count.fs.js";

export const defaultExport = {
    title: "Count",
    component: Count_CountComponent_39D2159E,
};

export default defaultExport;

Is there a way for the compiled ReactElement to be export const rather than export function?

export const Count_CountComponent_39D2159E = (count_CountComponent_39D2159EInputProps) => {
    // ... implementation
}
export function Count_CountComponent_39D2159E(count_CountComponent_39D2159EInputProps) {
    // ... implementation
}

Any help or advice is appreciated. Thank you.

MangelMaxime commented 2 years ago

Hello @rastreus,

What all do I need to change to get the following output for the Count.stories.fs.js file?

import { Count_CountComponent_39D2159E } from "./Count.fs.js";

export const defaultExport = {
    title: "Count",
    component: Count_CountComponent_39D2159E,
};

export default defaultExport;

Would it work if you had ?

export const defaultExport = {
    title: "Count",
    component: (props) => createElement(Count, props),
};

export default defaultExport;

I am asking because (props) => createElement(Count, props) is just a functional ReactComponent (which is unnamed (I invented this term))


Is there a way for the compiled ReactElement to be export const rather than export function?

Hum, for this one this is actually related to how Fable generates JavaScript.

In theory, function definition inside of a module are unique. I believe you cannot declare twice let test () = () so perhaps it possible generates the export as const but need to make sure that this is always true.

Otherwise, JavaScript will complained about:

Cannot redeclare block-scoped variable 'test'

rastreus commented 2 years ago

@MangelMaxime Thanks for replying. I tried Count.stories.fs again as below. It is working. I must have had something else messed up earlier. Sorry to have taken time out of your day.

module CountStories

open Fable.Core.JsInterop
open Count

let defaultExport =
    createObj [
        "title" ==> "Count"
        "component" ==> Count.CountComponent
    ]

exportDefault defaultExport

let Five () =
    Count.CountComponent ({| Count = 5 |})
MangelMaxime commented 2 years ago

@rastreus No problem, glad that you made it works :)