Skip to content

Commit 2cdd635

Browse files
committed
WIP dynamic callbacks
1 parent 2153a68 commit 2cdd635

File tree

13 files changed

+441
-91
lines changed

13 files changed

+441
-91
lines changed

@plotly/dash-test-components/src/components/StyledComponent.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ StyledComponent.propTypes = {
1515
/**
1616
* The style
1717
*/
18-
style: PropTypes.shape,
18+
style: PropTypes.any,
1919

2020
/**
2121
* The value to display
@@ -27,4 +27,4 @@ StyledComponent.defaultProps = {
2727
value: ''
2828
};
2929

30-
export default StyledComponent;
30+
export default StyledComponent;

dash/_dash_renderer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22

3-
__version__ = "1.17.0"
3+
__version__ = "1.17.1"
44

55
_available_react_versions = {"16.14.0", "18.2.0"}
66
_available_reactdom_versions = {"16.14.0", "18.2.0"}
@@ -64,7 +64,7 @@ def _set_react_version(v_react, v_reactdom=None):
6464
{
6565
"relative_package_path": "dash-renderer/build/dash_renderer.min.js",
6666
"dev_package_path": "dash-renderer/build/dash_renderer.dev.js",
67-
"external_url": "https://unpkg.com/[email protected].0"
67+
"external_url": "https://unpkg.com/[email protected].1"
6868
"/build/dash_renderer.min.js",
6969
"namespace": "dash",
7070
},

dash/dash-renderer/src/APIController.react.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {getAppState} from './reducers/constants';
2121
import {STATUS} from './constants/constants';
2222
import {getLoadingState, getLoadingHash} from './utils/TreeContainer';
2323
import wait from './utils/wait';
24+
import LibraryManager from './libraries/LibraryManager';
2425

2526
export const DashContext = createContext({});
2627

@@ -97,20 +98,24 @@ const UnconnectedContainer = props => {
9798

9899
content = (
99100
<DashContext.Provider value={provider.current}>
100-
<TreeContainer
101-
_dashprivate_error={error}
102-
_dashprivate_layout={layout}
103-
_dashprivate_loadingState={getLoadingState(
104-
layout,
105-
[],
106-
loadingMap
107-
)}
108-
_dashprivate_loadingStateHash={getLoadingHash(
109-
[],
110-
loadingMap
111-
)}
112-
_dashprivate_path={JSON.stringify([])}
113-
/>
101+
<LibraryManager
102+
requests_pathname_prefix={config.requests_pathname_prefix}
103+
>
104+
<TreeContainer
105+
_dashprivate_error={error}
106+
_dashprivate_layout={layout}
107+
_dashprivate_loadingState={getLoadingState(
108+
layout,
109+
[],
110+
loadingMap
111+
)}
112+
_dashprivate_loadingStateHash={getLoadingHash(
113+
[],
114+
loadingMap
115+
)}
116+
_dashprivate_path={JSON.stringify([])}
117+
/>
118+
</LibraryManager>
114119
</DashContext.Provider>
115120
);
116121
} else {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import checkPropTypes from './checkPropTypes';
2+
import {propTypeErrorHandler} from './exceptions';
3+
import {createLibraryElement} from './libraries/createLibraryElement';
4+
import PropTypes from 'prop-types';
5+
6+
export function CheckedComponent(p) {
7+
const {element, extraProps, props, children, type} = p;
8+
9+
const errorMessage = checkPropTypes(
10+
element.propTypes,
11+
props,
12+
'component prop',
13+
element
14+
);
15+
if (errorMessage) {
16+
propTypeErrorHandler(errorMessage, props, type);
17+
}
18+
19+
return createLibraryElement(element, props, extraProps, children);
20+
}
21+
22+
CheckedComponent.propTypes = {
23+
children: PropTypes.any,
24+
element: PropTypes.any,
25+
layout: PropTypes.any,
26+
props: PropTypes.any,
27+
extraProps: PropTypes.any,
28+
id: PropTypes.string,
29+
type: PropTypes.string
30+
};

dash/dash-renderer/src/TreeContainer.js

Lines changed: 16 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,44 @@
11
import React, {Component, memo, useContext} from 'react';
22
import PropTypes from 'prop-types';
3-
import Registry from './registry';
4-
import {propTypeErrorHandler} from './exceptions';
53
import {
64
addIndex,
75
assoc,
86
assocPath,
97
concat,
108
dissoc,
119
equals,
10+
has,
1211
isEmpty,
1312
isNil,
14-
has,
1513
keys,
1614
map,
1715
mapObjIndexed,
18-
mergeRight,
16+
path as rpath,
17+
pathOr,
1918
pick,
2019
pickBy,
2120
propOr,
22-
path as rpath,
23-
pathOr,
2421
type
2522
} from 'ramda';
23+
import {batch} from 'react-redux';
24+
2625
import {notifyObservers, updateProps} from './actions';
2726
import isSimpleComponent from './isSimpleComponent';
2827
import {recordUiEdit} from './persistence';
2928
import ComponentErrorBoundary from './components/error/ComponentErrorBoundary.react';
30-
import checkPropTypes from './checkPropTypes';
3129
import {getWatchedKeys, stringifyId} from './actions/dependencies';
3230
import {
3331
getLoadingHash,
3432
getLoadingState,
3533
validateComponent
3634
} from './utils/TreeContainer';
3735
import {DashContext} from './APIController.react';
38-
import {batch} from 'react-redux';
36+
import LibraryComponent from './libraries/LibraryComponent';
3937

4038
const NOT_LOADING = {
4139
is_loading: false
4240
};
4341

44-
function CheckedComponent(p) {
45-
const {element, extraProps, props, children, type} = p;
46-
47-
const errorMessage = checkPropTypes(
48-
element.propTypes,
49-
props,
50-
'component prop',
51-
element
52-
);
53-
if (errorMessage) {
54-
propTypeErrorHandler(errorMessage, props, type);
55-
}
56-
57-
return createElement(element, props, extraProps, children);
58-
}
59-
60-
CheckedComponent.propTypes = {
61-
children: PropTypes.any,
62-
element: PropTypes.any,
63-
layout: PropTypes.any,
64-
props: PropTypes.any,
65-
extraProps: PropTypes.any,
66-
id: PropTypes.string
67-
};
68-
69-
function createElement(element, props, extraProps, children) {
70-
const allProps = mergeRight(props, extraProps);
71-
if (Array.isArray(children)) {
72-
return React.createElement(element, allProps, ...children);
73-
}
74-
return React.createElement(element, allProps, children);
75-
}
76-
7742
function isDryComponent(obj) {
7843
return (
7944
type(obj) === 'Object' &&
@@ -240,7 +205,8 @@ class BaseTreeContainer extends Component {
240205
}
241206
validateComponent(_dashprivate_layout);
242207

243-
const element = Registry.resolve(_dashprivate_layout);
208+
// console.log("Dash private config", _dashprivate_config);
209+
// const element = Registry.resolve(_dashprivate_layout);
244210

245211
// Hydrate components props
246212
const childrenProps = pathOr(
@@ -445,17 +411,14 @@ class BaseTreeContainer extends Component {
445411
dispatch={_dashprivate_dispatch}
446412
error={_dashprivate_error}
447413
>
448-
{_dashprivate_config.props_check ? (
449-
<CheckedComponent
450-
children={children}
451-
element={element}
452-
props={props}
453-
extraProps={extraProps}
454-
type={_dashprivate_layout.type}
455-
/>
456-
) : (
457-
createElement(element, props, extraProps, children)
458-
)}
414+
<LibraryComponent
415+
children={children}
416+
type={_dashprivate_layout.type}
417+
namespace={_dashprivate_layout.namespace}
418+
props={props}
419+
extraProps={extraProps}
420+
props_check={_dashprivate_config.props_check}
421+
/>
459422
</ComponentErrorBoundary>
460423
);
461424
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React, {useContext, useEffect} from 'react';
2+
import {LibrariesContext} from './librariesContext';
3+
import Registry from '../registry';
4+
import {CheckedComponent} from '../CheckedComponent.react';
5+
import {createLibraryElement} from './createLibraryElement';
6+
7+
type LibraryComponentProps = {
8+
type: string;
9+
namespace: string;
10+
props: any;
11+
extraProps: any;
12+
children: any;
13+
props_check: boolean;
14+
};
15+
16+
const LibraryComponent = (props: LibraryComponentProps) => {
17+
const {props_check, namespace, type, ...rest} = props;
18+
19+
const context = useContext(LibrariesContext);
20+
21+
useEffect(() => {
22+
context.addToLoad(namespace);
23+
}, []);
24+
25+
if (!context.isLoaded(namespace)) {
26+
return <></>;
27+
}
28+
const element = Registry.resolve({namespace, type});
29+
if (props_check) {
30+
return (
31+
<CheckedComponent
32+
children={rest.children}
33+
element={element}
34+
props={rest.props}
35+
extraProps={rest.extraProps}
36+
type={type}
37+
/>
38+
);
39+
}
40+
return createLibraryElement(
41+
element,
42+
rest.props,
43+
rest.extraProps,
44+
rest.children
45+
);
46+
};
47+
export default LibraryComponent;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React, {JSX} from 'react';
2+
3+
import {createLibrariesContext, LibrariesContext} from './librariesContext';
4+
5+
type LibrariesManagerProps = {
6+
children: JSX.Element;
7+
requests_pathname_prefix: string;
8+
};
9+
10+
const LibraryManager = (props: LibrariesManagerProps) => {
11+
const {children, requests_pathname_prefix} = props;
12+
const contextValue = createLibrariesContext(requests_pathname_prefix);
13+
14+
return (
15+
<LibrariesContext.Provider value={contextValue}>
16+
{children}
17+
</LibrariesContext.Provider>
18+
);
19+
};
20+
21+
export default LibraryManager;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {mergeRight} from 'ramda';
2+
import React from 'react';
3+
4+
export function createLibraryElement(element, props, extraProps, children) {
5+
const allProps = mergeRight(props, extraProps);
6+
if (Array.isArray(children)) {
7+
return React.createElement(element, allProps, ...children);
8+
}
9+
return React.createElement(element, allProps, children);
10+
}

0 commit comments

Comments
 (0)