react-cosmos-core 6.0.0-alpha.13 → 6.0.0-alpha.16

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/dist/index.d.ts CHANGED
@@ -26,6 +26,7 @@ export * from './server/socketMessage.js';
26
26
  export * from './utils/array.js';
27
27
  export * from './utils/keys.js';
28
28
  export * from './utils/react/areNodesEqual.js';
29
+ export * from './utils/react/ClassStateMock.js';
29
30
  export * from './utils/react/getComponentName.js';
30
31
  export * from './utils/react/isReactElement.js';
31
32
  export * from './utils/string.js';
package/dist/index.js CHANGED
@@ -26,6 +26,7 @@ export * from './server/socketMessage.js';
26
26
  export * from './utils/array.js';
27
27
  export * from './utils/keys.js';
28
28
  export * from './utils/react/areNodesEqual.js';
29
+ export * from './utils/react/ClassStateMock.js';
29
30
  export * from './utils/react/getComponentName.js';
30
31
  export * from './utils/react/isReactElement.js';
31
32
  export * from './utils/string.js';
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { FixtureState, SetFixtureState } from '../fixtureState/types.js';
2
3
  import { ReactDecorator, ReactDecoratorModule, ReactFixture } from './userModuleTypes.js';
3
4
  type Props = {
@@ -10,7 +10,8 @@ type Props = {
10
10
  initialFixtureId?: FixtureId;
11
11
  selectedFixtureId?: null | FixtureId;
12
12
  renderMessage?: (msg: string) => ReactElement;
13
+ renderNoFixtureSelected?: boolean;
13
14
  onErrorReset?: () => unknown;
14
15
  };
15
- export declare function FixtureConnect({ rendererId, rendererConnect, moduleWrappers, systemDecorators, initialFixtureId, selectedFixtureId, onErrorReset, renderMessage, }: Props): JSX.Element;
16
+ export declare function FixtureConnect({ rendererId, rendererConnect, moduleWrappers, systemDecorators, initialFixtureId, selectedFixtureId, onErrorReset, renderMessage, renderNoFixtureSelected, }: Props): JSX.Element | null;
16
17
  export {};
@@ -5,12 +5,14 @@ import { LazyFixtureLoader } from './LazyFixtureLoader.js';
5
5
  import { useRendererRequest } from './useRendererRequest.js';
6
6
  import { useRendererResponse } from './useRendererResponse.js';
7
7
  import { useSelectedFixture } from './useSelectedFixture.js';
8
- export function FixtureConnect({ rendererId, rendererConnect, moduleWrappers, systemDecorators, initialFixtureId, selectedFixtureId, onErrorReset, renderMessage = defaultRenderMessage, }) {
8
+ export function FixtureConnect({ rendererId, rendererConnect, moduleWrappers, systemDecorators, initialFixtureId, selectedFixtureId, onErrorReset, renderMessage = defaultRenderMessage, renderNoFixtureSelected = true, }) {
9
9
  const { selectedFixture, setSelectedFixture, setFixtureState } = useSelectedFixture(initialFixtureId, selectedFixtureId);
10
10
  useRendererRequest(rendererId, rendererConnect, moduleWrappers, setSelectedFixture, onErrorReset);
11
11
  useRendererResponse(rendererId, rendererConnect, moduleWrappers, initialFixtureId);
12
12
  if (!selectedFixture) {
13
- return renderMessage('No fixture selected.');
13
+ return renderNoFixtureSelected
14
+ ? renderMessage('No fixture selected.')
15
+ : null;
14
16
  }
15
17
  const { fixtureId, fixtureState, renderKey } = selectedFixture;
16
18
  if (!moduleWrappers.fixtures[fixtureId.path]) {
@@ -10,7 +10,7 @@ export function FixtureLoader({ fixtureWrapper, decorators, systemDecorators, fi
10
10
  const fixtureExport = fixtureModule.default;
11
11
  const fixture = getFixture(fixtureExport, fixtureId.name);
12
12
  if (typeof fixture === 'undefined') {
13
- return renderMessage(`Invalid fixture ID: ${JSON.stringify(fixtureId)}`);
13
+ return renderMessage(`Invalid fixture name: ${fixtureId.name}`);
14
14
  }
15
15
  return (React.createElement(DecoratedFixture, { fixture: fixture, systemDecorators: systemDecorators, userDecoratorModules: decoratorModules, fixtureState: fixtureState, setFixtureState: setFixtureState, renderKey: renderKey, onErrorReset: onErrorReset }));
16
16
  }
@@ -14,7 +14,7 @@ export function LazyFixtureLoader({ rendererId, rendererConnect, fixtureWrapper,
14
14
  const fixtureExport = fixtureModule.default;
15
15
  const fixture = getFixture(fixtureExport, fixtureId.name);
16
16
  if (typeof fixture === 'undefined') {
17
- return renderMessage(`Invalid fixture ID: ${JSON.stringify(fixtureId)}`);
17
+ return renderMessage(`Invalid fixture name: ${fixtureId.name}`);
18
18
  }
19
19
  return (React.createElement(React.Fragment, null,
20
20
  React.createElement(DecoratedFixture, { fixture: fixture, systemDecorators: systemDecorators, userDecoratorModules: decoratorModules, fixtureState: fixtureState, setFixtureState: setFixtureState, renderKey: renderKey, onErrorReset: onErrorReset }),
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  import { ReactDecorator, ReactDecoratorProps, ReactFixture } from '../userModuleTypes.js';
2
3
  export declare function getDecoratedFixtureElement(fixture: ReactFixture, decorators: ReactDecorator[], decoratorProps: Omit<ReactDecoratorProps, 'children'>): JSX.Element;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ export type Props = {
3
+ children: React.ClassicElement<unknown>;
4
+ state?: {};
5
+ };
6
+ export declare class ClassStateMock extends React.Component<Props> {
7
+ static cosmosCapture: boolean;
8
+ childRef: React.Component | null;
9
+ render(): React.CElement<unknown, React.Component<{}, {}, any>>;
10
+ componentDidUpdate(prevProps: Props): void;
11
+ handleRef: (childRef: React.Component | null) => void;
12
+ }
@@ -0,0 +1,73 @@
1
+ import { isEqual } from 'lodash-es';
2
+ import React from 'react';
3
+ // Compied from https://github.com/skidding/react-mock/blob/c33dfa1d6f0c9ce7b3eaba073618d61731a0e82e/packages/state/src/index.js
4
+ class ClassStateMock extends React.Component {
5
+ static cosmosCapture = false;
6
+ childRef = null;
7
+ render() {
8
+ const { children } = this.props;
9
+ if (Array.isArray(children)) {
10
+ throw new Error('ClassStateMock only accepts a single child element');
11
+ }
12
+ return React.cloneElement(children, { ref: this.handleRef });
13
+ }
14
+ componentDidUpdate(prevProps) {
15
+ const { childRef } = this;
16
+ const { state } = this.props;
17
+ if (!childRef) {
18
+ throw new Error('childRef missing in ClassStateMock.componentDidUpdate');
19
+ }
20
+ if (state && !isEqual(state, prevProps.state)) {
21
+ replaceState(childRef, state);
22
+ }
23
+ }
24
+ handleRef = (childRef) => {
25
+ const prevRef = this.props.children.ref;
26
+ this.childRef = childRef;
27
+ if (!childRef) {
28
+ if (prevRef)
29
+ manuallyCallRef(prevRef, childRef);
30
+ // Nothing else to do on the unmount branch (when refs are set to NULL)
31
+ return;
32
+ }
33
+ if (this.props.state) {
34
+ // Wait until state has been set to call prev ref. This will give the
35
+ // impression that the mocked state is the initial state.
36
+ replaceState(childRef, this.props.state, () => {
37
+ manuallyCallRef(prevRef, childRef);
38
+ });
39
+ }
40
+ else {
41
+ manuallyCallRef(prevRef, childRef);
42
+ }
43
+ };
44
+ }
45
+ export { ClassStateMock };
46
+ function replaceState(childRef, state, cb) {
47
+ // We need to unset existing state keys because React doesn't provide a
48
+ // replaceState method (anymore)
49
+ // https://reactjs.org/docs/react-component.html#setstate
50
+ const nextState = resetOriginalKeys(childRef.state, state);
51
+ if (!isEqual(nextState, childRef.state)) {
52
+ childRef.setState(nextState, cb);
53
+ }
54
+ }
55
+ function resetOriginalKeys(original, current) {
56
+ const { keys } = Object;
57
+ return keys(original).reduce((result, key) => keys(result).indexOf(key) === -1
58
+ ? { ...result, [key]: undefined }
59
+ : result, current);
60
+ }
61
+ function manuallyCallRef(ref, elRef) {
62
+ if (typeof ref === 'string') {
63
+ throw new Error('StateMock does not support string refs');
64
+ }
65
+ // https://reactjs.org/docs/refs-and-the-dom.html#creating-refs
66
+ if (typeof ref === 'function') {
67
+ ref(elRef);
68
+ }
69
+ else if (ref && typeof ref === 'object') {
70
+ // @ts-ignore
71
+ ref.current = elRef;
72
+ }
73
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-cosmos-core",
3
- "version": "6.0.0-alpha.13",
3
+ "version": "6.0.0-alpha.16",
4
4
  "description": "React Cosmos Core",
5
5
  "repository": "https://github.com/react-cosmos/react-cosmos/tree/main/packages/react-cosmos-core",
6
6
  "license": "MIT",
@@ -11,5 +11,5 @@
11
11
  "lodash-es": "^4.17.21",
12
12
  "react-is": "^18.2.0"
13
13
  },
14
- "gitHead": "cf95e67ce942f6a242f023ecebe45d6916d5b753"
14
+ "gitHead": "2a4ec3107303a4a47e09d63e557cee5f8cceb972"
15
15
  }