react-cosmos-ui 6.0.0-alpha.13 → 6.0.0-alpha.14

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 (66) hide show
  1. package/dist/{plugins/ContentOverlay/shared.d.ts → components/ContentOverlay.d.ts} +2 -4
  2. package/dist/{plugins/ContentOverlay/shared.js → components/ContentOverlay.js} +7 -2
  3. package/dist/components/DelayedLoading.d.ts +7 -0
  4. package/dist/components/DelayedLoading.js +12 -0
  5. package/dist/index.d.ts +0 -1
  6. package/dist/index.js +0 -1
  7. package/dist/playground.bundle.js +485 -482
  8. package/dist/playground.bundle.js.map +1 -1
  9. package/dist/playground.js +7 -1
  10. package/dist/plugins/FixtureSearch/FixtureSearchHeader.d.ts +2 -2
  11. package/dist/plugins/FixtureSearch/FixtureSearchHeader.js +2 -2
  12. package/dist/plugins/FixtureSearch/index.js +2 -1
  13. package/dist/plugins/FixtureTree/FixtureTreeContainer.d.ts +1 -2
  14. package/dist/plugins/FixtureTree/FixtureTreeContainer.js +1 -3
  15. package/dist/plugins/FixtureTree/index.js +1 -1
  16. package/dist/plugins/RendererCore/index.js +8 -3
  17. package/dist/plugins/RendererCore/spec.d.ts +3 -1
  18. package/dist/plugins/RendererPreview/RendererOverlay/RendererNotResponding.js +110 -0
  19. package/dist/plugins/RendererPreview/RendererOverlay/RendererOverlay.d.ts +7 -0
  20. package/dist/plugins/RendererPreview/RendererOverlay/RendererOverlay.js +12 -0
  21. package/dist/plugins/RendererPreview/RendererOverlay/WaitingForRenderer.d.ts +1 -0
  22. package/dist/plugins/RendererPreview/RendererOverlay/WaitingForRenderer.js +28 -0
  23. package/dist/plugins/RendererPreview/RendererPreview.d.ts +3 -0
  24. package/dist/plugins/RendererPreview/RendererPreview.js +10 -4
  25. package/dist/plugins/RendererPreview/index.js +1 -1
  26. package/dist/plugins/RendererPreview/shared.d.ts +1 -3
  27. package/dist/plugins/ResponsivePreview/ResponsivePreview/ResponsivePreview.d.ts +1 -2
  28. package/dist/plugins/ResponsivePreview/ResponsivePreview/ResponsivePreview.js +2 -2
  29. package/dist/plugins/ResponsivePreview/index.js +2 -3
  30. package/dist/plugins/Root/GlobalHeader.d.ts +1 -4
  31. package/dist/plugins/Root/GlobalHeader.js +2 -23
  32. package/dist/plugins/Root/HomeOverlay/HomeOverlay.d.ts +7 -0
  33. package/dist/plugins/Root/HomeOverlay/HomeOverlay.js +6 -0
  34. package/dist/plugins/{ContentOverlay → Root/HomeOverlay}/KeyShortcut.js +2 -2
  35. package/dist/plugins/{ContentOverlay → Root/HomeOverlay}/NoFixtureSelected.js +5 -5
  36. package/dist/plugins/Root/HomeOverlay/WelcomeCosmos.js +159 -0
  37. package/dist/plugins/Root/HomeOverlay/welcomeDismiss.d.ts +7 -0
  38. package/dist/plugins/{ContentOverlay → Root/HomeOverlay}/welcomeDismiss.js +6 -4
  39. package/dist/plugins/Root/Root.d.ts +4 -3
  40. package/dist/plugins/Root/Root.js +9 -10
  41. package/dist/plugins/Root/index.js +5 -4
  42. package/dist/plugins/Root/panelOpen.js +0 -5
  43. package/dist/plugins/pluginEntry.d.ts +0 -1
  44. package/dist/plugins/pluginEntry.js +0 -1
  45. package/dist/style/vars.d.ts +1 -0
  46. package/dist/style/vars.js +1 -0
  47. package/dist/testHelpers/pluginMocks.d.ts +0 -2
  48. package/dist/testHelpers/pluginMocks.js +0 -1
  49. package/package.json +3 -3
  50. package/dist/plugins/ContentOverlay/ContentOverlay.d.ts +0 -13
  51. package/dist/plugins/ContentOverlay/ContentOverlay.js +0 -34
  52. package/dist/plugins/ContentOverlay/RendererNotResponding.js +0 -109
  53. package/dist/plugins/ContentOverlay/WelcomeCosmos.js +0 -158
  54. package/dist/plugins/ContentOverlay/cosmos.decorator.d.ts +0 -5
  55. package/dist/plugins/ContentOverlay/cosmos.decorator.js +0 -13
  56. package/dist/plugins/ContentOverlay/index.d.ts +0 -2
  57. package/dist/plugins/ContentOverlay/index.js +0 -19
  58. package/dist/plugins/ContentOverlay/spec.d.ts +0 -3
  59. package/dist/plugins/ContentOverlay/spec.js +0 -1
  60. package/dist/plugins/ContentOverlay/welcomeDismiss.d.ts +0 -7
  61. package/dist/plugins/RendererCore/isValidFixtureSelected.d.ts +0 -2
  62. package/dist/plugins/RendererCore/isValidFixtureSelected.js +0 -17
  63. /package/dist/plugins/{ContentOverlay → RendererPreview/RendererOverlay}/RendererNotResponding.d.ts +0 -0
  64. /package/dist/plugins/{ContentOverlay → Root/HomeOverlay}/KeyShortcut.d.ts +0 -0
  65. /package/dist/plugins/{ContentOverlay → Root/HomeOverlay}/NoFixtureSelected.d.ts +0 -0
  66. /package/dist/plugins/{ContentOverlay → Root/HomeOverlay}/WelcomeCosmos.d.ts +0 -0
