Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-cosmos-ui

Package Overview
Dependencies
Maintainers
1
Versions
261
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-cosmos-ui - npm Package Compare versions

Comparing version 6.0.0-canary.0f73dbd.0 to 6.0.0-canary.10c9ae9.0

dist/pluginMocks.d.ts

2

dist/components/BaseSvg.d.ts

@@ -8,3 +8,3 @@ import React from 'react';

};
export declare function BaseSvg({ children, ...attrs }: Props): JSX.Element;
export declare function BaseSvg({ children, ...attrs }: Props): React.JSX.Element;
export {};

@@ -10,3 +10,3 @@ import React from 'react';

};
export declare function Button32({ icon, label, title, disabled, selected, onClick, }: Props): JSX.Element;
export declare function Button32({ icon, label, title, disabled, selected, onClick, }: Props): React.JSX.Element;
export {};

@@ -10,3 +10,3 @@ import React from 'react';

};
export declare function Button8({ icon, label, title, disabled, selected, onClick, }: Props): JSX.Element;
export declare function Button8({ icon, label, title, disabled, selected, onClick, }: Props): React.JSX.Element;
export {};

@@ -9,3 +9,3 @@ import React from 'react';

};
export declare function IconButton32({ icon, title, disabled, selected, onClick, }: Props): JSX.Element;
export declare function IconButton32({ icon, title, disabled, selected, onClick, }: Props): React.JSX.Element;
export {};

@@ -9,3 +9,3 @@ import React from 'react';

};
export declare function IconButton8({ icon, title, disabled, selected, onClick, }: Props): JSX.Element;
export declare function IconButton8({ icon, title, disabled, selected, onClick, }: Props): React.JSX.Element;
export {};

@@ -17,3 +17,6 @@ import styled from 'styled-components';

outline: none;
transition: background ${quick}s, color ${quick}s, opacity ${quick}s;
transition:
background ${quick}s,
color ${quick}s,
opacity ${quick}s;

@@ -20,0 +23,0 @@ :hover {

@@ -0,7 +1,11 @@

import React from 'react';
import { SvgChildren } from './BaseSvg.js';
type IconProps = {
children: SvgChildren;
export type IconProps = {
size?: number | string;
strokeWidth?: number;
};
export declare function Icon({ children, size }: IconProps): JSX.Element;
type Props = IconProps & {
children: SvgChildren;
};
export declare function Icon({ children, size, strokeWidth }: Props): React.JSX.Element;
export {};
import React from 'react';
import { BaseSvg } from './BaseSvg.js';
export function Icon({ children, size = '100%' }) {
return (React.createElement(BaseSvg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }, children));
export function Icon({ children, size = '100%', strokeWidth = 1.5 }) {
return (React.createElement(BaseSvg, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }, children));
}

@@ -1,33 +0,31 @@

type Props = {
size?: number;
};
export declare const ChevronLeftIcon: () => JSX.Element;
export declare const ChevronRightIcon: () => JSX.Element;
export declare const ChevronDownIcon: () => JSX.Element;
export declare const FolderIcon: () => JSX.Element;
export declare const XIcon: () => JSX.Element;
export declare const XCircleIcon: () => JSX.Element;
export declare const MaximizeIcon: () => JSX.Element;
export declare const SmartphoneIcon: () => JSX.Element;
export declare const Minimize2Icon: () => JSX.Element;
export declare const RefreshCwIcon: () => JSX.Element;
export declare const RefreshCcwIcon: (props: Props) => JSX.Element;
export declare const HomeIcon: () => JSX.Element;
export declare const CastIcon: () => JSX.Element;
export declare const EditIcon: () => JSX.Element;
export declare const CheckCircleIcon: () => JSX.Element;
export declare const AlertCircleIcon: () => JSX.Element;
export declare const InfoIcon: () => JSX.Element;
export declare const LoaderIcon: () => JSX.Element;
export declare const SlidersIcon: () => JSX.Element;
export declare const CopyIcon: () => JSX.Element;
export declare const RotateCcwIcon: () => JSX.Element;
export declare const FileIcon: () => JSX.Element;
export declare const SearchIcon: () => JSX.Element;
export declare const MenuIcon: () => JSX.Element;
export declare const ExternalIcon: () => JSX.Element;
export declare const HelpCircleIcon: () => JSX.Element;
export declare const MinusSquareIcon: () => JSX.Element;
export declare const PlusSquareIcon: () => JSX.Element;
export declare const StarIcon: () => JSX.Element;
export {};
import React from 'react';
import { IconProps } from '../Icon.js';
export declare const ChevronLeftIcon: () => React.JSX.Element;
export declare const ChevronRightIcon: () => React.JSX.Element;
export declare const ChevronDownIcon: () => React.JSX.Element;
export declare const FolderIcon: () => React.JSX.Element;
export declare const XIcon: () => React.JSX.Element;
export declare const XCircleIcon: () => React.JSX.Element;
export declare const MaximizeIcon: () => React.JSX.Element;
export declare const SmartphoneIcon: () => React.JSX.Element;
export declare const Minimize2Icon: () => React.JSX.Element;
export declare const RefreshCwIcon: () => React.JSX.Element;
export declare const RefreshCcwIcon: (props: IconProps) => React.JSX.Element;
export declare const HomeIcon: () => React.JSX.Element;
export declare const CastIcon: () => React.JSX.Element;
export declare const EditIcon: () => React.JSX.Element;
export declare const CheckCircleIcon: (props: IconProps) => React.JSX.Element;
export declare const AlertCircleIcon: () => React.JSX.Element;
export declare const InfoIcon: () => React.JSX.Element;
export declare const LoaderIcon: () => React.JSX.Element;
export declare const SlidersIcon: () => React.JSX.Element;
export declare const CopyIcon: () => React.JSX.Element;
export declare const RotateCcwIcon: () => React.JSX.Element;
export declare const FileIcon: () => React.JSX.Element;
export declare const SearchIcon: () => React.JSX.Element;
export declare const MenuIcon: () => React.JSX.Element;
export declare const ExternalIcon: () => React.JSX.Element;
export declare const HelpCircleIcon: () => React.JSX.Element;
export declare const MinusSquareIcon: () => React.JSX.Element;
export declare const PlusSquareIcon: () => React.JSX.Element;
export declare const StarIcon: () => React.JSX.Element;

@@ -45,3 +45,3 @@ import React from 'react';

React.createElement("polygon", { points: "18 2 22 6 12 16 8 16 8 12 18 2" })));
export const CheckCircleIcon = () => (React.createElement(Icon, null,
export const CheckCircleIcon = (props) => (React.createElement(Icon, { ...props },
React.createElement("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),

@@ -48,0 +48,0 @@ React.createElement("polyline", { points: "22 4 12 14.01 9 11.01" })));

@@ -0,1 +1,2 @@

import React from 'react';
import { SvgChildren } from './BaseSvg.js';

@@ -7,3 +8,3 @@ type Props = {

};
export declare function Illustration({ children, viewBox, size }: Props): JSX.Element;
export declare function Illustration({ children, viewBox, size }: Props): React.JSX.Element;
export {};

@@ -0,3 +1,4 @@

import React from 'react';
export declare const ArtificialIntelligenceIllustration: ({ title, }: {
title: string;
}) => JSX.Element;
}) => React.JSX.Element;

@@ -0,3 +1,4 @@

import React from 'react';
export declare const AstronautIllustration: ({ title }: {
title: string;
}) => JSX.Element;
}) => React.JSX.Element;

@@ -0,3 +1,4 @@

import React from 'react';
export declare const BlankCanvasIllustration: ({ title }: {
title: string;
}) => JSX.Element;
}) => React.JSX.Element;

@@ -0,1 +1,2 @@

import React from 'react';
export type NumberInputStyles = {

@@ -14,3 +15,3 @@ focusedColor: string;

};
export declare function NumberInput({ id, value, minValue, maxValue, styles, onChange, }: Props): JSX.Element;
export declare function NumberInput({ id, value, minValue, maxValue, styles, onChange, }: Props): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
type BaseOption = {

@@ -15,3 +16,3 @@ value: string;

};
export declare function Select<Option extends BaseOption>({ id, testId, options, value, color, height, padding, onChange, }: Props<Option>): JSX.Element;
export declare function Select<Option extends BaseOption>({ id, testId, options, value, color, height, padding, onChange, }: Props<Option>): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -8,3 +9,3 @@ value: string;

};
export declare function KeyBox({ value, bgColor, textColor, size, fontSize, }: Props): JSX.Element;
export declare function KeyBox({ value, bgColor, textColor, size, fontSize, }: Props): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
export declare const SidePanelContainer: import("styled-components").StyledComponent<"div", any, {}, never>;

@@ -7,5 +8,5 @@ export declare const SidePanelHeader: import("styled-components").StyledComponent<"div", any, {}, never>;

};
export declare function SidePanelTitle({ label, componentName }: TitleProps): JSX.Element;
export declare function SidePanelTitle({ label, componentName }: TitleProps): React.JSX.Element;
export declare const SidePanelActions: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const SidePanelBody: import("styled-components").StyledComponent<"div", any, {}, never>;
export {};

@@ -23,3 +23,3 @@ import React from 'react';

React.createElement(TitleLabel, null, label),
typeof componentName === 'string' && (React.createElement(ComponentName, null, componentName ? componentName : React.createElement("em", null, "Unnamed")))));
typeof componentName === 'string' && (React.createElement(ComponentName, null, componentName ? componentName : `(anonymous)`))));
}

@@ -26,0 +26,0 @@ export const SidePanelActions = styled.div `

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -6,3 +7,3 @@ width: number;

};
export declare function Space(props: Props): JSX.Element;
export declare function Space(props: Props): React.JSX.Element;
export {};

@@ -1,2 +0,2 @@

import { ReactNode } from 'react';
import React, { ReactNode } from 'react';
import { TreeNode } from 'react-cosmos-core';

@@ -18,3 +18,3 @@ import { TreeExpansion } from '../shared/treeExpansion.js';

};
export declare function TreeView<Item>({ node, name, parents, expansion, setExpansion, renderNode, }: Props<Item>): JSX.Element;
export declare function TreeView<Item>({ node, name, parents, expansion, setExpansion, renderNode, }: Props<Item>): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
import { FixtureStateValues } from 'react-cosmos-core';

@@ -8,3 +9,3 @@ import { TreeExpansion } from '../../shared/treeExpansion.js';

};
export declare function ExpandCollapseValues({ values, expansion, setExpansion, }: Props): JSX.Element | null;
export declare function ExpandCollapseValues({ values, expansion, setExpansion, }: Props): React.JSX.Element | null;
export {};

@@ -1,4 +0,4 @@

export { stringifyElementId, stringifyFixtureId } from './shared.js';
export { ValueInputTree } from './ValueInputTree.js';
export { stringifyElementId } from './shared.js';
export { hasFsValues, sortFsValueGroups } from './valueGroups.js';
export { ValueInputTree } from './ValueInputTree.js';
export { FixtureExpansion, FixtureExpansionGroup, getFixtureExpansion, OnElementExpansionChange, updateElementExpansion, } from './valueTreeExpansion.js';
export { FixtureExpansion, FixtureExpansionGroup, OnElementExpansionChange, getFixtureExpansion, updateElementExpansion, } from './valueTreeExpansion.js';

@@ -1,4 +0,4 @@

export { stringifyElementId, stringifyFixtureId } from './shared.js';
export { ValueInputTree } from './ValueInputTree.js';
export { stringifyElementId } from './shared.js';
export { hasFsValues, sortFsValueGroups } from './valueGroups.js';
export { ValueInputTree } from './ValueInputTree.js';
export { getFixtureExpansion, updateElementExpansion, } from './valueTreeExpansion.js';

@@ -1,5 +0,6 @@

import { FixtureElementId, FixtureId, FixtureStatePrimitiveValue, FixtureStateUnserializableValue, TreeNode } from 'react-cosmos-core';
import { FixtureElementId, FixtureStatePrimitiveValue, FixtureStateUnserializableValue, TreeNode } from 'react-cosmos-core';
export type LeafValue = FixtureStatePrimitiveValue | FixtureStateUnserializableValue;
export type ValueNodeData = {
type: 'collection';
isArray: boolean;
} | {

@@ -15,3 +16,2 @@ type: 'item';

export declare function stringifyElementId(elementId: FixtureElementId): string;
export declare function stringifyFixtureId(fixtureId: FixtureId): string;
export {};

@@ -9,8 +9,4 @@ import styled from 'styled-components';

}
export function stringifyFixtureId(fixtureId) {
const { path, name } = fixtureId;
return name ? `${path}-${name}` : path;
}
function getLeftPadding(depth) {
return depth * 12;
}

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -7,3 +8,3 @@ id: string;

};
export declare function BooleanValueInput({ id, name, data, onChange }: Props): JSX.Element;
export declare function BooleanValueInput({ id, name, data, onChange }: Props): React.JSX.Element;
export {};

@@ -0,5 +1,6 @@

import React from 'react';
type Props = {
name: string;
};
export declare function NullValueInput({ name }: Props): JSX.Element;
export declare function NullValueInput({ name }: Props): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -7,3 +8,3 @@ id: string;

};
export declare function NumberValueInput({ id, name, data, onChange }: Props): JSX.Element;
export declare function NumberValueInput({ id, name, data, onChange }: Props): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -7,3 +8,3 @@ id: string;

};
export declare function StringValueInput({ id, name, data, onChange }: Props): JSX.Element;
export declare function StringValueInput({ id, name, data, onChange }: Props): React.JSX.Element;
export {};

@@ -1,2 +0,2 @@

import React from 'react';
import React, { useEffect, useState } from 'react';
import { useFocus } from '../../../hooks/useFocus.js';

@@ -8,5 +8,19 @@ import { blue, grey248, grey8 } from '../../../style/colors.js';

const { focused, onFocus, onBlur } = useFocus();
const onInputChange = React.useCallback((e) => onChange(e.currentTarget.value), [onChange]);
// The data state is duplicated locally to solve the jumping cursor bug
// that occurs in controlled React inputs that don't immediately re-render
// with the new input value on change (because they await for the parent to
// propagate the changed value back down).
// https://github.com/facebook/react/issues/955
// https://github.com/react-cosmos/react-cosmos/issues/1372
const [localData, setLocalData] = useState(data);
useEffect(() => {
if (!focused)
setLocalData(data);
}, [data, focused]);
const onInputChange = React.useCallback((e) => {
setLocalData(e.currentTarget.value);
onChange(e.currentTarget.value);
}, [onChange]);
// Mirror textarea behavior and add an extra row after user adds a new line
const mirrorText = focused ? data.replace(/\n$/, `\n `) : data;
const mirrorText = focused ? localData.replace(/\n$/, `\n `) : localData;
return (React.createElement(React.Fragment, null,

@@ -17,4 +31,4 @@ React.createElement(Label, { title: name, htmlFor: id }, name),

React.createElement(TextContainer, null,
React.createElement(TextMirror, { minWidth: 64, focused: focused }, data.length > 0 || focused ? mirrorText : React.createElement("em", null, "empty")),
React.createElement(TextField, { rows: 1, id: id, value: data, focused: focused, color: grey248, onChange: onInputChange, onFocus: onFocus, onBlur: onBlur }))))));
React.createElement(TextMirror, { minWidth: 64, focused: focused }, localData.length > 0 || focused ? mirrorText : React.createElement("em", null, "empty")),
React.createElement(TextField, { rows: 1, id: id, value: localData, focused: focused, color: grey248, onChange: onInputChange, onFocus: onFocus, onBlur: onBlur }))))));
}

@@ -0,5 +1,6 @@

import React from 'react';
type Props = {
name: string;
};
export declare function UndefinedValueInput({ name }: Props): JSX.Element;
export declare function UndefinedValueInput({ name }: Props): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -5,3 +6,3 @@ name: string;

};
export declare function UnserializableValueInput({ name, data }: Props): JSX.Element;
export declare function UnserializableValueInput({ name, data }: Props): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
import { PrimitiveData } from 'react-cosmos-core';

@@ -10,3 +11,3 @@ import { LeafValue } from '../shared.js';

};
export declare function ValueInput({ value, name, id, indentLevel, onChange }: Props): JSX.Element;
export declare function ValueInput({ value, name, id, indentLevel, onChange }: Props): React.JSX.Element;
export {};

@@ -7,6 +7,6 @@ import React from 'react';

import { NumberValueInput } from './NumberValueInput.js';
import { ValueInputContainer } from './shared.js';
import { StringValueInput } from './StringValueInput.js';
import { UndefinedValueInput } from './UndefinedValueInput.js';
import { UnserializableValueInput } from './UnserializableValueInput.js';
import { ValueInputContainer } from './shared.js';
export function ValueInput({ value, name, id, indentLevel, onChange }) {

@@ -13,0 +13,0 @@ return (React.createElement(ValueInputSlot, { slotProps: { id, name, value, indentLevel, onChange } },

@@ -0,4 +1,6 @@

import React from 'react';
type Props = {
name: string;
childNames: string[];
childrenText: string;
disabled: boolean;
expanded: boolean;

@@ -8,3 +10,3 @@ indentLevel: number;

};
export declare function ValueInputDir({ name, childNames, expanded, indentLevel, onToggle, }: Props): JSX.Element;
export declare function ValueInputDir({ name, childrenText, disabled, expanded, indentLevel, onToggle, }: Props): React.JSX.Element;
export {};

@@ -6,4 +6,3 @@ import React from 'react';

import { ValueTreeItem } from './shared.js';
export function ValueInputDir({ name, childNames, expanded, indentLevel, onToggle, }) {
const disabled = childNames.length === 0;
export function ValueInputDir({ name, childrenText, disabled, expanded, indentLevel, onToggle, }) {
return (React.createElement(ValueTreeItem, { indentLevel: indentLevel },

@@ -16,7 +15,4 @@ React.createElement(ButtonContainer, null,

React.createElement(DirName, { disabled: disabled }, name),
React.createElement(ChildrenInfo, null, getChildInfo(childNames))))))));
React.createElement(ChildrenInfo, null, childrenText)))))));
}
function getChildInfo(childNames) {
return childNames.length > 0 ? `{ ${childNames.join(', ')} }` : `{}`;
}
const ButtonContainer = styled.div `

