Skip to content

Commit

Permalink
Add rotate viewport button (#1257)
Browse files Browse the repository at this point in the history
  • Loading branch information
ovidiuch committed Aug 21, 2020
1 parent 4d3d59c commit c3be60a
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 44 deletions.
@@ -1,10 +1,19 @@
import React from 'react';
import styled from 'styled-components';
import { Button8 } from '../../../shared/buttons';
import { blue, grey128, grey248, grey8 } from '../../../shared/colors';
import { Minimize2Icon } from '../../../shared/icons';
import {
blue,
grey128,
grey144,
grey216,
grey248,
grey8,
} from '../../../shared/colors';
import { Minimize2Icon, RefreshCcwIcon } from '../../../shared/icons';
import { NumberInput } from '../../../shared/inputs/NumberInput';
import { Select } from '../../../shared/inputs/Select';
import { Space } from '../../../shared/Space';
import { quick } from '../../../shared/vars';
import { Device, Viewport } from '../public';

type Props = {
Expand Down Expand Up @@ -41,18 +50,21 @@ export const Header = React.memo(function Header({
const canScale = scaleFactor < 1;
return (
<Container data-testid="responsiveHeader">
<Select
testId="viewportSelect"
options={options}
value={stringifyViewport(selectedViewport)}
color={grey248}
height={32}
padding={8}
onChange={option =>
selectViewport({ width: option.width, height: option.height })
}
/>
<ViewportSize>
<Left>
<Select
testId="viewportSelect"
options={options}
value={stringifyViewport(selectedViewport)}
color={grey248}
height={32}
padding={8}
onChange={option =>
selectViewport({ width: option.width, height: option.height })
}
/>
</Left>
<Space width={4} />
<Center>
<NumberInput
value={selectedViewport.width}
minValue={1}
Expand All @@ -68,26 +80,40 @@ export const Header = React.memo(function Header({
styles={numberInputStypes}
onChange={height => selectViewport({ ...selectedViewport, height })}
/>
</ViewportSize>
{canScale ? (
<Button8
icon={<Minimize2Icon />}
label={getScalePercent(scaleFactor)}
title="Toggle fit to scale"
disabled={false}
selected={scaled}
onClick={toggleScale}
/>
) : (
<Button8
icon={<Minimize2Icon />}
label="100%"
title="Toggle fit to scale"
disabled={true}
selected={false}
onClick={() => {}}
/>
)}
<RotateButton
title="Rotate"
onClick={() =>
selectViewport({
width: selectedViewport.height,
height: selectedViewport.width,
})
}
>
<RefreshCcwIcon size={14} />
</RotateButton>
</Center>
<Space width={4} />
<Right>
{canScale ? (
<Button8
icon={<Minimize2Icon />}
label={getScalePercent(scaleFactor)}
title="Toggle fit to scale"
disabled={false}
selected={scaled}
onClick={toggleScale}
/>
) : (
<Button8
icon={<Minimize2Icon />}
label="100%"
title="Toggle fit to scale"
disabled={true}
selected={false}
onClick={() => {}}
/>
)}
</Right>
</Container>
);
});
Expand All @@ -105,22 +131,58 @@ const Container = styled.div`
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 4px;
background: ${grey8};
white-space: nowrap;
overflow-x: auto;
`;

const ViewportSize = styled.div`
const Left = styled.div`
flex: 1;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
`;

const Right = styled.div`
flex: 1;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
`;

const Center = styled.div`
display: flex;
flex-direction: row;
align-items: center;
margin: 0 2px;
`;

const ViewportX = styled.div`
padding: 0 1px;
line-height: 32px;
color: ${grey128};
`;

export const RotateButton = styled.button`
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
border: 0;
background: transparent;
color: ${grey144};
outline: none;
transition: color ${quick}s;
:hover,
:focus {
color: ${grey216};
}
::-moz-focus-inner {
border: 0;
}
`;
Expand Up @@ -7,7 +7,7 @@ import { IconButton32 } from '../../shared/buttons';
import { grey176, grey32, white10 } from '../../shared/colors';
import {
MenuIcon,
RefreshCwIcon,
RotateCcwIcon,
SlidersIcon,
XCircleIcon,
} from '../../shared/icons';
Expand Down Expand Up @@ -66,7 +66,7 @@ export const RendererHeader = React.memo(function RendererHeader({
onClick={onClose}
/>
<IconButton32
icon={<RefreshCwIcon />}
icon={<RotateCcwIcon />}
title="Reload fixture"
onClick={onReload}
/>
Expand Down
13 changes: 13 additions & 0 deletions packages/react-cosmos-playground2/src/shared/icons/index.tsx
@@ -1,6 +1,11 @@
import React from 'react';
import { Icon } from '../svg';

// Add common interface to each icon when needed
type Props = {
size?: number;
};

export const ChevronLeftIcon = () => (
<Icon>
<polyline points="15 18 9 12 15 6"></polyline>
Expand Down Expand Up @@ -70,6 +75,14 @@ export const RefreshCwIcon = () => (
</Icon>
);

export const RefreshCcwIcon = (props: Props) => (
<Icon {...props}>
<polyline points="1 4 1 10 7 10"></polyline>
<polyline points="23 20 23 14 17 14"></polyline>
<path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"></path>
</Icon>
);

export const HomeIcon = () => (
<Icon>
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
Expand Down
13 changes: 8 additions & 5 deletions packages/react-cosmos-playground2/src/shared/svg.tsx
Expand Up @@ -16,11 +16,16 @@ type SvgElementType = React.ReactElement<

type SvgChildren = SvgElementType | SvgElementType[];

export function Icon({ children }: { children: SvgChildren }) {
type IconProps = {
size?: number | string;
children: SvgChildren;
};

export function Icon({ size = '100%', children }: IconProps) {
return (
<BaseSvg
width="24"
height="24"
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
Expand Down Expand Up @@ -59,6 +64,4 @@ function BaseSvg({

const StyledSvg = styled.svg`
display: block;
width: 100%;
height: 100%;
`;

0 comments on commit c3be60a

Please sign in to comment.