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.5c6e532.0 to 6.0.0-canary.5d4f82c.0

dist/plugins/RendererCore/onRouterFixtureReselect.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 {};

@@ -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';

@@ -9,0 +8,0 @@ export * from './plugins/ControlSelect/spec.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';

@@ -9,0 +8,0 @@ export * from './plugins/ControlSelect/spec.js';

@@ -31,7 +31,18 @@ import React from 'react';

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 @@ };

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

import React from 'react';
import { FixtureState, FixtureStateClassState, StateUpdater } from 'react-cosmos-core';

@@ -9,3 +10,3 @@ import { FixtureExpansion, OnElementExpansionChange } from '../../../components/ValueInputTree/index.js';

};
export declare function ComponentClassState({ fsClassState, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }: Props): JSX.Element;
export declare function ComponentClassState({ fsClassState, 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 { 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';

@@ -10,0 +10,0 @@ export function ComponentClassState({ fsClassState, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }) {

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

import React from 'react';
import { FixtureState, StateUpdater } from 'react-cosmos-core';

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

};
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';

@@ -7,0 +7,0 @@ import { ControlSlot } from '../../slots/ControlSlot.js';

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

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

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

};
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")))))));

@@ -182,0 +182,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 `

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

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);
const hasProps = fixtureState.props && fixtureState.props.some(hasFsValues);
if (hasProps)

@@ -48,0 +45,0 @@ return false;

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

import React from 'react';
import { FixtureState, FixtureStateProps, StateUpdater } from 'react-cosmos-core';

@@ -9,3 +10,3 @@ import { FixtureExpansion, OnElementExpansionChange } from '../../../components/ValueInputTree/index.js';

};
export declare function ComponentProps({ fsProps, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }: Props): JSX.Element;
export declare function ComponentProps({ fsProps, fixtureExpansion, onFixtureStateChange, onElementExpansionChange, }: Props): React.JSX.Element;
export {};

@@ -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();
}
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({
const { on, register, onLoad } = createPlugin({
name: 'rendererCore',
defaultConfig: {
fixtures: {},
rendererUrl: null,
},
initialState: {

@@ -15,2 +21,3 @@ connectedRendererIds: [],

methods: {
getRendererUrl,
getConnectedRendererIds,

@@ -21,3 +28,3 @@ getPrimaryRendererId,

isRendererConnected,
isValidFixtureSelected,
reloadRenderer,
setFixtureState,

@@ -28,6 +35,17 @@ selectPrimaryRenderer,

});
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 }) {

@@ -34,0 +52,0 @@ return getState().connectedRendererIds;

@@ -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;

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

import { isEqual } from 'lodash-es';
import { postSelectFixtureRequest } from '../shared/postRequest.js';
import { getSelectedFixtureId } from '../shared/router.js';
export function receiveRendererReadyResponse(context, { payload }) {
const { rendererId, fixtures, initialFixtureId } = payload;
const { rendererId } = payload;
const { connectedRendererIds: prevRendererIds } = 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,19 @@ return {

primaryRendererId,
fixtures,
fixtureState: isPrimaryRenderer ? {} : fixtureState,
fixtureState: rendererId === primaryRendererId ? {} : 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);
}
// 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 +35,0 @@ const notifications = getMethodsOf('notifications');

import { FixtureId, FixtureState, RendererId } from 'react-cosmos-core';
import { RendererCoreContext } from '../shared/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, {

import { FixtureList, FixtureState, MessageType, RendererId, StateUpdater } from 'react-cosmos-core';
export type RendererCoreSpec = {
name: 'rendererCore';
config: {
fixtures: FixtureList;
rendererUrl: null | string;
};
state: {

@@ -11,2 +15,3 @@ connectedRendererIds: RendererId[];

methods: {
getRendererUrl(): null | string;
getConnectedRendererIds(): RendererId[];

@@ -17,3 +22,3 @@ getPrimaryRendererId(): null | RendererId;

isRendererConnected(): boolean;
isValidFixtureSelected(): boolean;
reloadRenderer(): void;
setFixtureState(stateUpdater: StateUpdater<FixtureState>): void;

@@ -20,0 +25,0 @@ selectPrimaryRenderer(primaryRendererId: RendererId): void;

@@ -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;

@@ -29,0 +28,0 @@ return (React.createElement(ToggleButton, { selected: enabled, onToggle: () => {

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

import { Dispatch, ReactNode, SetStateAction } from 'react';
import React, { Dispatch, ReactNode, SetStateAction } from 'react';
import { ResponsiveDevice, ResponsiveViewport } from '../spec.js';

@@ -9,7 +9,6 @@ type Props = {

scaled: boolean;
validFixtureSelected: boolean;
setViewport: Dispatch<SetStateAction<ResponsiveViewport>>;
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 },

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 },
};

@@ -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(), 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, onReloadRenderer: rendererCore.reloadRenderer, onCloseFixture: router.unselectFixture, onFixtureStateChange: rendererCore.setFixtureState, 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 }) {

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

import React from 'react';
import { FixtureId, FixtureState, FlatFixtureTreeItem, StateUpdater } from 'react-cosmos-core';
type Props = {
storageCacheReady: boolean;
fixtureItems: FlatFixtureTreeItem[];
selectedFixtureId: FixtureId | null;
rendererConnected: boolean;
validFixtureSelected: boolean;
fixtureState: FixtureState;

@@ -21,9 +20,12 @@ navOpen: boolean;

onTogglePanel: () => unknown;
onFixtureSelect: (fixtureId: FixtureId) => unknown;
onFixtureClose: () => unknown;
onReloadRenderer: () => unknown;
onCloseFixture: () => unknown;
onFixtureStateChange: (stateUpdater: StateUpdater<FixtureState>) => void;
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, fixtureState, navOpen, panelOpen, navWidth, panelWidth, sidePanelRowOrder, globalActionOrder, globalOrder, navRowOrder, fixtureActionOrder, rendererActionOrder, onToggleNav, onTogglePanel, onReloadRenderer, onCloseFixture, onFixtureStateChange, 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, fixtureState, navOpen, panelOpen, navWidth, panelWidth, sidePanelRowOrder, globalActionOrder, globalOrder, navRowOrder, fixtureActionOrder, rendererActionOrder, onToggleNav, onTogglePanel, onReloadRenderer, onCloseFixture, onFixtureStateChange, 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 } },
selectedFixtureId && panelOpen && (React.createElement(ControlPanelContainer, { style: { width: panelWidth, zIndex: 3 } },
React.createElement(SidePanel, { fixtureId: selectedFixtureId, fixtureState: fixtureState, sidePanelRowOrder: sidePanelRowOrder, onFixtureStateChange: onFixtureStateChange }),
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 }))));

@@ -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;
};
};

@@ -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 || './';
}

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

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

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

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

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

import React from 'react';
import { FixtureState, FixtureStateControl, StateUpdater } from 'react-cosmos-core';

@@ -10,3 +11,3 @@ export type ControlSlotProps<TControl extends FixtureStateControl> = {

};
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 {};

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

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

@@ -11,3 +12,3 @@ export type SidePanelRowSlotProps = {

};
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,5 +33,5 @@ /// <reference types="jest" />

isDevServerOn(): boolean;
getWebRendererUrl(): string | null;
};
export declare function getRendererCoreMethods(): {
getRendererUrl(): string | null;
getConnectedRendererIds(): string[];

@@ -42,3 +42,3 @@ getPrimaryRendererId(): string | null;

isRendererConnected(): boolean;
isValidFixtureSelected(): boolean;
reloadRenderer(): void;
setFixtureState(stateUpdater: import("react-cosmos-core").StateUpdater<import("react-cosmos-core").FixtureState>): void;

@@ -54,3 +54,2 @@ selectPrimaryRenderer(primaryRendererId: string): void;

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

@@ -77,3 +76,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);
};

@@ -84,2 +82,3 @@ 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[]);

@@ -90,3 +89,3 @@ getPrimaryRendererId: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => string | null);

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);
reloadRenderer: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>) => void);
setFixtureState: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>, stateUpdater: import("react-cosmos-core").StateUpdater<import("react-cosmos-core").FixtureState>) => void);

@@ -97,4 +96,4 @@ selectPrimaryRenderer: jest.Mock<any, any, any> | ((context: import("react-plugin").PluginContext<RendererCoreSpec>, primaryRendererId: string) => 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>;
};

@@ -113,3 +112,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, []>;
};

@@ -116,0 +117,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,2 +73,3 @@ };

const allMethods = {
getRendererUrl: jest.fn(),
getConnectedRendererIds: jest.fn(),

@@ -80,3 +80,3 @@ getPrimaryRendererId: jest.fn(),

isRendererConnected: jest.fn(),
isValidFixtureSelected: jest.fn(),
reloadRenderer: jest.fn(),
setFixtureState: jest.fn(),

@@ -119,3 +119,5 @@ selectPrimaryRenderer: jest.fn(),

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

@@ -122,0 +124,0 @@ };

{
"name": "react-cosmos-ui",
"version": "6.0.0-canary.5c6e532.0+5c6e532",
"version": "6.0.0-canary.5d4f82c.0+5d4f82c",
"description": "React Cosmos UI",

@@ -13,5 +13,8 @@ "repository": "https://github.com/react-cosmos/react-cosmos/tree/main/packages/react-cosmos-ui",

],
"scripts": {
"playground": "cosmos"
},
"dependencies": {
"lodash-es": "^4.17.21",
"react-cosmos-core": "^6.0.0-canary.5c6e532.0+5c6e532"
"react-cosmos-core": "6.0.0-canary.5d4f82c.0+5d4f82c"
},

@@ -22,5 +25,5 @@ "devDependencies": {

"react-plugin": "^3.0.0-alpha.4",
"styled-components": "^5.3.6"
"styled-components": "^5.3.10"
},
"gitHead": "5c6e532cb3b5daa901b02e09a7bf66ec06719da0"
"gitHead": "5d4f82ce3770c2f4ee092cced83f6759e9905309"
}

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