@bpmn-io/properties-panel 0.8.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -85
- package/LICENSE +20 -20
- package/README.md +34 -34
- package/assets/properties-panel.css +891 -848
- package/dist/index.esm.js +1609 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +1650 -0
- package/dist/index.js.map +1 -0
- package/package.json +87 -78
- package/preact/LICENSE +21 -0
- package/preact/README.md +185 -0
- package/preact/compat/dist/compat.js +2 -0
- package/preact/compat/dist/compat.js.map +1 -0
- package/preact/compat/dist/compat.mjs +2 -0
- package/preact/compat/dist/compat.module.js +2 -0
- package/preact/compat/dist/compat.module.js.map +1 -0
- package/preact/compat/dist/compat.umd.js +2 -0
- package/preact/compat/dist/compat.umd.js.map +1 -0
- package/preact/compat/jsx-dev-runtime.js +1 -0
- package/preact/compat/jsx-dev-runtime.mjs +1 -0
- package/preact/compat/jsx-runtime.js +1 -0
- package/preact/compat/jsx-runtime.mjs +1 -0
- package/preact/compat/package.json +19 -0
- package/preact/compat/server.js +15 -0
- package/preact/compat/server.mjs +4 -0
- package/preact/compat/src/Children.js +21 -0
- package/preact/compat/src/PureComponent.js +15 -0
- package/preact/compat/src/forwardRef.js +51 -0
- package/preact/compat/src/index.d.ts +140 -0
- package/preact/compat/src/index.js +175 -0
- package/preact/compat/src/internal.d.ts +47 -0
- package/preact/compat/src/memo.js +34 -0
- package/preact/compat/src/portals.js +80 -0
- package/preact/compat/src/render.js +219 -0
- package/preact/compat/src/scheduler.js +24 -0
- package/preact/compat/src/suspense-list.d.ts +14 -0
- package/preact/compat/src/suspense-list.js +126 -0
- package/preact/compat/src/suspense.d.ts +15 -0
- package/preact/compat/src/suspense.js +270 -0
- package/preact/compat/src/util.js +28 -0
- package/preact/compat/test-utils.js +1 -0
- package/preact/debug/dist/debug.js +2 -0
- package/preact/debug/dist/debug.js.map +1 -0
- package/preact/debug/dist/debug.mjs +2 -0
- package/preact/debug/dist/debug.module.js +2 -0
- package/preact/debug/dist/debug.module.js.map +1 -0
- package/preact/debug/dist/debug.umd.js +2 -0
- package/preact/debug/dist/debug.umd.js.map +1 -0
- package/preact/debug/package.json +18 -0
- package/preact/debug/src/check-props.js +54 -0
- package/preact/debug/src/component-stack.js +146 -0
- package/preact/debug/src/constants.js +3 -0
- package/preact/debug/src/debug.js +442 -0
- package/preact/debug/src/index.js +6 -0
- package/preact/debug/src/internal.d.ts +82 -0
- package/preact/debug/src/util.js +11 -0
- package/preact/devtools/dist/devtools.js +2 -0
- package/preact/devtools/dist/devtools.js.map +1 -0
- package/preact/devtools/dist/devtools.mjs +2 -0
- package/preact/devtools/dist/devtools.module.js +2 -0
- package/preact/devtools/dist/devtools.module.js.map +1 -0
- package/preact/devtools/dist/devtools.umd.js +2 -0
- package/preact/devtools/dist/devtools.umd.js.map +1 -0
- package/preact/devtools/package.json +16 -0
- package/preact/devtools/src/devtools.js +10 -0
- package/preact/devtools/src/index.d.ts +8 -0
- package/preact/devtools/src/index.js +15 -0
- package/preact/dist/preact.js +2 -0
- package/preact/dist/preact.js.map +1 -0
- package/preact/dist/preact.min.js +2 -0
- package/preact/dist/preact.min.js.map +1 -0
- package/preact/dist/preact.mjs +2 -0
- package/preact/dist/preact.module.js +2 -0
- package/preact/dist/preact.module.js.map +1 -0
- package/preact/dist/preact.umd.js +2 -0
- package/preact/dist/preact.umd.js.map +1 -0
- package/preact/hooks/dist/hooks.js +2 -0
- package/preact/hooks/dist/hooks.js.map +1 -0
- package/preact/hooks/dist/hooks.mjs +2 -0
- package/preact/hooks/dist/hooks.module.js +2 -0
- package/preact/hooks/dist/hooks.module.js.map +1 -0
- package/preact/hooks/dist/hooks.umd.js +2 -0
- package/preact/hooks/dist/hooks.umd.js.map +1 -0
- package/preact/hooks/package.json +26 -0
- package/preact/hooks/src/index.d.ts +130 -0
- package/preact/hooks/src/index.js +386 -0
- package/preact/hooks/src/internal.d.ts +75 -0
- package/preact/jsx-runtime/dist/jsxRuntime.js +2 -0
- package/preact/jsx-runtime/dist/jsxRuntime.js.map +1 -0
- package/preact/jsx-runtime/dist/jsxRuntime.mjs +2 -0
- package/preact/jsx-runtime/dist/jsxRuntime.module.js +2 -0
- package/preact/jsx-runtime/dist/jsxRuntime.module.js.map +1 -0
- package/preact/jsx-runtime/dist/jsxRuntime.umd.js +2 -0
- package/preact/jsx-runtime/dist/jsxRuntime.umd.js.map +1 -0
- package/preact/jsx-runtime/package.json +19 -0
- package/preact/jsx-runtime/src/index.d.ts +50 -0
- package/preact/jsx-runtime/src/index.js +72 -0
- package/preact/package.json +268 -0
- package/preact/src/cjs.js +3 -0
- package/preact/src/clone-element.js +39 -0
- package/preact/src/component.js +225 -0
- package/preact/src/constants.js +3 -0
- package/preact/src/create-context.js +68 -0
- package/preact/src/create-element.js +100 -0
- package/preact/src/diff/catch-error.js +38 -0
- package/preact/src/diff/children.js +347 -0
- package/preact/src/diff/index.js +516 -0
- package/preact/src/diff/props.js +158 -0
- package/preact/src/index.d.ts +310 -0
- package/preact/src/index.js +13 -0
- package/preact/src/internal.d.ts +147 -0
- package/preact/src/jsx.d.ts +955 -0
- package/preact/src/options.js +17 -0
- package/preact/src/render.js +74 -0
- package/preact/src/util.js +23 -0
- package/preact/test-utils/dist/testUtils.js +2 -0
- package/preact/test-utils/dist/testUtils.js.map +1 -0
- package/preact/test-utils/dist/testUtils.mjs +2 -0
- package/preact/test-utils/dist/testUtils.module.js +2 -0
- package/preact/test-utils/dist/testUtils.module.js.map +1 -0
- package/preact/test-utils/dist/testUtils.umd.js +2 -0
- package/preact/test-utils/dist/testUtils.umd.js.map +1 -0
- package/preact/test-utils/package.json +19 -0
- package/preact/test-utils/src/index.d.ts +3 -0
- package/preact/test-utils/src/index.js +117 -0
- package/lib/PropertiesPanel.js +0 -126
- package/lib/PropertiesPanel.js.map +0 -1
- package/lib/components/DropdownButton.js +0 -109
- package/lib/components/DropdownButton.js.map +0 -1
- package/lib/components/Group.js +0 -75
- package/lib/components/Group.js.map +0 -1
- package/lib/components/Header.js +0 -49
- package/lib/components/Header.js.map +0 -1
- package/lib/components/HeaderButton.js +0 -16
- package/lib/components/HeaderButton.js.map +0 -1
- package/lib/components/ListGroup.js +0 -167
- package/lib/components/ListGroup.js.map +0 -1
- package/lib/components/ListItem.js +0 -37
- package/lib/components/ListItem.js.map +0 -1
- package/lib/components/entries/Checkbox.js +0 -81
- package/lib/components/entries/Checkbox.js.map +0 -1
- package/lib/components/entries/Collapsible.js +0 -48
- package/lib/components/entries/Collapsible.js.map +0 -1
- package/lib/components/entries/List.js +0 -204
- package/lib/components/entries/List.js.map +0 -1
- package/lib/components/entries/NumberField.js +0 -108
- package/lib/components/entries/NumberField.js.map +0 -1
- package/lib/components/entries/Select.js +0 -107
- package/lib/components/entries/Select.js.map +0 -1
- package/lib/components/entries/Simple.js +0 -56
- package/lib/components/entries/Simple.js.map +0 -1
- package/lib/components/entries/TextArea.js +0 -96
- package/lib/components/entries/TextArea.js.map +0 -1
- package/lib/components/entries/TextField.js +0 -121
- package/lib/components/entries/TextField.js.map +0 -1
- package/lib/components/entries/ToggleSwitch.js +0 -87
- package/lib/components/entries/ToggleSwitch.js.map +0 -1
- package/lib/components/icons/index.js +0 -51
- package/lib/components/icons/index.js.map +0 -1
- package/lib/context/LayoutContext.js +0 -9
- package/lib/context/LayoutContext.js.map +0 -1
- package/lib/context/index.js +0 -2
- package/lib/context/index.js.map +0 -1
- package/lib/features/debounce-input/debounceInput.js +0 -14
- package/lib/features/debounce-input/debounceInput.js.map +0 -1
- package/lib/features/debounce-input/index.js +0 -5
- package/lib/features/debounce-input/index.js.map +0 -1
- package/lib/hooks/index.js +0 -4
- package/lib/hooks/index.js.map +0 -1
- package/lib/hooks/useKeyFactory.js +0 -39
- package/lib/hooks/useKeyFactory.js.map +0 -1
- package/lib/hooks/useLayoutState.js +0 -36
- package/lib/hooks/useLayoutState.js.map +0 -1
- package/lib/hooks/usePrevious.js +0 -16
- package/lib/hooks/usePrevious.js.map +0 -1
- package/lib/index.js +0 -2
- package/lib/index.js.map +0 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createElement, render } from '../..';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {import('../../src/index').RenderableProps<{ context: any }>} props
|
|
5
|
+
*/
|
|
6
|
+
function ContextProvider(props) {
|
|
7
|
+
this.getChildContext = () => props.context;
|
|
8
|
+
return props.children;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Portal component
|
|
13
|
+
* @this {import('./internal').Component}
|
|
14
|
+
* @param {object | null | undefined} props
|
|
15
|
+
*
|
|
16
|
+
* TODO: use createRoot() instead of fake root
|
|
17
|
+
*/
|
|
18
|
+
function Portal(props) {
|
|
19
|
+
const _this = this;
|
|
20
|
+
let container = props._container;
|
|
21
|
+
|
|
22
|
+
_this.componentWillUnmount = function() {
|
|
23
|
+
render(null, _this._temp);
|
|
24
|
+
_this._temp = null;
|
|
25
|
+
_this._container = null;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// When we change container we should clear our old container and
|
|
29
|
+
// indicate a new mount.
|
|
30
|
+
if (_this._container && _this._container !== container) {
|
|
31
|
+
_this.componentWillUnmount();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// When props.vnode is undefined/false/null we are dealing with some kind of
|
|
35
|
+
// conditional vnode. This should not trigger a render.
|
|
36
|
+
if (props._vnode) {
|
|
37
|
+
if (!_this._temp) {
|
|
38
|
+
_this._container = container;
|
|
39
|
+
|
|
40
|
+
// Create a fake DOM parent node that manages a subset of `container`'s children:
|
|
41
|
+
_this._temp = {
|
|
42
|
+
nodeType: 1,
|
|
43
|
+
parentNode: container,
|
|
44
|
+
childNodes: [],
|
|
45
|
+
appendChild(child) {
|
|
46
|
+
this.childNodes.push(child);
|
|
47
|
+
_this._container.appendChild(child);
|
|
48
|
+
},
|
|
49
|
+
insertBefore(child, before) {
|
|
50
|
+
this.childNodes.push(child);
|
|
51
|
+
_this._container.appendChild(child);
|
|
52
|
+
},
|
|
53
|
+
removeChild(child) {
|
|
54
|
+
this.childNodes.splice(this.childNodes.indexOf(child) >>> 1, 1);
|
|
55
|
+
_this._container.removeChild(child);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Render our wrapping element into temp.
|
|
61
|
+
render(
|
|
62
|
+
createElement(ContextProvider, { context: _this.context }, props._vnode),
|
|
63
|
+
_this._temp
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
// When we come from a conditional render, on a mounted
|
|
67
|
+
// portal we should clear the DOM.
|
|
68
|
+
else if (_this._temp) {
|
|
69
|
+
_this.componentWillUnmount();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Create a `Portal` to continue rendering the vnode tree at a different DOM node
|
|
75
|
+
* @param {import('./internal').VNode} vnode The vnode to render
|
|
76
|
+
* @param {import('./internal').PreactElement} container The DOM node to continue rendering in to.
|
|
77
|
+
*/
|
|
78
|
+
export function createPortal(vnode, container) {
|
|
79
|
+
return createElement(Portal, { _vnode: vnode, _container: container });
|
|
80
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import {
|
|
2
|
+
render as preactRender,
|
|
3
|
+
hydrate as preactHydrate,
|
|
4
|
+
options,
|
|
5
|
+
toChildArray,
|
|
6
|
+
Component
|
|
7
|
+
} from '../..';
|
|
8
|
+
|
|
9
|
+
export const REACT_ELEMENT_TYPE =
|
|
10
|
+
(typeof Symbol != 'undefined' && Symbol.for && Symbol.for('react.element')) ||
|
|
11
|
+
0xeac7;
|
|
12
|
+
|
|
13
|
+
const CAMEL_PROPS = /^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/;
|
|
14
|
+
|
|
15
|
+
// Input types for which onchange should not be converted to oninput.
|
|
16
|
+
// type="file|checkbox|radio", plus "range" in IE11.
|
|
17
|
+
// (IE11 doesn't support Symbol, which we use here to turn `rad` into `ra` which matches "range")
|
|
18
|
+
const onChangeInputType = type =>
|
|
19
|
+
(typeof Symbol != 'undefined' && typeof Symbol() == 'symbol'
|
|
20
|
+
? /fil|che|rad/i
|
|
21
|
+
: /fil|che|ra/i
|
|
22
|
+
).test(type);
|
|
23
|
+
|
|
24
|
+
// Some libraries like `react-virtualized` explicitly check for this.
|
|
25
|
+
Component.prototype.isReactComponent = {};
|
|
26
|
+
|
|
27
|
+
// `UNSAFE_*` lifecycle hooks
|
|
28
|
+
// Preact only ever invokes the unprefixed methods.
|
|
29
|
+
// Here we provide a base "fallback" implementation that calls any defined UNSAFE_ prefixed method.
|
|
30
|
+
// - If a component defines its own `componentDidMount()` (including via defineProperty), use that.
|
|
31
|
+
// - If a component defines `UNSAFE_componentDidMount()`, `componentDidMount` is the alias getter/setter.
|
|
32
|
+
// - If anything assigns to an `UNSAFE_*` property, the assignment is forwarded to the unprefixed property.
|
|
33
|
+
// See https://github.com/preactjs/preact/issues/1941
|
|
34
|
+
[
|
|
35
|
+
'componentWillMount',
|
|
36
|
+
'componentWillReceiveProps',
|
|
37
|
+
'componentWillUpdate'
|
|
38
|
+
].forEach(key => {
|
|
39
|
+
Object.defineProperty(Component.prototype, key, {
|
|
40
|
+
configurable: true,
|
|
41
|
+
get() {
|
|
42
|
+
return this['UNSAFE_' + key];
|
|
43
|
+
},
|
|
44
|
+
set(v) {
|
|
45
|
+
Object.defineProperty(this, key, {
|
|
46
|
+
configurable: true,
|
|
47
|
+
writable: true,
|
|
48
|
+
value: v
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Proxy render() since React returns a Component reference.
|
|
56
|
+
* @param {import('./internal').VNode} vnode VNode tree to render
|
|
57
|
+
* @param {import('./internal').PreactElement} parent DOM node to render vnode tree into
|
|
58
|
+
* @param {() => void} [callback] Optional callback that will be called after rendering
|
|
59
|
+
* @returns {import('./internal').Component | null} The root component reference or null
|
|
60
|
+
*/
|
|
61
|
+
export function render(vnode, parent, callback) {
|
|
62
|
+
// React destroys any existing DOM nodes, see #1727
|
|
63
|
+
// ...but only on the first render, see #1828
|
|
64
|
+
if (parent._children == null) {
|
|
65
|
+
parent.textContent = '';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
preactRender(vnode, parent);
|
|
69
|
+
if (typeof callback == 'function') callback();
|
|
70
|
+
|
|
71
|
+
return vnode ? vnode._component : null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function hydrate(vnode, parent, callback) {
|
|
75
|
+
preactHydrate(vnode, parent);
|
|
76
|
+
if (typeof callback == 'function') callback();
|
|
77
|
+
|
|
78
|
+
return vnode ? vnode._component : null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let oldEventHook = options.event;
|
|
82
|
+
options.event = e => {
|
|
83
|
+
if (oldEventHook) e = oldEventHook(e);
|
|
84
|
+
e.persist = empty;
|
|
85
|
+
e.isPropagationStopped = isPropagationStopped;
|
|
86
|
+
e.isDefaultPrevented = isDefaultPrevented;
|
|
87
|
+
return (e.nativeEvent = e);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
function empty() {}
|
|
91
|
+
|
|
92
|
+
function isPropagationStopped() {
|
|
93
|
+
return this.cancelBubble;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function isDefaultPrevented() {
|
|
97
|
+
return this.defaultPrevented;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let classNameDescriptor = {
|
|
101
|
+
configurable: true,
|
|
102
|
+
get() {
|
|
103
|
+
return this.class;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
let oldVNodeHook = options.vnode;
|
|
108
|
+
options.vnode = vnode => {
|
|
109
|
+
let type = vnode.type;
|
|
110
|
+
let props = vnode.props;
|
|
111
|
+
let normalizedProps = props;
|
|
112
|
+
|
|
113
|
+
// only normalize props on Element nodes
|
|
114
|
+
if (typeof type === 'string') {
|
|
115
|
+
normalizedProps = {};
|
|
116
|
+
|
|
117
|
+
for (let i in props) {
|
|
118
|
+
let value = props[i];
|
|
119
|
+
|
|
120
|
+
if (i === 'value' && 'defaultValue' in props && value == null) {
|
|
121
|
+
// Skip applying value if it is null/undefined and we already set
|
|
122
|
+
// a default value
|
|
123
|
+
continue;
|
|
124
|
+
} else if (
|
|
125
|
+
i === 'defaultValue' &&
|
|
126
|
+
'value' in props &&
|
|
127
|
+
props.value == null
|
|
128
|
+
) {
|
|
129
|
+
// `defaultValue` is treated as a fallback `value` when a value prop is present but null/undefined.
|
|
130
|
+
// `defaultValue` for Elements with no value prop is the same as the DOM defaultValue property.
|
|
131
|
+
i = 'value';
|
|
132
|
+
} else if (i === 'download' && value === true) {
|
|
133
|
+
// Calling `setAttribute` with a truthy value will lead to it being
|
|
134
|
+
// passed as a stringified value, e.g. `download="true"`. React
|
|
135
|
+
// converts it to an empty string instead, otherwise the attribute
|
|
136
|
+
// value will be used as the file name and the file will be called
|
|
137
|
+
// "true" upon downloading it.
|
|
138
|
+
value = '';
|
|
139
|
+
} else if (/ondoubleclick/i.test(i)) {
|
|
140
|
+
i = 'ondblclick';
|
|
141
|
+
} else if (
|
|
142
|
+
/^onchange(textarea|input)/i.test(i + type) &&
|
|
143
|
+
!onChangeInputType(props.type)
|
|
144
|
+
) {
|
|
145
|
+
i = 'oninput';
|
|
146
|
+
} else if (/^on(Ani|Tra|Tou|BeforeInp)/.test(i)) {
|
|
147
|
+
i = i.toLowerCase();
|
|
148
|
+
} else if (CAMEL_PROPS.test(i)) {
|
|
149
|
+
i = i.replace(/[A-Z0-9]/, '-$&').toLowerCase();
|
|
150
|
+
} else if (value === null) {
|
|
151
|
+
value = undefined;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
normalizedProps[i] = value;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Add support for array select values: <select multiple value={[]} />
|
|
158
|
+
if (
|
|
159
|
+
type == 'select' &&
|
|
160
|
+
normalizedProps.multiple &&
|
|
161
|
+
Array.isArray(normalizedProps.value)
|
|
162
|
+
) {
|
|
163
|
+
// forEach() always returns undefined, which we abuse here to unset the value prop.
|
|
164
|
+
normalizedProps.value = toChildArray(props.children).forEach(child => {
|
|
165
|
+
child.props.selected =
|
|
166
|
+
normalizedProps.value.indexOf(child.props.value) != -1;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Adding support for defaultValue in select tag
|
|
171
|
+
if (type == 'select' && normalizedProps.defaultValue != null) {
|
|
172
|
+
normalizedProps.value = toChildArray(props.children).forEach(child => {
|
|
173
|
+
if (normalizedProps.multiple) {
|
|
174
|
+
child.props.selected =
|
|
175
|
+
normalizedProps.defaultValue.indexOf(child.props.value) != -1;
|
|
176
|
+
} else {
|
|
177
|
+
child.props.selected =
|
|
178
|
+
normalizedProps.defaultValue == child.props.value;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
vnode.props = normalizedProps;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (type && props.class != props.className) {
|
|
187
|
+
classNameDescriptor.enumerable = 'className' in props;
|
|
188
|
+
if (props.className != null) normalizedProps.class = props.className;
|
|
189
|
+
Object.defineProperty(normalizedProps, 'className', classNameDescriptor);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
vnode.$$typeof = REACT_ELEMENT_TYPE;
|
|
193
|
+
|
|
194
|
+
if (oldVNodeHook) oldVNodeHook(vnode);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// Only needed for react-relay
|
|
198
|
+
let currentComponent;
|
|
199
|
+
const oldBeforeRender = options._render;
|
|
200
|
+
options._render = function(vnode) {
|
|
201
|
+
if (oldBeforeRender) {
|
|
202
|
+
oldBeforeRender(vnode);
|
|
203
|
+
}
|
|
204
|
+
currentComponent = vnode._component;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// This is a very very private internal function for React it
|
|
208
|
+
// is used to sort-of do runtime dependency injection. So far
|
|
209
|
+
// only `react-relay` makes use of it. It uses it to read the
|
|
210
|
+
// context value.
|
|
211
|
+
export const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = {
|
|
212
|
+
ReactCurrentDispatcher: {
|
|
213
|
+
current: {
|
|
214
|
+
readContext(context) {
|
|
215
|
+
return currentComponent._globalContext[context._id].props.value;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// This file includes experimental React APIs exported from the "scheduler"
|
|
2
|
+
// npm package. Despite being explicitely marked as unstable some libraries
|
|
3
|
+
// already make use of them. This file is not a full replacement for the
|
|
4
|
+
// scheduler package, but includes the necessary shims to make those libraries
|
|
5
|
+
// work with Preact.
|
|
6
|
+
|
|
7
|
+
export const unstable_ImmediatePriority = 1;
|
|
8
|
+
export const unstable_UserBlockingPriority = 2;
|
|
9
|
+
export const unstable_NormalPriority = 3;
|
|
10
|
+
export const unstable_LowPriority = 4;
|
|
11
|
+
export const unstable_IdlePriority = 5;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {number} priority
|
|
15
|
+
* @param {() => void} callback
|
|
16
|
+
*/
|
|
17
|
+
export function unstable_runWithPriority(priority, callback) {
|
|
18
|
+
return callback();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const unstable_now =
|
|
22
|
+
typeof performance === 'object' && typeof performance.now === 'function'
|
|
23
|
+
? performance.now.bind(performance)
|
|
24
|
+
: () => Date.now();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Component, ComponentChild } from '../../src';
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
// SuspenseList
|
|
5
|
+
// -----------------------------------
|
|
6
|
+
|
|
7
|
+
export interface SuspenseListProps {
|
|
8
|
+
children?: preact.ComponentChildren;
|
|
9
|
+
revealOrder?: 'forwards' | 'backwards' | 'together';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class SuspenseList extends Component<SuspenseListProps> {
|
|
13
|
+
render(): ComponentChild;
|
|
14
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Component, toChildArray } from '../..';
|
|
2
|
+
import { suspended } from './suspense.js';
|
|
3
|
+
|
|
4
|
+
// Indexes to linked list nodes (nodes are stored as arrays to save bytes).
|
|
5
|
+
const SUSPENDED_COUNT = 0;
|
|
6
|
+
const RESOLVED_COUNT = 1;
|
|
7
|
+
const NEXT_NODE = 2;
|
|
8
|
+
|
|
9
|
+
// Having custom inheritance instead of a class here saves a lot of bytes.
|
|
10
|
+
export function SuspenseList() {
|
|
11
|
+
this._next = null;
|
|
12
|
+
this._map = null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Mark one of child's earlier suspensions as resolved.
|
|
16
|
+
// Some pending callbacks may become callable due to this
|
|
17
|
+
// (e.g. the last suspended descendant gets resolved when
|
|
18
|
+
// revealOrder === 'together'). Process those callbacks as well.
|
|
19
|
+
const resolve = (list, child, node) => {
|
|
20
|
+
if (++node[RESOLVED_COUNT] === node[SUSPENDED_COUNT]) {
|
|
21
|
+
// The number a child (or any of its descendants) has been suspended
|
|
22
|
+
// matches the number of times it's been resolved. Therefore we
|
|
23
|
+
// mark the child as completely resolved by deleting it from ._map.
|
|
24
|
+
// This is used to figure out when *all* children have been completely
|
|
25
|
+
// resolved when revealOrder is 'together'.
|
|
26
|
+
list._map.delete(child);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// If revealOrder is falsy then we can do an early exit, as the
|
|
30
|
+
// callbacks won't get queued in the node anyway.
|
|
31
|
+
// If revealOrder is 'together' then also do an early exit
|
|
32
|
+
// if all suspended descendants have not yet been resolved.
|
|
33
|
+
if (
|
|
34
|
+
!list.props.revealOrder ||
|
|
35
|
+
(list.props.revealOrder[0] === 't' && list._map.size)
|
|
36
|
+
) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Walk the currently suspended children in order, calling their
|
|
41
|
+
// stored callbacks on the way. Stop if we encounter a child that
|
|
42
|
+
// has not been completely resolved yet.
|
|
43
|
+
node = list._next;
|
|
44
|
+
while (node) {
|
|
45
|
+
while (node.length > 3) {
|
|
46
|
+
node.pop()();
|
|
47
|
+
}
|
|
48
|
+
if (node[RESOLVED_COUNT] < node[SUSPENDED_COUNT]) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
list._next = node = node[NEXT_NODE];
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Things we do here to save some bytes but are not proper JS inheritance:
|
|
56
|
+
// - call `new Component()` as the prototype
|
|
57
|
+
// - do not set `Suspense.prototype.constructor` to `Suspense`
|
|
58
|
+
SuspenseList.prototype = new Component();
|
|
59
|
+
|
|
60
|
+
SuspenseList.prototype._suspended = function(child) {
|
|
61
|
+
const list = this;
|
|
62
|
+
const delegated = suspended(list._vnode);
|
|
63
|
+
|
|
64
|
+
let node = list._map.get(child);
|
|
65
|
+
node[SUSPENDED_COUNT]++;
|
|
66
|
+
|
|
67
|
+
return unsuspend => {
|
|
68
|
+
const wrappedUnsuspend = () => {
|
|
69
|
+
if (!list.props.revealOrder) {
|
|
70
|
+
// Special case the undefined (falsy) revealOrder, as there
|
|
71
|
+
// is no need to coordinate a specific order or unsuspends.
|
|
72
|
+
unsuspend();
|
|
73
|
+
} else {
|
|
74
|
+
node.push(unsuspend);
|
|
75
|
+
resolve(list, child, node);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
if (delegated) {
|
|
79
|
+
delegated(wrappedUnsuspend);
|
|
80
|
+
} else {
|
|
81
|
+
wrappedUnsuspend();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
SuspenseList.prototype.render = function(props) {
|
|
87
|
+
this._next = null;
|
|
88
|
+
this._map = new Map();
|
|
89
|
+
|
|
90
|
+
const children = toChildArray(props.children);
|
|
91
|
+
if (props.revealOrder && props.revealOrder[0] === 'b') {
|
|
92
|
+
// If order === 'backwards' (or, well, anything starting with a 'b')
|
|
93
|
+
// then flip the child list around so that the last child will be
|
|
94
|
+
// the first in the linked list.
|
|
95
|
+
children.reverse();
|
|
96
|
+
}
|
|
97
|
+
// Build the linked list. Iterate through the children in reverse order
|
|
98
|
+
// so that `_next` points to the first linked list node to be resolved.
|
|
99
|
+
for (let i = children.length; i--; ) {
|
|
100
|
+
// Create a new linked list node as an array of form:
|
|
101
|
+
// [suspended_count, resolved_count, next_node]
|
|
102
|
+
// where suspended_count and resolved_count are numeric counters for
|
|
103
|
+
// keeping track how many times a node has been suspended and resolved.
|
|
104
|
+
//
|
|
105
|
+
// Note that suspended_count starts from 1 instead of 0, so we can block
|
|
106
|
+
// processing callbacks until componentDidMount has been called. In a sense
|
|
107
|
+
// node is suspended at least until componentDidMount gets called!
|
|
108
|
+
//
|
|
109
|
+
// Pending callbacks are added to the end of the node:
|
|
110
|
+
// [suspended_count, resolved_count, next_node, callback_0, callback_1, ...]
|
|
111
|
+
this._map.set(children[i], (this._next = [1, 0, this._next]));
|
|
112
|
+
}
|
|
113
|
+
return props.children;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
SuspenseList.prototype.componentDidUpdate = SuspenseList.prototype.componentDidMount = function() {
|
|
117
|
+
// Iterate through all children after mounting for two reasons:
|
|
118
|
+
// 1. As each node[SUSPENDED_COUNT] starts from 1, this iteration increases
|
|
119
|
+
// each node[RELEASED_COUNT] by 1, therefore balancing the counters.
|
|
120
|
+
// The nodes can now be completely consumed from the linked list.
|
|
121
|
+
// 2. Handle nodes that might have gotten resolved between render and
|
|
122
|
+
// componentDidMount.
|
|
123
|
+
this._map.forEach((node, child) => {
|
|
124
|
+
resolve(this, child, node);
|
|
125
|
+
});
|
|
126
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Component, ComponentChild } from '../../src';
|
|
2
|
+
|
|
3
|
+
//
|
|
4
|
+
// Suspense/lazy
|
|
5
|
+
// -----------------------------------
|
|
6
|
+
export function lazy<T>(loader: () => Promise<{ default: T }>): T;
|
|
7
|
+
|
|
8
|
+
export interface SuspenseProps {
|
|
9
|
+
children?: preact.ComponentChildren;
|
|
10
|
+
fallback: preact.ComponentChildren;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class Suspense extends Component<SuspenseProps> {
|
|
14
|
+
render(): ComponentChild;
|
|
15
|
+
}
|