@@ -37,5 +37,11 @@ async function loadPluginScript(scriptPath) {
37
37
  const normalizedPath = scriptPath.startsWith('/')
38
38
  ? scriptPath
39
39
  : `/${scriptPath}`;
40
- await import(/* webpackIgnore: true */ `./_plugin${normalizedPath}`);
40
+ try {
41
+ await import(/* webpackIgnore: true */ `./_plugin${normalizedPath}`);
42
+ }
43
+ catch (err) {
44
+ console.log(`[Cosmos] Failed to load plugin script ${scriptPath}`);
45
+ console.log(err);
46
+ }
41
47
  }
@@ -1,7 +1,7 @@
1
1
  type Props = {
2
- validFixtureSelected: boolean;
2
+ fixtureSelected: boolean;
3
3
  onOpen: () => unknown;
4
4
  onCloseNav: () => unknown;
5
5
  };
6
- export declare function FixtureSearchHeader({ validFixtureSelected, onOpen, onCloseNav, }: Props): JSX.Element;
6
+ export declare function FixtureSearchHeader({ fixtureSelected, onOpen, onCloseNav, }: Props): JSX.Element;
7
7
  export {};
@@ -4,7 +4,7 @@ import { IconButton32 } from '../../components/buttons/index.js';
4
4
  import { ChevronLeftIcon, SearchIcon } from '../../components/icons/index.js';
5
5
  import { KeyBox } from '../../components/KeyBox.js';
6
6
  import { blue, grey160, grey32, white10 } from '../../style/colors.js';
