fable-compiler / fable-react

Fable bindings and helpers for React and React Native
MIT License
275 stars 66 forks source link

How to import react elements as members of other elements #60

Closed Zaid-Ajaj closed 6 years ago

Zaid-Ajaj commented 6 years ago

Concretely, suppose you have the following in javascript (which seems quite common):

import { Select } from 'react-select' 
let render = () => <Select.Creatable options={...} /> 

How to import the Creatable element from the Select component?

alfonsogarciacaro commented 6 years ago

It's funny that you asked that, because in Fable 1.x you can use a . to select a member when importing a value, like:

ofImport "Select.Creatable" "react-select" myOptions []

...but exactly right now I just removed it from Fable 2 because I thought nobody was using it 😅Can you give it a try and check if it works for you? If it does, I guess I should put it back in dev2.0 :wink:

Zaid-Ajaj commented 6 years ago

I tried just now it but it didn't work with my example and I am not sure why. I have this function:

let creatable (props: ICreatableProps list) = 
    ofImport "Select.Creatable"
             "react-select"
             (keyValueList CaseRules.LowerFirst props)
             [] 

I get runtime error: Cannot read property Creatable of undefined and also a compile warning export 'Select' was not found in 'react-select' which is weird because I have installed react-select correctly. Now even if I change Select.Creatable to Select I get the same warning . . . strange.

Anyways, if you are thinking of removing this pattern completely, their should be alternative way to do it because major UI frameworks (Elemental/Material/Semantic...) use this nesting to group elements.

I guess the reason no one is using this feature is because no one has tried yet to port these large frameworks.

alfonsogarciacaro commented 6 years ago

This is the usual confusion with JS imports :wink: According to react-select README, it must be imported as follows:

import Select from 'react-select';

This is a default import (not a member import like import { Select } from 'react-select'). For this, in Fable you just have to write "default". Can you try the following?

let creatable (props: ICreatableProps list) = 
    ofImport "default.Creatable" "react-select"
             (keyValueList CaseRules.LowerFirst props)
             [] 
Zaid-Ajaj commented 6 years ago

Wow facepalm hahah, this worked like a charm! thanks a lot :heart:

alfonsogarciacaro commented 6 years ago

Don't worry, I've made the same mistake thousands of times. Unfortunately, it's not something Fable can check at compile time :/ We need to make it more prominent in the docs.

Thanks for confirming it's working! I'll put back the feature in Fable 2 :+1:

realvictorprm commented 6 years ago

@alfonsogarciacaro would it be worth to note this somewhere on this repository? Aka a FAQ ;)

alfonsogarciacaro commented 6 years ago

@realvictorprm You're right. This feature is not documented, we should add it in the doc section talking about imports :+1:

realvictorprm commented 6 years ago

I'm going to add some notes.

realvictorprm commented 6 years ago

done