How do I get intellisense to work inside es6 classes? - visual-studio-code

I have a class that extends React. Component like so:
class Main extends Component {
static propTypes = {
flavor: string.isRequired,
iceCreamMap: object.isRequired,
restUrl: string.isRequired,
token: string.isRequired,
username: string.isRequired
};
}
I want the methods of Component.prototype to show up in intellisense but it is not working. It however will work when I do. React.Component.prototype.

Related

Custom Material UI theme not picked up in emotion component

Im implementing a mui theme through createStyles via `
import { createTheme, ThemeProvider } from '#mui/material/styles'
which looks something like
createTheme({
...other stuff
borders: { ... }
})
The theme gets created fine, and when using useTheme in a child component im able to see the custom borders object. However when logging the same from within the styled emotion component, it removes the non standard keys:
const t = useTheme()
console.log('t===',t)
const S = styled('div')`
backgroud-color: ${props => {
console.log('inside----', props.theme)
return 'red'
}}`
t=== logs fine with the borders
inside---- logs with the theme but without borders attached
Ive tried importing styled from #mui/material instead of #emotion/styled and both do the same.
Ive also created a theme.d.ts for defining the custom theme via module augmentation but that also doesnt assis
declare module '#mui/material/styles' {
interface CustomTheme {
borders?: {
lrg: any;
};
}
interface Theme extends CustomTheme {}
interface ThemeOptions extends CustomTheme {}
}
does anyone have any ideas?

AngularDart structural directive add custom content

Is there some chance to simple update _viewContainer??
I am trying create directive for material-button component, that add hidden classic button for submit form by hit enter key. I need to add simple html to _viewContainer, something like this
import 'package:angular/angular.dart';
#Directive(
selector: '[kpMaterialSubmit]',
)
class KpMaterialSubmit {
final TemplateRef _templateRef;
final ViewContainerRef _viewContainer;
KpMaterialSubmit(this._viewContainer, this._templateRef);
#Input()
set kpMaterialSubmit(bool showButton) {
_viewContainer.clear();
if (showButton) {
_viewContainer.createEmbeddedView(_templateRef);
//THIS IS THE IMPORTANT PART
_viewContainer.createMyCustomView('<button class="hidden">Submit</button>');
} else {
_viewContainer.createEmbeddedView(_templateRef);
}
}
}
I have done something similar and it works. I don't know if there is a better way.
Instead of using html text directly, create a component.
Add the import to the component template:
import 'package:<your package>/<path to component>/<component source name>.template.dart';
Then add the component with the createComponent() method (instead of createMyCustomView()):
_viewContainer.createComponent(<componentName>NgFactory);
That's all!
If you need to style the component or add any attribute you can get the reference and derive the HtmlElement instance:
ComponentRef _componentRef = _viewContainer.createComponent(<componentName>NgFactory);
HtmlElement element = _componentRef.location;
element.style.background = 'green';
element.setAttribute('value', 'text');

ES6 property decorator #Prop() decorator not working

I have the following Vue typescript component class:
import { Component, Prop, Vue } from 'vue-property-decorator';
import ChildComp from './ChildComp';
console.log(Prop);
#Component({
template: `
<div>
<ChildComp></ChildComp>
</div>
`,
props: {
state: String,
},
components: {
ChildComp: ChildComp,
},
})
export default class MissionComp extends Vue {
#Prop() test: string;
mounted() {
console.log(this.state, this.test);
}
}
I declare 2 props, state through the #Component decorator (vue-class-component) and test through the #Prop decorator (vue-property-decorator). Only state works. The #Prop decorator does not add a prop to Vue, but no error is ever thrown.
The console.log(Prop); logs the Prop function, so the package is loaded and found, but it seems it is never executed. The application never stops at a breakpoint placed there.
I use Webpack and babel-loader for transpiling. Could the error be somwhere in the build process?
The solution to this problem is provided by Babel. The Babel plugin #babel/plugin-proposal-decorators currently transpiles decorators for classes and functions. To transpile class property decorators you have to use another plugin: transform-decorators-legacy.

Mobx React Form - How to implement Custom onSubmit

I am using mobx-react-from and i have a a problem to figure how i can use an action that i have in my store inside obSubmit hook ....
the mobx form is working ok .. i can see the inputs and the validation
and when i submit the form all i want is to use an action from store ...
my AutStore file :
import {observable,action} from 'mobx';
class AuthStore {
constructor(store) {
this.store = store
}
#action authLogin=(form)=>{
this.store.firebaseAuth.signInWithEmailAndPassword().then(()=>{
}).catch(()=>{
})
}
}
export default AuthStore
my AuthForm File :
import {observable, action} from 'mobx';
import MobxReactForm from 'mobx-react-form';
import {formFields,formValidation} from './formSettings';
const fields = [
formFields.email,
formFields.password
];
const hooks = {
onSuccess(form) {
// Here i want to use an action - authLogin from my AuthStore
console.log('Form Values!', form.values());
},
onError(form) {
console.log('All form errors', form.errors());
}
};
const AuthForm = new MobxReactForm({fields}, {plugins:formValidation,
hooks});
export default AuthForm
i would like to know how can i connect all together thanks !!!
I haven't used mobx-react-form before but have used mobx and react extensively. There's a couple ways to do this. The way I have done it is as follows, assuming Webpack & ES6 & React 14 here. Instantiate the store, and use a Provider around the component that hosts the form.
import { Provider } from 'mobx-react'
import React, { Component, PropTypes } from 'react'
import AuthStore from '{your auth store rel path}'
import FormComponent from '{your form component rel path}'
// instantiate store
const myAuthStore = new AuthStore()
// i don't think the constructor for AuthStore needs a store arg.
export default class SingleFormApplication extends Component {
render() {
return (
<Provider store={myAuthStore} >
<FormComponent />
</Provider>
)
}
}
Your FormComponent class will need to take advantage of both the observer and inject methods of the mobx-react package that will wrap it in a higher order component that both injects the store object as a prop and registers a listener on the store for changes that will rerender the component. I typically use the annotation syntax and it looks like this.
#inject('{name of provider store prop to inject}') #observer
export default class Example extends Component {
constructor(props) {
super(props)
this.store = this.props.store
}
}
Finally, with the store injected, you can now pass an action from the store into an AuthForm method, which I would advise you modify accordingly. Have the AuthForm file export a method that takes an onSuccess method as an arg and returns the mobx-react-form object. I would also modify your store action to simply take the email and password as an arg instead of the whole form. In the FormComponent try this:
import { formWithSuccessAction } from '{rel path to auth form}'
then in constructor after this.store = this.props.store assignment...
this.form = formWithSuccessAction(this.store.authLogin)
then in your render method of the FormComponent use the this.form class variable to render a form as you would in the mobx-react-form docs.
To be as clear as possible, the AuthForm.formWithSuccessAction method should look something like this:
const formWithSuccessAction = (storeSuccessAction) => {
const fields = [
formFields.email,
formFields.password
];
const hooks = {
onSuccess(form) {
// Here i want to use an action - authLogin from my AuthStore
console.log('Form Values!', form.values());
// get email and password in separate vars or not, up to you
storeSuccessAction(email, password)
},
onError(form) {
console.log('All form errors', form.errors());
}
};
const AuthForm = new MobxReactForm({fields}, {plugins:formValidation,
hooks});
return AuthForm
}
Hopefully this helps you on your way.

Is it OK to put propTypes and defaultProps as static props inside React class?

This is the way I've been doing it for quite some time now:
export default class AttachmentCreator extends Component {
render() {
return <div>
<RaisedButton primary label="Add Attachment" />
</div>
}
}
AttachmentCreator.propTypes = {
id: PropTypes.string,
};
But I've seen people doing it this way:
export default class AttachmentCreator extends Component {
static propTypes = {
id: PropTypes.string,
};
render() {
return <div>
<RaisedButton primary label="Add Attachment" />
</div>
}
}
And in fact I've seen people setting initial state outside the constructor as well. Is this good practice? It's been bugging me, but I remember a discussion somewhere where someone said that setting default props as a static is not a good idea - I just don't remember why.
In fact, it's exactly the same in terms of performance. React.JS is a relatively new technology, so it's not clear yet what are considered good practices or don't. If you want to trust someone, check this AirBNB's styleguide:
https://github.com/airbnb/javascript/tree/master/react#ordering
import React, { PropTypes } from 'react';
const propTypes = {
id: PropTypes.number.isRequired,
url: PropTypes.string.isRequired,
text: PropTypes.string,
};
const defaultProps = {
text: 'Hello World',
};
class Link extends React.Component {
static methodsAreOk() {
return true;
}
render() {
return <a href={this.props.url} data-id={this.props.id}>{this.props.text}</a>
}
}
Link.propTypes = propTypes;
Link.defaultProps = defaultProps;
export default Link;
They are declaring a const with the propTypes object literals, keep the class pretty clean and assign them later to the static properties. I personally like this approach :)
Oh yes, it's totaly legit with Babel (or other transpilers)
class DataLoader extends React.Component {
static propTypes = {
onFinishedLoading: PropTypes.func
}
static defaultProps = {
onFinishedLoading: () => {}
}
}
...as it gets transpiled to this anyway.
class DataLoader extends React.Component {}
DataLoader.propTypes = {
onFinishedLoading: PropTypes.func
};
DataLoader.defaultProps = {
onFinishedLoading: () => {}
};
Static fields get transpiled as properties on the class object under the hood.
Look here at Babel REPL.
Moreover, assigning state or other class fields directly in the class body gets transpiled into the constructor.
non-function properties are not currently supported for es2015 classes. its a proposal for es2016. the second method is considerably more convenient, but a plugin would be required to support the syntax (theres a very common babel plugin for it).
On the other end, a hand full of open source projects are beginning to treat proptypes like TypeScript interfaces, or ActionConstants and actually create separate folders/files that house various component prop types and are then imported into the component.
So in summary, both syntaxes are ok to use. but if you want to only use strictly ES2015, the latter syntax is not yet supported in the specification.
If the component is state-less, meaning it does not change it's own state at all, you should declare it as a stateless component (export default function MyComponent(props)) and declare the propTypes outside.
Whether it's good practice to put initial state declaration in constructor is up to you. In our project we declare initial state in componentWillMount() just because we do not like the super(props) boilerplate you have to use with the constructor.