@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.
Files changed (177) hide show
  1. package/CHANGELOG.md +112 -85
  2. package/LICENSE +20 -20
  3. package/README.md +34 -34
  4. package/assets/properties-panel.css +891 -848
  5. package/dist/index.esm.js +1609 -0
  6. package/dist/index.esm.js.map +1 -0
  7. package/dist/index.js +1650 -0
  8. package/dist/index.js.map +1 -0
  9. package/package.json +87 -78
  10. package/preact/LICENSE +21 -0
  11. package/preact/README.md +185 -0
  12. package/preact/compat/dist/compat.js +2 -0
  13. package/preact/compat/dist/compat.js.map +1 -0
  14. package/preact/compat/dist/compat.mjs +2 -0
  15. package/preact/compat/dist/compat.module.js +2 -0
  16. package/preact/compat/dist/compat.module.js.map +1 -0
  17. package/preact/compat/dist/compat.umd.js +2 -0
  18. package/preact/compat/dist/compat.umd.js.map +1 -0
  19. package/preact/compat/jsx-dev-runtime.js +1 -0
  20. package/preact/compat/jsx-dev-runtime.mjs +1 -0
  21. package/preact/compat/jsx-runtime.js +1 -0
  22. package/preact/compat/jsx-runtime.mjs +1 -0
  23. package/preact/compat/package.json +19 -0
  24. package/preact/compat/server.js +15 -0
  25. package/preact/compat/server.mjs +4 -0
  26. package/preact/compat/src/Children.js +21 -0
  27. package/preact/compat/src/PureComponent.js +15 -0
  28. package/preact/compat/src/forwardRef.js +51 -0
  29. package/preact/compat/src/index.d.ts +140 -0
  30. package/preact/compat/src/index.js +175 -0
  31. package/preact/compat/src/internal.d.ts +47 -0
  32. package/preact/compat/src/memo.js +34 -0
  33. package/preact/compat/src/portals.js +80 -0
  34. package/preact/compat/src/render.js +219 -0
  35. package/preact/compat/src/scheduler.js +24 -0
  36. package/preact/compat/src/suspense-list.d.ts +14 -0
  37. package/preact/compat/src/suspense-list.js +126 -0
  38. package/preact/compat/src/suspense.d.ts +15 -0
  39. package/preact/compat/src/suspense.js +270 -0
  40. package/preact/compat/src/util.js +28 -0
  41. package/preact/compat/test-utils.js +1 -0
  42. package/preact/debug/dist/debug.js +2 -0
  43. package/preact/debug/dist/debug.js.map +1 -0
  44. package/preact/debug/dist/debug.mjs +2 -0
  45. package/preact/debug/dist/debug.module.js +2 -0
  46. package/preact/debug/dist/debug.module.js.map +1 -0
  47. package/preact/debug/dist/debug.umd.js +2 -0
  48. package/preact/debug/dist/debug.umd.js.map +1 -0
  49. package/preact/debug/package.json +18 -0
  50. package/preact/debug/src/check-props.js +54 -0
  51. package/preact/debug/src/component-stack.js +146 -0
  52. package/preact/debug/src/constants.js +3 -0
  53. package/preact/debug/src/debug.js +442 -0
  54. package/preact/debug/src/index.js +6 -0
  55. package/preact/debug/src/internal.d.ts +82 -0
  56. package/preact/debug/src/util.js +11 -0
  57. package/preact/devtools/dist/devtools.js +2 -0
  58. package/preact/devtools/dist/devtools.js.map +1 -0
  59. package/preact/devtools/dist/devtools.mjs +2 -0
  60. package/preact/devtools/dist/devtools.module.js +2 -0
  61. package/preact/devtools/dist/devtools.module.js.map +1 -0
  62. package/preact/devtools/dist/devtools.umd.js +2 -0
  63. package/preact/devtools/dist/devtools.umd.js.map +1 -0
  64. package/preact/devtools/package.json +16 -0
  65. package/preact/devtools/src/devtools.js +10 -0
  66. package/preact/devtools/src/index.d.ts +8 -0
  67. package/preact/devtools/src/index.js +15 -0
  68. package/preact/dist/preact.js +2 -0
  69. package/preact/dist/preact.js.map +1 -0
  70. package/preact/dist/preact.min.js +2 -0
  71. package/preact/dist/preact.min.js.map +1 -0
  72. package/preact/dist/preact.mjs +2 -0
  73. package/preact/dist/preact.module.js +2 -0
  74. package/preact/dist/preact.module.js.map +1 -0
  75. package/preact/dist/preact.umd.js +2 -0
  76. package/preact/dist/preact.umd.js.map +1 -0
  77. package/preact/hooks/dist/hooks.js +2 -0
  78. package/preact/hooks/dist/hooks.js.map +1 -0
  79. package/preact/hooks/dist/hooks.mjs +2 -0
  80. package/preact/hooks/dist/hooks.module.js +2 -0
  81. package/preact/hooks/dist/hooks.module.js.map +1 -0
  82. package/preact/hooks/dist/hooks.umd.js +2 -0
  83. package/preact/hooks/dist/hooks.umd.js.map +1 -0
  84. package/preact/hooks/package.json +26 -0
  85. package/preact/hooks/src/index.d.ts +130 -0
  86. package/preact/hooks/src/index.js +386 -0
  87. package/preact/hooks/src/internal.d.ts +75 -0
  88. package/preact/jsx-runtime/dist/jsxRuntime.js +2 -0
  89. package/preact/jsx-runtime/dist/jsxRuntime.js.map +1 -0
  90. package/preact/jsx-runtime/dist/jsxRuntime.mjs +2 -0
  91. package/preact/jsx-runtime/dist/jsxRuntime.module.js +2 -0
  92. package/preact/jsx-runtime/dist/jsxRuntime.module.js.map +1 -0
  93. package/preact/jsx-runtime/dist/jsxRuntime.umd.js +2 -0
  94. package/preact/jsx-runtime/dist/jsxRuntime.umd.js.map +1 -0
  95. package/preact/jsx-runtime/package.json +19 -0
  96. package/preact/jsx-runtime/src/index.d.ts +50 -0
  97. package/preact/jsx-runtime/src/index.js +72 -0
  98. package/preact/package.json +268 -0
  99. package/preact/src/cjs.js +3 -0
  100. package/preact/src/clone-element.js +39 -0
  101. package/preact/src/component.js +225 -0
  102. package/preact/src/constants.js +3 -0
  103. package/preact/src/create-context.js +68 -0
  104. package/preact/src/create-element.js +100 -0
  105. package/preact/src/diff/catch-error.js +38 -0
  106. package/preact/src/diff/children.js +347 -0
  107. package/preact/src/diff/index.js +516 -0
  108. package/preact/src/diff/props.js +158 -0
  109. package/preact/src/index.d.ts +310 -0
  110. package/preact/src/index.js +13 -0
  111. package/preact/src/internal.d.ts +147 -0
  112. package/preact/src/jsx.d.ts +955 -0
  113. package/preact/src/options.js +17 -0
  114. package/preact/src/render.js +74 -0
  115. package/preact/src/util.js +23 -0
  116. package/preact/test-utils/dist/testUtils.js +2 -0
  117. package/preact/test-utils/dist/testUtils.js.map +1 -0
  118. package/preact/test-utils/dist/testUtils.mjs +2 -0
  119. package/preact/test-utils/dist/testUtils.module.js +2 -0
  120. package/preact/test-utils/dist/testUtils.module.js.map +1 -0
  121. package/preact/test-utils/dist/testUtils.umd.js +2 -0
  122. package/preact/test-utils/dist/testUtils.umd.js.map +1 -0
  123. package/preact/test-utils/package.json +19 -0
  124. package/preact/test-utils/src/index.d.ts +3 -0
  125. package/preact/test-utils/src/index.js +117 -0
  126. package/lib/PropertiesPanel.js +0 -126
  127. package/lib/PropertiesPanel.js.map +0 -1
  128. package/lib/components/DropdownButton.js +0 -109
  129. package/lib/components/DropdownButton.js.map +0 -1
  130. package/lib/components/Group.js +0 -75
  131. package/lib/components/Group.js.map +0 -1
  132. package/lib/components/Header.js +0 -49
  133. package/lib/components/Header.js.map +0 -1
  134. package/lib/components/HeaderButton.js +0 -16
  135. package/lib/components/HeaderButton.js.map +0 -1
  136. package/lib/components/ListGroup.js +0 -167
  137. package/lib/components/ListGroup.js.map +0 -1
  138. package/lib/components/ListItem.js +0 -37
  139. package/lib/components/ListItem.js.map +0 -1
  140. package/lib/components/entries/Checkbox.js +0 -81
  141. package/lib/components/entries/Checkbox.js.map +0 -1
  142. package/lib/components/entries/Collapsible.js +0 -48
  143. package/lib/components/entries/Collapsible.js.map +0 -1
  144. package/lib/components/entries/List.js +0 -204
  145. package/lib/components/entries/List.js.map +0 -1
  146. package/lib/components/entries/NumberField.js +0 -108
  147. package/lib/components/entries/NumberField.js.map +0 -1
  148. package/lib/components/entries/Select.js +0 -107
  149. package/lib/components/entries/Select.js.map +0 -1
  150. package/lib/components/entries/Simple.js +0 -56
  151. package/lib/components/entries/Simple.js.map +0 -1
  152. package/lib/components/entries/TextArea.js +0 -96
  153. package/lib/components/entries/TextArea.js.map +0 -1
  154. package/lib/components/entries/TextField.js +0 -121
  155. package/lib/components/entries/TextField.js.map +0 -1
  156. package/lib/components/entries/ToggleSwitch.js +0 -87
  157. package/lib/components/entries/ToggleSwitch.js.map +0 -1
  158. package/lib/components/icons/index.js +0 -51
  159. package/lib/components/icons/index.js.map +0 -1
  160. package/lib/context/LayoutContext.js +0 -9
  161. package/lib/context/LayoutContext.js.map +0 -1
  162. package/lib/context/index.js +0 -2
  163. package/lib/context/index.js.map +0 -1
  164. package/lib/features/debounce-input/debounceInput.js +0 -14
  165. package/lib/features/debounce-input/debounceInput.js.map +0 -1
  166. package/lib/features/debounce-input/index.js +0 -5
  167. package/lib/features/debounce-input/index.js.map +0 -1
  168. package/lib/hooks/index.js +0 -4
  169. package/lib/hooks/index.js.map +0 -1
  170. package/lib/hooks/useKeyFactory.js +0 -39
  171. package/lib/hooks/useKeyFactory.js.map +0 -1
  172. package/lib/hooks/useLayoutState.js +0 -36
  173. package/lib/hooks/useLayoutState.js.map +0 -1
  174. package/lib/hooks/usePrevious.js +0 -16
  175. package/lib/hooks/usePrevious.js.map +0 -1
  176. package/lib/index.js +0 -2
  177. 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
+ }