@@ -23,0 +19,0 @@ padding: 2px 0;

@@ -14,5 +14,12 @@ import { clone, setWith } from 'lodash-es';

const { data, children } = node;
if (data.type === 'item')
if (data.type === 'item') {
return (React.createElement(ValueInput, { value: data.value, name: name, id: getInputId(id, parents, name), indentLevel: parents.length, onChange: newData => onValueChange(setValueAtPath(values, { type: 'primitive', data: newData }, getValuePath(name, parents))) }));
return (children && (React.createElement(ValueInputDir, { name: name, childNames: Object.keys(children), expanded: expanded, indentLevel: parents.length, onToggle: onToggle })));
}
if (children) {
const childKeys = Object.keys(children);
return (React.createElement(ValueInputDir, { name: name, childrenText: getChildrenText(childKeys, data.isArray), disabled: childKeys.length === 0, expanded: expanded, indentLevel: parents.length, onToggle: onToggle }));
}
else {
return null;
}
} })));

@@ -30,2 +37,10 @@ });

}
function getChildrenText(childKeys, isArray) {
if (childKeys.length > 0) {
return isArray ? `[ ${childKeys.length} ]` : `{ ${childKeys.join(', ')} }`;
}
else {
return isArray ? `[]` : `{}`;
}
}
const Container = styled.div `

@@ -32,0 +47,0 @@ background: ${grey32};

import { FixtureStateValues } from 'react-cosmos-core';
import { ValueNode } from './shared.js';
export declare function createValueTree(values: FixtureStateValues): ValueNode;
export declare function createValueTree(values: FixtureStateValues, isArray?: boolean): ValueNode;

@@ -1,2 +0,2 @@

export function createValueTree(values) {
export function createValueTree(values, isArray = false) {
const children = {};

@@ -6,3 +6,3 @@ Object.keys(values).forEach(key => {

if (value.type === 'object') {
children[key] = createValueTree(value.values);
children[key] = createValueTree(value.values, false);
}

@@ -14,9 +14,14 @@ else if (value.type === 'array') {

});
children[key] = createValueTree(objValues);
children[key] = createValueTree(objValues, true);
}
else {
children[key] = { data: { type: 'item', value } };
children[key] = {
data: { type: 'item', value },
};
}
});
return { data: { type: 'collection' }, children };
return {
data: { type: 'collection', isArray },
children,
};
}
import { clone, setWith } from 'lodash-es';
import { stringifyElementId, stringifyFixtureId } from './shared.js';
import { stringifyFixtureId, } from 'react-cosmos-core';
import { stringifyElementId } from './shared.js';
const DEFAULT_EXPANSION = {};

@@ -4,0 +5,0 @@ export function getFixtureExpansion(groupExpansion, fixtureId) {

import React from 'react';
declare const _default: ({ children }: {
children: React.ReactNode;
}) => JSX.Element;
}) => React.JSX.Element;
export default _default;
import { loadPlugins } from 'react-plugin';
import './plugins/pluginEntry.js';
import { DEFAULT_PLUGIN_CONFIG } from './shared/defaultPluginConfig.js';
const rendererConfig = {
...DEFAULT_PLUGIN_CONFIG,
core: {
projectId: 'testProjectId',
fixturesDir: '__fixtures__',
fixtureFileSuffix: 'fixture',
devServerOn: true,
},
rendererCore: {
fixtures: {},
rendererUrl: '/renderer.html',
},
};
// This file is required to run globally with side effects for the "inception"
// fixture to work.
loadPlugins({
config: {
...DEFAULT_PLUGIN_CONFIG,
core: {
projectId: 'testProjectId',
fixturesDir: '__fixtures__',
fixtureFileSuffix: 'fixture',
devServerOn: true,
webRendererUrl: '/_renderer.html',
},
},
config: rendererConfig,
});

@@ -6,3 +6,2 @@ export * from './components/buttons/index.js';

export * from './plugins/ClassStatePanel/spec.js';
export * from './plugins/ContentOverlay/spec.js';
export * from './plugins/ControlPanel/spec.js';

@@ -37,2 +36,1 @@ export * from './plugins/ControlSelect/spec.js';

export * from './style/vars.js';
export * from './testHelpers/pluginMocks.js';

@@ -6,3 +6,2 @@ export * from './components/buttons/index.js';

export * from './plugins/ClassStatePanel/spec.js';
export * from './plugins/ContentOverlay/spec.js';
export * from './plugins/ControlPanel/spec.js';

@@ -37,2 +36,1 @@ export * from './plugins/ControlSelect/spec.js';

export * from './style/vars.js';
export * from './testHelpers/pluginMocks.js';

@@ -16,4 +16,2 @@ import React from 'react';

const { loadPlugins, Slot } = ReactPlugin;
const config = { ...DEFAULT_PLUGIN_CONFIG, ...playgroundConfig };
loadPlugins({ config });
// We can make plugin loading unblocking if react-plugin exports the

@@ -25,2 +23,4 @@ // reloadPlugins method.

}));
const config = { ...DEFAULT_PLUGIN_CONFIG, ...playgroundConfig };
loadPlugins({ config });
const root = ReactDom.createRoot(document.getElementById('root'));

@@ -33,7 +33,18 @@ root.render(React.createElement(React.Fragment, null,

console.log(`[Cosmos] Loading plugin script at ${scriptPath}`);
// Handle both absolute (dev server) and relative paths (static export)
// Paths are absolute with the dev server, and relative with static
// exports. Why aren't they always relative? Because in dev mode
// the plugins could be loaded from folders outside the project rootDir,
// for example when using a monorepo. In that case relative paths would
// have to contain "../" segments, which are not allowed in URLs, and
// for this reason we pass full paths when using the dev server.
const normalizedPath = scriptPath.startsWith('/')
? scriptPath
: `/${scriptPath}`;
await import(/* webpackIgnore: true */ `./_plugin${normalizedPath}`);
try {
await import(/* webpackIgnore: true */ `./_plugin${normalizedPath}`);
}
catch (err) {
console.log(`[Cosmos] Failed to load plugin script ${scriptPath}`);
console.log(err);
}
}
import { CosmosPluginConfig } from 'react-cosmos-core';
import { CoreSpec } from './plugins/Core/spec.js';
import { RendererCoreSpec } from './plugins/RendererCore/spec.js';
export type PlaygroundConfig = {
core: CoreSpec['config'];
rendererCore: RendererCoreSpec['config'];
[pluginName: string]: {};

@@ -6,0 +8,0 @@ };

@@ -1,10 +0,12 @@

import { FixtureState, FixtureStateClassState, StateUpdater } from 'react-cosmos-core';
import React from 'react';
import { ClassStateFixtureStateItem } from 'react-cosmos-core';
import { FixtureExpansion, OnElementExpansionChange } from '../../../components/ValueInputTree/index.js';
import { SetClassStateFixtureState } from '../shared.js';
type Props = {
fsClassState: FixtureStateClassState;
classStateFsItem: ClassStateFixtureStateItem;
fixtureExpansion: FixtureExpansion;
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
onFixtureStateChange: SetClassStateFixtureState;
onElementExpansionChange: OnElementExpansionChange;
};
export declare function ComponentClassState({ fsClassState, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }: Props): JSX.Element;
export declare function ComponentClassState({ classStateFsItem, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }: Props): React.JSX.Element;
export {};
import { isEqual } from 'lodash-es';
import React, { useCallback } from 'react';
import { updateFixtureStateClassState, } from 'react-cosmos-core';
import { updateClassStateFixtureStateItem, } from 'react-cosmos-core';
import { SidePanelActions, SidePanelBody, SidePanelContainer, SidePanelHeader, SidePanelTitle, } from '../../../components/SidePanel.js';
import { ExpandCollapseValues } from '../../../components/ValueInputTree/ExpandCollapseValues.js';
import { ValueInputTree, stringifyElementId, } from '../../../components/ValueInputTree/index.js';
import { IconButton32 } from '../../../components/buttons/index.js';
import { RotateCcwIcon } from '../../../components/icons/index.js';
import { SidePanelActions, SidePanelBody, SidePanelContainer, SidePanelHeader, SidePanelTitle, } from '../../../components/SidePanel.js';
import { ExpandCollapseValues } from '../../../components/ValueInputTree/ExpandCollapseValues.js';
import { stringifyElementId, ValueInputTree, } from '../../../components/ValueInputTree/index.js';
import { createClassStateFsUpdater } from './shared.js';
export function ComponentClassState({ fsClassState, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }) {
const { componentName, elementId, values } = fsClassState;
import { classStateFsItemUpdater } from './shared.js';
export function ComponentClassState({ classStateFsItem, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }) {
const { componentName, elementId, values } = classStateFsItem;
const [initialValues] = React.useState(() => values);
const handleValuesReset = React.useCallback(() => onFixtureStateChange(createClassStateFsUpdater(elementId, prevFs => updateFixtureStateClassState({
fixtureState: prevFs,
const handleValuesReset = React.useCallback(() => onFixtureStateChange(classStateFsItemUpdater(elementId, prevFs => updateClassStateFixtureStateItem({
classStateFs: prevFs,
elementId,

@@ -19,4 +19,4 @@ values: initialValues,

const handleValueChange = React.useCallback((newValues) => {
onFixtureStateChange(createClassStateFsUpdater(elementId, prevFs => updateFixtureStateClassState({
fixtureState: prevFs,
onFixtureStateChange(classStateFsItemUpdater(elementId, prevFs => updateClassStateFixtureStateItem({
classStateFs: prevFs,
elementId,

@@ -23,0 +23,0 @@ values: newValues,

import React from 'react';
import { FixtureState, StateUpdater } from 'react-cosmos-core';
import { ClassStateFixtureState } from 'react-cosmos-core';
import { FixtureExpansion, OnElementExpansionChange } from '../../../components/ValueInputTree/index.js';
import { SetClassStateFixtureState } from '../shared.js';
type Props = {
fixtureState: FixtureState;
fixtureState: ClassStateFixtureState | undefined;
fixtureExpansion: FixtureExpansion;
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
onFixtureStateChange: SetClassStateFixtureState;
onElementExpansionChange: OnElementExpansionChange;

@@ -9,0 +10,0 @@ };

@@ -5,10 +5,10 @@ import React from 'react';

export const ClassStatePanel = React.memo(function ClassStatePanel({ fixtureState, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }) {
if (!fixtureState.classState) {
if (!fixtureState) {
return null;
}
const classStateWithValues = fixtureState.classState.filter(hasFsValues);
return (React.createElement(React.Fragment, null, sortFsValueGroups(classStateWithValues).map(fsClassState => {
const strElementId = stringifyElementId(fsClassState.elementId);
return (React.createElement(ComponentClassState, { key: strElementId, fsClassState: fsClassState, fixtureExpansion: fixtureExpansion, onFixtureStateChange: onFixtureStateChange, onElementExpansionChange: onElementExpansionChange }));
const classStateWithValues = fixtureState.filter(hasFsValues);
return (React.createElement(React.Fragment, null, sortFsValueGroups(classStateWithValues).map(fsItem => {
const strElementId = stringifyElementId(fsItem.elementId);
return (React.createElement(ComponentClassState, { key: strElementId, classStateFsItem: fsItem, fixtureExpansion: fixtureExpansion, onFixtureStateChange: onFixtureStateChange, onElementExpansionChange: onElementExpansionChange }));
})));
});

@@ -1,2 +0,2 @@

import { FixtureElementId, FixtureState, FixtureStateClassState, StateUpdater } from 'react-cosmos-core';
export declare function createClassStateFsUpdater(elementId: FixtureElementId, cb: (prevFs: FixtureState) => FixtureStateClassState[]): StateUpdater<FixtureState>;
import { ClassStateFixtureState, FixtureElementId, FixtureStateUpdater } from 'react-cosmos-core';
export declare function classStateFsItemUpdater(elementId: FixtureElementId, cb: FixtureStateUpdater<ClassStateFixtureState>): FixtureStateUpdater<ClassStateFixtureState>;

@@ -1,16 +0,13 @@

import { findFixtureStateClassState, } from 'react-cosmos-core';
import { findClassStateFixtureStateItem, } from 'react-cosmos-core';
import { stringifyElementId } from '../../../components/ValueInputTree/index.js';
export function createClassStateFsUpdater(elementId, cb) {
export function classStateFsItemUpdater(elementId, cb) {
return prevFs => {
const fsClassState = findFixtureStateClassState(prevFs, elementId);
if (!fsClassState) {
const fsItem = findClassStateFixtureStateItem(prevFs, elementId);
if (!fsItem) {
const elId = stringifyElementId(elementId);
console.warn(`Trying to update missing element with ID: ${elId}`);
return prevFs;
return prevFs ?? [];
}
return {
...prevFs,
classState: cb(prevFs),
};
return cb(prevFs);
};
}

@@ -1,6 +0,6 @@

import React from 'react';
import React, { useCallback } from 'react';
import { createPlugin } from 'react-plugin';
import { getFixtureExpansion, updateElementExpansion, } from '../../components/ValueInputTree/index.js';
import { ClassStatePanel } from './ClassStatePanel/index.js';
import { CLASS_STATE_TREE_EXPANSION_STORAGE_KEY } from './shared.js';
import { CLASS_STATE_TREE_EXPANSION_STORAGE_KEY, } from './shared.js';
const { namedPlug, register } = createPlugin({

@@ -10,4 +10,6 @@ name: 'classStatePanel',

namedPlug('sidePanelRow', 'classState', ({ pluginContext, slotProps }) => {
const { fixtureId, fixtureState, onFixtureStateChange } = slotProps;
const { fixtureId, getFixtureState, setFixtureState } = slotProps;
const { fixtureExpansion, onElementExpansionChange } = useFixtureExpansion(pluginContext, fixtureId);
const fixtureState = getFixtureState('classState');
const onFixtureStateChange = useCallback(update => setFixtureState('classState', update), [setFixtureState]);
return (React.createElement(ClassStatePanel, { fixtureState: fixtureState, fixtureExpansion: fixtureExpansion, onFixtureStateChange: onFixtureStateChange, onElementExpansionChange: onElementExpansionChange }));

@@ -14,0 +16,0 @@ });

@@ -0,1 +1,3 @@

import { ClassStateFixtureState, FixtureStateUpdater } from 'react-cosmos-core';
export type SetClassStateFixtureState = (updater: FixtureStateUpdater<ClassStateFixtureState>) => void;
export declare const CLASS_STATE_TREE_EXPANSION_STORAGE_KEY = "classStateTreeExpansion";

@@ -1,8 +0,10 @@

import { FixtureState, StateUpdater } from 'react-cosmos-core';
import React from 'react';
import { ControlsFixtureState } from 'react-cosmos-core';
import { SetControlsFixtureState } from './shared.js';
type Props = {
fixtureState: FixtureState;
fixtureState: ControlsFixtureState | undefined;
controlActionOrder: string[];
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
onFixtureStateChange: SetControlsFixtureState;
};
export declare function ControlPanel({ fixtureState, controlActionOrder, onFixtureStateChange, }: Props): JSX.Element | null;
export declare function ControlPanel({ fixtureState, controlActionOrder, onFixtureStateChange, }: Props): React.JSX.Element | null;
export {};
import { isEqual } from 'lodash-es';
import React from 'react';
import { SidePanelActions, SidePanelBody, SidePanelContainer, SidePanelHeader, SidePanelTitle, } from '../../components/SidePanel.js';
import { IconButton32 } from '../../components/buttons/index.js';
import { RotateCcwIcon } from '../../components/icons/index.js';
import { SidePanelActions, SidePanelBody, SidePanelContainer, SidePanelHeader, SidePanelTitle, } from '../../components/SidePanel.js';
import { ControlActionSlot } from '../../slots/ControlActionSlot.js';

@@ -10,3 +10,3 @@ import { ControlSlot } from '../../slots/ControlSlot.js';

const handleControlsReset = React.useCallback(() => onFixtureStateChange(resetControls), [onFixtureStateChange]);
const controls = fixtureState.controls || {};
const controls = fixtureState ?? {};
if (Object.keys(controls).length === 0)

@@ -30,7 +30,7 @@ return null;

function resetControls(fixtureState) {
const controls = fixtureState.controls ? { ...fixtureState.controls } : {};
const controls = fixtureState ? { ...fixtureState } : {};
Object.keys(controls).forEach(controlName => {
controls[controlName] = resetControl(controls[controlName]);
});
return { ...fixtureState, controls };
return controls;
}

@@ -37,0 +37,0 @@ function resetControl(control) {

@@ -1,2 +0,2 @@

import React from 'react';
import React, { useCallback } from 'react';
import { createPlugin } from 'react-plugin';

@@ -12,3 +12,5 @@ import { ControlPanel } from './ControlPanel.js';

const { controlActionOrder } = pluginContext.getConfig();
const { fixtureState, onFixtureStateChange } = slotProps;
const { getFixtureState, setFixtureState } = slotProps;
const fixtureState = getFixtureState('controls');
const onFixtureStateChange = useCallback(update => setFixtureState('controls', update), [setFixtureState]);
return (React.createElement(ControlPanel, { fixtureState: fixtureState, controlActionOrder: controlActionOrder, onFixtureStateChange: onFixtureStateChange }));

@@ -15,0 +17,0 @@ });

@@ -10,8 +10,5 @@ import React, { useCallback } from 'react';

const handleChange = useCallback((selectName, updatedControl) => {
onFixtureStateChange(fixtureState => ({
...fixtureState,
controls: {
...fixtureState.controls,
[selectName]: updatedControl,
},
onFixtureStateChange(prevFs => ({
...prevFs,
[selectName]: updatedControl,
}));

@@ -18,0 +15,0 @@ }, [onFixtureStateChange]);

@@ -1,8 +0,9 @@

import { FixtureStateSelectControl } from 'react-cosmos-core';
import React from 'react';
import { SelectControlFixtureState } from 'react-cosmos-core';
type Props = {
name: string;
control: FixtureStateSelectControl;
onChange: (name: string, select: FixtureStateSelectControl) => unknown;
control: SelectControlFixtureState;
onChange: (name: string, select: SelectControlFixtureState) => unknown;
};
export declare function SelectValueInput({ name, control, onChange }: Props): JSX.Element;
export declare function SelectValueInput({ name, control, onChange }: Props): React.JSX.Element;
export {};
import React from 'react';
import { Label, ValueDataContainer, ValueInputContainer, } from '../../components/ValueInputTree/ValueInput/shared.js';
import { Select } from '../../components/inputs/Select.js';
import { Label, ValueDataContainer, ValueInputContainer, } from '../../components/ValueInputTree/ValueInput/shared.js';
import { lightBlue } from '../../style/colors.js';

@@ -5,0 +5,0 @@ export function SelectValueInput({ name, control, onChange }) {

@@ -14,3 +14,2 @@ import { omit } from 'lodash-es';

devServerOn: false,
webRendererUrl: null,
},

@@ -23,3 +22,2 @@ methods: {

isDevServerOn,
getWebRendererUrl,
},

@@ -68,4 +66,1 @@ });

}
function getWebRendererUrl({ getConfig }) {
return getConfig().webRendererUrl;
}

@@ -9,3 +9,2 @@ export type Commands = Record<string, () => unknown>;

devServerOn: boolean;
webRendererUrl: null | string;
};

@@ -24,4 +23,3 @@ state: {

isDevServerOn(): boolean;
getWebRendererUrl(): null | string;
};
};

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -5,3 +6,3 @@ selected: boolean;

};
export declare function BookmarkFixtureButton({ selected, onClick }: Props): JSX.Element;
export declare function BookmarkFixtureButton({ selected, onClick }: Props): React.JSX.Element;
export {};

@@ -1,10 +0,10 @@

import { FixtureId, FlatFixtureTree } from 'react-cosmos-core';
import React from 'react';
import { FixtureId, FlatFixtureTree, FlatFixtureTreeItem } from 'react-cosmos-core';
type Props = {
fixtureItems: FlatFixtureTree;
bookmarks: FixtureId[];
bookmarks: FlatFixtureTree;
selectedFixtureId: FixtureId | null;
onFixtureSelect: (fixtureId: FixtureId) => void;
onBookmarkDelete: (fixtureId: FixtureId) => void;
onBookmarkDelete: (fixtureItem: FlatFixtureTreeItem) => void;
};
export declare function FixtureBookmarks({ fixtureItems, bookmarks, selectedFixtureId, onFixtureSelect, onBookmarkDelete, }: Props): JSX.Element | null;
export declare function FixtureBookmarks({ bookmarks, selectedFixtureId, onFixtureSelect, onBookmarkDelete, }: Props): React.JSX.Element | null;
export {};

@@ -1,12 +0,12 @@

import { isEqual } from 'lodash-es';
import { isEqual, sortBy } from 'lodash-es';
import React from 'react';
import { stringifyFixtureId, } from 'react-cosmos-core';
import styled from 'styled-components';
import { XIcon } from '../../components/icons/index.js';
import { stringifyFixtureId } from '../../components/ValueInputTree/index.js';
import { createRelativePlaygroundUrl } from '../../shared/url.js';
import { blue, grey128, grey224, grey24, grey248, grey32, grey8, selectedColors, white10, } from '../../style/colors.js';
import { quick } from '../../style/vars.js';
export function FixtureBookmarks({ fixtureItems, bookmarks, selectedFixtureId, onFixtureSelect, onBookmarkDelete, }) {
const bookmarkedItems = fixtureItems.filter(item => bookmarks.some(b => isEqual(b, item.fixtureId)));
if (!bookmarkedItems.length)
export function FixtureBookmarks({ bookmarks, selectedFixtureId, onFixtureSelect, onBookmarkDelete, }) {
const sortedBookmarks = useSortedBookmarks(bookmarks);
if (!sortedBookmarks.length)
return null;

@@ -16,3 +16,3 @@ return (React.createElement(Container, null,

React.createElement(HeaderTitle, null, "Bookmarks")),
bookmarkedItems.map(fixtureItem => {
sortedBookmarks.map(fixtureItem => {
const { fixtureId } = fixtureItem;

@@ -32,3 +32,3 @@ const itemKey = stringifyFixtureId(fixtureId);

React.createElement(FixtureLink, { href: createRelativePlaygroundUrl({ fixtureId }), selected: selected, onClick: handleClick }, getFixtureName(fixtureItem)),
React.createElement(DeleteButton, { onClick: () => onBookmarkDelete(fixtureId) },
React.createElement(DeleteButton, { onClick: () => onBookmarkDelete(fixtureItem) },
React.createElement(DeleteIconContainer, null,

@@ -38,2 +38,5 @@ React.createElement(XIcon, null)))));

}
function useSortedBookmarks(bookmarks) {
return React.useMemo(() => sortBy(bookmarks, b => b.fixtureId.path, b => b.fixtureId.name), [bookmarks]);
}
function openAnchorInNewTab(anchorEl) {

@@ -40,0 +43,0 @@ // Allow users to cmd+click to open fixtures in new tab

import { isEqual } from 'lodash-es';
import React from 'react';
import { createFixtureTree, flattenFixtureTree, } from 'react-cosmos-core';
import { createPlugin } from 'react-plugin';

@@ -11,9 +10,9 @@ import { BookmarkFixtureButton } from './BookmarkFixtureButton.js';

namedPlug('fixtureAction', 'bookmarkFixture', ({ pluginContext, slotProps }) => {
const { fixtureId } = slotProps;
const { fixtureItem } = slotProps;
const { getBookmarks, setBookmarks } = getStorageApi(pluginContext);
const bookmarks = getBookmarks();
const selected = bookmarks.some(b => isEqual(b, fixtureId));
const selected = bookmarks.some(b => isEqual(b, fixtureItem));
return (React.createElement(BookmarkFixtureButton, { selected: selected, onClick: () => setBookmarks(selected
? bookmarks.filter(b => !isEqual(b, fixtureId))
: [...bookmarks, fixtureId]) }));
? bookmarks.filter(b => !isEqual(b, fixtureItem))
: [...bookmarks, fixtureItem]) }));
});

@@ -24,4 +23,3 @@ namedPlug('navRow', 'fixtureBookmarks', ({ pluginContext }) => {

const bookmarks = getBookmarks();
const fixtureItems = useFixtureItems(pluginContext);
return (React.createElement(FixtureBookmarks, { fixtureItems: fixtureItems, bookmarks: bookmarks, selectedFixtureId: router.getSelectedFixtureId(), onFixtureSelect: router.selectFixture, onBookmarkDelete: fixtureId => setBookmarks(bookmarks.filter(b => !isEqual(b, fixtureId))) }));
return (React.createElement(FixtureBookmarks, { bookmarks: bookmarks, selectedFixtureId: router.getSelectedFixtureId(), onFixtureSelect: router.selectFixture, onBookmarkDelete: fixtureItem => setBookmarks(bookmarks.filter(b => !isEqual(b, fixtureItem))) }));
});

@@ -34,16 +32,8 @@ export { register };

function getBookmarks() {
return storage.getItem('fixtureBookmarks') || [];
return storage.getItem('fixtureBookmarks.1') || [];
}
function setBookmarks(bookmarks) {
storage.setItem('fixtureBookmarks', bookmarks);
storage.setItem('fixtureBookmarks.1', bookmarks);
}
return { getBookmarks, setBookmarks };
}
function useFixtureItems(pluginContext) {
const { getMethodsOf } = pluginContext;
const core = getMethodsOf('core');
const { fixturesDir, fixtureFileSuffix } = core.getFixtureFileVars();
const rendererCore = getMethodsOf('rendererCore');
const fixtures = rendererCore.getFixtures();
return React.useMemo(() => flattenFixtureTree(createFixtureTree({ fixturesDir, fixtureFileSuffix, fixtures })), [fixtureFileSuffix, fixtures, fixturesDir]);
}

@@ -0,7 +1,8 @@

import React from 'react';
type Props = {
validFixtureSelected: boolean;
fixtureSelected: boolean;
onOpen: () => unknown;
onCloseNav: () => unknown;
};
export declare function FixtureSearchHeader({ validFixtureSelected, onOpen, onCloseNav, }: Props): JSX.Element;
export declare function FixtureSearchHeader({ fixtureSelected, onOpen, onCloseNav, }: Props): React.JSX.Element;
export {};
import React from 'react';
import styled from 'styled-components';
import { KeyBox } from '../../components/KeyBox.js';
import { IconButton32 } from '../../components/buttons/index.js';
import { ChevronLeftIcon, SearchIcon } from '../../components/icons/index.js';
import { KeyBox } from '../../components/KeyBox.js';
import { blue, grey160, grey32, white10 } from '../../style/colors.js';
export function FixtureSearchHeader({ validFixtureSelected, onOpen, onCloseNav, }) {
export function FixtureSearchHeader({ fixtureSelected, onOpen, onCloseNav, }) {
return (React.createElement(Container, null,

@@ -16,3 +16,3 @@ React.createElement(SearchButton, { onClick: onOpen },

React.createElement(NavButtonContainer, null,
React.createElement(IconButton32, { icon: React.createElement(ChevronLeftIcon, null), title: "Hide fixture list", disabled: !validFixtureSelected, selected: false, onClick: onCloseNav }))));
React.createElement(IconButton32, { icon: React.createElement(ChevronLeftIcon, null), title: "Hide fixture list", disabled: !fixtureSelected, selected: false, onClick: onCloseNav }))));
}

@@ -19,0 +19,0 @@ const Container = styled.div `

