89 lines
2.6 KiB
Python
89 lines
2.6 KiB
Python
import collections
|
|
import json
|
|
import os
|
|
|
|
from ._py_components_generation import (
|
|
generate_class_file,
|
|
generate_imports,
|
|
generate_classes_files,
|
|
generate_class,
|
|
)
|
|
from .base_component import ComponentRegistry
|
|
|
|
|
|
def _get_metadata(metadata_path):
|
|
# Start processing
|
|
with open(metadata_path, encoding="utf-8") as data_file:
|
|
json_string = data_file.read()
|
|
data = json.JSONDecoder(object_pairs_hook=collections.OrderedDict).decode(
|
|
json_string
|
|
)
|
|
return data
|
|
|
|
|
|
def load_components(metadata_path, namespace="default_namespace"):
|
|
"""Load React component metadata into a format Dash can parse.
|
|
|
|
Usage: load_components('../../component-suites/lib/metadata.json')
|
|
|
|
Keyword arguments:
|
|
metadata_path -- a path to a JSON file created by
|
|
[`react-docgen`](https://github.com/reactjs/react-docgen).
|
|
|
|
Returns:
|
|
components -- a list of component objects with keys
|
|
`type`, `valid_kwargs`, and `setup`.
|
|
"""
|
|
|
|
# Register the component lib for index include.
|
|
ComponentRegistry.registry.add(namespace)
|
|
components = []
|
|
|
|
data = _get_metadata(metadata_path)
|
|
|
|
# Iterate over each property name (which is a path to the component)
|
|
for componentPath in data:
|
|
componentData = data[componentPath]
|
|
|
|
# Extract component name from path
|
|
# e.g. src/components/MyControl.react.js
|
|
# TODO Make more robust - some folks will write .jsx and others
|
|
# will be on windows. Unfortunately react-docgen doesn't include
|
|
# the name of the component atm.
|
|
name = componentPath.split("/").pop().split(".")[0]
|
|
component = generate_class(
|
|
name, componentData["props"], componentData["description"], namespace, None
|
|
)
|
|
|
|
components.append(component)
|
|
|
|
return components
|
|
|
|
|
|
def generate_classes(namespace, metadata_path="lib/metadata.json"):
|
|
"""Load React component metadata into a format Dash can parse, then create
|
|
Python class files.
|
|
|
|
Usage: generate_classes()
|
|
|
|
Keyword arguments:
|
|
namespace -- name of the generated Python package (also output dir)
|
|
|
|
metadata_path -- a path to a JSON file created by
|
|
[`react-docgen`](https://github.com/reactjs/react-docgen).
|
|
|
|
Returns:
|
|
"""
|
|
|
|
data = _get_metadata(metadata_path)
|
|
imports_path = os.path.join(namespace, "_imports_.py")
|
|
|
|
# Make sure the file doesn't exist, as we use append write
|
|
if os.path.exists(imports_path):
|
|
os.remove(imports_path)
|
|
|
|
components = generate_classes_files(namespace, data, generate_class_file)
|
|
|
|
# Add the __all__ value so we can import * from _imports_
|
|
generate_imports(namespace, components)
|