7
- export function FixtureSearchHeader({ validFixtureSelected, onOpen, onCloseNav, }) {
7
+ export function FixtureSearchHeader({ fixtureSelected, onOpen, onCloseNav, }) {
8
8
  return (React.createElement(Container, null,
9
9
  React.createElement(SearchButton, { onClick: onOpen },
10
10
  React.createElement(SearchIconContainer, null,
@@ -13,7 +13,7 @@ export function FixtureSearchHeader({ validFixtureSelected, onOpen, onCloseNav,
13
13
  React.createElement(KeyBox, { value: '⌘', bgColor: white10, textColor: grey160, size: 20 }),
14
14
  React.createElement(KeyBox, { value: 'P', bgColor: white10, textColor: grey160, size: 20 })),
15
15
  React.createElement(NavButtonContainer, null,
16
- React.createElement(IconButton32, { icon: React.createElement(ChevronLeftIcon, null), title: "Hide fixture list", disabled: !validFixtureSelected, selected: false, onClick: onCloseNav }))));
16
+ React.createElement(IconButton32, { icon: React.createElement(ChevronLeftIcon, null), title: "Hide fixture list", disabled: !fixtureSelected, selected: false, onClick: onCloseNav }))));
17
17
  }
18
18
  const Container = styled.div `
19
19
  display: flex;
@@ -18,6 +18,7 @@ onLoad(pluginContext => {
18
18
  });
19
19
  namedPlug('navRow', 'fixtureSearch', ({ pluginContext, slotProps }) => {
20
20
  const { getMethodsOf } = pluginContext;
21
+ const router = getMethodsOf('router');
21
22
  const rendererCore = getMethodsOf('rendererCore');
22
23
  const fixtures = rendererCore.getFixtures();
23
24
  const onOpen = useOnOpen(pluginContext);
@@ -26,7 +27,7 @@ namedPlug('navRow', 'fixtureSearch', ({ pluginContext, slotProps }) => {
26
27
  if (Object.keys(fixtures).length === 0) {
27
28
  return null;
28
29
  }
29
- return (React.createElement(FixtureSearchHeader, { validFixtureSelected: rendererCore.isValidFixtureSelected(), onOpen: onOpen, onCloseNav: onCloseNav }));
30
+ return (React.createElement(FixtureSearchHeader, { fixtureSelected: router.getSelectedFixtureId() !== null, onOpen: onOpen, onCloseNav: onCloseNav }));
30
31
  });
31
32
  namedPlug('global', 'fixtureSearch', ({ pluginContext }) => {
32
33
  const { getState, getMethodsOf } = pluginContext;
@@ -4,11 +4,10 @@ type Props = {
4
4
  fixturesDir: string;
5
5
  fixtureFileSuffix: string;
6
6
  selectedFixtureId: null | FixtureId;
7
- rendererConnected: boolean;
8
7
  fixtures: FixtureList;
9
8
  expansion: TreeExpansion;
10
9
  selectFixture: (fixtureId: FixtureId) => void;
11
10
  setExpansion: (expansion: TreeExpansion) => unknown;
12
11
  };
13
- export declare function FixtureTreeContainer({ fixturesDir, fixtureFileSuffix, selectedFixtureId, rendererConnected, fixtures, expansion, selectFixture, setExpansion, }: Props): JSX.Element;
12
+ export declare function FixtureTreeContainer({ fixturesDir, fixtureFileSuffix, selectedFixtureId, fixtures, expansion, selectFixture, setExpansion, }: Props): JSX.Element;
14
13
  export {};
@@ -6,11 +6,9 @@ import { BlankState } from './BlankState.js';
6
6
  import { FixtureTree } from './FixtureTree/FixtureTree.js';
7
7
  import { FixtureTreeHeader } from './FixtureTreeHeader.js';
8
8
  import { useScrollToSelected } from './useScrollToSelected.js';
9
- export function FixtureTreeContainer({ fixturesDir, fixtureFileSuffix, selectedFixtureId, rendererConnected, fixtures, expansion, selectFixture, setExpansion, }) {
9
+ export function FixtureTreeContainer({ fixturesDir, fixtureFileSuffix, selectedFixtureId, fixtures, expansion, selectFixture, setExpansion, }) {
10
10
  const rootNode = useMemo(() => createFixtureTree({ fixtures, fixturesDir, fixtureFileSuffix }), [fixtures, fixturesDir, fixtureFileSuffix]);
11
11
  const { containerRef, selectedRef } = useScrollToSelected(selectedFixtureId);
12
- if (!rendererConnected)
13
- return React.createElement(TreeContainer, null);
14
12
  if (Object.keys(fixtures).length === 0) {
15
13
  return (React.createElement(TreeContainer, null,
16
14
  React.createElement(BlankState, { fixturesDir: fixturesDir, fixtureFileSuffix: fixtureFileSuffix })));
@@ -18,7 +18,7 @@ namedPlug('navRow', 'fixtureTree', ({ pluginContext }) => {
18
18
  const rendererCore = getMethodsOf('rendererCore');
19
19
  const expansion = getTreeExpansion(storage);
20
20
  const setExpansionMemo = useCallback((newExpansion) => setTreeExpansion(storage, newExpansion), [storage]);
21
- return (React.createElement(FixtureTreeContainer, { fixturesDir: fixturesDir, fixtureFileSuffix: fixtureFileSuffix, selectedFixtureId: router.getSelectedFixtureId(), rendererConnected: rendererCore.isRendererConnected(), fixtures: rendererCore.getFixtures(), expansion: expansion, selectFixture: router.selectFixture, setExpansion: setExpansionMemo }));
21
+ return (React.createElement(FixtureTreeContainer, { fixturesDir: fixturesDir, fixtureFileSuffix: fixtureFileSuffix, selectedFixtureId: router.getSelectedFixtureId(), fixtures: rendererCore.getFixtures(), expansion: expansion, selectFixture: router.selectFixture, setExpansion: setExpansionMemo }));
22
22
  });
23
23
  export { register };
24
24
  if (process.env.NODE_ENV !== 'test')
@@ -1,10 +1,12 @@
1
1
  import { createPlugin } from 'react-plugin';
2
- import { isValidFixtureSelected } from './isValidFixtureSelected.js';
3
2
  import { onRouterFixtureChange } from './onRouterFixtureChange.js';
4
3
  import { receiveResponse } from './receiveResponse/index.js';
5
4
  import { setFixtureState } from './setFixtureState.js';
6
- const { on, register } = createPlugin({
5
+ const { on, register, onLoad } = createPlugin({
7
6
  name: 'rendererCore',
7
+ defaultConfig: {
8
+ fixtures: {},
9
+ },
8
10
  initialState: {
9
11
  connectedRendererIds: [],
10
12
  primaryRendererId: null,
@@ -17,12 +19,15 @@ const { on, register } = createPlugin({
17
19
  getFixtures,
18
20
  getFixtureState,
19
21
  isRendererConnected,
20
- isValidFixtureSelected,
21
22
  setFixtureState,
22
23
  selectPrimaryRenderer,
23
24
  receiveResponse,
24
25
  },
25
26
  });
27
+ onLoad(({ getConfig, setState }) => {
28
+ const { fixtures } = getConfig();
29
+ setState(prevState => ({ ...prevState, fixtures }));
30
+ });
26
31
  on('router', { fixtureChange: onRouterFixtureChange });
27
32
  export { register };
28
33
  if (process.env.NODE_ENV !== 'test')
@@ -1,6 +1,9 @@
1
1
  import { FixtureList, FixtureState, MessageType, RendererId, StateUpdater } from 'react-cosmos-core';
2
2
  export type RendererCoreSpec = {
3
3
  name: 'rendererCore';
4
+ config: {
5
+ fixtures: FixtureList;
6
+ };
4
7
  state: {
5
8
  connectedRendererIds: RendererId[];
6
9
  primaryRendererId: null | RendererId;
@@ -13,7 +16,6 @@ export type RendererCoreSpec = {
13
16
  getFixtures(): FixtureList;
14
17
  getFixtureState(): FixtureState;
15
18
  isRendererConnected(): boolean;
16
- isValidFixtureSelected(): boolean;
17
19
  setFixtureState(stateUpdater: StateUpdater<FixtureState>): void;
18
20
  selectPrimaryRenderer(primaryRendererId: RendererId): void;
19
21
  receiveResponse(msg: MessageType): void;
@@ -0,0 +1,110 @@
1
+ import React from 'react';
2
+ import { Slot } from 'react-plugin';
3
+ import styled from 'styled-components';
4
+ import { IllustrationContainer, NoWrap, OverlayBody, RendererOverlayContainer, TextContainer, } from '../../../components/ContentOverlay.js';
5
+ import { ArtificialIntelligenceIllustration } from '../../../components/illustrations/ArtificialIntelligence.js';
6
+ import { screenGrey3, screenGrey5, screenPrimary2, screenPrimary3, } from '../../../style/colors.js';
7
+ export function RendererNotResponding() {
8
+ return (React.createElement(RendererOverlayContainer, null,
9
+ React.createElement(OverlayBody, null,
10
+ React.createElement(TextContainer, null,
11
+ React.createElement(Header, null,
12
+ "Renderer ",
13
+ React.createElement(NoWrap, null, "not responding")),
14
+ React.createElement(Paragraph, null, `It's usually one of the following...`),
15
+ React.createElement(List, null,
16
+ React.createElement("li", null,
17
+ React.createElement(No, null, "1"),
18
+ React.createElement("span", null,
19
+ React.createElement("strong", null, "Please check your terminal for errors."),
20
+ React.createElement("br", null),
21
+ "Your build might be broken.")),
22
+ React.createElement("li", null,
23
+ React.createElement(No, null, "2"),
24
+ React.createElement("span", null,
25
+ React.createElement(Slot, { name: "rendererError" },
26
+ "If you use a bundler plugin,",
27
+ ' ',
28
+ React.createElement("strong", null,
29
+ "make sure",
30
+ React.createElement("br", null),
31
+ "your build is generating an index.html page."))))),
32
+ React.createElement(Paragraph, null,
33
+ React.createElement(ActionLink, { href: "https://discord.gg/3X95VgfnW5", rel: "noopener noreferrer", target: "_blank" }, "ask for help"))),
34
+ React.createElement(IllustrationContainer, null,
35
+ React.createElement(ArtificialIntelligenceIllustration, { title: "robot" })))));
36
+ }
37
+ const Header = styled.h1 `
38
+ position: relative;
39
+ margin: 0 0 64px 0;
40
+ color: ${screenPrimary2};
41
+ font-size: 30px;
42
+ font-weight: 700;
43
+ line-height: 1.2em;
44
+ text-transform: uppercase;
45
+ letter-spacing: 0.015em;
46
+
47
+ ::after {
48
+ content: '';
49
+ position: absolute;
50
+ bottom: -12px;
51
+ left: 0;
52
+ width: 64px;
53
+ height: 3px;
54
+ background: ${screenPrimary2};
55
+ }
56
+ `;
57
+ const Paragraph = styled.p `
58
+ margin: 16px 0;
59
+
60
+ :last-child {
61
+ margin-bottom: 0;
62
+ }
63
+ `;
64
+ const List = styled.ul `
65
+ margin: 0 0 48px 0;
66
+ padding: 0;
67
+ list-style: none;
68
+
69
+ li {
70
+ display: flex;
71
+ flex-direction: row;
72
+ align-items: flex-start;
73
+ margin-bottom: 12px;
74
+ }
75
+ `;
76
+ const No = styled.span `
77
+ flex-shrink: 0;
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: flex-end;
81
+ box-sizing: border-box;
82
+ width: 32px;
83
+ height: 32px;
84
+ margin: 6px 16px 0 0;
85
+ padding: 0 6px 0 0;
86
+ border-radius: 100%;
87
+ font-size: 18px;
88
+ font-weight: 600;
89
+ background: ${screenGrey5};
90
+ color: ${screenGrey3};
91
+
92
+ ::after {
93
+ content: '.';
94
+ }
95
+ `;
96
+ const actionLinkHeight = 36;
97
+ const ActionLink = styled.a `
98
+ display: inline-block;
99
+ height: ${actionLinkHeight}px;
100
+ padding: 0 16px;
101
+ background: ${screenPrimary3};
102
+ color: #fff;
103
+ border-radius: 5px;
104
+ font-size: 12px;
105
+ font-weight: 700;
106
+ line-height: ${actionLinkHeight}px;
107
+ text-transform: uppercase;
108
+ letter-spacing: 0.1em;
109
+ text-decoration: none;
110
+ `;
@@ -0,0 +1,7 @@
1
+ import { RuntimeStatus, UrlStatus } from '../spec.js';
2
+ type Props = {
3
+ rendererPreviewUrlStatus: UrlStatus;
4
+ rendererPreviewRuntimeStatus: RuntimeStatus;
5
+ };
6
+ export declare function RendererOverlay({ rendererPreviewUrlStatus, rendererPreviewRuntimeStatus, }: Props): JSX.Element | null;
7
+ export {};
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { RendererNotResponding } from './RendererNotResponding.js';
3
+ import { WaitingForRenderer } from './WaitingForRenderer.js';
4
+ export function RendererOverlay({ rendererPreviewUrlStatus, rendererPreviewRuntimeStatus, }) {
5
+ if (rendererPreviewUrlStatus === 'error') {
6
+ return React.createElement(RendererNotResponding, null);
7
+ }
8
+ if (rendererPreviewRuntimeStatus === 'pending') {
9
+ return React.createElement(WaitingForRenderer, null);
10
+ }
11
+ return null;
12
+ }
@@ -0,0 +1 @@
1
+ export declare function WaitingForRenderer(): JSX.Element;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { OverlayBody, RendererOverlayContainer, TextContainer, } from '../../../components/ContentOverlay.js';
4
+ import { DelayedLoading } from '../../../components/DelayedLoading.js';
5
+ export function WaitingForRenderer() {
6
+ const [count, setCount] = React.useState(0);
7
+ React.useEffect(() => {
8
+ const interval = setInterval(() => setCount(prev => prev + 1), 600);
9
+ return () => clearInterval(interval);
10
+ });
11
+ const dots = Array((count % 3) + 1)
12
+ .fill('.')
13
+ .join('');
14
+ return (React.createElement(DelayedLoading, { delay: 500 },
15
+ React.createElement(RendererOverlayContainer, null,
16
+ React.createElement(OverlayBody, null,
17
+ React.createElement(TextContainer, null,
18
+ React.createElement(Message, null,
19
+ "Waiting for renderer",
20
+ dots))))));
21
+ }
22
+ const Message = styled.p `
23
+ margin: 0 auto;
24
+ width: 210px;
25
+ font-weight: 600;
26
+ text-transform: uppercase;
27
+ white-space: nowrap;
28
+ `;
@@ -1,7 +1,10 @@
1
1
  import React from 'react';