@@ -0,1 +1,2 @@

import React from 'react';
import { FixtureId, FixtureList } from 'react-cosmos-core';

@@ -12,3 +13,3 @@ type Props = {

};
export declare function FixtureSearchOverlay({ searchText, fixturesDir, fixtureFileSuffix, fixtures, selectedFixtureId, onSetSearchText, onClose, onSelect, }: Props): JSX.Element;
export declare function FixtureSearchOverlay({ searchText, fixturesDir, fixtureFileSuffix, fixtures, selectedFixtureId, onSetSearchText, onClose, onSelect, }: Props): React.JSX.Element;
export {};
import { filter } from 'fuzzaldrin-plus';
import { isEqual } from 'lodash-es';
import React, { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
import { createFixtureTree, flattenFixtureTree, KEY_DOWN, KEY_ENTER, KEY_ESC, KEY_FWD_SLASH, KEY_TAB, KEY_UP, } from 'react-cosmos-core';
import { KEY_DOWN, KEY_ENTER, KEY_ESC, KEY_FWD_SLASH, KEY_TAB, KEY_UP, createFixtureTree, flattenFixtureTree, } from 'react-cosmos-core';
import styled from 'styled-components';

@@ -179,3 +179,3 @@ import { HelpCircleIcon, SearchIcon } from '../../components/icons/index.js';

React.createElement(ResultsContainer, null,
matchingFixturePaths.map(cleanFixturePath => (React.createElement(FixtureSearchResult, { key: cleanFixturePath, cleanFixturePath: cleanFixturePath, fixtureItem: fixtureItems[cleanFixturePath], active: cleanFixturePath === activeFixturePath, onSelect: onSelect }))),
matchingFixturePaths.map(cleanFixturePath => fixtureItems[cleanFixturePath] && (React.createElement(FixtureSearchResult, { key: cleanFixturePath, cleanFixturePath: cleanFixturePath, fixtureItem: fixtureItems[cleanFixturePath], active: cleanFixturePath === activeFixturePath, onSelect: onSelect }))),
matchingFixturePaths.length === 0 && (React.createElement(NoResults, null, "No results")))))));

@@ -234,4 +234,6 @@ }

background: ${grey248};
box-shadow: rgba(15, 15, 15, 0.05) 0px 0px 0px 1px,
rgba(15, 15, 15, 0.1) 0px 5px 10px, rgba(15, 15, 15, 0.2) 0px 15px 40px;
box-shadow:
rgba(15, 15, 15, 0.05) 0px 0px 0px 1px,
rgba(15, 15, 15, 0.1) 0px 5px 10px,
rgba(15, 15, 15, 0.2) 0px 15px 40px;
display: flex;

@@ -282,3 +284,5 @@ flex-direction: column;

cursor: pointer;
transition: background ${quick}s, color ${quick}s;
transition:
background ${quick}s,
color ${quick}s;

@@ -293,3 +297,5 @@ :hover {

opacity: ${props => (props.visible ? 1 : 0)};
transition: height ${quick}s, opacity ${quick}s;
transition:
height ${quick}s,
opacity ${quick}s;
user-select: none;

@@ -296,0 +302,0 @@ `;

@@ -0,1 +1,2 @@

import React from 'react';
import { FixtureId, FlatFixtureTreeItem } from 'react-cosmos-core';

@@ -8,3 +9,3 @@ type Props = {

};
export declare function FixtureSearchResult({ active, cleanFixturePath, fixtureItem, onSelect, }: Props): JSX.Element;
export declare function FixtureSearchResult({ active, cleanFixturePath, fixtureItem, onSelect, }: Props): React.JSX.Element;
export {};

@@ -1,1 +0,2 @@

export declare function FixtureSearchShortcuts(): JSX.Element;
import React from 'react';
export declare function FixtureSearchShortcuts(): React.JSX.Element;

@@ -21,2 +21,3 @@ import React from 'react';

const { getMethodsOf } = pluginContext;
const router = getMethodsOf('router');
const rendererCore = getMethodsOf('rendererCore');

@@ -30,3 +31,3 @@ const fixtures = rendererCore.getFixtures();

}
return (React.createElement(FixtureSearchHeader, { validFixtureSelected: rendererCore.isValidFixtureSelected(), onOpen: onOpen, onCloseNav: onCloseNav }));
return (React.createElement(FixtureSearchHeader, { fixtureSelected: router.getSelectedFixtureId() !== null, onOpen: onOpen, onCloseNav: onCloseNav }));
});

@@ -33,0 +34,0 @@ namedPlug('global', 'fixtureSearch', ({ pluginContext }) => {

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -5,5 +6,5 @@ fixturesDir: string;

};
export declare function BlankState({ fixturesDir, fixtureFileSuffix }: Props): JSX.Element;
export declare function BlankState({ fixturesDir, fixtureFileSuffix }: Props): React.JSX.Element;
export declare const IconContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const NoWrap: import("styled-components").StyledComponent<"span", any, {}, never>;
export {};
import React from 'react';
import { DelayRender } from 'react-cosmos-core';
import styled from 'styled-components';

@@ -6,26 +7,24 @@ import { FileIcon } from '../../components/icons/index.js';

export function BlankState({ fixturesDir, fixtureFileSuffix }) {
return (React.createElement(Container, { "data-testid": "nav-blank-state" },
React.createElement(IconContainer, null,
React.createElement(FileIcon, null)),
React.createElement(Title, null,
"No component ",
React.createElement(NoWrap, null, "fixtures found")),
React.createElement(Description, null,
React.createElement("ol", null,
React.createElement("li", null,
"Place fixture files under ",
React.createElement("code", null, fixturesDir),
" dirs or add the",
' ',
React.createElement("code", null,
".",
fixtureFileSuffix),
" suffix to",
' ',
React.createElement(NoWrap, null, "their name")),
React.createElement("li", null,
"Default exports from your fixtures (any React element or component)",
' ',
"will ",
React.createElement(NoWrap, null, "appear here"))))));
return (React.createElement(DelayRender, { delay: 500 },
React.createElement(Container, { "data-testid": "nav-blank-state" },
React.createElement(IconContainer, null,
React.createElement(FileIcon, null)),
React.createElement(Title, null,
"No component ",
React.createElement(NoWrap, null, "fixtures found")),
React.createElement(Description, null,
React.createElement("ol", null,
React.createElement("li", null,
"Place fixture files under ",
React.createElement("code", null, fixturesDir),
" dirs or add the ",
React.createElement("code", null,
".",
fixtureFileSuffix),
" suffix to",
' ',
React.createElement(NoWrap, null, "their name")),
React.createElement("li", null,
"Default exports from your fixtures (any React element or component) will ",
React.createElement(NoWrap, null, "appear here")))))));
}

@@ -32,0 +31,0 @@ const Container = styled.div `

@@ -1,6 +0,6 @@

import { RefObject } from 'react';
import React, { RefObject } from 'react';
import { FixtureId } from 'react-cosmos-core';
type Props = {
name: string;
fixtureId: FixtureId;
fixturePath: string;
indentLevel: number;

@@ -11,3 +11,3 @@ selected: boolean;

};
export declare function FixtureButton({ name, fixtureId, indentLevel, selected, selectedRef, onSelect, }: Props): JSX.Element;
export declare function FixtureButton({ name, fixturePath, indentLevel, selected, selectedRef, onSelect, }: Props): React.JSX.Element;
export {};

@@ -6,4 +6,4 @@ import React from 'react';

import { FixtureTreeItem } from './FixtureTreeItem.js';
export function FixtureButton({ name, fixtureId, indentLevel, selected, selectedRef, onSelect, }) {
return (React.createElement(FixtureLink, { fixtureId: fixtureId, onSelect: onSelect },
export function FixtureButton({ name, fixturePath, indentLevel, selected, selectedRef, onSelect, }) {
return (React.createElement(FixtureLink, { fixtureId: { path: fixturePath }, onSelect: onSelect },
React.createElement(FixtureTreeItem, { ref: selected ? selectedRef : undefined, indentLevel: indentLevel, selected: selected },

@@ -10,0 +10,0 @@ React.createElement(Name, null, name))));

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -8,3 +9,3 @@ name: string;

};
export declare function FixtureDir({ name, expanded, indentLevel, selected, onToggle, }: Props): JSX.Element;
export declare function FixtureDir({ name, expanded, indentLevel, selected, onToggle, }: Props): React.JSX.Element;
export {};

@@ -1,2 +0,2 @@

import { ReactNode } from 'react';
import React, { ReactNode } from 'react';
import { FixtureId } from 'react-cosmos-core';

@@ -8,3 +8,3 @@ type Props = {

};
export declare function FixtureLink({ children, fixtureId, onSelect }: Props): JSX.Element;
export declare function FixtureLink({ children, fixtureId, onSelect }: Props): React.JSX.Element;
export {};

@@ -1,6 +0,5 @@

import { isEqual } from 'lodash-es';
import React from 'react';
import styled from 'styled-components';
import { TreeView } from '../../../components/TreeView.js';
import { nodeContainsFixtureId, recordContainsFixtureId, } from '../../../shared/fixtureTree.js';
import { fixtureTreeNodeContainsFixtureId } from '../../../shared/fixtureTree.js';
import { grey32 } from '../../../style/colors.js';

@@ -15,9 +14,8 @@ import { FixtureButton } from './FixtureButton.js';

if (data.type === 'fixture') {
const selected = isEqual(selectedFixtureId, data.fixtureId);
return (React.createElement(FixtureButton, { name: name, fixtureId: data.fixtureId, indentLevel: parents.length, selected: selected, selectedRef: selectedRef, onSelect: onSelect }));
const selected = selectedFixtureId?.path === data.path;
return (React.createElement(FixtureButton, { name: name, fixturePath: data.path, indentLevel: parents.length, selected: selected, selectedRef: selectedRef, onSelect: onSelect }));
}
if (data.type === 'multiFixture') {
const selected = selectedFixtureId !== null &&
recordContainsFixtureId(data.fixtureIds, selectedFixtureId);
return (React.createElement(MultiFixtureButton, { name: name, fixtureIds: data.fixtureIds, indentLevel: parents.length, selected: selected, selectedFixtureId: selectedFixtureId, selectedRef: selectedRef, onSelect: onSelect }));
const selected = selectedFixtureId?.path === data.path;
return (React.createElement(MultiFixtureButton, { name: name, fixturePath: data.path, fixtureNames: data.names, indentLevel: parents.length, selected: selected, selectedFixtureId: selectedFixtureId, selectedRef: selectedRef, onSelect: onSelect }));
}

@@ -28,3 +26,3 @@ if (!children)

selectedFixtureId !== null &&
nodeContainsFixtureId(node, selectedFixtureId);
fixtureTreeNodeContainsFixtureId(node, selectedFixtureId);
return (React.createElement(FixtureDir, { name: name, indentLevel: parents.length, expanded: expanded, selected: selected, onToggle: onToggle }));

@@ -31,0 +29,0 @@ } })));

