Skip to content

Commit

Permalink
Add function components
Browse files Browse the repository at this point in the history
- Add different component choices to backend engine that include both
  class and function components
- Add Class to current  Async and Component templates
  - AsynComponent.react.js -> AsyncClassComponent.react.js
  - Component.react.js -> ClassComponent.react.js
- Add 2 additional function components templates.
- Replace use_async boolean choice with component_type list choices
  • Loading branch information
aeltanawy committed Aug 9, 2023
1 parent 994fb0a commit 2e2f70d
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 33 deletions.
7 changes: 6 additions & 1 deletion cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
"author_email": "Enter your email (For package.json)",
"github_org": "",
"description": "Project Description",
"use_async": ["False", "True"],
"component_type": [
"Async with Class Component",
"Async with Function Component",
"Class Component",
"Function Component"
],
"license": [
"MIT License",
"BSD License",
Expand Down
10 changes: 5 additions & 5 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

install_deps = '{{cookiecutter.install_dependencies}}'
project_shortname = '{{cookiecutter.project_shortname}}'
use_async = '{{cookiecutter.use_async}}'
component_type = '{{cookiecutter.component_type}}'


is_windows = sys.platform == 'win32'
Expand Down Expand Up @@ -41,11 +41,11 @@ def _execute_command(cmd):
template_dir = os.path.join(os.getcwd(), 'cookiecutter_templates')
shutil.rmtree(template_dir)

print("\n\n\nuse_async")
print(use_async)
print("\n\n\ncomponent_type")
print(component_type)
# If it doesn't use async, we can remove the fragments and lazyloader.js
if use_async != "True":
print('use_async is set to False, your component will not be lazy loaded and fragments will not be created.')
if "Async" not in component_type:
print('Since Async component is not in use, your component will not be lazy loaded and fragments will not be created.')
shutil.rmtree(os.path.join(os.getcwd(), 'src', 'lib', 'fragments'))
os.remove(os.path.join(os.getcwd(), 'src', 'lib', 'LazyLoader.js'))

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import PropTypes from 'prop-types';
import { {{cookiecutter.component_name}} as RealComponent } from '../LazyLoader';

/**
* ExampleComponent is an example component.
* It takes a property, `label`, and
* displays it.
* It renders an input with the property `value`
* which is editable by the user.
*/
const {{cookiecutter.component_name}} = (props) => {
return (
<React.Suspense fallback={null}>
<RealComponent {...props}/>
</React.Suspense>
);
};

{{cookiecutter.component_name}}.defaultProps = {};

{{cookiecutter.component_name}}.propTypes = {
/**
* The ID used to identify this component in Dash callbacks.
*/
id: PropTypes.string,

/**
* A label that will be printed when this component is rendered.
*/
label: PropTypes.string.isRequired,

/**
* The value displayed in the input.
*/
value: PropTypes.string,

/**
* Dash-assigned callback that should be called to report property changes
* to Dash, to make them available for callbacks.
*/
setProps: PropTypes.func
};

export default {{cookiecutter.component_name}};

export const defaultProps = {{cookiecutter.component_name}}.defaultProps;
export const propTypes = {{ cookiecutter.component_name }}.propTypes;
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';

/**
* ExampleComponent is an example component.
* It takes a property, `label`, and
* displays it.
* It renders an input with the property `value`
* which is editable by the user.
*/
const {{cookiecutter.component_name}} = (props) => {
const {id, label, setProps, value} = props;

return (
<div id={id}>
ExampleComponent: {label}&nbsp;
<input
value={value}
onChange={
/*
* Send the new value to the parent component.
* setProps is a prop that is automatically supplied
* by dash's front-end ("dash-renderer").
* In a Dash app, this will update the component's
* props and send the data back to the Python Dash
* app server if a callback uses the modified prop as
* Input or State.
*/
e => setProps({ value: e.target.value })
}
/>
</div>
);
}

{{cookiecutter.component_name}}.defaultProps = {};

{{cookiecutter.component_name}}.propTypes = {
/**
* The ID used to identify this component in Dash callbacks.
*/
id: PropTypes.string,

/**
* A label that will be printed when this component is rendered.
*/
label: PropTypes.string.isRequired,

/**
* The value displayed in the input.
*/
value: PropTypes.string,

/**
* Dash-assigned callback that should be called to report property changes
* to Dash, to make them available for callbacks.
*/
setProps: PropTypes.func
};

export default {{cookiecutter.component_name}};
36 changes: 14 additions & 22 deletions {{cookiecutter.project_shortname}}/src/demo/App.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
/* eslint no-magic-numbers: 0 */
import React, {Component} from 'react';
import React, { useState } from 'react';

import { {{cookiecutter.component_name}} } from '../lib';

class App extends Component {
const App = () => {

constructor(props) {
super(props);
this.state = {
value: ''
const [state, setState] = useState({value:'', label:'Type Here'});
const setProps = (newProps) => {
setState(newProps);
};
this.setProps = this.setProps.bind(this);
}

setProps(newProps) {
this.setState(newProps);
}
return (
<div>
<{{cookiecutter.component_name}}
setProps={setProps}
{...state}
/>
</div>
)
};

render() {
return (
<div>
<{{cookiecutter.component_name}}
setProps={this.setProps}
{...this.state}
/>
</div>
)
}
}

export default App;
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{%- if cookiecutter.use_async == "True" -%}
{%- include 'cookiecutter_templates/AsyncComponent.react.js' -%}
{%- if "Async" in cookiecutter.component_type and "Class" in cookiecutter.component_type -%}
{%- include 'cookiecutter_templates/AsyncClassComponent.react.js' -%}
{%- elif "Async" in cookiecutter.component_type and "Function" in cookiecutter.component_type -%}
{%- include 'cookiecutter_templates/AsyncFunctionComponent.react.js' -%}
{%- elif "Class" in cookiecutter.component_type -%}
{%- include 'cookiecutter_templates/ClassComponent.react.js' -%}
{%- else -%}
{%- include 'cookiecutter_templates/Component.react.js' -%}
{%- endif -%}
{%- include 'cookiecutter_templates/FunctionComponent.react.js' -%}
{%- endif -%}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
_this_module = _sys.modules[__name__]

async_resources = [
{%- if cookiecutter.use_async == "True" -%}
{%- if "Async" in cookiecutter.component_type -%}
"{{cookiecutter.component_name}}",
{%- endif -%}
]
Expand Down

0 comments on commit 2e2f70d

Please sign in to comment.