2
+ import { RuntimeStatus, UrlStatus } from './spec.js';
2
3
  export type OnIframeRef = (elRef: null | HTMLIFrameElement) => void;
3
4
  type Props = {
4
5
  rendererUrl: null | string;
6
+ urlStatus: UrlStatus;
7
+ runtimeStatus: RuntimeStatus;
5
8
  onIframeRef: OnIframeRef;
6
9
  };
7
10
  export declare const RendererPreview: React.NamedExoticComponent<Props>;
@@ -1,19 +1,25 @@
1
1
  import React from 'react';
2
2
  import { Slot } from 'react-plugin';
3
3
  import styled from 'styled-components';
4
- export const RendererPreview = React.memo(function RendererPreview({ rendererUrl, onIframeRef, }) {
4
+ import { rendererBg } from '../../style/vars.js';
5
+ import { RendererOverlay } from './RendererOverlay/RendererOverlay.js';
6
+ import { WaitingForRenderer } from './RendererOverlay/WaitingForRenderer.js';
7
+ export const RendererPreview = React.memo(function RendererPreview({ rendererUrl, urlStatus, runtimeStatus, onIframeRef, }) {
5
8
  if (!rendererUrl) {
6
- return null;
9
+ // This code path is used when Cosmos is in React Native mode
10
+ return (React.createElement(Container, null, runtimeStatus === 'pending' && React.createElement(WaitingForRenderer, null)));
7
11
  }
8
12
  return (React.createElement(Slot, { name: "rendererPreviewOuter" },
9
13
  React.createElement(Container, null,
10
- React.createElement(Iframe, { "data-testid": "previewIframe", ref: onIframeRef, src: rendererUrl, frameBorder: 0, allow: "clipboard-write *" }))));
14
+ React.createElement(Iframe, { "data-testid": "previewIframe", ref: onIframeRef, src: rendererUrl, frameBorder: 0, allow: "clipboard-write *" }),
15
+ React.createElement(RendererOverlay, { rendererPreviewUrlStatus: urlStatus, rendererPreviewRuntimeStatus: runtimeStatus }))));
11
16
  });