@@ -1,6 +0,7 @@

import { RefObject } from 'react';
import React, { RefObject } from 'react';
import { FixtureId } from 'react-cosmos-core';
type Props = {
name: string;
fixtureIds: Record<string, FixtureId>;
fixturePath: string;
fixtureNames: string[];
indentLevel: number;

@@ -12,3 +13,3 @@ selected: boolean;

};
export declare function MultiFixtureButton({ name, fixtureIds, indentLevel, selected, selectedFixtureId, selectedRef, onSelect, }: Props): JSX.Element | null;
export declare function MultiFixtureButton({ name, fixturePath, fixtureNames, indentLevel, selected, selectedFixtureId, selectedRef, onSelect, }: Props): React.JSX.Element;
export {};

@@ -1,2 +0,1 @@

import { isEqual } from 'lodash-es';
import React from 'react';

@@ -8,12 +7,13 @@ import styled from 'styled-components';

import { MultiFixtureChildButton } from './MultiFixtureChildButton.js';
export function MultiFixtureButton({ name, fixtureIds, indentLevel, selected, selectedFixtureId, selectedRef, onSelect, }) {
const fixtureNames = Object.keys(fixtureIds);
const firstFixtureId = fixtureIds[fixtureNames[0]];
if (!firstFixtureId)
return null;
if (!selected)
return (React.createElement(FixtureLink, { fixtureId: firstFixtureId, onSelect: onSelect },
export function MultiFixtureButton({ name, fixturePath, fixtureNames, indentLevel, selected, selectedFixtureId, selectedRef, onSelect, }) {
if (!selected) {
const [firstFixtureName] = fixtureNames;
const fixtureId = firstFixtureName
? { path: fixturePath, name: firstFixtureName }
: { path: fixturePath };
return (React.createElement(FixtureLink, { fixtureId: fixtureId, onSelect: onSelect },
React.createElement(FixtureTreeItem, { indentLevel: indentLevel, selected: false },
React.createElement(Name, null, name),
React.createElement(Count, null, fixtureNames.length))));
}
return (React.createElement(React.Fragment, null,

@@ -23,5 +23,10 @@ React.createElement(FixtureTreeItem, { indentLevel: indentLevel, selected: true },

React.createElement(Count, null, fixtureNames.length)),
fixtureNames.map(fixtureName => {
const fixtureId = fixtureIds[fixtureName];
const childSelected = isEqual(fixtureId, selectedFixtureId);
fixtureNames.map((fixtureName, index) => {
const fixtureId = { path: fixturePath, name: fixtureName };
// Select first child when only the path of a multi fixture is selected
const childSelected = selectedFixtureId !== null &&
selectedFixtureId.path === fixturePath &&
(selectedFixtureId.name === undefined
? index === 0
: fixtureName === selectedFixtureId.name);
return (React.createElement(MultiFixtureChildButton, { key: fixtureName, name: fixtureName, fixtureId: fixtureId, indentLevel: indentLevel + 1, selected: childSelected, selectedRef: selectedRef, onSelect: onSelect }));

@@ -28,0 +33,0 @@ }),

@@ -1,2 +0,2 @@

import { RefObject } from 'react';
import React, { RefObject } from 'react';
import { FixtureId } from 'react-cosmos-core';

@@ -11,3 +11,3 @@ type Props = {

};
export declare function MultiFixtureChildButton({ name, fixtureId, indentLevel, selected, selectedRef, onSelect, }: Props): JSX.Element;
export declare function MultiFixtureChildButton({ name, fixtureId, indentLevel, selected, selectedRef, onSelect, }: Props): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
import { FixtureId, FixtureList } from 'react-cosmos-core';

@@ -7,3 +8,2 @@ import { TreeExpansion } from '../../shared/treeExpansion.js';

selectedFixtureId: null | FixtureId;
rendererConnected: boolean;
fixtures: FixtureList;

@@ -14,3 +14,3 @@ expansion: TreeExpansion;

};
export declare function FixtureTreeContainer({ fixturesDir, fixtureFileSuffix, selectedFixtureId, rendererConnected, fixtures, expansion, selectFixture, setExpansion, }: Props): JSX.Element;
export declare function FixtureTreeContainer({ fixturesDir, fixtureFileSuffix, selectedFixtureId, fixtures, expansion, selectFixture, setExpansion, }: Props): React.JSX.Element;
export {};

@@ -9,7 +9,5 @@ import React, { useMemo } from 'react';

import { useScrollToSelected } from './useScrollToSelected.js';
export function FixtureTreeContainer({ fixturesDir, fixtureFileSuffix, selectedFixtureId, rendererConnected, fixtures, expansion, selectFixture, setExpansion, }) {
export function FixtureTreeContainer({ fixturesDir, fixtureFileSuffix, selectedFixtureId, fixtures, expansion, selectFixture, setExpansion, }) {
const rootNode = useMemo(() => createFixtureTree({ fixtures, fixturesDir, fixtureFileSuffix }), [fixtures, fixturesDir, fixtureFileSuffix]);
const { containerRef, selectedRef } = useScrollToSelected(selectedFixtureId);
if (!rendererConnected)
return React.createElement(TreeContainer, null);
if (Object.keys(fixtures).length === 0) {

@@ -16,0 +14,0 @@ return (React.createElement(TreeContainer, null,

@@ -0,1 +1,2 @@

import React from 'react';
import { FixtureList } from 'react-cosmos-core';

@@ -10,3 +11,3 @@ import { TreeExpansion } from '../../shared/treeExpansion.js';

};
export declare function FixtureTreeHeader({ fixturesDir, fixtureFileSuffix, fixtures, expansion, setExpansion, }: Props): JSX.Element;
export declare function FixtureTreeHeader({ fixturesDir, fixtureFileSuffix, fixtures, expansion, setExpansion, }: Props): React.JSX.Element;
export {};

@@ -21,3 +21,3 @@ import React, { useCallback } from 'react';

const setExpansionMemo = useCallback((newExpansion) => setTreeExpansion(storage, newExpansion), [storage]);
return (React.createElement(FixtureTreeContainer, { fixturesDir: fixturesDir, fixtureFileSuffix: fixtureFileSuffix, selectedFixtureId: router.getSelectedFixtureId(), rendererConnected: rendererCore.isRendererConnected(), fixtures: rendererCore.getFixtures(), expansion: expansion, selectFixture: router.selectFixture, setExpansion: setExpansionMemo }));
return (React.createElement(FixtureTreeContainer, { fixturesDir: fixturesDir, fixtureFileSuffix: fixtureFileSuffix, selectedFixtureId: router.getSelectedFixtureId(), fixtures: rendererCore.getFixtures(), expansion: expansion, selectFixture: router.selectFixture, setExpansion: setExpansionMemo }));
});

@@ -24,0 +24,0 @@ export { register };

import { createFixtureTree, } from 'react-cosmos-core';
import { nodeContainsFixtureId } from '../../shared/fixtureTree.js';
import { fixtureTreeNodeContainsFixtureId } from '../../shared/fixtureTree.js';
import { getTreeExpansion, setTreeExpansion, } from './shared.js';

@@ -35,3 +35,3 @@ export function revealFixture(context, fixtureId) {

if (childNode.data.type !== 'fileDir') {
if (nodeContainsFixtureId(childNode, fixtureId))
if (fixtureTreeNodeContainsFixtureId(childNode, fixtureId))
return parents;

@@ -38,0 +38,0 @@ }

@@ -6,3 +6,3 @@ import { PluginContext } from 'react-plugin';

export type FixtureTreeContext = PluginContext<FixtureTreeSpec>;
export declare function getTreeExpansion({ getItem }: StorageSpec['methods']): TreeExpansion;
export declare function getTreeExpansion({ getItem }: StorageSpec['methods']): {};
export declare function setTreeExpansion({ setItem }: StorageSpec['methods'], treeExpansion: TreeExpansion): void;

@@ -0,5 +1,6 @@

import React from 'react';
type Props = {
onClick: () => void;
};
export declare function FullScreenButton({ onClick }: Props): JSX.Element;
export declare function FullScreenButton({ onClick }: Props): React.JSX.Element;
export {};
import React from 'react';
import { createRendererUrl } from 'react-cosmos-core';
import { createPlugin } from 'react-plugin';
import { stringifyRendererUrlQuery } from 'react-cosmos-core';
import { FullScreenButton } from './FullScreenButton.js';

@@ -12,7 +12,13 @@ const { namedPlug, register } = createPlugin({

const core = getMethodsOf('core');
const rendererUrl = core.getWebRendererUrl();
const rendererCore = getMethodsOf('rendererCore');
const rendererUrl = rendererCore.getRendererUrl();
const onSelect = React.useCallback(() => {
const query = stringifyRendererUrlQuery({ _fixtureId: fixtureId });
const fixtureUrl = `${rendererUrl}?${query}`;
window.open(fixtureUrl, '_blank');
if (rendererUrl) {
const fixtureUrl = createRendererUrl(rendererUrl, fixtureId, true);
// noopener is required to prevent reuse of sessionStorage from the
// Playground window, thus making sure the remote renderer will generate
// a different rendererId from the iframe renderer.
// https://stackoverflow.com/a/73821739
window.open(fixtureUrl, '_blank', 'noopener=true');
}
}, [fixtureId, rendererUrl]);

@@ -19,0 +25,0 @@ React.useEffect(() => {

@@ -9,3 +9,3 @@ import { rendererSocketMessage, } from 'react-cosmos-core';

}
socket = new WebSocket(location.origin.replace(/^https?:/, 'ws:'));
socket = new WebSocket(location.origin.replace(/^https:/, 'wss:').replace(/^http:/, 'ws:'));
socket.addEventListener('open', () => {

@@ -12,0 +12,0 @@ if (socket && pendingMessages.length > 0) {

@@ -0,1 +1,2 @@

import React from 'react';
import { NotificationItem } from './spec.js';

@@ -5,3 +6,3 @@ type Props = {

};
export declare function Notifications({ notifications }: Props): JSX.Element;
export declare function Notifications({ notifications }: Props): React.JSX.Element;
export {};
import './BuildNotifications/index.js';
import './ClassStatePanel/index.js';
import './ContentOverlay/index.js';
import './ControlPanel/index.js';

@@ -5,0 +4,0 @@ import './ControlSelect/index.js';

import { enablePlugin } from 'react-plugin';
import './BuildNotifications/index.js';
import './ClassStatePanel/index.js';
import './ContentOverlay/index.js';
import './ControlPanel/index.js';

@@ -6,0 +5,0 @@ import './ControlSelect/index.js';

@@ -0,1 +1,2 @@

import React from 'react';
export type SimplePlugin = {

@@ -9,3 +10,3 @@ name: string;

};
export declare function PluginList({ plugins, enable }: Props): JSX.Element;
export declare function PluginList({ plugins, enable }: Props): React.JSX.Element;
export {};

@@ -1,3 +0,4 @@

export declare function BlankState(): JSX.Element;
import React from 'react';
export declare function BlankState(): React.JSX.Element;
export declare const IconContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
export declare const NoWrap: import("styled-components").StyledComponent<"span", any, {}, never>;
import React from 'react';
import { DelayRender } from 'react-cosmos-core';
import styled from 'styled-components';

@@ -6,14 +7,15 @@ import { SlidersIcon } from '../../components/icons/index.js';

export function BlankState() {
return (React.createElement(Container, null,
React.createElement(IconContainer, null,
React.createElement(SlidersIcon, null)),
React.createElement(Title, null,
"No visible props in ",
React.createElement(NoWrap, null, "selected fixture")),
React.createElement(Description, null,
"Props of exported JSX ",
React.createElement(NoWrap, null, "elements from"),
" your fixtures",
' ',
React.createElement(NoWrap, null, "will appear here."))));
return (React.createElement(DelayRender, { delay: 500 },
React.createElement(Container, null,
React.createElement(IconContainer, null,
React.createElement(SlidersIcon, null)),
React.createElement(Title, null,
"No visible props in ",
React.createElement(NoWrap, null, "selected fixture")),
React.createElement(Description, null,
"Props of exported JSX ",
React.createElement(NoWrap, null, "elements from"),
" your fixtures",
' ',
React.createElement(NoWrap, null, "will appear here.")))));
}

@@ -20,0 +22,0 @@ const Container = styled.div `

@@ -1,2 +0,2 @@

import React from 'react';
import React, { useCallback } from 'react';
import { createPlugin } from 'react-plugin';

@@ -6,3 +6,3 @@ import { getFixtureExpansion, hasFsValues, updateElementExpansion, } from '../../components/ValueInputTree/index.js';

import { PropsPanel } from './PropsPanel/index.js';
import { PROPS_TREE_EXPANSION_STORAGE_KEY } from './shared.js';
import { PROPS_TREE_EXPANSION_STORAGE_KEY, } from './shared.js';
const { namedPlug, register } = createPlugin({

@@ -12,4 +12,6 @@ name: 'propsPanel',

namedPlug('sidePanelRow', 'props', ({ pluginContext, slotProps }) => {
const { fixtureId, fixtureState, onFixtureStateChange } = slotProps;
const { fixtureId, getFixtureState, setFixtureState } = slotProps;
const { fixtureExpansion, onElementExpansionChange } = useFixtureExpansion(pluginContext, fixtureId);
const fixtureState = getFixtureState('props');
const onFixtureStateChange = useCallback(change => setFixtureState('props', change), [setFixtureState]);
return (React.createElement(PropsPanel, { fixtureState: fixtureState, fixtureExpansion: fixtureExpansion, onFixtureStateChange: onFixtureStateChange, onElementExpansionChange: onElementExpansionChange }));

@@ -22,4 +24,4 @@ });

namedPlug('sidePanelRow', 'blankState', ({ slotProps }) => {
const { fixtureState } = slotProps;
return shouldShowBlankState(fixtureState) ? React.createElement(BlankState, null) : null;
const { getFixtureState } = slotProps;
return shouldShowBlankState(getFixtureState) ? React.createElement(BlankState, null) : null;
});

@@ -44,13 +46,13 @@ export { register };

}
function shouldShowBlankState(fixtureState) {
// Don't show blank state until props (empty or not) have been read
if (!fixtureState.props)
return false;
const hasProps = fixtureState.props.some(hasFsValues);
function shouldShowBlankState(getFixtureState) {
const props = getFixtureState('props');
const hasProps = props && props.some(hasFsValues);
if (hasProps)
return false;
const hasClassState = fixtureState.classState && fixtureState.classState.some(hasFsValues);
const classState = getFixtureState('classState');
const hasClassState = classState && classState.some(hasFsValues);
if (hasClassState)
return false;
const hasControls = fixtureState.controls && Object.keys(fixtureState.controls).length > 0;
const controls = getFixtureState('controls');
const hasControls = controls && Object.keys(controls).length > 0;
if (hasControls)

@@ -57,0 +59,0 @@ return false;

@@ -1,10 +0,12 @@

import { FixtureState, FixtureStateProps, StateUpdater } from 'react-cosmos-core';
import React from 'react';
import { PropsFixtureStateItem } from 'react-cosmos-core';
import { FixtureExpansion, OnElementExpansionChange } from '../../../components/ValueInputTree/index.js';
import { SetPropsFixtureState } from '../shared.js';
type Props = {
fsProps: FixtureStateProps;
propsFsItem: PropsFixtureStateItem;
fixtureExpansion: FixtureExpansion;
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
onFixtureStateChange: SetPropsFixtureState;
onElementExpansionChange: OnElementExpansionChange;
};
export declare function ComponentProps({ fsProps, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }: Props): JSX.Element;
export declare function ComponentProps({ propsFsItem, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }: Props): React.JSX.Element;
export {};
import { isEqual } from 'lodash-es';
import React, { useCallback } from 'react';
import { resetFixtureStateProps, updateFixtureStateProps, } from 'react-cosmos-core';
import { resetPropsFixtureStateItem, updatePropsFixtureStateItem, } from 'react-cosmos-core';
import { SidePanelActions, SidePanelBody, SidePanelContainer, SidePanelHeader, SidePanelTitle, } from '../../../components/SidePanel.js';
import { ExpandCollapseValues } from '../../../components/ValueInputTree/ExpandCollapseValues.js';
import { ValueInputTree, stringifyElementId, } from '../../../components/ValueInputTree/index.js';
import { IconButton32 } from '../../../components/buttons/index.js';
import { CopyIcon, RotateCcwIcon } from '../../../components/icons/index.js';
import { SidePanelActions, SidePanelBody, SidePanelContainer, SidePanelHeader, SidePanelTitle, } from '../../../components/SidePanel.js';
import { ExpandCollapseValues } from '../../../components/ValueInputTree/ExpandCollapseValues.js';
import { stringifyElementId, ValueInputTree, } from '../../../components/ValueInputTree/index.js';
import { createPropsFsUpdater } from './shared.js';
export function ComponentProps({ fsProps, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }) {
const { componentName, elementId, values } = fsProps;
import { propsFsItemUpdater } from './shared.js';
export function ComponentProps({ propsFsItem, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }) {
const { componentName, elementId, values } = propsFsItem;
const [reset, setReset] = React.useState(true);
const handleResetToggle = React.useCallback(() => setReset(!reset), [reset]);
const [initialValues] = React.useState(() => values);
const handleValuesReset = React.useCallback(() => onFixtureStateChange(createPropsFsUpdater(elementId, prevFs => resetFixtureStateProps({
fixtureState: prevFs,
const handleValuesReset = React.useCallback(() => onFixtureStateChange(propsFsItemUpdater(elementId, prevFs => resetPropsFixtureStateItem({
propsFs: prevFs,
elementId,

@@ -21,5 +21,7 @@ values: initialValues,

const handleValueChange = React.useCallback((newValues) => {
const changeFn = reset ? resetFixtureStateProps : updateFixtureStateProps;
onFixtureStateChange(createPropsFsUpdater(elementId, prevFs => changeFn({
fixtureState: prevFs,
const changeFn = reset
? resetPropsFixtureStateItem
: updatePropsFixtureStateItem;
onFixtureStateChange(propsFsItemUpdater(elementId, prevFs => changeFn({
propsFs: prevFs,
elementId,

@@ -26,0 +28,0 @@ values: newValues,

import React from 'react';
import { FixtureState, StateUpdater } from 'react-cosmos-core';
import { PropsFixtureState } from 'react-cosmos-core';
import { FixtureExpansion, OnElementExpansionChange } from '../../../components/ValueInputTree/index.js';
import { SetPropsFixtureState } from '../shared.js';
type Props = {
fixtureState: FixtureState;
fixtureState: PropsFixtureState | undefined;
fixtureExpansion: FixtureExpansion;
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
onFixtureStateChange: SetPropsFixtureState;
onElementExpansionChange: OnElementExpansionChange;

@@ -9,0 +10,0 @@ };

@@ -5,10 +5,10 @@ import React from 'react';

export const PropsPanel = React.memo(function PropsPanel({ fixtureState, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }) {
if (!fixtureState.props) {
if (!fixtureState) {
return null;
}
const propsWithValues = fixtureState.props.filter(hasFsValues);
return (React.createElement(React.Fragment, null, sortFsValueGroups(propsWithValues).map(fsProps => {
const strElementId = stringifyElementId(fsProps.elementId);
return (React.createElement(ComponentProps, { key: strElementId, fsProps: fsProps, fixtureExpansion: fixtureExpansion, onFixtureStateChange: onFixtureStateChange, onElementExpansionChange: onElementExpansionChange }));
const propsWithValues = fixtureState.filter(hasFsValues);
return (React.createElement(React.Fragment, null, sortFsValueGroups(propsWithValues).map(fsItem => {
const strElementId = stringifyElementId(fsItem.elementId);
return (React.createElement(ComponentProps, { key: strElementId, propsFsItem: fsItem, fixtureExpansion: fixtureExpansion, onFixtureStateChange: onFixtureStateChange, onElementExpansionChange: onElementExpansionChange }));
})));
});

@@ -1,2 +0,2 @@

import { FixtureElementId, FixtureState, FixtureStateProps, StateUpdater } from 'react-cosmos-core';
export declare function createPropsFsUpdater(elementId: FixtureElementId, cb: (prevFs: FixtureState) => FixtureStateProps[]): StateUpdater<FixtureState>;
import { FixtureElementId, FixtureStateUpdater, PropsFixtureState } from 'react-cosmos-core';
export declare function propsFsItemUpdater(elementId: FixtureElementId, cb: FixtureStateUpdater<PropsFixtureState>): FixtureStateUpdater<PropsFixtureState>;

@@ -1,16 +0,13 @@

import { findFixtureStateProps, } from 'react-cosmos-core';
import { findPropsFixtureStateItem, } from 'react-cosmos-core';
import { stringifyElementId } from '../../../components/ValueInputTree/index.js';
export function createPropsFsUpdater(elementId, cb) {
export function propsFsItemUpdater(elementId, cb) {
return prevFs => {
const fsProps = findFixtureStateProps(prevFs, elementId);
if (!fsProps) {
const fsItem = findPropsFixtureStateItem(prevFs, elementId);
if (!fsItem) {
const elId = stringifyElementId(elementId);
console.warn(`Trying to update missing element with ID: ${elId}`);
return prevFs;
return prevFs ?? [];
}
return {
...prevFs,
props: cb(prevFs),
};
return cb(prevFs);
};
}

@@ -0,1 +1,3 @@

import { FixtureStateUpdater, PropsFixtureState } from 'react-cosmos-core';
export type SetPropsFixtureState = (updater: FixtureStateUpdater<PropsFixtureState>) => void;
export declare const PROPS_TREE_EXPANSION_STORAGE_KEY = "propsTreeExpansion";

@@ -27,4 +27,5 @@ import React from 'react';

const core = getMethodsOf('core');
const rendererCore = getMethodsOf('rendererCore');
const notifications = getMethodsOf('notifications');
return (React.createElement(RemoteButton, { devServerOn: core.isDevServerOn(), webRendererUrl: core.getWebRendererUrl(), pushNotification: notifications.pushTimedNotification }));
return (React.createElement(RemoteButton, { devServerOn: core.isDevServerOn(), rendererUrl: rendererCore.getRendererUrl(), pushNotification: notifications.pushTimedNotification }));
});

@@ -31,0 +32,0 @@ export { register };

@@ -0,8 +1,9 @@

import React from 'react';
import { NotificationItem } from '../../Notifications/spec.js';
type Props = {
devServerOn: boolean;
webRendererUrl: null | string;
rendererUrl: null | string;
pushNotification: (notification: NotificationItem) => unknown;
};
export declare function RemoteButton({ devServerOn, webRendererUrl, pushNotification, }: Props): JSX.Element | null;
export declare function RemoteButton({ devServerOn, rendererUrl, pushNotification, }: Props): React.JSX.Element | null;
export {};
import React from 'react';
import { createRendererUrl } from 'react-cosmos-core';
import { IconButton32 } from '../../../components/buttons/index.js';
import { CastIcon } from '../../../components/icons/index.js';
import { copyToClipboard } from './copyToClipboard.js';
export function RemoteButton({ devServerOn, webRendererUrl, pushNotification, }) {
if (!devServerOn || !webRendererUrl) {
export function RemoteButton({ devServerOn, rendererUrl, pushNotification, }) {
if (!devServerOn || !rendererUrl) {
return null;
}
return (React.createElement(IconButton32, { icon: React.createElement(CastIcon, null), title: "Copy remote renderer URL", onClick: () => copyRendererUrlToClipboard(webRendererUrl) }));
return (React.createElement(IconButton32, { icon: React.createElement(CastIcon, null), title: "Copy remote renderer URL", onClick: () => copyRendererUrlToClipboard(createRendererUrl(rendererUrl)) }));
async function copyRendererUrlToClipboard(url) {

@@ -36,3 +37,3 @@ const fullUrl = getFullUrl(url);

return rendererUrl;
return `${location.origin}${rendererUrl}`;
return new URL(rendererUrl, location.origin).toString();
}

@@ -0,8 +1,16 @@

import { fixtureStateByName } from 'react-cosmos-core';
import { createPlugin } from 'react-plugin';
import { isValidFixtureSelected } from './isValidFixtureSelected.js';
import { onRouterFixtureChange } from './onRouterFixtureChange.js';
import { onRouterFixtureReselect } from './onRouterFixtureReselect.js';
import { onRouterFixtureSelect } from './onRouterFixtureSelect.js';
import { onRouterFixtureUnselect } from './onRouterFixtureUnselect.js';
import { receiveResponse } from './receiveResponse/index.js';
import { reloadRenderer } from './reloadRenderer.js';
import { setFixtureState } from './setFixtureState.js';
const { on, register } = createPlugin({
import { setGlobalFixtureState } from './setGlobalFixtureState.js';
const { on, register, onLoad } = createPlugin({
name: 'rendererCore',
defaultConfig: {
fixtures: {},
rendererUrl: null,
},
initialState: {

@@ -13,19 +21,34 @@ connectedRendererIds: [],

fixtureState: {},
globalFixtureState: {},
},
methods: {
getRendererUrl,
getConnectedRendererIds,
getPrimaryRendererId,
getFixtures,
getFixtureState,
isRendererConnected,
isValidFixtureSelected,
setFixtureState,
reloadRenderer,
selectPrimaryRenderer,
receiveResponse,
getAllFixtureState,
getFixtureState,
setFixtureState,
setGlobalFixtureState,
},
});
on('router', { fixtureChange: onRouterFixtureChange });
onLoad(({ getConfig, setState }) => {
const { fixtures } = getConfig();
setState(prevState => ({ ...prevState, fixtures }));
});
on('router', {
fixtureSelect: onRouterFixtureSelect,
fixtureReselect: onRouterFixtureReselect,
fixtureUnselect: onRouterFixtureUnselect,
});
export { register };
if (process.env.NODE_ENV !== 'test')
register();
function getRendererUrl({ getConfig }) {
return getConfig().rendererUrl;
}
function getConnectedRendererIds({ getState }) {

@@ -40,5 +63,8 @@ return getState().connectedRendererIds;

}
function getFixtureState({ getState }) {
function getAllFixtureState({ getState }) {
return getState().fixtureState;
}
function getFixtureState({ getState }, name) {
return fixtureStateByName(getState().fixtureState, name);
}
function isRendererConnected({ getState }) {

@@ -45,0 +71,0 @@ return getState().connectedRendererIds.length > 0;

@@ -8,2 +8,6 @@ import { isEqual } from 'lodash-es';

const { primaryRendererId, fixtureState: prevFixtureState } = context.getState();
// Discard updates from secondary renderers
if (rendererId !== primaryRendererId) {
return;
}
if (!isEqual(fixtureId, selectedFixtureId)) {

@@ -14,6 +18,2 @@ console.warn('[Renderer] fixtureStateChange response ignored ' +

}
// Discard updates from secondary renderers
if (rendererId !== primaryRendererId) {
return;
}
if (isEqual(fixtureState, prevFixtureState)) {

@@ -20,0 +20,0 @@ return;

@@ -1,5 +0,6 @@

import { postSelectFixtureRequest } from '../shared/postRequest.js';
import { getSelectedFixtureId } from '../shared/router.js';
import { isEqual } from 'lodash-es';
import { postSelectFixtureRequest, postSetFixtureStateRequest, } from '../shared/postRequest.js';
export function receiveRendererReadyResponse(context, { payload }) {
const { rendererId, fixtures, initialFixtureId } = payload;
const { rendererId } = payload;
const { connectedRendererIds: prevRendererIds, globalFixtureState } = context.getState();
context.setState(stateUpdater, afterStateChanged);

@@ -9,3 +10,2 @@ function stateUpdater(prevState) {

const primaryRendererId = prevState.primaryRendererId || rendererId;
const isPrimaryRenderer = rendererId === primaryRendererId;
const { connectedRendererIds, fixtureState } = prevState;

@@ -16,25 +16,24 @@ return {

primaryRendererId,
fixtures,
fixtureState: isPrimaryRenderer ? {} : fixtureState,
fixtureState: rendererId === primaryRendererId ? globalFixtureState : fixtureState,
};
}
function afterStateChanged() {
if (initialFixtureId)
selectInitialFixture(context, initialFixtureId);
else
selectFixtureFromUrlParams(context, rendererId);
notifyRendererConnection(context, rendererId);
const router = context.getMethodsOf('router');
const rendererFixtureId = payload.selectedFixtureId;
const routerFixtureId = router.getSelectedFixtureId();
if (routerFixtureId && !isEqual(routerFixtureId, rendererFixtureId)) {
const { fixtureState } = context.getState();
postSelectFixtureRequest(context, rendererId, routerFixtureId, fixtureState);
}
else if (rendererFixtureId) {
if (Object.keys(globalFixtureState).length > 0) {
postSetFixtureStateRequest(context, rendererId, rendererFixtureId, globalFixtureState);
}
}
// Notify about connected renderers that weren't connected before
if (!prevRendererIds.includes(rendererId)) {
notifyRendererConnection(context, rendererId);
}
}
}
function selectInitialFixture({ getMethodsOf }, fixtureId) {
const router = getMethodsOf('router');
router.selectFixture(fixtureId);
}
function selectFixtureFromUrlParams(context, rendererId) {
const fixtureId = getSelectedFixtureId(context);
if (fixtureId) {
const { fixtureState } = context.getState();
postSelectFixtureRequest(context, rendererId, fixtureId, fixtureState);
}
}
function notifyRendererConnection({ getMethodsOf }, rendererId) {

@@ -41,0 +40,0 @@ const notifications = getMethodsOf('notifications');

@@ -1,3 +0,3 @@

import { FixtureState, StateUpdater } from 'react-cosmos-core';
import { FixtureStateChange } from 'react-cosmos-core';
import { RendererCoreContext } from './shared/index.js';
export declare function setFixtureState(context: RendererCoreContext, stateUpdater: StateUpdater<FixtureState>): void;
export declare function setFixtureState(context: RendererCoreContext, name: string, change: FixtureStateChange<unknown>): void;

@@ -0,4 +1,5 @@

import { updateFixtureState, } from 'react-cosmos-core';
import { postSetFixtureStateRequest } from './shared/postRequest.js';
import { getSelectedFixtureId } from './shared/router.js';
export function setFixtureState(context, stateUpdater) {
export function setFixtureState(context, name, change) {
const fixtureId = getSelectedFixtureId(context);

@@ -9,9 +10,9 @@ if (!fixtureId) {

}
context.setState(change, () => {
context.setState(stateUpdater, () => {
postRendererRequest(fixtureId);
});
function change(prevState) {
function stateUpdater(prevState) {
return {
...prevState,
fixtureState: stateUpdater(prevState.fixtureState),
fixtureState: updateFixtureState(prevState.fixtureState, name, change),
};

@@ -18,0 +19,0 @@ }

import { FixtureId, FixtureState, RendererId } from 'react-cosmos-core';
import { RendererCoreContext } from '../shared/index.js';
import { RendererCoreContext } from './index.js';
export declare function postReloadRendererRequest(context: RendererCoreContext, rendererId: RendererId): void;
export declare function postSelectFixtureRequest(context: RendererCoreContext, rendererId: RendererId, fixtureId: FixtureId, fixtureState: FixtureState): void;
export declare function postUnselectFixtureRequest(context: RendererCoreContext, rendererId: RendererId): void;
export declare function postSetFixtureStateRequest(context: RendererCoreContext, rendererId: RendererId, fixtureId: FixtureId, fixtureState: FixtureState): void;

@@ -0,1 +1,9 @@

export function postReloadRendererRequest(context, rendererId) {
postRendererRequest(context, {
type: 'reloadRenderer',
payload: {
rendererId,
},
});
}
export function postSelectFixtureRequest(context, rendererId, fixtureId, fixtureState) {

@@ -2,0 +10,0 @@ postRendererRequest(context, {

@@ -1,4 +0,10 @@

import { FixtureList, FixtureState, MessageType, RendererId, StateUpdater } from 'react-cosmos-core';
import { FixtureList, FixtureState, FixtureStateChange, MessageType, RendererId } from 'react-cosmos-core';
export type GetFixtureState = <T>(name: string) => T | undefined;
export type SetFixtureStateByName = <T>(name: string, change: FixtureStateChange<T>) => void;
export type RendererCoreSpec = {
name: 'rendererCore';
config: {
fixtures: FixtureList;
rendererUrl: null | string;
};
state: {

@@ -9,13 +15,17 @@ connectedRendererIds: RendererId[];

fixtureState: FixtureState;
globalFixtureState: FixtureState;
};
methods: {
getRendererUrl(): null | string;
getConnectedRendererIds(): RendererId[];
getPrimaryRendererId(): null | RendererId;
getFixtures(): FixtureList;
getFixtureState(): FixtureState;
isRendererConnected(): boolean;
isValidFixtureSelected(): boolean;
setFixtureState(stateUpdater: StateUpdater<FixtureState>): void;
reloadRenderer(): void;
selectPrimaryRenderer(primaryRendererId: RendererId): void;
receiveResponse(msg: MessageType): void;
getAllFixtureState(): FixtureState;
getFixtureState: GetFixtureState;
setFixtureState: SetFixtureStateByName;
setGlobalFixtureState<T>(name: string, state: T): void;
};

@@ -22,0 +32,0 @@ events: {

@@ -37,3 +37,3 @@ const notificationId = 'renderer-location-change';

title: 'Renderer iframe location changed',
info: `Reload or select another fixture to reset your preview.`,
info: `Select a fixture to reset your preview.`,
});

@@ -63,7 +63,8 @@ }

const { href } = iframeWindow.location;
const locationWithoutHash = href.split('#')[0];
return (locationWithoutHash !== iframeSrc &&
// Some static servers strip .html extensions automatically
// https://github.com/zeit/serve-handler/tree/ce35fcd4e1c67356348f4735eed88fb084af9b43#cleanurls-booleanarray
locationWithoutHash !== iframeSrc.replace(/\.html$/, ''));
return (
// Don't register a location change when renderer searchParams change
!href.startsWith(
// Some static servers strip .html extensions automatically
// https://github.com/zeit/serve-handler/tree/ce35fcd4e1c67356348f4735eed88fb084af9b43#cleanurls-booleanarray
iframeSrc.replace(/\.html$/, '')));
}

@@ -70,0 +71,0 @@ catch (err) {

@@ -32,4 +32,13 @@ export function handleWindowMessages(context) {

}
function updateRuntimeStatus({ getState, setState }, response) {
function updateRuntimeStatus({ getState, setState, getMethodsOf }, response) {
const { runtimeStatus } = getState();
if (response.type === 'rendererError') {
const notifications = getMethodsOf('notifications');
notifications.pushTimedNotification({
id: 'renderer-error',
type: 'error',
title: 'Renderer error',
info: 'Check the browser console for details.',
});
}
// Errors are not of interest anymore after renderer connectivity has been

@@ -36,0 +45,0 @@ // established. Errors that occur after renderer is connected are likely

import React from 'react';
import { createPlugin } from 'react-plugin';
import { checkRendererStatus } from './checkRendererStatus.js';
import { RendererPreview } from './RendererPreview.js';
import { createRendererRequestHandler } from './handleRendererRequests.js';
import { handleWindowMessages } from './handleWindowMessages.js';
import { RendererPreview } from './RendererPreview.js';
const { postRendererRequest, setIframeRef } = createRendererRequestHandler();

@@ -11,7 +10,5 @@ const { onLoad, on, plug, register } = createPlugin({

initialState: {
urlStatus: 'unknown',
runtimeStatus: 'pending',
},
methods: {
getUrlStatus,
getRuntimeStatus,

@@ -28,6 +25,3 @@ },

}
return [
checkRendererStatus(context, rendererUrl),
handleWindowMessages(context),
];
return [handleWindowMessages(context)];
});

@@ -38,3 +32,3 @@ plug('rendererPreview', ({ pluginContext }) => {

}
return (React.createElement(RendererPreview, { rendererUrl: getRendererUrl(pluginContext), onIframeRef: handleIframeRef }));
return (React.createElement(RendererPreview, { rendererUrl: getRendererUrl(pluginContext), rendererConnected: getRendererConnected(pluginContext), runtimeStatus: pluginContext.getState().runtimeStatus, onIframeRef: handleIframeRef }));
});

@@ -44,5 +38,2 @@ export { register };

register();
function getUrlStatus({ getState }) {
return getState().urlStatus;
}
function getRuntimeStatus({ getState }) {

@@ -52,3 +43,6 @@ return getState().runtimeStatus;

function getRendererUrl({ getMethodsOf }) {
return getMethodsOf('core').getWebRendererUrl();
return getMethodsOf('rendererCore').getRendererUrl();
}
function getRendererConnected({ getMethodsOf }) {
return getMethodsOf('rendererCore').isRendererConnected();
}
import React from 'react';
import { RuntimeStatus } from './spec.js';
export type OnIframeRef = (elRef: null | HTMLIFrameElement) => void;
type Props = {
rendererUrl: null | string;
rendererConnected: boolean;
runtimeStatus: RuntimeStatus;
onIframeRef: OnIframeRef;

@@ -6,0 +9,0 @@ };

import React from 'react';
import { createRendererUrl } from 'react-cosmos-core';
import { Slot } from 'react-plugin';
import styled from 'styled-components';
export const RendererPreview = React.memo(function RendererPreview({ rendererUrl, onIframeRef, }) {
import { RemoteRendererOverlay } from './RendererOverlay/RemoteRendererOverlay.js';
import { RendererOverlay } from './RendererOverlay/RendererOverlay.js';
export const RendererPreview = React.memo(function RendererPreview({ rendererUrl, rendererConnected, runtimeStatus, onIframeRef, }) {
if (!rendererUrl) {
return null;
// This code path is used when Cosmos is in React Native mode
return (React.createElement(Container, null,
React.createElement(RemoteRendererOverlay, { rendererConnected: rendererConnected })));
}
return (React.createElement(Slot, { name: "rendererPreviewOuter" },
React.createElement(Container, null,
React.createElement(Iframe, { "data-testid": "previewIframe", ref: onIframeRef, src: rendererUrl, frameBorder: 0, allow: "clipboard-write *" }))));
React.createElement(Iframe, { "data-testid": "previewIframe", ref: onIframeRef, src: createRendererUrl(rendererUrl), frameBorder: 0, allow: "clipboard-write *; fullscreen *;" }),
React.createElement(RendererOverlay, { runtimeStatus: runtimeStatus }))));
});
const Container = styled.div `
position: relative;
width: 100%;

@@ -14,0 +21,0 @@ height: 100%;

import { PluginContext } from 'react-plugin';
import { RendererPreviewSpec } from './spec.js';
export type UrlStatus = 'unknown' | 'ok' | 'error';
export type RuntimeStatus = 'pending' | 'connected' | 'error';
export type State = {
urlStatus: UrlStatus;
runtimeStatus: RuntimeStatus;
};
export type RendererPreviewContext = PluginContext<RendererPreviewSpec>;

@@ -1,2 +0,1 @@

export type UrlStatus = 'unknown' | 'ok' | 'error';
export type RuntimeStatus = 'pending' | 'connected' | 'error';

@@ -6,9 +5,7 @@ export type RendererPreviewSpec = {

state: {
urlStatus: UrlStatus;
runtimeStatus: RuntimeStatus;
};
methods: {
getUrlStatus(): UrlStatus;
getRuntimeStatus(): RuntimeStatus;
};
};
import React from 'react';
import { createPlugin } from 'react-plugin';
import { ResponsivePreview } from './ResponsivePreview/ResponsivePreview.js';
import { ToggleButton } from './ToggleButton/index.js';
import { DEFAULT_DEVICES, DEFAULT_VIEWPORT_STATE, VIEWPORT_STORAGE_KEY, } from './shared.js';
import { ToggleButton } from './ToggleButton/index.js';
const { plug, namedPlug, register } = createPlugin({

@@ -13,16 +13,15 @@ name: 'responsivePreview',

plug('rendererPreviewOuter', ({ children, pluginContext }) => {
const { getConfig, getMethodsOf } = pluginContext;
const { getConfig } = pluginContext;
const { devices } = getConfig();
const rendererCore = getMethodsOf('rendererCore');
const { enabled, viewport, scaled } = getViewportState(pluginContext);
const onViewportChange = useViewportChange(pluginContext);
const onScaledChange = useScaledChange(pluginContext);
return (React.createElement(ResponsivePreview, { devices: devices, enabled: enabled, viewport: viewport, scaled: scaled, validFixtureSelected: rendererCore.isValidFixtureSelected(), setViewport: onViewportChange, setScaled: onScaledChange }, children));
return (React.createElement(ResponsivePreview, { devices: devices, enabled: enabled, viewport: viewport, scaled: scaled, setViewport: onViewportChange, setScaled: onScaledChange }, children));
});
namedPlug('rendererAction', 'responsivePreview', ({ pluginContext }) => {
const { getMethodsOf } = pluginContext;
const core = getMethodsOf('core');
const rendererCore = getMethodsOf('rendererCore');
const viewportState = getViewportState(pluginContext);
const { enabled, viewport } = viewportState;
if (!core.getWebRendererUrl())
if (!rendererCore.getRendererUrl())
return null;

@@ -32,7 +31,7 @@ return (React.createElement(ToggleButton, { selected: enabled, onToggle: () => {

setViewportState(pluginContext, { ...viewportState, enabled: false });
setFixtureStateViewport(pluginContext, null);
setViewportFixtureState(pluginContext, null);
}
else {
setViewportState(pluginContext, { ...viewportState, enabled: true });
setFixtureStateViewport(pluginContext, viewport);
setViewportFixtureState(pluginContext, viewport);
}

@@ -46,8 +45,6 @@ } }));

const viewportState = getViewportState(context);
return React.useCallback((viewportChange) => {
const viewport = typeof viewportChange === 'function'
? viewportChange(viewportState.viewport)
: viewportChange;
return React.useCallback((change) => {
const viewport = typeof change === 'function' ? change(viewportState.viewport) : change;
setViewportState(context, { ...viewportState, enabled: true, viewport });
setFixtureStateViewport(context, viewport);
setViewportFixtureState(context, viewport);
}, [context, viewportState]);

@@ -65,5 +62,5 @@ }

const rendererCore = getMethodsOf('rendererCore');
const fixtureState = rendererCore.getFixtureState();
return fixtureState.viewport
? { ...viewportState, enabled: true, viewport: fixtureState.viewport }
const viewport = rendererCore.getFixtureState('viewport');
return viewport
? { ...viewportState, enabled: true, viewport }
: viewportState;

@@ -76,9 +73,6 @@ }

}
function setFixtureStateViewport(context, viewport) {
function setViewportFixtureState(context, viewport) {
const { getMethodsOf } = context;
const rendererCore = getMethodsOf('rendererCore');
rendererCore.setFixtureState(fixtureState => ({
...fixtureState,
viewport,
}));
rendererCore.setFixtureState('viewport', viewport);
}

@@ -1,3 +0,4 @@

import { Dispatch, ReactNode, SetStateAction } from 'react';
import { ResponsiveDevice, ResponsiveViewport } from '../spec.js';
import React, { Dispatch, ReactNode, SetStateAction } from 'react';
import { Viewport } from 'react-cosmos-core';
import { ResponsiveDevice } from '../spec.js';
type Props = {

@@ -7,9 +8,8 @@ children?: ReactNode;

enabled: boolean;
viewport: ResponsiveViewport;
viewport: Viewport;
scaled: boolean;
validFixtureSelected: boolean;
setViewport: Dispatch<SetStateAction<ResponsiveViewport>>;
setViewport: Dispatch<SetStateAction<Viewport>>;
setScaled: (scaled: boolean) => unknown;
};
export declare function ResponsivePreview({ children, devices, enabled, viewport, scaled, validFixtureSelected, setViewport, setScaled, }: Props): JSX.Element;
export declare function ResponsivePreview({ children, devices, enabled, viewport, scaled, setViewport, setScaled, }: Props): React.JSX.Element;
export {};

@@ -6,5 +6,5 @@ import { isEqual } from 'lodash-es';

import { grey64, grey8 } from '../../../style/colors.js';
import { Header } from './Header.js';
import { ResponsiveHeader } from './ResponsiveHeader.js';
import { getStyles, getViewportScaleFactor, responsivePreviewBorderWidth, responsivePreviewPadding, stretchStyle, } from './style.js';
export function ResponsivePreview({ children, devices, enabled, viewport, scaled, validFixtureSelected, setViewport, setScaled, }) {
export function ResponsivePreview({ children, devices, enabled, viewport, scaled, setViewport, setScaled, }) {
const [container, setContainer] = useState(null);

@@ -57,3 +57,3 @@ const onWidthChange = useCallback((width) => setViewport(prevViewport => ({ ...prevViewport, width })), [setViewport]);

// component instances are preserved and the transition is seamless.
if (!validFixtureSelected || !enabled || !container) {
if (!enabled || !container) {
return (React.createElement(Container, null,

@@ -68,3 +68,3 @@ React.createElement("div", { key: "preview", ref: handleContainerRef, style: stretchStyle },

return (React.createElement(Container, null,
React.createElement(Header, { devices: devices, selectedViewport: viewport, scaleFactor: scaleFactor, scaled: scaled, selectViewport: setViewport, toggleScale: () => setScaled(!scaled) }),
React.createElement(ResponsiveHeader, { devices: devices, selectedViewport: viewport, scaleFactor: scaleFactor, scaled: scaled, selectViewport: setViewport, toggleScale: () => setScaled(!scaled) }),
React.createElement("div", { key: "preview", ref: handleContainerRef, style: maskContainerStyle },

@@ -71,0 +71,0 @@ React.createElement("div", { style: padContainerStyle },

@@ -1,2 +0,2 @@

import { ResponsiveViewport } from '../spec.js';
import { Viewport } from 'react-cosmos-core';
export declare const responsivePreviewPadding: {

@@ -14,4 +14,4 @@ top: number;

export declare function getStyles({ container, viewport, scaled, }: {
container: ResponsiveViewport;
viewport: ResponsiveViewport;
container: Viewport;
viewport: Viewport;
scaled: boolean;

@@ -46,2 +46,2 @@ }): {

};
export declare function getViewportScaleFactor(viewport: ResponsiveViewport, container: ResponsiveViewport): number;
export declare function getViewportScaleFactor(viewport: Viewport, container: Viewport): number;

@@ -1,14 +0,11 @@

import { FixtureState } from 'react-cosmos-core';
import { Viewport } from 'react-cosmos-core';
import { PluginContext } from 'react-plugin';
import { StorageSpec } from '../Storage/spec.js';
import { ResponsivePreviewSpec, ResponsiveViewport } from './spec.js';
import { ResponsivePreviewSpec } from './spec.js';
export type ResponsivePreviewContext = PluginContext<ResponsivePreviewSpec>;
export type StorageMethods = StorageSpec['methods'];
export type FixtureStateWithViewport = FixtureState & {
viewport?: ResponsiveViewport;
};
export type ViewportState = {
enabled: boolean;
scaled: boolean;
viewport: ResponsiveViewport;
viewport: Viewport;
};

@@ -15,0 +12,0 @@ export declare const DEFAULT_DEVICES: {

export const DEFAULT_DEVICES = [
{ label: 'iPhone 5/SE', width: 320, height: 568 },
{ label: 'iPhone 6/7/8', width: 375, height: 667 },
{ label: 'iPhone 6/7/8 Plus', width: 414, height: 736 },
{ label: 'iPhone X', width: 375, height: 812 },
{ label: 'iPad', width: 768, height: 1024 },
{ label: 'iPad Pro', width: 1024, height: 1366 },
{ label: 'iPhone SE', width: 375, height: 667 },
{ label: 'iPhone 12/13/14', width: 390, height: 844 },
{ label: 'iPhone 14 Pro', width: 393, height: 852 },
{ label: 'iPhone 14 Plus', width: 428, height: 926 },
{ label: 'iPhone 14 Pro Max', width: 430, height: 932 },
{ label: 'iPad mini', width: 744, height: 1133 },
{ label: 'iPad', width: 820, height: 1180 },
{ label: 'iPad Pro 11"', width: 834, height: 1194 },
{ label: 'iPad Pro 12.9"', width: 1024, height: 1366 },
{ label: 'Small laptop', width: 1280, height: 720 },
{ label: 'Laptop', width: 1366, height: 768 },
{ label: 'Large laptop', width: 1600, height: 900 },
{ label: 'Full HD', width: 1920, height: 1080 },
{ label: 'Quad HD', width: 2560, height: 1440 },
{ label: 'Large laptop', width: 1536, height: 864 },
{ label: '1080p', width: 1920, height: 1080 },
{ label: '1440p', width: 2560, height: 1440 },
];

@@ -18,3 +21,3 @@ export const VIEWPORT_STORAGE_KEY = 'responsiveViewportState';

scaled: true,
viewport: { width: 320, height: 568 },
viewport: { width: 375, height: 667 },
};

@@ -1,6 +0,3 @@

export type ResponsiveViewport = {
width: number;
height: number;
};
export type ResponsiveDevice = ResponsiveViewport & {
import { Viewport } from 'react-cosmos-core';
export type ResponsiveDevice = Viewport & {
label: string;

@@ -7,0 +4,0 @@ };

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -5,3 +6,3 @@ selected: boolean;

};
export declare function ToggleButton({ selected, onToggle }: Props): JSX.Element;
export declare function ToggleButton({ selected, onToggle }: Props): React.JSX.Element;
export {};

@@ -1,9 +0,7 @@

import { FixtureId } from 'react-cosmos-core';
import React from 'react';
type Props = {
selectedFixtureId: FixtureId | null;
rendererConnected: boolean;
validFixtureSelected: boolean;
globalActionOrder: string[];
};
export declare function GlobalHeader({ selectedFixtureId, rendererConnected, validFixtureSelected, globalActionOrder, }: Props): JSX.Element;
export declare function GlobalHeader({ rendererConnected, globalActionOrder }: Props): React.JSX.Element;
export {};
import React from 'react';
import { ArraySlot } from 'react-plugin';
import styled from 'styled-components';
import { grey176, grey32, white10 } from '../../style/colors.js';
export function GlobalHeader({ selectedFixtureId, rendererConnected, validFixtureSelected, globalActionOrder, }) {
function getMessage() {
if (!rendererConnected) {
return React.createElement(Message, null, "Waiting for renderer...");
}
if (!selectedFixtureId) {
return React.createElement(Message, null, "No fixture selected");
}
if (!validFixtureSelected) {
return React.createElement(Message, null, "Fixture not found");
}
return null;
}
import { grey32, white10 } from '../../style/colors.js';
export function GlobalHeader({ rendererConnected, globalActionOrder }) {
return (React.createElement(Container, null,
React.createElement(Left, null),
getMessage(),
React.createElement(Right, null, rendererConnected && (React.createElement(ArraySlot, { name: "globalAction", plugOrder: globalActionOrder })))));

@@ -52,9 +39,1 @@ }

`;
const Message = styled.div `
padding: 4px;
color: ${grey176};
line-height: 24px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
`;
import React from 'react';
import { createFixtureTree, flattenFixtureTree } from 'react-cosmos-core';
import { createPlugin } from 'react-plugin';
import { useWelcomeDismiss } from './HomeOverlay/welcomeDismiss.js';
import { Root } from './Root.js';
import { isNavOpen, openNav } from './navOpen.js';

@@ -8,3 +10,2 @@ import { getNavWidthApi } from './navWidth.js';

import { getPanelWidthApi } from './panelWidth.js';
import { Root } from './Root.js';
const { onLoad, plug, register } = createPlugin({

@@ -45,10 +46,10 @@ name: 'root',

const onTogglePanel = useOpenPanel(pluginContext);
const welcomeDismiss = useWelcomeDismiss(pluginContext);
const { storageCacheReady } = getState();
if (!storageCacheReady) {
return (React.createElement(Root, { storageCacheReady: false, fixtureItems: [], selectedFixtureId: null, rendererConnected: false, validFixtureSelected: false, fixtureState: {}, navOpen: false, panelOpen: false, navWidth: 0, panelWidth: 0, sidePanelRowOrder: [], globalActionOrder: [], globalOrder: [], navRowOrder: [], fixtureActionOrder: [], rendererActionOrder: [], onToggleNav: () => { }, onTogglePanel: () => { }, onFixtureSelect: () => { }, onFixtureClose: () => { }, onFixtureStateChange: () => { }, setNavWidth: () => { }, setPanelWidth: () => { } }));
}
if (!storageCacheReady)
return null;
const { navWidth, setNavWidth } = getNavWidthApi(pluginContext);
const { panelWidth, setPanelWidth } = getPanelWidthApi(pluginContext);
const { sidePanelRowOrder, globalActionOrder, globalOrder, navRowOrder, fixtureActionOrder, rendererActionOrder, } = getConfig();
return (React.createElement(Root, { storageCacheReady: true, fixtureItems: fixtureItems, selectedFixtureId: router.getSelectedFixtureId(), rendererConnected: rendererCore.isRendererConnected(), validFixtureSelected: rendererCore.isValidFixtureSelected(), fixtureState: rendererCore.getFixtureState(), navOpen: isNavOpen(pluginContext), panelOpen: isPanelOpen(pluginContext), navWidth: navWidth, panelWidth: panelWidth, sidePanelRowOrder: sidePanelRowOrder, globalActionOrder: globalActionOrder, globalOrder: globalOrder, navRowOrder: navRowOrder, fixtureActionOrder: fixtureActionOrder, rendererActionOrder: rendererActionOrder, onToggleNav: onToggleNav, onTogglePanel: onTogglePanel, onFixtureSelect: router.selectFixture, onFixtureClose: router.unselectFixture, onFixtureStateChange: rendererCore.setFixtureState, setNavWidth: setNavWidth, setPanelWidth: setPanelWidth }));
return (React.createElement(Root, { fixtureItems: fixtureItems, selectedFixtureId: router.getSelectedFixtureId(), rendererConnected: rendererCore.isRendererConnected(), getFixtureState: rendererCore.getFixtureState, setFixtureState: rendererCore.setFixtureState, navOpen: isNavOpen(pluginContext), panelOpen: isPanelOpen(pluginContext), navWidth: navWidth, panelWidth: panelWidth, sidePanelRowOrder: sidePanelRowOrder, globalActionOrder: globalActionOrder, globalOrder: globalOrder, navRowOrder: navRowOrder, fixtureActionOrder: fixtureActionOrder, rendererActionOrder: rendererActionOrder, onToggleNav: onToggleNav, onTogglePanel: onTogglePanel, onReloadRenderer: rendererCore.reloadRenderer, onCloseFixture: router.unselectFixture, setNavWidth: setNavWidth, setPanelWidth: setPanelWidth, welcomeDismissed: welcomeDismiss.isWelcomeDismissed(), onDismissWelcome: welcomeDismiss.onDismissWelcome, onShowWelcome: welcomeDismiss.onShowWelcome }));
});

@@ -55,0 +56,0 @@ export { register };

export const NAV_OPEN_STORAGE_KEY = 'navOpen';
const NAV_OPEN_DEFAULT = true;
const NAV_OPEN_DEFAULT = window.innerWidth >= 640;
export function isNavOpen(context) {

@@ -4,0 +4,0 @@ const storage = context.getMethodsOf('storage');

export const PANEL_OPEN_STORAGE_KEY = 'sidePanelOpen';
const PANEL_OPEN_DEFAULT = true;
const PANEL_OPEN_DEFAULT = window.innerWidth >= 960;
export function isPanelOpen(context) {
const { getMethodsOf } = context;
const rendererCore = getMethodsOf('rendererCore');
if (!rendererCore.isValidFixtureSelected()) {
return false;
}
const storage = context.getMethodsOf('storage');

@@ -10,0 +5,0 @@ const open = storage.getItem(PANEL_OPEN_STORAGE_KEY);

@@ -12,3 +12,3 @@ import React from 'react';

onTogglePanel: () => unknown;
onFixtureSelect: (fixtureId: FixtureId) => unknown;
onReloadRenderer: () => unknown;
onClose: () => unknown;

@@ -15,0 +15,0 @@ };

@@ -9,6 +9,5 @@ import { isEqual } from 'lodash-es';

import { grey176, grey32, white10 } from '../../style/colors.js';
export const RendererHeader = React.memo(function RendererHeader({ fixtureItems, fixtureId, navOpen, panelOpen, fixtureActionOrder, rendererActionOrder, onOpenNav, onTogglePanel, onFixtureSelect, onClose, }) {
export const RendererHeader = React.memo(function RendererHeader({ fixtureItems, fixtureId, navOpen, panelOpen, fixtureActionOrder, rendererActionOrder, onOpenNav, onTogglePanel, onReloadRenderer, onClose, }) {
const fixtureItem = findFixtureItemById(fixtureItems, fixtureId);
const slotProps = React.useMemo(() => ({ fixtureId }), [fixtureId]);
const onReload = React.useCallback(() => onFixtureSelect(fixtureId), [fixtureId, onFixtureSelect]);
return (React.createElement(Container, null,

@@ -20,4 +19,4 @@ React.createElement(Left, null,

React.createElement(IconButton32, { icon: React.createElement(XCircleIcon, null), title: "Close fixture", onClick: onClose }),
React.createElement(IconButton32, { icon: React.createElement(RotateCcwIcon, null), title: "Reload fixture", onClick: onReload }),
React.createElement(FixtureActionSlot, { slotProps: slotProps, plugOrder: fixtureActionOrder })),
React.createElement(IconButton32, { icon: React.createElement(RotateCcwIcon, null), title: "Reload fixture", onClick: onReloadRenderer }),
fixtureItem && (React.createElement(FixtureActionSlotContainer, { fixtureActionOrder: fixtureActionOrder, fixtureItem: fixtureItem }))),
fixtureItem && React.createElement(FixtureName, null, getFixtureName(fixtureItem)),

@@ -28,4 +27,13 @@ React.createElement(Right, null,

});
function FixtureActionSlotContainer({ fixtureActionOrder, fixtureItem, }) {
const slotProps = React.useMemo(() => ({ fixtureItem }), [fixtureItem]);
return (React.createElement(FixtureActionSlot, { slotProps: slotProps, plugOrder: fixtureActionOrder }));
}
function findFixtureItemById(fixtureItems, fixtureId) {
return fixtureItems.find(fixtureItem => isEqual(fixtureItem.fixtureId, fixtureId));
if (fixtureId.name) {
return fixtureItems.find(fixtureItem => isEqual(fixtureItem.fixtureId, fixtureId));
}
// When a multi fixture is selected by path only, the first of its named
// fixtures will be selected.
return fixtureItems.find(fixtureItem => fixtureItem.fixtureId.path === fixtureId.path);
}

@@ -32,0 +40,0 @@ function getFixtureName({ name, fileName }) {

@@ -1,9 +0,10 @@

import { FixtureId, FixtureState, FlatFixtureTreeItem, StateUpdater } from 'react-cosmos-core';
import React from 'react';
import { FixtureId, FlatFixtureTreeItem } from 'react-cosmos-core';
import { GetFixtureState, SetFixtureStateByName } from '../RendererCore/spec.js';
type Props = {
storageCacheReady: boolean;
fixtureItems: FlatFixtureTreeItem[];
selectedFixtureId: FixtureId | null;
rendererConnected: boolean;
validFixtureSelected: boolean;
fixtureState: FixtureState;
getFixtureState: GetFixtureState;
setFixtureState: SetFixtureStateByName;
navOpen: boolean;

@@ -21,9 +22,11 @@ panelOpen: boolean;

onTogglePanel: () => unknown;
onFixtureSelect: (fixtureId: FixtureId) => unknown;
onFixtureClose: () => unknown;
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
onReloadRenderer: () => unknown;
onCloseFixture: () => unknown;
setNavWidth: (width: number) => unknown;
setPanelWidth: (width: number) => unknown;
welcomeDismissed: boolean;
onDismissWelcome: () => unknown;
onShowWelcome: () => unknown;
};
export declare function Root({ storageCacheReady, fixtureItems, selectedFixtureId, rendererConnected, validFixtureSelected, fixtureState, navOpen, panelOpen, navWidth, panelWidth, sidePanelRowOrder, globalActionOrder, globalOrder, navRowOrder, fixtureActionOrder, rendererActionOrder, onToggleNav, onTogglePanel, onFixtureSelect, onFixtureClose, onFixtureStateChange, setNavWidth, setPanelWidth, }: Props): JSX.Element;
export declare function Root({ fixtureItems, selectedFixtureId, rendererConnected, getFixtureState, setFixtureState, navOpen, panelOpen, navWidth, panelWidth, sidePanelRowOrder, globalActionOrder, globalOrder, navRowOrder, fixtureActionOrder, rendererActionOrder, onToggleNav, onTogglePanel, onReloadRenderer, onCloseFixture, setNavWidth, setPanelWidth, welcomeDismissed, onDismissWelcome, onShowWelcome, }: Props): React.JSX.Element;
export {};

@@ -8,5 +8,6 @@ import React from 'react';

import { GlobalHeader } from './GlobalHeader.js';
import { HomeOverlay } from './HomeOverlay/HomeOverlay.js';
import { RendererHeader } from './RendererHeader.js';
import { SidePanel } from './SidePanel.js';
export function Root({ storageCacheReady, fixtureItems, selectedFixtureId, rendererConnected, validFixtureSelected, fixtureState, navOpen, panelOpen, navWidth, panelWidth, sidePanelRowOrder, globalActionOrder, globalOrder, navRowOrder, fixtureActionOrder, rendererActionOrder, onToggleNav, onTogglePanel, onFixtureSelect, onFixtureClose, onFixtureStateChange, setNavWidth, setPanelWidth, }) {
export function Root({ fixtureItems, selectedFixtureId, rendererConnected, getFixtureState, setFixtureState, navOpen, panelOpen, navWidth, panelWidth, sidePanelRowOrder, globalActionOrder, globalOrder, navRowOrder, fixtureActionOrder, rendererActionOrder, onToggleNav, onTogglePanel, onReloadRenderer, onCloseFixture, setNavWidth, setPanelWidth, welcomeDismissed, onDismissWelcome, onShowWelcome, }) {
const navDrag = useDrag({

@@ -21,6 +22,3 @@ value: navWidth,

});
if (!storageCacheReady) {
return React.createElement(Container, null);
}
const showNav = rendererConnected && (navOpen || !validFixtureSelected);
const showNav = navOpen || !selectedFixtureId;
const dragging = navDrag.dragging || panelDrag.dragging;

@@ -30,17 +28,18 @@ // z-indexes are set here on purpose to show the layer hierarchy at a glance

showNav && (React.createElement(Draggable, { style: { width: navWidth, zIndex: 2 } },
React.createElement(Nav, null, rendererConnected && (React.createElement(NavRowSlot, { slotProps: { onCloseNav: onToggleNav }, plugOrder: navRowOrder }))),
React.createElement(Nav, null,
React.createElement(NavRowSlot, { slotProps: { onCloseNav: onToggleNav }, plugOrder: navRowOrder })),
navDrag.dragging && React.createElement(DragOverlay, null),
React.createElement(NavDragHandle, { ref: navDrag.dragElRef }))),
React.createElement(MainContainer, { key: "main", style: { zIndex: 1 } },
!validFixtureSelected && (React.createElement(GlobalHeader, { selectedFixtureId: selectedFixtureId, rendererConnected: rendererConnected, validFixtureSelected: validFixtureSelected, globalActionOrder: globalActionOrder })),
!selectedFixtureId && (React.createElement(GlobalHeader, { rendererConnected: rendererConnected, globalActionOrder: globalActionOrder })),
React.createElement(RendererContainer, { key: "rendererContainer" },
selectedFixtureId && validFixtureSelected && (React.createElement(RendererHeader, { fixtureItems: fixtureItems, fixtureId: selectedFixtureId, navOpen: navOpen, panelOpen: panelOpen, fixtureActionOrder: fixtureActionOrder, rendererActionOrder: rendererActionOrder, onOpenNav: onToggleNav, onTogglePanel: onTogglePanel, onFixtureSelect: onFixtureSelect, onClose: onFixtureClose })),
selectedFixtureId && (React.createElement(RendererHeader, { fixtureItems: fixtureItems, fixtureId: selectedFixtureId, navOpen: navOpen, panelOpen: panelOpen, fixtureActionOrder: fixtureActionOrder, rendererActionOrder: rendererActionOrder, onOpenNav: onToggleNav, onTogglePanel: onTogglePanel, onReloadRenderer: onReloadRenderer, onClose: onCloseFixture })),
React.createElement(RendererBody, { key: "rendererBody" },
React.createElement(Slot, { name: "rendererPreview" }),
dragging && React.createElement(DragOverlay, null),
panelOpen && selectedFixtureId && (React.createElement(ControlPanelContainer, { style: { width: panelWidth, zIndex: 3 } },
React.createElement(SidePanel, { fixtureId: selectedFixtureId, fixtureState: fixtureState, sidePanelRowOrder: sidePanelRowOrder, onFixtureStateChange: onFixtureStateChange }),
selectedFixtureId && panelOpen && (React.createElement(ControlPanelContainer, { style: { width: panelWidth, zIndex: 3 } },
React.createElement(SidePanel, { fixtureId: selectedFixtureId, getFixtureState: getFixtureState, setFixtureState: setFixtureState, sidePanelRowOrder: sidePanelRowOrder }),
panelDrag.dragging && React.createElement(DragOverlay, null),
React.createElement(PanelDragHandle, { ref: panelDrag.dragElRef })))),
React.createElement(Slot, { name: "contentOverlay" }))),
!selectedFixtureId && (React.createElement(HomeOverlay, { welcomeDismissed: welcomeDismissed, onDismissWelcome: onDismissWelcome, onShowWelcome: onShowWelcome })))),
React.createElement("div", { style: { zIndex: 4 } },

@@ -47,0 +46,0 @@ React.createElement(ArraySlot, { name: "global", plugOrder: globalOrder }))));

import React from 'react';
import { FixtureId, FixtureState, StateUpdater } from 'react-cosmos-core';
import { FixtureId } from 'react-cosmos-core';
import { GetFixtureState, SetFixtureStateByName } from '../RendererCore/spec.js';
type Props = {
fixtureId: FixtureId;
fixtureState: FixtureState;
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
getFixtureState: GetFixtureState;
setFixtureState: SetFixtureStateByName;
sidePanelRowOrder: string[];

@@ -8,0 +9,0 @@ };

@@ -5,4 +5,4 @@ import React from 'react';

import { grey32 } from '../../style/colors.js';
export const SidePanel = React.memo(function SidePanel({ fixtureId, fixtureState, onFixtureStateChange, sidePanelRowOrder, }) {
const slotProps = React.useMemo(() => ({ fixtureId, fixtureState, onFixtureStateChange }), [fixtureId, fixtureState, onFixtureStateChange]);
export const SidePanel = React.memo(function SidePanel({ fixtureId, getFixtureState, setFixtureState, sidePanelRowOrder, }) {
const slotProps = React.useMemo(() => ({ fixtureId, getFixtureState, setFixtureState }), [fixtureId, getFixtureState, setFixtureState]);
return (React.createElement(Container, null,

@@ -9,0 +9,0 @@ React.createElement(Content, null,

@@ -0,1 +1,2 @@

import React from 'react';
type Props = {

@@ -6,3 +7,3 @@ disabled?: boolean;

};
export declare function ToggleNavButton({ disabled, selected, onToggle }: Props): JSX.Element;
export declare function ToggleNavButton({ disabled, selected, onToggle }: Props): React.JSX.Element;
export {};

@@ -6,2 +6,5 @@ import { isEqual } from 'lodash-es';

name: 'router',
defaultConfig: {
initialFixtureId: null,
},
initialState: {

@@ -17,4 +20,8 @@ urlParams: {},

onLoad(context => {
const { setState } = context;
const { getConfig, setState } = context;
setState({ urlParams: getUrlParams() });
const { initialFixtureId } = getConfig();
if (initialFixtureId) {
selectFixture(context, initialFixtureId);
}
return subscribeToLocationChanges((urlParams) => {

@@ -25,3 +32,3 @@ const { fixtureId } = context.getState().urlParams;

if (fixtureChanged) {
emitFixtureChangeEvent(context);
emitFixtureChangeEvent(context, true);
}

@@ -47,14 +54,26 @@ });

const urlParamsEqual = isEqual(nextUrlParams, urlParams);
context.setState({ urlParams: nextUrlParams }, () => {
// Setting identical url params is considered a "reset" request
if (fixtureChanged || urlParamsEqual) {
emitFixtureChangeEvent(context);
}
if (!urlParamsEqual) {
if (urlParamsEqual) {
// Setting identical URL params can be considered a "reset" request, but
// this will only re-render the fixture if the renderer implements an
// auto-incrementing render key in its state
emitFixtureChangeEvent(context, false);
}
else {
context.setState({ urlParams: nextUrlParams }, () => {
pushUrlParams(context.getState().urlParams);
}
});
emitFixtureChangeEvent(context, fixtureChanged);
});
}
}
function emitFixtureChangeEvent(context) {
context.emit('fixtureChange', getSelectedFixtureId(context));
function emitFixtureChangeEvent(context, fixtureChanged) {
const fixtureId = getSelectedFixtureId(context);
if (!fixtureId) {
context.emit('fixtureUnselect');
}
else if (fixtureChanged) {
context.emit('fixtureSelect', fixtureId);
}
else {
context.emit('fixtureReselect', fixtureId);
}
}

@@ -1,6 +0,9 @@

import { FixtureId, PlaygroundUrlParams } from 'react-cosmos-core';
import { FixtureId, PlaygroundParams } from 'react-cosmos-core';
export type RouterSpec = {
name: 'router';
config: {
initialFixtureId: null | FixtureId;
};
state: {
urlParams: PlaygroundUrlParams;
urlParams: PlaygroundParams;
};

@@ -13,4 +16,6 @@ methods: {

events: {
fixtureChange(fixtureId: null | FixtureId): void;
fixtureSelect(fixtureId: FixtureId): void;
fixtureReselect(fixtureId: FixtureId): void;
fixtureUnselect(): void;
};
};

@@ -16,8 +16,5 @@ import React, { useCallback, useMemo } from 'react';

...fixtureState,
controls: {
...fixtureState.controls,
[controlName]: {
...control,
currentValue: updatedValues[controlName],
},
[controlName]: {
...control,
currentValue: updatedValues[controlName],
},

@@ -24,0 +21,0 @@ }));

@@ -5,4 +5,4 @@ import { PluginContext } from 'react-plugin';

export declare function useTreeExpansionStorage(pluginContext: PluginContext<StandardControlSpec>): {
expansion: TreeExpansion;
expansion: {};
setExpansion: (newTreeExpansion: TreeExpansion) => void;
};
import { FixtureId, FixtureTreeNode } from 'react-cosmos-core';
export declare function recordContainsFixtureId(fixtureIds: Record<string, FixtureId>, fixtureId: FixtureId): boolean;
export declare function nodeContainsFixtureId({ data, children }: FixtureTreeNode, fixtureId: FixtureId): boolean;
export declare function fixtureTreeNodeContainsFixtureId({ data, children }: FixtureTreeNode, fixtureId: FixtureId): boolean;

@@ -1,12 +0,7 @@

import { isEqual } from 'lodash-es';
export function recordContainsFixtureId(fixtureIds, fixtureId) {
return Object.keys(fixtureIds).some(fixtureName => isEqual(fixtureIds[fixtureName], fixtureId));
}
export function nodeContainsFixtureId({ data, children }, fixtureId) {
if (data.type === 'fixture')
return isEqual(data.fixtureId, fixtureId);
if (data.type === 'multiFixture')
return recordContainsFixtureId(data.fixtureIds, fixtureId);
export function fixtureTreeNodeContainsFixtureId({ data, children }, fixtureId) {
if (data.type === 'fixture' || data.type === 'multiFixture') {
return data.path === fixtureId.path;
}
return (children !== undefined &&
Object.keys(children).some(childName => nodeContainsFixtureId(children[childName], fixtureId)));
Object.keys(children).some(childName => fixtureTreeNodeContainsFixtureId(children[childName], fixtureId)));
}

@@ -1,5 +0,6 @@

import { PlaygroundUrlParams } from 'react-cosmos-core';
export declare function getUrlParams(): PlaygroundUrlParams;
export declare function pushUrlParams(urlParams: PlaygroundUrlParams): void;
export declare function subscribeToLocationChanges(userHandler: (urlParams: PlaygroundUrlParams) => unknown): () => void;
export declare function createRelativePlaygroundUrl(urlParams: PlaygroundUrlParams): string;
import { PlaygroundParams } from 'react-cosmos-core';
export declare function getUrlParams(): PlaygroundParams;
export declare function pushUrlParams(urlParams: PlaygroundParams): void;
export declare function subscribeToLocationChanges(userHandler: (urlParams: PlaygroundParams) => unknown): () => void;
export declare function createRelativePlaygroundUrl(urlParams: PlaygroundParams): string;
export declare function createRelativeUrlWithQuery(query: string): string;

@@ -1,7 +0,7 @@

import { parsePlaygroundUrlQuery, stringifyPlaygroundUrlQuery, } from 'react-cosmos-core';
import { buildPlaygroundQueryString, parsePlaygroundQueryString, } from 'react-cosmos-core';
export function getUrlParams() {
return parsePlaygroundUrlQuery(location.search);
return parsePlaygroundQueryString(location.search);
}
export function pushUrlParams(urlParams) {
const query = stringifyPlaygroundUrlQuery(urlParams);
const query = buildPlaygroundQueryString(urlParams);
// Refresh page completely when pushState isn't supported

@@ -25,10 +25,10 @@ if (!history.pushState) {

export function createRelativePlaygroundUrl(urlParams) {
const query = stringifyPlaygroundUrlQuery(urlParams);
const query = buildPlaygroundQueryString(urlParams);
return createRelativeUrlWithQuery(query);
}
function createRelativeUrlWithQuery(query) {
export function createRelativeUrlWithQuery(query) {
// NOTE: "./" is used to return to the home URL. Passing an empty string
// doesn't do anything. And passing "/" doesn't work if Cosmos is not hosted
// at root (sub)domain level.
return query.length > 0 ? `?${query}` : './';
return query || './';
}

@@ -1,4 +0,5 @@

import { FixtureStateControls } from 'react-cosmos-core';
import React from 'react';
import { ControlsFixtureState } from 'react-cosmos-core';
export type ControlActionSlotProps = {
controls: FixtureStateControls;
controls: ControlsFixtureState;
};

@@ -9,3 +10,3 @@ type Props = {

};
export declare function ControlActionSlot({ slotProps, plugOrder }: Props): JSX.Element;
export declare function ControlActionSlot({ slotProps, plugOrder }: Props): React.JSX.Element;
export {};

@@ -1,6 +0,7 @@

import { FixtureState, FixtureStateControl, StateUpdater } from 'react-cosmos-core';
export type ControlSlotProps<TControl extends FixtureStateControl> = {
import React from 'react';
import { ControlFixtureState, ControlsFixtureState, FixtureStateUpdater } from 'react-cosmos-core';
export type ControlSlotProps<TControl extends ControlFixtureState> = {
controlName: string;
control: TControl;
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
onFixtureStateChange: (updater: FixtureStateUpdater<ControlsFixtureState>) => void;
};

@@ -10,3 +11,3 @@ type Props = {

};
export declare function ControlSlot({ slotProps }: Props): JSX.Element;
export declare function ControlSlot({ slotProps }: Props): React.JSX.Element;
export {};

@@ -1,4 +0,5 @@

import { FixtureId } from 'react-cosmos-core';
import React from 'react';
import { FlatFixtureTreeItem } from 'react-cosmos-core';
export type FixtureActionSlotProps = {
fixtureId: FixtureId;
fixtureItem: FlatFixtureTreeItem;
};

@@ -9,3 +10,3 @@ type Props = {

};
export declare function FixtureActionSlot({ slotProps, plugOrder }: Props): JSX.Element;
export declare function FixtureActionSlot({ slotProps, plugOrder }: Props): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
export type NavRowSlotProps = {

@@ -8,3 +9,3 @@ onCloseNav: () => unknown;

};
export declare function NavRowSlot({ slotProps, plugOrder }: Props): JSX.Element;
export declare function NavRowSlot({ slotProps, plugOrder }: Props): React.JSX.Element;
export {};

@@ -0,1 +1,2 @@

import React from 'react';
import { FixtureId } from 'react-cosmos-core';

@@ -9,3 +10,3 @@ export type RendererActionSlotProps = {

};
export declare function RendererActionSlot({ slotProps, plugOrder }: Props): JSX.Element;
export declare function RendererActionSlot({ slotProps, plugOrder }: Props): React.JSX.Element;
export {};

@@ -1,6 +0,8 @@

import { FixtureId, FixtureState, StateUpdater } from 'react-cosmos-core';
import React from 'react';
import { FixtureId } from 'react-cosmos-core';
import { GetFixtureState, SetFixtureStateByName } from '../plugins/RendererCore/spec.js';
export type SidePanelRowSlotProps = {
fixtureId: FixtureId;
fixtureState: FixtureState;
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
getFixtureState: GetFixtureState;
setFixtureState: SetFixtureStateByName;
};

@@ -11,3 +13,3 @@ type Props = {

};
export declare function SidePanelRowSlot({ slotProps, plugOrder }: Props): JSX.Element;
export declare function SidePanelRowSlot({ slotProps, plugOrder }: Props): React.JSX.Element;
export {};

@@ -1,2 +0,2 @@

import { ReactNode } from 'react';
import React, { ReactNode } from 'react';
import { FixtureStatePrimitiveValue, FixtureStateUnserializableValue, PrimitiveData } from 'react-cosmos-core';

@@ -15,3 +15,3 @@ type LeafValue = FixtureStatePrimitiveValue | FixtureStateUnserializableValue;

};
export declare function ValueInputSlot({ children, slotProps }: Props): JSX.Element;
export declare function ValueInputSlot({ children, slotProps }: Props): React.JSX.Element;
export {};

@@ -33,14 +33,16 @@ /// <reference types="jest" />

isDevServerOn(): boolean;
getWebRendererUrl(): string | null;
};
export declare function getRendererCoreMethods(): {
getRendererUrl(): string | null;
getConnectedRendererIds(): string[];
getPrimaryRendererId(): string | null;
getFixtures(): import("react-cosmos-core").FixtureList;
getFixtureState(): import("react-cosmos-core").FixtureState;
isRendererConnected(): boolean;
isValidFixtureSelected(): boolean;
setFixtureState(stateUpdater: import("react-cosmos-core").StateUpdater<import("react-cosmos-core").FixtureState>): void;
reloadRenderer(): void;
selectPrimaryRenderer(primaryRendererId: string): void;
receiveResponse(msg: import("react-cosmos-core").MessageType): void;
getAllFixtureState(): import("react-cosmos-core").FixtureState;
getFixtureState: import("../plugins/RendererCore/spec.js").GetFixtureState;
setFixtureState: import("../plugins/RendererCore/spec.js").SetFixtureStateByName;
setGlobalFixtureState<T>(name: string, state: T): void;
};

@@ -53,3 +55,2 @@ export declare function getNotificationsMethods(): {

export declare function getRendererPreviewMethods(): {
getUrlStatus(): import("../plugins/RendererPreview/spec.js").UrlStatus;
getRuntimeStatus(): import("../plugins/RendererPreview/spec.js").RuntimeStatus;

@@ -76,3 +77,2 @@ };

isDevServerOn: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<CoreSpec>) => boolean);
getWebRendererUrl: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<CoreSpec>) => string | null);
};

@@ -83,15 +83,18 @@ export declare function mockMessageHandler(methods?: MethodsOf<MessageHandlerSpec>): {

export declare function mockRendererCore(methods?: MethodsOf<RendererCoreSpec>): {
getRendererUrl: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => string | null);
getConnectedRendererIds: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => string[]);
getPrimaryRendererId: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => string | null);
getFixtures: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => import("react-cosmos-core").FixtureList);
getFixtureState: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => import("react-cosmos-core").FixtureState);
isRendererConnected: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => boolean);
isValidFixtureSelected: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => boolean);
setFixtureState: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>, stateUpdater: import("react-cosmos-core").StateUpdater<import("react-cosmos-core").FixtureState>) => void);
reloadRenderer: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => void);
selectPrimaryRenderer: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>, primaryRendererId: string) => void);
receiveResponse: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>, msg: import("react-cosmos-core").MessageType) => void);
getAllFixtureState: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => import("react-cosmos-core").FixtureState);
getFixtureState: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>, name: string) => unknown);
setFixtureState: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>, name: string, change: unknown) => void);
setGlobalFixtureState: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>, name: string, state: unknown) => void);
};
export declare function mockRendererPreview(methods?: MethodsOf<RendererPreviewSpec>): {
getUrlStatus: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererPreviewSpec>) => import("../plugins/RendererPreview/spec.js").UrlStatus);
getRuntimeStatus: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererPreviewSpec>) => import("../plugins/RendererPreview/spec.js").RuntimeStatus);
getUrlStatus: jest.Mock<any, any, any>;
};

@@ -110,3 +113,5 @@ export declare function mockNotifications(methods?: MethodsOf<NotificationsSpec>): {

export declare function onRouter(events?: EventsOf<RouterSpec>): {
fixtureChange: jest.Mock<any, any, any> | import("ui-plugin/dist/types/PluginContextHandlers.js").PluginEventHandler<any, [fixtureId: import("react-cosmos-core").FixtureId | null]>;
fixtureSelect: jest.Mock<any, any, any> | import("ui-plugin/dist/types/PluginContextHandlers.js").PluginEventHandler<any, [fixtureId: import("react-cosmos-core").FixtureId]>;
fixtureReselect: jest.Mock<any, any, any> | import("ui-plugin/dist/types/PluginContextHandlers.js").PluginEventHandler<any, [fixtureId: import("react-cosmos-core").FixtureId]>;
fixtureUnselect: jest.Mock<any, any, any> | import("ui-plugin/dist/types/PluginContextHandlers.js").PluginEventHandler<any, []>;
};

@@ -113,0 +118,0 @@ export declare function onMessageHandler(events?: EventsOf<MessageHandlerSpec>): {

@@ -57,3 +57,2 @@ import { getPluginContext, } from 'react-plugin';

isDevServerOn: jest.fn(),
getWebRendererUrl: jest.fn(),
...methods,

@@ -74,11 +73,14 @@ };

const allMethods = {
getRendererUrl: jest.fn(),
getConnectedRendererIds: jest.fn(),
getPrimaryRendererId: jest.fn(),
getFixtures: jest.fn(),
getFixtureState: jest.fn(),
isRendererConnected: jest.fn(),
isValidFixtureSelected: jest.fn(),
setFixtureState: jest.fn(),
reloadRenderer: jest.fn(),
selectPrimaryRenderer: jest.fn(),
receiveResponse: jest.fn(),
getAllFixtureState: jest.fn(),
getFixtureState: jest.fn(),
setFixtureState: jest.fn(),
setGlobalFixtureState: jest.fn(),
...methods,

@@ -118,3 +120,5 @@ };

const allEvents = {
fixtureChange: jest.fn(),
fixtureSelect: jest.fn(),
fixtureReselect: jest.fn(),
fixtureUnselect: jest.fn(),
...events,

@@ -121,0 +125,0 @@ };

{
"name": "react-cosmos-ui",
"version": "6.0.0-canary.0f73dbd.0+0f73dbd",
"version": "6.0.0-canary.10c9ae9.0+10c9ae9",
"description": "React Cosmos UI",

@@ -17,12 +17,12 @@ "repository": "https://github.com/react-cosmos/react-cosmos/tree/main/packages/react-cosmos-ui",

"dependencies": {
"lodash-es": "^4.17.21",
"react-cosmos-core": "^6.0.0-canary.0f73dbd.0+0f73dbd"
"lodash-es": "4.17.21",
"react-cosmos-core": "6.0.0-canary.10c9ae9.0+10c9ae9"
},
"devDependencies": {
"fuzzaldrin-plus": "^0.6.0",
"localforage": "^1.10.0",
"react-plugin": "^3.0.0-alpha.4",
"styled-components": "^5.3.8"
"fuzzaldrin-plus": "0.6.0",
"localforage": "1.10.0",
"react-plugin": "3.0.0-alpha.4",
"styled-components": "5.3.11"
},
"gitHead": "0f73dbdeff46d2ddf4d85da71fdb41ea4df7322e"
"gitHead": "10c9ae9ecc9886484f3a495f713fedef4cbfd8f6"
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc