convert to emotion

Summary:
My benchmarks have shown react-emotion to be faster than the current implementation of `styled`. For this reason, I am converting all styling to [emotion](https://emotion.sh).

Benchmark results:
{F136839093}

The syntax is very similar between the two libraries. The main difference is that emotion only allows a single function for the whole style attribute, whereas the old implementation had functions for every style-attirbute.

Before:
```
{
  color: props => props.color,
  fontSize: props => props.size,
}
```

After:
```
props => ({
  color: props.color,
  fontSize: props.size,
})
```

Reviewed By: jknoxville

Differential Revision: D9479893

fbshipit-source-id: 2c39e4618f7e52ceacb67bbec8ae26114025723f
This commit is contained in:
Daniel Büchele
2018-08-23 09:32:12 -07:00
committed by Facebook Github Bot
parent 4151c73409
commit 726966fdc0
88 changed files with 886 additions and 4068 deletions

View File

@@ -7,6 +7,6 @@
import styled from '../styled/index.js';
export default styled.view({
export default styled('div')({
display: 'block',
});

View File

@@ -6,8 +6,9 @@
*/
import FlexBox from './FlexBox.js';
import styled from '../styled/index.js';
export default FlexBox.extends({
export default styled(FlexBox)({
height: '100%',
overflow: 'auto',
position: 'relative',

View File

@@ -7,12 +7,12 @@
import Glyph from './Glyph.js';
import styled from '../styled/index.js';
import type {StyledComponent} from '../styled/index.js';
import {findDOMNode} from 'react-dom';
import PropTypes from 'prop-types';
import {colors} from './colors.js';
import {connect} from 'react-redux';
import electron from 'electron';
import {keyframes} from 'react-emotion';
const borderColor = props => {
if (!props.windowIsFocused) {
@@ -35,129 +35,122 @@ const borderBottomColor = props => {
}
};
const StyledButton = styled.view(
{
backgroundColor: props => {
if (!props.windowIsFocused) {
return colors.macOSTitleBarButtonBackgroundBlur;
} else {
return colors.white;
}
},
backgroundImage: props => {
if (props.windowIsFocused) {
if (props.depressed) {
return `linear-gradient(to bottom, ${
colors.macOSTitleBarBorderBlur
} 1px, ${colors.macOSTitleBarButtonBorderBlur} 0%, ${
colors.macOSTitleBarButtonBackgroundActive
} 100%)`;
} else {
return `linear-gradient(to bottom, transparent 0%,${
colors.macOSTitleBarButtonBackground
} 100%)`;
}
} else {
return 'none';
}
},
const backgroundImage = props => {
if (props.windowIsFocused) {
if (props.depressed) {
return `linear-gradient(to bottom, ${
colors.macOSTitleBarBorderBlur
} 1px, ${colors.macOSTitleBarButtonBorderBlur} 0%, ${
colors.macOSTitleBarButtonBackgroundActive
} 100%)`;
} else {
return `linear-gradient(to bottom, transparent 0%,${
colors.macOSTitleBarButtonBackground
} 100%)`;
}
} else {
return 'none';
}
};
const color = props => {
if (props.type === 'danger' && props.windowIsFocused) {
return colors.red;
} else if (props.disabled) {
return colors.macOSTitleBarIconBlur;
} else {
return colors.light50;
}
};
const pulse = keyframes({
'0%': {
boxShadow: `0 0 4px 0 ${colors.macOSTitleBarIconSelected}`,
},
'70%': {
boxShadow: '0 0 4px 6px transparent',
},
'100%': {
boxShadow: '0 0 4px 0 transparent',
},
});
const StyledButton = styled('div')(props => ({
backgroundColor: !props.windowIsFocused
? colors.macOSTitleBarButtonBackgroundBlur
: colors.white,
backgroundImage: backgroundImage(props),
borderStyle: 'solid',
borderWidth: 1,
borderColor: borderColor(props),
borderBottomColor: borderBottomColor(props),
fontSize: props.compact === true ? 11 : '1em',
color: color(props),
borderRadius: 4,
position: 'relative',
padding: '0 6px',
height: props.compact === true ? 24 : 28,
margin: 0,
marginLeft: props.inButtonGroup === true ? 0 : 10,
minWidth: 34,
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
boxShadow:
props.pulse && props.windowIsFocused
? `0 0 0 ${colors.macOSTitleBarIconSelected}`
: '',
animation: props.pulse && props.windowIsFocused ? `${pulse} 1s infinite` : '',
'&:not(:first-child)': {
borderTopLeftRadius: props.inButtonGroup === true ? 0 : 4,
borderBottomLeftRadius: props.inButtonGroup === true ? 0 : 4,
},
'&:not(:last-child)': {
borderTopRightRadius: props.inButtonGroup === true ? 0 : 4,
borderBottomRightRadius: props.inButtonGroup === true ? 0 : 4,
borderRight: props.inButtonGroup === true ? 0 : '',
},
'&:first-of-type': {
marginLeft: 0,
},
'&:active': {
borderColor: colors.macOSTitleBarButtonBorder,
borderBottomColor: colors.macOSTitleBarButtonBorderBottom,
background: `linear-gradient(to bottom, ${
colors.macOSTitleBarButtonBackgroundActiveHighlight
} 1px, ${colors.macOSTitleBarButtonBackgroundActive} 0%, ${
colors.macOSTitleBarButtonBorderBlur
} 100%)`,
},
'&:disabled': {
borderColor: borderColor(props),
borderBottomColor: borderBottomColor(props),
pointerEvents: 'none',
},
'&:hover::before': {
content: props.dropdown ? "''" : '',
position: 'absolute',
bottom: 1,
right: 2,
borderStyle: 'solid',
borderWidth: 1,
borderColor,
borderBottomColor,
fontSize: props => (props.compact === true ? 11 : '1em'),
color: props => {
if (props.type === 'danger' && props.windowIsFocused) {
return colors.red;
} else if (props.disabled) {
return colors.macOSTitleBarIconBlur;
} else {
return colors.light50;
}
},
borderRadius: 4,
position: 'relative',
padding: '0 6px',
height: props => (props.compact === true ? 24 : 28),
margin: 0,
marginLeft: props => (props.inButtonGroup === true ? 0 : 10),
minWidth: 34,
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
boxShadow: props =>
props.pulse && props.windowIsFocused
? `0 0 0 ${colors.macOSTitleBarIconSelected}`
: '',
animation: props =>
props.pulse && props.windowIsFocused ? 'pulse 1s infinite' : '',
'&:not(:first-child)': {
borderTopLeftRadius: props => (props.inButtonGroup === true ? 0 : 4),
borderBottomLeftRadius: props => (props.inButtonGroup === true ? 0 : 4),
},
'&:not(:last-child)': {
borderTopRightRadius: props => (props.inButtonGroup === true ? 0 : 4),
borderBottomRightRadius: props => (props.inButtonGroup === true ? 0 : 4),
borderRight: props => (props.inButtonGroup === true ? 0 : ''),
},
'&:first-of-type': {
marginLeft: 0,
},
'&:active': {
borderColor: colors.macOSTitleBarButtonBorder,
borderBottomColor: colors.macOSTitleBarButtonBorderBottom,
background: `linear-gradient(to bottom, ${
colors.macOSTitleBarButtonBackgroundActiveHighlight
} 1px, ${colors.macOSTitleBarButtonBackgroundActive} 0%, ${
colors.macOSTitleBarButtonBorderBlur
} 100%)`,
},
'&:disabled': {
borderColor,
borderBottomColor,
pointerEvents: 'none',
},
'&:hover::before': {
content: props => (props.dropdown ? "''" : ''),
position: 'absolute',
bottom: 1,
right: 2,
borderStyle: 'solid',
borderWidth: '4px 3px 0 3px',
borderColor: props =>
`${colors.macOSTitleBarIcon} transparent transparent transparent`,
},
borderWidth: '4px 3px 0 3px',
borderColor: `${
colors.macOSTitleBarIcon
} transparent transparent transparent`,
},
{
ignoreAttributes: [
'dropdown',
'dispatch',
'compact',
'large',
'windowIsFocused',
'inButtonGroup',
'danger',
'pulse',
],
},
);
}));
const Icon = Glyph.extends(
{
marginRight: props => (props.hasText ? 3 : 0),
},
{
ignoreAttributes: ['hasText', 'type'],
},
);
const Icon = styled(Glyph)(({hasText}) => ({
marginRight: hasText ? 3 : 0,
}));
type Props = {
/**
@@ -252,7 +245,7 @@ type State = {
* @example Disabled button
* <Button disabled={true}>Click me</Button>
*/
class Button extends styled.StylableComponent<
class Button extends React.Component<
Props & {windowIsFocused: boolean},
State,
> {
@@ -350,25 +343,6 @@ class Button extends styled.StylableComponent<
inButtonGroup={this.context.inButtonGroup}>
{iconComponent}
{children}
{this.props.pulse === true && (
<style
dangerouslySetInnerHTML={{
__html: `
@keyframes pulse {
0% {
box-shadow: 0 0 4px 0 ${colors.macOSTitleBarIconSelected};
}
70% {
box-shadow: 0 0 4px 6px transparent;
}
100% {
box-shadow: 0 0 4px 0 transparent;
}
}
`,
}}
/>
)}
</StyledButton>
);
}

View File

@@ -10,7 +10,7 @@ import {Component} from 'react';
const PropTypes = require('prop-types');
const ButtonGroupContainer = styled.view({
const ButtonGroupContainer = styled('div')({
display: 'inline-flex',
marginLeft: 10,
'&:first-child': {

View File

@@ -13,7 +13,7 @@ type CheckboxProps = {
onChange: (checked: boolean) => void,
};
const CheckboxContainer = styled.textInput({
const CheckboxContainer = styled('input')({
display: 'inline-block',
marginRight: 5,
verticalAlign: 'middle',

View File

@@ -1,12 +0,0 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import styled from '../styled/index.js';
export default styled.view({
marginBottom: 10,
});

View File

@@ -1,33 +0,0 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
import styled from '../styled/index.js';
import {colors} from './colors.js';
export default styled.view(
{
backgroundColor: ({active, windowFocused}) => {
if (active && windowFocused) {
return colors.macOSTitleBarIconSelected;
} else if (active && !windowFocused) {
return colors.macOSTitleBarBorderBlur;
} else {
return 'none';
}
},
color: ({active, windowFocused}) =>
active && windowFocused ? colors.white : colors.macOSSidebarSectionItem,
lineHeight: '25px',
padding: '0 10px',
'&[disabled]': {
color: 'rgba(0, 0, 0, 0.5)',
},
},
{
ignoreAttributes: ['active', 'windowFocused'],
},
);

View File

@@ -7,6 +7,6 @@
import styled from '../styled/index.js';
export default styled.view({
export default styled('div')({
fontFamily: 'monospace',
});

View File

@@ -6,7 +6,6 @@
*/
import FlexColumn from './FlexColumn.js';
import styled from '../styled/index.js';
import PropTypes from 'prop-types';
type MenuTemplate = Array<Electron$MenuItemOptions>;
@@ -18,7 +17,7 @@ type Props = {
component: React.ComponentType<any> | string,
};
export default class ContextMenu extends styled.StylablePureComponent<Props> {
export default class ContextMenu extends React.Component<Props> {
static defaultProps = {
component: FlexColumn,
};

View File

@@ -13,7 +13,7 @@ const PropTypes = require('prop-types');
type MenuTemplate = Array<Electron$MenuItemOptions>;
const Container = styled.view({
const Container = styled('div')({
display: 'contents',
});

View File

@@ -6,9 +6,10 @@
*/
import styled from '../styled/index.js';
import React from 'react';
import CodeBlock from './CodeBlock.js';
const ErrorBlockContainer = CodeBlock.extends({
const ErrorBlockContainer = styled(CodeBlock)({
backgroundColor: '#f2dede',
border: '1px solid #ebccd1',
borderRadius: 4,
@@ -17,7 +18,7 @@ const ErrorBlockContainer = CodeBlock.extends({
padding: 10,
});
export default class ErrorBlock extends styled.StylableComponent<{
export default class ErrorBlock extends React.Component<{
error: Error | string | void,
className?: string,
}> {

View File

@@ -11,13 +11,14 @@ import Heading from './Heading.js';
import Button from './Button.js';
import View from './View.js';
import LogManager from '../../fb-stubs/Logger.js';
import styled from '../styled/index.js';
const ErrorBoundaryContainer = View.extends({
const ErrorBoundaryContainer = styled(View)({
overflow: 'auto',
padding: 10,
});
const ErrorBoundaryStack = ErrorBlock.extends({
const ErrorBoundaryStack = styled(ErrorBlock)({
marginBottom: 10,
whiteSpace: 'pre',
});

View File

@@ -6,13 +6,9 @@
*/
import View from './View.js';
import styled from '../styled/index.js';
export default View.extends(
{
display: 'flex',
flexShrink: props => (props.shrink == null || props.shrink ? 1 : 0),
},
{
ignoreAttributes: ['shrink'],
},
);
export default styled(View)(({shrink}) => ({
display: 'flex',
flexShrink: shrink == null || shrink ? 1 : 0,
}));

View File

@@ -6,8 +6,9 @@
*/
import View from './View.js';
import styled from '../styled/index.js';
export default View.extends({
export default styled(View)({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',

View File

@@ -6,7 +6,8 @@
*/
import FlexBox from './FlexBox.js';
import styled from '../styled/index.js';
export default FlexBox.extends({
export default styled(FlexBox)({
flexDirection: 'column',
});

View File

@@ -6,7 +6,8 @@
*/
import FlexBox from './FlexBox.js';
import styled from '../styled/index.js';
export default FlexBox.extends({
export default styled(FlexBox)({
flexDirection: 'row',
});

View File

@@ -8,21 +8,17 @@
import {Component} from 'react';
import Box from './Box.js';
import {colors} from './colors';
import styled from '../styled/index.js';
const FocusableBoxBorder = Box.extends(
{
border: `1px solid ${colors.highlight}`,
bottom: '0',
left: '0',
pointerEvents: 'none',
position: 'absolute',
right: '0',
top: '0',
},
{
ignoreAttributes: [],
},
);
const FocusableBoxBorder = styled(Box)({
border: `1px solid ${colors.highlight}`,
bottom: '0',
left: '0',
pointerEvents: 'none',
position: 'absolute',
right: '0',
top: '0',
});
export default class FocusableBox extends Component<
Object,

View File

@@ -5,39 +5,28 @@
* @format
*/
import React from 'react';
import styled from '../styled/index.js';
const PropTypes = require('prop-types');
import {getIconUrl} from '../../utils/icons.js';
const ColoredIconBlack = styled.image(
{
height: props => props.size,
verticalAlign: 'middle',
width: props => props.size,
},
{
ignoreAttributes: ['size'],
},
);
const ColoredIconBlack = styled('img')(({size}) => ({
height: size,
verticalAlign: 'middle',
width: size,
}));
const ColoredIconCustom = styled.view(
{
height: props => props.size,
verticalAlign: 'middle',
width: props => props.size,
backgroundColor: props => props.color,
display: 'inline-block',
maskImage: props => `url('${props.src}')`,
maskSize: '100% 100%',
// $FlowFixMe: prefixed property
WebkitMaskImage: props => `url('${props.src}')`,
// $FlowFixMe: prefixed property
WebkitMaskSize: '100% 100%',
},
{
ignoreAttributes: ['color', 'size', 'src'],
},
);
const ColoredIconCustom = styled('div')(props => ({
height: props.size,
verticalAlign: 'middle',
width: props.size,
backgroundColor: props.color,
display: 'inline-block',
maskImage: `url('${props.src}')`,
maskSize: '100% 100%',
WebkitMaskImage: `url('${props.src}')`,
WebkitMaskSize: '100% 100%',
}));
export function ColoredIcon(
props: {|
@@ -84,7 +73,7 @@ ColoredIcon.contextTypes = {
glyphColor: PropTypes.string,
};
export default class Glyph extends styled.StylablePureComponent<{
export default class Glyph extends React.Component<{
name: string,
size?: 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32,
variant?: 'filled' | 'outline',

View File

@@ -7,7 +7,7 @@
import styled from '../styled/index.js';
const LargeHeading = styled.view({
const LargeHeading = styled('div')({
fontSize: 18,
fontWeight: 'bold',
lineHeight: '20px',
@@ -15,7 +15,7 @@ const LargeHeading = styled.view({
marginBottom: 10,
});
const SmallHeading = styled.view({
const SmallHeading = styled('div')({
fontSize: 12,
color: '#90949c',
fontWeight: 'bold',

View File

@@ -7,7 +7,7 @@
import styled from '../styled/index.js';
export default styled.view({
export default styled('div')({
backgroundColor: '#c9ced4',
height: 1,
margin: '5px 0',

View File

@@ -8,13 +8,13 @@
import styled from '../styled/index.js';
import {colors} from './colors.js';
export const inputStyle = {
export const inputStyle = (compact: boolean) => ({
border: `1px solid ${colors.light15}`,
borderRadius: 4,
font: 'inherit',
fontSize: '1em',
height: (props: Object) => (props.compact ? '17px' : '28px'),
lineHeight: (props: Object) => (props.compact ? '17px' : '28px'),
height: compact ? '17px' : '28px',
lineHeight: compact ? '17px' : '28px',
marginRight: 5,
'&:disabled': {
@@ -22,17 +22,12 @@ export const inputStyle = {
borderColor: '#ccc',
cursor: 'not-allowed',
},
};
});
const Input = styled.textInput(
{
...inputStyle,
padding: props => (props.compact ? '0 5px' : '0 10px'),
},
{
ignoreAttributes: ['compact'],
},
);
const Input = styled('input')(({compact}) => ({
...inputStyle(compact),
padding: compact ? '0 5px' : '0 10px',
}));
Input.defaultProps = {
type: 'text',

View File

@@ -86,11 +86,11 @@ type InteractiveState = {|
resizingInitialCursor: ?CursorState,
|};
const InteractiveContainer = styled.view({
const InteractiveContainer = styled('div')({
willChange: 'transform, height, width, z-index',
});
export default class Interactive extends styled.StylableComponent<
export default class Interactive extends React.Component<
InteractiveProps,
InteractiveState,
> {

View File

@@ -7,7 +7,7 @@
import styled from '../styled/index.js';
export default styled.view({
export default styled('div')({
fontSize: 12,
fontWeight: 'bold',
});

View File

@@ -10,18 +10,13 @@ import {colors} from './colors.js';
import {Component} from 'react';
import {shell} from 'electron';
const StyledLink = styled.text(
{
color: colors.highlight,
'&:hover': {
cursor: 'pointer',
textDecoration: 'underline',
},
const StyledLink = styled('span')({
color: colors.highlight,
'&:hover': {
cursor: 'pointer',
textDecoration: 'underline',
},
{
ignoreAttributes: [],
},
);
});
export default class Link extends Component<{
href: string,

View File

@@ -5,10 +5,10 @@
* @format
*/
import type {StyledComponent} from '../styled/index.js';
import styled from '../styled/index.js';
import {keyframes} from 'react-emotion';
const animation = styled.keyframes({
const animation = keyframes({
'0%': {
transform: 'rotate(0deg)',
},
@@ -17,23 +17,16 @@ const animation = styled.keyframes({
},
});
const LoadingIndicator: StyledComponent<{
size?: number,
}> = styled.view(
{
animation: `${animation} 1s infinite linear`,
width: props => props.size,
height: props => props.size,
minWidth: props => props.size,
minHeight: props => props.size,
borderRadius: '50%',
border: props => `${props.size / 6}px solid rgba(0, 0, 0, 0.2)`,
borderLeftColor: 'rgba(0, 0, 0, 0.4)',
},
{
ignoreAttributes: ['size'],
},
);
const LoadingIndicator = styled('div')(props => ({
animation: `${animation} 1s infinite linear`,
width: props.size,
height: props.size,
minWidth: props.size,
minHeight: props.size,
borderRadius: '50%',
border: `${props.size / 6}px solid rgba(0, 0, 0, 0.2)`,
borderLeftColor: 'rgba(0, 0, 0, 0.4)',
}));
LoadingIndicator.defaultProps = {
size: 50,

View File

@@ -8,7 +8,7 @@
import styled from '../styled/index.js';
import {Component} from 'react';
const Overlay = styled.view({
const Overlay = styled('div')({
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.6)',
bottom: 0,

View File

@@ -37,19 +37,13 @@ type TabSizes = {
[key: string]: Rect,
};
const OrderableContainer = styled.view({
const OrderableContainer = styled('div')({
position: 'relative',
});
const OrderableItemContainer = styled.view(
{
display: props =>
props.orientation === 'vertical' ? 'block' : 'inline-block',
},
{
ignoreAttributes: ['orientation'],
},
);
const OrderableItemContainer = styled('div')(props => ({
display: props.orientation === 'vertical' ? 'block' : 'inline-block',
}));
class OrderableItem extends Component<{
orientation: OrderableOrientation,
@@ -79,7 +73,7 @@ class OrderableItem extends Component<{
}
}
export default class Orderable extends styled.StylableComponent<
export default class Orderable extends React.Component<
OrderableProps,
OrderableState,
> {

View File

@@ -5,18 +5,16 @@
* @format
*/
import FlexColumn from './FlexColumn.js';
import React from 'react';
import styled from '../styled/index.js';
import FlexColumn from './FlexColumn.js';
import FlexBox from './FlexBox.js';
import {colors} from './colors.js';
import Glyph from './Glyph.js';
const BORDER = '1px solid #dddfe2';
const ignoreAttributes = ['floating', 'padded'];
const Chevron = Glyph.extends({
const Chevron = styled(Glyph)({
marginRight: 4,
marginLeft: -2,
marginBottom: 1,
@@ -25,7 +23,7 @@ const Chevron = Glyph.extends({
/**
* A Panel component.
*/
export default class Panel extends styled.StylableComponent<
export default class Panel extends React.Component<
{|
/**
* Class name to customise styling.
@@ -84,46 +82,37 @@ export default class Panel extends styled.StylableComponent<
collapsable: true,
};
static PanelContainer = FlexColumn.extends(
{
flexShrink: 0,
padding: props => (props.floating ? 10 : 0),
borderBottom: props => (props.collapsed ? 'none' : BORDER),
},
{ignoreAttributes: ['collapsed', ...ignoreAttributes]},
);
static PanelContainer = styled(FlexColumn)(props => ({
flexShrink: 0,
padding: props.floating ? 10 : 0,
borderBottom: props.collapsed ? 'none' : BORDER,
}));
static PanelHeader = FlexBox.extends(
{
backgroundColor: '#f6f7f9',
border: props => (props.floating ? BORDER : 'none'),
borderBottom: BORDER,
borderTopLeftRadius: 2,
borderTopRightRadius: 2,
justifyContent: 'space-between',
lineHeight: '27px',
fontWeight: 500,
flexShrink: 0,
padding: props => (props.padded ? '0 10px' : 0),
'&:not(:first-child)': {
borderTop: BORDER,
},
static PanelHeader = styled(FlexBox)(props => ({
backgroundColor: '#f6f7f9',
border: props.floating ? BORDER : 'none',
borderBottom: BORDER,
borderTopLeftRadius: 2,
borderTopRightRadius: 2,
justifyContent: 'space-between',
lineHeight: '27px',
fontWeight: 500,
flexShrink: 0,
padding: props.padded ? '0 10px' : 0,
'&:not(:first-child)': {
borderTop: BORDER,
},
{ignoreAttributes},
);
}));
static PanelBody = FlexColumn.extends(
{
backgroundColor: '#fff',
border: props => (props.floating ? BORDER : 'none'),
borderBottomLeftRadius: 2,
borderBottomRightRadius: 2,
borderTop: 'none',
flexGrow: 1,
padding: props => (props.padded ? 10 : 0),
},
{ignoreAttributes},
);
static PanelBody = styled(FlexColumn)(props => ({
backgroundColor: '#fff',
border: props.floating ? BORDER : 'none',
borderBottomLeftRadius: 2,
borderBottomRightRadius: 2,
borderTop: 'none',
flexGrow: 1,
padding: props.padded ? 10 : 0,
}));
state = {
collapsed: this.props.collapsed == null ? false : this.props.collapsed,
};

View File

@@ -10,7 +10,7 @@ import FlexColumn from './FlexColumn.js';
import styled from '../styled/index.js';
import {colors} from './colors.js';
const Anchor = styled.image({
const Anchor = styled('img')({
zIndex: 6,
position: 'absolute',
bottom: 0,
@@ -18,7 +18,7 @@ const Anchor = styled.image({
transform: 'translate(-50%, calc(100% + 2px))',
});
const PopoverContainer = FlexColumn.extends({
const PopoverContainer = styled(FlexColumn)({
backgroundColor: colors.white,
borderRadius: 7,
border: '1px solid rgba(0,0,0,0.3)',

View File

@@ -8,7 +8,7 @@
import styled from '../styled/index.js';
import {Component} from 'react';
const IFrame = styled.customHTMLTag('iframe', {
const IFrame = styled('iframe')({
height: '100%',
width: '100%',
border: 'none',

View File

@@ -5,43 +5,30 @@
* @format
*/
import type {StyledComponent} from '../styled/index.js';
import Interactive from './Interactive.js';
import FlexColumn from './FlexColumn.js';
import {colors} from './colors';
import {Component} from 'react';
import styled from '../styled/index.js';
const SidebarInteractiveContainer = Interactive.extends({
const SidebarInteractiveContainer = styled(Interactive)({
flex: 'none',
});
type SidebarPosition = 'left' | 'top' | 'right' | 'bottom';
const SidebarContainer: StyledComponent<{
position: SidebarPosition,
overflow?: boolean,
}> = FlexColumn.extends(
{
backgroundColor: props =>
props.backgroundColor || colors.macOSTitleBarBackgroundBlur,
borderLeft: props =>
props.position === 'right' ? '1px solid #b3b3b3' : 'none',
borderTop: props =>
props.position === 'bottom' ? '1px solid #b3b3b3' : 'none',
borderRight: props =>
props.position === 'left' ? '1px solid #b3b3b3' : 'none',
borderBottom: props =>
props.position === 'top' ? '1px solid #b3b3b3' : 'none',
height: '100%',
overflowX: 'hidden',
overflowY: 'auto',
textOverflow: props => (props.overflow ? 'ellipsis' : 'auto'),
whiteSpace: props => (props.overflow ? 'nowrap' : 'normal'),
},
{
ignoreAttributes: ['backgroundColor', 'position'],
},
);
const SidebarContainer = styled(FlexColumn)(props => ({
backgroundColor: props.backgroundColor || colors.macOSTitleBarBackgroundBlur,
borderLeft: props.position === 'right' ? '1px solid #b3b3b3' : 'none',
borderTop: props.position === 'bottom' ? '1px solid #b3b3b3' : 'none',
borderRight: props.position === 'left' ? '1px solid #b3b3b3' : 'none',
borderBottom: props.position === 'top' ? '1px solid #b3b3b3' : 'none',
height: '100%',
overflowX: 'hidden',
overflowY: 'auto',
textOverflow: props.overflow ? 'ellipsis' : 'auto',
whiteSpace: props.overflow ? 'nowrap' : 'normal',
}));
type SidebarProps = {
/**

View File

@@ -7,8 +7,9 @@
import {colors} from './colors.js';
import Label from './Label.js';
import styled from '../styled/index.js';
export default Label.extends({
export default styled(Label)({
color: colors.blackAlpha30,
fontSize: 12,
padding: 10,

View File

@@ -12,45 +12,38 @@ import FlexRow from './FlexRow.js';
import {colors} from './colors.js';
import Tab from './Tab.js';
const TabList = FlexRow.extends({
const TabList = styled(FlexRow)({
alignItems: 'stretch',
});
const TabListItem = styled.view(
{
backgroundColor: props => (props.active ? colors.light15 : colors.light02),
borderBottom: '1px solid #dddfe2',
boxShadow: props =>
props.active ? 'inset 0px 0px 3px rgba(0,0,0,0.25)' : 'none',
color: colors.dark80,
flex: 1,
fontSize: 13,
lineHeight: '28px',
overflow: 'hidden',
padding: '0 10px',
position: 'relative',
textAlign: 'center',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
const TabListItem = styled('div')(props => ({
backgroundColor: props.active ? colors.light15 : colors.light02,
borderBottom: '1px solid #dddfe2',
boxShadow: props.active ? 'inset 0px 0px 3px rgba(0,0,0,0.25)' : 'none',
color: colors.dark80,
flex: 1,
fontSize: 13,
lineHeight: '28px',
overflow: 'hidden',
padding: '0 10px',
position: 'relative',
textAlign: 'center',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
'&:hover': {
backgroundColor: props =>
props.active ? colors.light15 : colors.light05,
},
'&:hover': {
backgroundColor: props.active ? colors.light15 : colors.light05,
},
{
ignoreAttributes: ['active'],
},
);
}));
const TabListAddItem = TabListItem.extends({
const TabListAddItem = styled(TabListItem)({
borderRight: 'none',
flex: 0,
flexGrow: 0,
fontWeight: 'bold',
});
const CloseButton = styled.view({
const CloseButton = styled('div')({
color: '#000',
float: 'right',
fontSize: 10,
@@ -69,11 +62,11 @@ const CloseButton = styled.view({
},
});
const OrderableContainer = styled.view({
const OrderableContainer = styled('div')({
display: 'inline-block',
});
const TabContent = styled.view({
const TabContent = styled('div')({
height: '100%',
overflow: 'auto',
width: '100%',

View File

@@ -5,155 +5,31 @@
* @format
*/
import type {StyledComponent} from '../styled/index.js';
import styled from '../styled/index.js';
/**
* A Text component.
*/
const Text: StyledComponent<{
/**
* Color of text.
*/
color?: string,
/**
* Whether this text is bold. Equivalent to the following CSS:
*
* font-weight: bold;
*/
bold?: boolean,
/**
* Whether this text is italic. Equivalent to the following CSS:
*
* font-style: italic;
*/
italic?: boolean,
/**
* Whether to format the text as code. Equivalent to the following CSS:
*
* font-size: Andale Mono, monospace;
* overflow: auto;
* user-select: text;
* white-space: pre-wrap;
* word-wrap: break-word;
*/
code?: boolean,
/**
* Whether this text is underlined. Equivalent to the following CSS:
*
* text-decoration: underline;
*/
underline?: boolean,
/**
* Whether this text is striked. Equivalent to the following CSS:
*
* text-decoration: line-through;
*/
strike?: boolean,
/**
* Whether this text is selectable by the cursor. Equivalent to the following CSS:
*
* user-select: text;
*/
selectable?: boolean,
/**
* Alignment of the text. Equivalent to the `text-align` CSS rule.
*/
align?: 'left' | 'center' | 'right',
/**
* Font size to use. Equivalent to the `font-size` CSS rule.
*/
size?: string | number,
/**
* Font family to use. Equivalent to the `font-family` CSS rule.
*/
family?: string,
/**
* Word wrap to use. Equivalent to the `word-wrap` CSS rule.
*/
wordWrap?: string,
/**
* White space to use. Equivalent to the `white-space` CSS rule.
*/
whiteSpace?: string,
}> = styled.text(
{
color: props => (props.color ? props.color : 'inherit'),
display: 'inline',
fontWeight: props => (props.bold ? 'bold' : 'inherit'),
fontStyle: props => (props.italic ? 'italic' : 'normal'),
textAlign: props => props.align || 'left',
fontSize: props => {
if (props.size == null && props.code) {
return 12;
} else {
return props.size;
}
},
fontFamily: props => {
if (props.code) {
return 'SF Mono, Monaco, Andale Mono, monospace';
} else {
return props.family;
}
},
overflow: props => {
if (props.code) {
return 'auto';
} else {
return 'visible';
}
},
textDecoration: props => {
if (props.underline) {
return 'underline';
} else if (props.strike) {
return 'line-through';
} else {
return 'none';
}
},
userSelect: props => {
if (
props.selectable ||
(props.code && typeof props.selectable === 'undefined')
) {
return 'text';
} else {
return 'none';
}
},
wordWrap: props => {
if (props.code) {
return 'break-word';
} else {
return props.wordWrap;
}
},
whiteSpace: props => {
if (props.code && typeof props.whiteSpace === 'undefined') {
return 'pre';
} else {
return props.whiteSpace;
}
},
},
{
ignoreAttributes: [
'selectable',
'whiteSpace',
'wordWrap',
'align',
'code',
'family',
'size',
'bold',
'italic',
'strike',
'underline',
'color',
],
},
);
const Text = styled('span')(props => ({
color: props.color ? props.color : 'inherit',
display: 'inline',
fontWeight: props.bold ? 'bold' : 'inherit',
fontStyle: props.italic ? 'italic' : 'normal',
textAlign: props.align || 'left',
fontSize: props.size == null && props.code ? 12 : props.size,
fontFamily: props.code
? 'SF Mono, Monaco, Andale Mono, monospace'
: props.family,
overflow: props.code ? 'auto' : 'visible',
userSelect:
props.selectable || (props.code && typeof props.selectable === 'undefined')
? 'text'
: 'none',
wordWrap: props.code ? 'break-word' : props.wordWrap,
whiteSpace:
props.code && typeof props.whiteSpace === 'undefined'
? 'pre'
: props.whiteSpace,
}));
export default Text;

View File

@@ -10,7 +10,7 @@ import styled from '../styled/index.js';
/**
* A TextParagraph component.
*/
const TextParagraph = styled.view({
const TextParagraph = styled('div')({
marginBottom: 10,
'&:last-child': {

View File

@@ -8,15 +8,9 @@
import styled from '../styled/index.js';
import {inputStyle} from './Input.js';
export default styled.customHTMLTag(
'textarea',
{
...inputStyle,
lineHeight: 'normal',
padding: props => (props.compact ? '5px' : '8px'),
resize: 'none',
},
{
ignoreAttributes: ['compact'],
},
);
export default styled('textarea')(({compact}) => ({
...inputStyle(compact),
lineHeight: 'normal',
padding: compact ? '5px' : '8px',
resize: 'none',
}));

View File

@@ -9,11 +9,11 @@ import React from 'react';
import styled from '../styled/index.js';
import {colors} from './colors.js';
export const StyledButton = styled.view({
export const StyledButton = styled('div')(props => ({
cursor: 'pointer',
width: '30px',
height: '16px',
background: props => (props.toggled ? colors.green : colors.grey),
background: props.toggled ? colors.green : colors.grey,
display: 'block',
borderRadius: '100px',
position: 'relative',
@@ -22,14 +22,14 @@ export const StyledButton = styled.view({
content: `''`,
position: 'absolute',
top: '3px',
left: props => (props.toggled ? '18px' : '3px'),
left: props.toggled ? '18px' : '3px',
width: '10px',
height: '10px',
background: 'white',
borderRadius: '100px',
transition: 'all cubic-bezier(0.3, 1.5, 0.7, 1) 0.3s',
},
});
}));
type Props = {
/**
@@ -52,7 +52,7 @@ type Props = {
* <ToggleButton onClick={handler} toggled={boolean}/>
* ```
*/
export default class ToggleButton extends styled.StylableComponent<Props> {
export default class ToggleButton extends React.Component<Props> {
render() {
return (
<StyledButton toggled={this.props.toggled} onClick={this.props.onClick} />

View File

@@ -5,44 +5,33 @@
* @format
*/
import type {StyledComponent} from '../styled/index.js';
import {colors} from './colors.js';
import FlexRow from './FlexRow.js';
import FlexBox from './FlexBox.js';
import styled from '../styled/index.js';
/**
* A toolbar.
*/
const Toolbar: StyledComponent<{
/**
* Position of the toolbar. Dictates the location of the border.
*/
position?: 'top' | 'bottom',
compact?: boolean,
}> = FlexRow.extends(
{
backgroundColor: colors.light02,
borderBottom: props =>
props.position === 'bottom'
? 'none'
: `1px solid ${colors.sectionHeaderBorder}`,
borderTop: props =>
props.position === 'bottom'
? `1px solid ${colors.sectionHeaderBorder}`
: 'none',
flexShrink: 0,
height: props => (props.compact ? 28 : 42),
lineHeight: '32px',
alignItems: 'center',
padding: 6,
width: '100%',
},
{
ignoreAttributes: ['position'],
},
);
const Toolbar = styled(FlexRow)(props => ({
backgroundColor: colors.light02,
borderBottom:
props.position === 'bottom'
? 'none'
: `1px solid ${colors.sectionHeaderBorder}`,
borderTop:
props.position === 'bottom'
? `1px solid ${colors.sectionHeaderBorder}`
: 'none',
flexShrink: 0,
height: props.compact ? 28 : 42,
lineHeight: '32px',
alignItems: 'center',
padding: 6,
width: '100%',
}));
export const Spacer = FlexBox.extends({
export const Spacer = styled(FlexBox)({
flexGrow: 1,
});

View File

@@ -12,7 +12,7 @@ import {Component} from 'react';
const PropTypes = require('prop-types');
const TooltipContainer = styled.view({
const TooltipContainer = styled('div')({
display: 'contents',
});

View File

@@ -10,25 +10,20 @@ import {Component} from 'react';
const PropTypes = require('prop-types');
const TooltipBubble = styled.view(
{
backgroundColor: '#000',
lineHeight: '25px',
padding: '0 6px',
borderRadius: 4,
position: 'absolute',
width: 'auto',
top: props => props.top,
left: props => props.left,
zIndex: 99999999999,
pointerEvents: 'none',
color: '#fff',
marginTop: '-30px',
},
{
ignoreAttributes: ['top', 'left'],
},
);
const TooltipBubble = styled('div')(props => ({
backgroundColor: '#000',
lineHeight: '25px',
padding: '0 6px',
borderRadius: 4,
position: 'absolute',
width: 'auto',
top: props.top,
left: props.left,
zIndex: 99999999999,
pointerEvents: 'none',
color: '#fff',
marginTop: '-30px',
}));
type TooltipProps = {
children: React$Node,

View File

@@ -7,7 +7,7 @@
import styled from '../styled/index.js';
export default styled.view({
export default styled('div')({
backgroundColor: '#c9ced4',
width: 3,
margin: '0',

View File

@@ -7,16 +7,11 @@
import styled from '../styled/index.js';
const View = styled.view(
{
height: props => (props.fill ? '100%' : 'auto'),
overflow: props => (props.scrollable ? 'auto' : 'visible'),
position: 'relative',
width: props => (props.fill ? '100%' : 'auto'),
},
{
ignoreAttributes: ['fill', 'scrollable'],
},
);
const View = styled('div')(props => ({
height: props.fill ? '100%' : 'auto',
overflow: props.scrollable ? 'auto' : 'visible',
position: 'relative',
width: props.fill ? '100%' : 'auto',
}));
export default View;

View File

@@ -8,33 +8,24 @@
import FlexColumn from './FlexColumn.js';
import {Component} from 'react';
import View from './View.js';
import styled from '../styled/index.js';
const Inner = FlexColumn.extends(
{
alignItems: 'flex-start',
height: props => props.height,
minHeight: '100%',
minWidth: '100%',
overflow: 'visible',
width: '100%',
},
{
ignoreAttributes: ['height'],
},
);
const Inner = styled(FlexColumn)(({height}) => ({
alignItems: 'flex-start',
height,
minHeight: '100%',
minWidth: '100%',
overflow: 'visible',
width: '100%',
}));
const Content = FlexColumn.extends(
{
alignItems: 'flex-start',
height: '100%',
marginTop: props => props.top,
minWidth: '100%',
overflow: 'visible',
},
{
ignoreAttributes: ['top'],
},
);
const Content = styled(FlexColumn)(({top}) => ({
alignItems: 'flex-start',
height: '100%',
marginTop: top,
minWidth: '100%',
overflow: 'visible',
}));
type VirtualListProps = {|
data: Array<any>,

View File

@@ -15,6 +15,7 @@ import {
Input,
View,
} from '../index';
import styled from '../styled/index';
import type {TableBodyRow, TableRows} from 'sonar';
import type {PluginClient} from '../../plugin';
@@ -50,7 +51,7 @@ class ConsoleError extends Component<{
error: Error | string | void,
className?: string,
}> {
static Container = CodeBlock.extends({
static Container = styled(CodeBlock)({
backgroundColor: colors.redTint,
color: colors.red,
overflow: 'auto',
@@ -81,11 +82,11 @@ export class Console extends Component<Props, State> {
},
};
static Window = FlexColumn.extends({
static Window = styled(FlexColumn)({
padding: '15px',
flexGrow: 1,
});
static Input = Input.extends({
static Input = styled(Input)({
width: '100%',
});

View File

@@ -14,55 +14,50 @@ import Popover from '../Popover.js';
import {colors} from '../colors.js';
import Input from '../Input.js';
const NullValue = styled.text({
const NullValue = styled('span')({
color: 'rgb(128, 128, 128)',
});
const UndefinedValue = styled.text({
const UndefinedValue = styled('span')({
color: 'rgb(128, 128, 128)',
});
const StringValue = styled.text({
const StringValue = styled('span')({
color: colors.cherryDark1,
});
const ColorValue = styled.text({
const ColorValue = styled('span')({
color: colors.blueGrey,
});
const SymbolValue = styled.text({
const SymbolValue = styled('span')({
color: 'rgb(196, 26, 22)',
});
const NumberValue = styled.text({
const NumberValue = styled('span')({
color: colors.tealDark1,
});
const ColorBox = styled.text(
{
backgroundColor: props => props.color,
boxShadow: 'inset 0 0 1px rgba(0, 0, 0, 1)',
display: 'inline-block',
height: 12,
marginRight: 5,
verticalAlign: 'middle',
width: 12,
},
{
ignoreAttributes: ['color'],
},
);
const ColorBox = styled('span')(props => ({
backgroundColor: props.color,
boxShadow: 'inset 0 0 1px rgba(0, 0, 0, 1)',
display: 'inline-block',
height: 12,
marginRight: 5,
verticalAlign: 'middle',
width: 12,
}));
const FunctionKeyword = styled.text({
const FunctionKeyword = styled('span')({
color: 'rgb(170, 13, 145)',
fontStyle: 'italic',
});
const FunctionName = styled.text({
const FunctionName = styled('span')({
fontStyle: 'italic',
});
const ColorPickerDescription = styled.view({
const ColorPickerDescription = styled('div')({
display: 'inline',
position: 'relative',
});

View File

@@ -18,34 +18,29 @@ import {clipboard} from 'electron';
const deepEqual = require('deep-equal');
const BaseContainer = styled.view(
{
fontFamily: 'Menlo, monospace',
fontSize: 11,
lineHeight: '17px',
filter: props => (props.disabled ? 'grayscale(100%)' : ''),
margin: props => (props.depth === 0 ? '7.5px 0' : '0'),
paddingLeft: 10,
userSelect: 'text',
},
{
ignoreAttributes: ['depth', 'disabled'],
},
);
const BaseContainer = styled('div')(props => ({
fontFamily: 'Menlo, monospace',
fontSize: 11,
lineHeight: '17px',
filter: props.disabled ? 'grayscale(100%)' : '',
margin: props.depth === 0 ? '7.5px 0' : '0',
paddingLeft: 10,
userSelect: 'text',
}));
const RecursiveBaseWrapper = styled.text({
const RecursiveBaseWrapper = styled('span')({
color: colors.red,
});
const Wrapper = styled.text({
const Wrapper = styled('span')({
color: '#555',
});
const PropertyContainer = styled.text({
const PropertyContainer = styled('span')({
paddingTop: '2px',
});
const ExpandControl = styled.text({
const ExpandControl = styled('span')({
color: '#6e6e6e',
fontSize: 10,
marginLeft: -11,
@@ -53,7 +48,7 @@ const ExpandControl = styled.text({
whiteSpace: 'pre',
});
export const InspectorName = styled.text({
export const InspectorName = styled('span')({
color: colors.grapeDark1,
});
@@ -474,10 +469,10 @@ export default class DataInspector extends Component<DataInspectorProps> {
const keys = getSortedKeys({...value, ...diffValue});
const Added = styled.view({
const Added = styled('div')({
backgroundColor: colors.tealTint70,
});
const Removed = styled.view({
const Removed = styled('div')({
backgroundColor: colors.cherryTint70,
});

View File

@@ -12,7 +12,7 @@ import styled from '../../styled/index.js';
import {getSortedKeys} from './utils.js';
import {PureComponent} from 'react';
const PreviewContainer = styled.text({
const PreviewContainer = styled('span')({
fontStyle: 'italic',
});

View File

@@ -10,7 +10,7 @@ import {colors, darkColors} from './colors.js';
const React = require('react');
const DesktopDropdownContainer = styled.view({
const DesktopDropdownContainer = styled('div')({
borderBottom: `1px solid ${darkColors.dividers}`,
lineHeight: '25px',
marginTop: 5,
@@ -45,22 +45,15 @@ export function DesktopDropdown(props: {|
);
}
const DesktopDropdownItemContainer = styled.view(
{
listStyle: 'none',
opacity: props => (props.onClick || props.onHover ? 1 : 0.5),
padding: '0 20px',
'&:hover': {
backgroundColor: props =>
props.onClick || props.onHover ? colors.highlight : '',
color: props => (props.onClick || props.onHover ? '#fff' : 'inherit'),
},
const DesktopDropdownItemContainer = styled('div')(props => ({
listStyle: 'none',
opacity: props.onClick || props.onHover ? 1 : 0.5,
padding: '0 20px',
'&:hover': {
backgroundColor: props.onClick || props.onHover ? colors.highlight : '',
color: props.onClick || props.onHover ? '#fff' : 'inherit',
},
{
ignoreAttributes: [],
},
);
}));
type DesktopDropdownItemState = {|hovered: boolean|};
@@ -71,7 +64,7 @@ type DesktopDropdownItemProps = {
deactivate?: () => void,
};
export class DesktopDropdownItem extends styled.StylableComponent<
export class DesktopDropdownItem extends React.Component<
DesktopDropdownItemProps,
DesktopDropdownItemState,
> {
@@ -121,7 +114,7 @@ export class DesktopDropdownItem extends styled.StylableComponent<
}
}
export const DesktopDropdownSelectedItem = DesktopDropdownItem.extends({
export const DesktopDropdownSelectedItem = styled(DesktopDropdownItem)({
position: 'relative',
'&::before': {

View File

@@ -25,54 +25,51 @@ import {FixedSizeList as List} from 'react-window';
const ROW_HEIGHT = 23;
const ElementsRowContainer = ContextMenu.extends(
{
flexDirection: 'row',
alignItems: 'center',
backgroundColor: props => {
if (props.selected) {
return colors.macOSTitleBarIconSelected;
} else if (props.focused) {
return colors.lime;
} else if (props.even) {
return colors.light02;
} else {
return '';
}
},
color: props =>
props.selected || props.focused ? colors.white : colors.grapeDark3,
flexShrink: 0,
flexWrap: 'nowrap',
height: ROW_HEIGHT,
minWidth: '100%',
paddingLeft: props => (props.level - 1) * 12,
paddingRight: 20,
position: 'relative',
const backgroundColor = props => {
if (props.selected) {
return colors.macOSTitleBarIconSelected;
} else if (props.focused) {
return colors.lime;
} else if (props.even) {
return colors.light02;
} else {
return '';
}
};
'& *': {
color: props =>
props.selected || props.focused ? `${colors.white} !important` : '',
},
const backgroundColorHover = props => {
if (props.selected) {
return colors.macOSTitleBarIconSelected;
} else if (props.focused) {
return colors.lime;
} else {
return '#EBF1FB';
}
};
'&:hover': {
backgroundColor: props => {
if (props.selected) {
return colors.macOSTitleBarIconSelected;
} else if (props.focused) {
return colors.lime;
} else {
return '#EBF1FB';
}
},
},
const ElementsRowContainer = styled(ContextMenu)(props => ({
flexDirection: 'row',
alignItems: 'center',
backgroundColor: backgroundColor(props),
color: props.selected || props.focused ? colors.white : colors.grapeDark3,
flexShrink: 0,
flexWrap: 'nowrap',
height: ROW_HEIGHT,
minWidth: '100%',
paddingLeft: (props.level - 1) * 12,
paddingRight: 20,
position: 'relative',
'& *': {
color: props.selected || props.focused ? `${colors.white} !important` : '',
},
{
ignoreAttributes: ['level', 'selected', 'even', 'focused'],
},
);
const ElementsRowDecoration = FlexRow.extends({
'&:hover': {
backgroundColor: backgroundColorHover(props),
},
}));
const ElementsRowDecoration = styled(FlexRow)({
flexShrink: 0,
justifyContent: 'flex-end',
alignItems: 'center',
@@ -82,29 +79,24 @@ const ElementsRowDecoration = FlexRow.extends({
top: -1,
});
const ElementsLine = styled.view(
{
backgroundColor: colors.light20,
height: props => props.childrenCount * ROW_HEIGHT - 4,
position: 'absolute',
right: 3,
top: ROW_HEIGHT - 3,
zIndex: 2,
width: 2,
borderRadius: '999em',
},
{
ignoreAttributes: ['childrenCount'],
},
);
const ElementsLine = styled('div')(props => ({
backgroundColor: colors.light20,
height: props.childrenCount * ROW_HEIGHT - 4,
position: 'absolute',
right: 3,
top: ROW_HEIGHT - 3,
zIndex: 2,
width: 2,
borderRadius: '999em',
}));
const DecorationImage = styled.image({
const DecorationImage = styled('img')({
height: 12,
marginRight: 5,
width: 12,
});
const NoShrinkText = Text.extends({
const NoShrinkText = styled(Text)({
flexShrink: 0,
flexWrap: 'nowrap',
overflow: 'hidden',
@@ -112,17 +104,17 @@ const NoShrinkText = Text.extends({
fontWeight: 400,
});
const ElementsRowAttributeContainer = NoShrinkText.extends({
const ElementsRowAttributeContainer = styled(NoShrinkText)({
color: colors.dark80,
fontWeight: 300,
marginLeft: 5,
});
const ElementsRowAttributeKey = styled.text({
const ElementsRowAttributeKey = styled('span')({
color: colors.tomato,
});
const ElementsRowAttributeValue = styled.text({
const ElementsRowAttributeValue = styled('span')({
color: colors.slateDark3,
});
@@ -131,11 +123,10 @@ class PartialHighlight extends PureComponent<{
highlighted: ?string,
content: string,
}> {
static HighlightedText = styled.text({
static HighlightedText = styled('span')(({selected}) => ({
backgroundColor: '#ffff33',
color: props =>
props.selected ? `${colors.grapeDark3} !important` : 'auto',
});
color: selected ? `${colors.grapeDark3} !important` : 'auto',
}));
render() {
const {highlighted, content, selected} = this.props;
@@ -380,14 +371,14 @@ class ElementsRow extends PureComponent<ElementsRowProps, ElementsRowState> {
}
}
const ElementsContainer = FlexColumn.extends({
const ElementsContainer = styled(FlexColumn)({
backgroundColor: colors.white,
minHeight: '100%',
minWidth: '100%',
overflow: 'auto',
});
const ElementsBox = FlexColumn.extends({
const ElementsBox = styled(FlexColumn)({
alignItems: 'flex-start',
flex: 1,
overflow: 'auto',

View File

@@ -12,36 +12,31 @@ import textContent from '../../../utils/textContent.js';
import styled from '../../styled/index.js';
import {colors} from '../colors.js';
const FilterText = styled.view(
{
display: 'flex',
alignSelf: 'baseline',
userSelect: 'none',
cursor: 'pointer',
position: 'relative',
maxWidth: '100%',
'&:hover': {
color: colors.white,
},
'&:hover::after': {
content: '""',
position: 'absolute',
top: 3,
bottom: -2,
left: -6,
right: -6,
borderRadius: '999em',
backgroundColor: 'rgba(0, 0, 0, 0.3)',
},
'&:hover *': {
color: `${colors.white} !important`,
zIndex: 2,
},
const FilterText = styled('div')({
display: 'flex',
alignSelf: 'baseline',
userSelect: 'none',
cursor: 'pointer',
position: 'relative',
maxWidth: '100%',
'&:hover': {
color: colors.white,
},
{
ignoreAttributes: ['filterKey', 'addFilter'],
'&:hover::after': {
content: '""',
position: 'absolute',
top: 3,
bottom: -2,
left: -6,
right: -6,
borderRadius: '999em',
backgroundColor: 'rgba(0, 0, 0, 0.3)',
},
);
'&:hover *': {
color: `${colors.white} !important`,
zIndex: 2,
},
});
type Props = {
children: React.Node,

View File

@@ -18,7 +18,7 @@ import {
PureComponent,
} from 'sonar';
const Containter = FlexColumn.extends({
const Containter = styled(FlexColumn)({
fontSize: 17,
justifyContent: 'center',
marginLeft: 60,
@@ -30,12 +30,12 @@ const Containter = FlexColumn.extends({
minWidth: 450,
});
const TitleRow = FlexRow.extends({
const TitleRow = styled(FlexRow)({
alignItems: 'center',
marginBottom: 40,
});
const Icon = FlexBox.extends({
const Icon = styled(FlexBox)({
justifyContent: 'center',
alignItems: 'center',
backgroundColor: brandColors.Sonar,
@@ -45,13 +45,13 @@ const Icon = FlexBox.extends({
borderRadius: 6,
});
const Title = Text.extends({
const Title = styled(Text)({
fontSize: 30,
fontWeight: 300,
paddingLeft: 10,
});
const Button = View.extends({
const Button = styled(View)({
marginTop: 40,
marginBottom: 30,
borderRadius: 6,
@@ -64,7 +64,7 @@ const Button = View.extends({
alignSelf: 'flex-start',
});
const Screenshot = styled.customHTMLTag('img', {
const Screenshot = styled('img')({
alignSelf: 'center',
boxShadow: '0 5px 35px rgba(0,0,0,0.3)',
borderRadius: 5,

View File

@@ -13,58 +13,47 @@ import {findDOMNode} from 'react-dom';
import {colors} from '../colors.js';
import electron from 'electron';
const Token = Text.extends(
{
display: 'inline-flex',
alignItems: 'center',
backgroundColor: props =>
props.focused
? colors.macOSHighlightActive
: props.color || colors.macOSHighlight,
borderRadius: 4,
marginRight: 4,
padding: 4,
paddingLeft: 6,
height: 21,
color: props => (props.focused ? 'white' : 'inherit'),
'&:active': {
backgroundColor: colors.macOSHighlightActive,
color: colors.white,
},
'&:first-of-type': {
marginLeft: 3,
},
const Token = styled(Text)(props => ({
display: 'inline-flex',
alignItems: 'center',
backgroundColor: props.focused
? colors.macOSHighlightActive
: props.color || colors.macOSHighlight,
borderRadius: 4,
marginRight: 4,
padding: 4,
paddingLeft: 6,
height: 21,
color: props.focused ? 'white' : 'inherit',
'&:active': {
backgroundColor: colors.macOSHighlightActive,
color: colors.white,
},
{
ignoreAttributes: ['focused', 'color'],
'&:first-of-type': {
marginLeft: 3,
},
);
}));
const Key = Text.extends(
{
position: 'relative',
fontWeight: 500,
paddingRight: 12,
textTransform: 'capitalize',
lineHeight: '21px',
'&:after': {
content: props => (props.type === 'exclude' ? '"≠"' : '"="'),
paddingLeft: 5,
position: 'absolute',
top: -1,
right: 0,
fontSize: 14,
},
'&:active:after': {
backgroundColor: colors.macOSHighlightActive,
},
const Key = styled(Text)(props => ({
position: 'relative',
fontWeight: 500,
paddingRight: 12,
textTransform: 'capitalize',
lineHeight: '21px',
'&:after': {
content: props.type === 'exclude' ? '"≠"' : '"="',
paddingLeft: 5,
position: 'absolute',
top: -1,
right: 0,
fontSize: 14,
},
{
ignoreAttributes: ['type', 'focused'],
'&:active:after': {
backgroundColor: colors.macOSHighlightActive,
},
);
}));
const Value = Text.extends({
const Value = styled(Text)({
whiteSpace: 'nowrap',
maxWidth: 160,
overflow: 'hidden',
@@ -73,29 +62,24 @@ const Value = Text.extends({
paddingLeft: 3,
});
const Chevron = styled.view(
{
const Chevron = styled('div')(props => ({
border: 0,
paddingLeft: 3,
paddingRight: 1,
marginRight: 0,
fontSize: 16,
backgroundColor: 'transparent',
position: 'relative',
top: -2,
height: 'auto',
lineHeight: 'initial',
color: props.focused ? colors.white : 'inherit',
'&:hover, &:active, &:focus': {
color: 'inherit',
border: 0,
paddingLeft: 3,
paddingRight: 1,
marginRight: 0,
fontSize: 16,
backgroundColor: 'transparent',
position: 'relative',
top: -2,
height: 'auto',
lineHeight: 'initial',
color: props => (props.focused ? colors.white : 'inherit'),
'&:hover, &:active, &:focus': {
color: 'inherit',
border: 0,
backgroundColor: 'transparent',
},
},
{
ignoreAttributes: ['focused'],
},
);
}));
type Props = {|
filter: Filter,

View File

@@ -16,15 +16,16 @@ import FlexBox from '../FlexBox.js';
import Glyph from '../Glyph.js';
import FilterToken from './FilterToken.js';
import PropTypes from 'prop-types';
import styled from '../../styled/index.js';
const SEARCHABLE_STORAGE_KEY = (key: string) => `SEARCHABLE_STORAGE_KEY_${key}`;
const SearchBar = Toolbar.extends({
const SearchBar = styled(Toolbar)({
height: 42,
padding: 6,
});
export const SearchBox = FlexBox.extends({
export const SearchBox = styled(FlexBox)({
backgroundColor: colors.white,
borderRadius: '999em',
border: `1px solid ${colors.light15}`,
@@ -34,8 +35,8 @@ export const SearchBox = FlexBox.extends({
paddingLeft: 4,
});
export const SearchInput = Input.extends({
border: props => (props.focus ? '1px solid black' : 0),
export const SearchInput = styled(Input)(props => ({
border: props.focus ? '1px solid black' : 0,
padding: 0,
fontSize: '1em',
flexGrow: 1,
@@ -47,9 +48,9 @@ export const SearchInput = Input.extends({
color: colors.placeholder,
fontWeight: 300,
},
});
}));
const Clear = Text.extends({
const Clear = styled(Text)({
position: 'absolute',
right: 6,
top: '50%',
@@ -68,14 +69,14 @@ const Clear = Text.extends({
},
});
export const SearchIcon = Glyph.extends({
export const SearchIcon = styled(Glyph)({
marginRight: 3,
marginLeft: 3,
marginTop: -1,
minWidth: 16,
});
const Actions = FlexRow.extends({
const Actions = styled(FlexRow)({
marginLeft: 8,
flexShrink: 0,
});

View File

@@ -117,13 +117,11 @@ type ManagedTableState = {|
shouldScrollToBottom: boolean,
|};
/**
* Wrapper around `Table` that handles row state.
*
* If you require lower level access to the state then use [`<Table>`]()
* directly.
*/
class ManagedTable extends styled.StylableComponent<
const Container = styled(FlexColumn)({
flexGrow: 1,
});
class ManagedTable extends React.Component<
ManagedTableProps,
ManagedTableState,
> {
@@ -446,7 +444,7 @@ class ManagedTable extends styled.StylableComponent<
.filter(Boolean);
return (
<FlexColumn style={{flexGrow: 1}}>
<Container>
<TableHead
columnOrder={columnOrder}
onColumnOrder={this.onColumnOrder}
@@ -456,10 +454,7 @@ class ManagedTable extends styled.StylableComponent<
columnSizes={columnSizes}
onSort={this.onSort}
/>
<FlexColumn
style={{
flexGrow: 1,
}}>
<Container>
<AutoSizer>
{({width, height}) => (
<ContextMenu buildItems={this.buildContextMenuItems}>
@@ -500,8 +495,8 @@ class ManagedTable extends styled.StylableComponent<
</ContextMenu>
)}
</AutoSizer>
</FlexColumn>
</FlexColumn>
</Container>
</Container>
);
}
}

View File

@@ -27,11 +27,11 @@ const invariant = require('invariant');
type MenuTemplate = Array<Electron$MenuItemOptions>;
const TableHeaderArrow = styled.text({
const TableHeaderArrow = styled('span')({
float: 'right',
});
const TableHeaderColumnInteractive = Interactive.extends({
const TableHeaderColumnInteractive = styled(Interactive)({
display: 'inline-block',
overflow: 'hidden',
textOverflow: 'ellipsis',
@@ -39,11 +39,11 @@ const TableHeaderColumnInteractive = Interactive.extends({
width: '100%',
});
const TableHeaderColumnContainer = styled.view({
const TableHeaderColumnContainer = styled('div')({
padding: '0 8px',
});
const TableHeadContainer = FlexRow.extends({
const TableHeadContainer = styled(FlexRow)({
borderBottom: `1px solid ${colors.sectionHeaderBorder}`,
color: colors.light50,
flexShrink: 0,
@@ -56,33 +56,28 @@ const TableHeadContainer = FlexRow.extends({
zIndex: 2,
});
const TableHeadColumnContainer = styled.view(
{
position: 'relative',
backgroundColor: colors.white,
flexShrink: props => (props.width === 'flex' ? 1 : 0),
height: 23,
lineHeight: '23px',
fontSize: '0.85em',
fontWeight: 500,
width: props => (props.width === 'flex' ? '100%' : props.width),
'&::after': {
position: 'absolute',
content: '""',
right: 0,
top: 5,
height: 13,
width: 1,
background: colors.light15,
},
'&:last-child::after': {
display: 'none',
},
const TableHeadColumnContainer = styled('div')(props => ({
position: 'relative',
backgroundColor: colors.white,
flexShrink: props.width === 'flex' ? 1 : 0,
height: 23,
lineHeight: '23px',
fontSize: '0.85em',
fontWeight: 500,
width: props.width === 'flex' ? '100%' : props.width,
'&::after': {
position: 'absolute',
content: '""',
right: 0,
top: 5,
height: 13,
width: 1,
background: colors.light15,
},
{
ignoreAttributes: ['width'],
'&:last-child::after': {
display: 'none',
},
);
}));
const RIGHT_RESIZABLE = {right: true};

View File

@@ -20,81 +20,60 @@ import {colors} from '../colors.js';
import {normaliseColumnWidth} from './utils.js';
import {DEFAULT_ROW_HEIGHT} from './types';
const TableBodyRowContainer = FlexRow.extends(
{
backgroundColor: props => {
if (props.highlighted) {
if (props.highlightedBackgroundColor) {
return props.highlightedBackgroundColor;
} else {
return colors.macOSTitleBarIconSelected;
}
} else {
if (props.backgroundColor) {
return props.backgroundColor;
} else if (props.even && props.zebra) {
return colors.light02;
} else {
return 'transparent';
}
}
},
boxShadow: props => (props.zebra ? 'none' : 'inset 0 -1px #E9EBEE'),
color: props =>
props.highlighted ? colors.white : props.color || 'inherit',
'& *': {
color: props => (props.highlighted ? `${colors.white} !important` : null),
},
'& img': {
backgroundColor: props =>
props.highlighted ? `${colors.white} !important` : 'none',
},
height: props => (props.multiline ? 'auto' : props.rowLineHeight),
lineHeight: props =>
`${String(props.rowLineHeight || DEFAULT_ROW_HEIGHT)}px`,
fontWeight: props => props.fontWeight || 'inherit',
overflow: 'hidden',
width: '100%',
userSelect: 'none',
flexShrink: 0,
'&:hover': {
backgroundColor: props =>
!props.highlighted && props.highlightOnHover ? colors.light02 : 'none',
},
},
{
ignoreAttributes: [
'highlightedBackgroundColor',
'highlightOnHover',
'backgroundColor',
'rowLineHeight',
'highlighted',
'multiline',
'hasHover',
'zebra',
'even',
],
},
);
const backgroundColor = props => {
if (props.highlighted) {
if (props.highlightedBackgroundColor) {
return props.highlightedBackgroundColor;
} else {
return colors.macOSTitleBarIconSelected;
}
} else {
if (props.backgroundColor) {
return props.backgroundColor;
} else if (props.even && props.zebra) {
return colors.light02;
} else {
return 'transparent';
}
}
};
const TableBodyColumnContainer = styled.view(
{
display: 'flex',
flexShrink: props => (props.width === 'flex' ? 1 : 0),
overflow: 'hidden',
padding: '0 8px',
userSelect: 'none',
textOverflow: 'ellipsis',
verticalAlign: 'top',
whiteSpace: props => (props.multiline ? 'normal' : 'nowrap'),
wordWrap: props => (props.multiline ? 'break-word' : 'normal'),
width: props => (props.width === 'flex' ? '100%' : props.width),
maxWidth: '100%',
const TableBodyRowContainer = styled(FlexRow)(props => ({
backgroundColor: backgroundColor(props),
boxShadow: props.zebra ? 'none' : 'inset 0 -1px #E9EBEE',
color: props.highlighted ? colors.white : props.color || 'inherit',
'& *': {
color: props.highlighted ? `${colors.white} !important` : null,
},
{
ignoreAttributes: ['multiline', 'width'],
'& img': {
backgroundColor: props.highlighted ? `${colors.white} !important` : 'none',
},
);
height: props.multiline ? 'auto' : props.rowLineHeight,
lineHeight: `${String(props.rowLineHeight || DEFAULT_ROW_HEIGHT)}px`,
fontWeight: props.fontWeight || 'inherit',
overflow: 'hidden',
width: '100%',
userSelect: 'none',
flexShrink: 0,
'&:hover': {
backgroundColor:
!props.highlighted && props.highlightOnHover ? colors.light02 : 'none',
},
}));
const TableBodyColumnContainer = styled('div')(props => ({
display: 'flex',
flexShrink: props.width === 'flex' ? 1 : 0,
overflow: 'hidden',
padding: '0 8px',
userSelect: 'none',
textOverflow: 'ellipsis',
verticalAlign: 'top',
whiteSpace: props.multiline ? 'normal' : 'nowrap',
wordWrap: props.multiline ? 'break-word' : 'normal',
width: props.width === 'flex' ? '100%' : props.width,
maxWidth: '100%',
}));
type Props = {
columnSizes: TableColumnSizes,