12
17
  const Container = styled.div `
18
+ position: relative;
13
19
  width: 100%;
14
20
  height: 100%;
15
21
  background-color: #fff;
16
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23f1f1f1' fill-opacity='0.4'%3E%3Cpath opacity='.5' d='M96 95h4v1h-4v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9zm-1 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9z'/%3E%3Cpath d='M6 5V0H5v5H0v1h5v94h1V6h94V5H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
22
+ background-image: ${rendererBg};
17
23
  `;
18
24
  const Iframe = styled.iframe `
19
25
  display: block;
@@ -33,7 +33,7 @@ plug('rendererPreview', ({ pluginContext }) => {
33
33
  function handleIframeRef(ref) {
34
34
  setIframeRef(pluginContext, ref);
35
35
  }
36
- return (React.createElement(RendererPreview, { rendererUrl: getRendererUrl(pluginContext), onIframeRef: handleIframeRef }));
36
+ return (React.createElement(RendererPreview, { rendererUrl: getRendererUrl(pluginContext), urlStatus: pluginContext.getState().urlStatus, runtimeStatus: pluginContext.getState().runtimeStatus, onIframeRef: handleIframeRef }));
37
37
  });
38
38
  export { register };
39
39
  if (process.env.NODE_ENV !== 'test')
@@ -1,7 +1,5 @@
1
1
  import { PluginContext } from 'react-plugin';
2
- import { RendererPreviewSpec } from './spec.js';
3
- export type UrlStatus = 'unknown' | 'ok' | 'error';
4
- export type RuntimeStatus = 'pending' | 'connected' | 'error';
2
+ import { RendererPreviewSpec, RuntimeStatus, UrlStatus } from './spec.js';
5
3
  export type State = {
6
4
  urlStatus: UrlStatus;
7
5
  runtimeStatus: RuntimeStatus;
@@ -6,9 +6,8 @@ type Props = {
6
6
  enabled: boolean;
7
7
  viewport: ResponsiveViewport;
8
8
  scaled: boolean;
9
- validFixtureSelected: boolean;
10
9
  setViewport: Dispatch<SetStateAction<ResponsiveViewport>>;
11
10
  setScaled: (scaled: boolean) => unknown;
12
11
  };
13
- export declare function ResponsivePreview({ children, devices, enabled, viewport, scaled, validFixtureSelected, setViewport, setScaled, }: Props): JSX.Element;
12
+ export declare function ResponsivePreview({ children, devices, enabled, viewport, scaled, setViewport, setScaled, }: Props): JSX.Element;
14
13
  export {};
@@ -5,7 +5,7 @@ import { useDrag } from '../../../hooks/useDrag.js';
5
5
  import { grey64, grey8 } from '../../../style/colors.js';
6
6
  import { Header } from './Header.js';
7
7
  import { getStyles, getViewportScaleFactor, responsivePreviewBorderWidth, responsivePreviewPadding, stretchStyle, } from './style.js';
8
- export function ResponsivePreview({ children, devices, enabled, viewport, scaled, validFixtureSelected, setViewport, setScaled, }) {
8
+ export function ResponsivePreview({ children, devices, enabled, viewport, scaled, setViewport, setScaled, }) {
9
9
  const [container, setContainer] = useState(null);
10
10
  const onWidthChange = useCallback((width) => setViewport(prevViewport => ({ ...prevViewport, width })), [setViewport]);
11
11
  const onHeightChange = useCallback((height) => setViewport(prevViewport => ({ ...prevViewport, height })), [setViewport]);
@@ -53,7 +53,7 @@ export function ResponsivePreview({ children, devices, enabled, viewport, scaled
53
53
  // whenever switching between responsive and non responsive mode. By
54
54
  // returning the same element nesting between states for Preview the
55
55
  // component instances are preserved and the transition is seamless.
56
- if (!validFixtureSelected || !enabled || !container) {
56
+ if (!enabled || !container) {
57
57
  return (React.createElement(Container, null,
58
58
  React.createElement("div", { key: "preview", ref: handleContainerRef, style: stretchStyle },
59
59
  React.createElement("div", { style: stretchStyle },
@@ -10,13 +10,12 @@ const { plug, namedPlug, register } = createPlugin({
10
10
  },
11
11
  });
12
12
  plug('rendererPreviewOuter', ({ children, pluginContext }) => {
13
- const { getConfig, getMethodsOf } = pluginContext;
13
+ const { getConfig } = pluginContext;
14
14
  const { devices } = getConfig();
15
- const rendererCore = getMethodsOf('rendererCore');
16
15
  const { enabled, viewport, scaled } = getViewportState(pluginContext);
17
16
  const onViewportChange = useViewportChange(pluginContext);
18
17
  const onScaledChange = useScaledChange(pluginContext);
19
- return (React.createElement(ResponsivePreview, { devices: devices, enabled: enabled, viewport: viewport, scaled: scaled, validFixtureSelected: rendererCore.isValidFixtureSelected(), setViewport: onViewportChange, setScaled: onScaledChange }, children));
18
+ return (React.createElement(ResponsivePreview, { devices: devices, enabled: enabled, viewport: viewport, scaled: scaled, setViewport: onViewportChange, setScaled: onScaledChange }, children));
20
19
  });
21
20
  namedPlug('rendererAction', 'responsivePreview', ({ pluginContext }) => {
22
21
  const { getMethodsOf } = pluginContext;
@@ -1,9 +1,6 @@
1
- import { FixtureId } from 'react-cosmos-core';
2
1
  type Props = {
3
- selectedFixtureId: FixtureId | null;
4
2
  rendererConnected: boolean;
5
- validFixtureSelected: boolean;
6
3
  globalActionOrder: string[];
7
4
  };
8
- export declare function GlobalHeader({ selectedFixtureId, rendererConnected, validFixtureSelected, globalActionOrder, }: Props): JSX.Element;
5
+ export declare function GlobalHeader({ rendererConnected, globalActionOrder }: Props): JSX.Element;
9
6
  export {};
@@ -1,23 +1,10 @@
1
1
  import React from 'react';
2
2
  import { ArraySlot } from 'react-plugin';
3
3
  import styled from 'styled-components';
4
- import { grey176, grey32, white10 } from '../../style/colors.js';
5
- export function GlobalHeader({ selectedFixtureId, rendererConnected, validFixtureSelected, globalActionOrder, }) {
6
- function getMessage() {
7
- if (!rendererConnected) {
8
- return React.createElement(Message, null, "Waiting for renderer...");
9
- }
10
- if (!selectedFixtureId) {
11
- return React.createElement(Message, null, "No fixture selected");
12
- }
13
- if (!validFixtureSelected) {
14
- return React.createElement(Message, null, "Fixture not found");
15
- }
16
- return null;
17
- }
4
+ import { grey32, white10 } from '../../style/colors.js';
5
+ export function GlobalHeader({ rendererConnected, globalActionOrder }) {
18
6
  return (React.createElement(Container, null,
19
7
  React.createElement(Left, null),
20
- getMessage(),
21
8
  React.createElement(Right, null, rendererConnected && (React.createElement(ArraySlot, { name: "globalAction", plugOrder: globalActionOrder })))));
22
9
  }
23
10
  const Container = styled.div `
@@ -49,11 +36,3 @@ const Right = styled(Actions) `
49
36
  flex-direction: row;
50
37
  align-items: center;
51
38
  `;
52
- const Message = styled.div `
53
- padding: 4px;
54
- color: ${grey176};
55
- line-height: 24px;
56
- white-space: nowrap;
57
- text-overflow: ellipsis;
58
- overflow: hidden;
59
- `;
@@ -0,0 +1,7 @@
1
+ type Props = {
2
+ welcomeDismissed: boolean;
3
+ onDismissWelcome: () => unknown;
4
+ onShowWelcome: () => unknown;
5
+ };
6
+ export declare function HomeOverlay({ welcomeDismissed, onDismissWelcome, onShowWelcome, }: Props): JSX.Element;
7
+ export {};
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { NoFixtureSelected } from './NoFixtureSelected.js';
3
+ import { WelcomeCosmos } from './WelcomeCosmos.js';
4
+ export function HomeOverlay({ welcomeDismissed, onDismissWelcome, onShowWelcome, }) {
5
+ return welcomeDismissed ? (React.createElement(NoFixtureSelected, { onShowWelcome: onShowWelcome })) : (React.createElement(WelcomeCosmos, { onDismissWelcome: onDismissWelcome }));
6
+ }
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import styled from 'styled-components';
3
- import { KeyBox } from '../../components/KeyBox.js';
4
- import { screenGrey1, screenGrey5 } from '../../style/colors.js';
3
+ import { KeyBox } from '../../../components/KeyBox.js';
4
+ import { screenGrey1, screenGrey5 } from '../../../style/colors.js';
5
5
  export function KeyShortcut({ keys, label }) {
6
6
  return (React.createElement(Container, null,
7
7
  React.createElement(Keys, null, keys.map(key => (React.createElement(KeyBox, { key: key, value: key, bgColor: screenGrey5, textColor: screenGrey1, size: 26, fontSize: 16 })))),
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  import styled from 'styled-components';
3
- import { BlankCanvasIllustration } from '../../components/illustrations/BlankCanvas.js';
4
- import { screenGrey3 } from '../../style/colors.js';
3
+ import { IllustrationContainer, OverlayBody, OverlayContainer, SecondaryButton, TextContainer, } from '../../../components/ContentOverlay.js';
4
+ import { BlankCanvasIllustration } from '../../../components/illustrations/BlankCanvas.js';
5
+ import { screenGrey3 } from '../../../style/colors.js';
5
6
  import { KeyShortcut } from './KeyShortcut.js';
6
- import { ContentContainer, IllustrationContainer, SecondaryButton, TextContainer, } from './shared.js';
7
7
  export function NoFixtureSelected({ onShowWelcome }) {
8
- return (React.createElement(React.Fragment, null,
9
- React.createElement(ContentContainer, null,
8
+ return (React.createElement(OverlayContainer, { "data-testid": "blank" },
9
+ React.createElement(OverlayBody, null,
10
10
  React.createElement(TextContainer, null,
11
11
  React.createElement(KeyShortcut, { keys: ['⌘', 'P'], label: "Search fixtures" }),
12
12
  React.createElement(Subtitle, null, "FIXTURE SELECTED"),