Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
feat: update styling of property pane (#436)
Browse files Browse the repository at this point in the history
* feat(component): update styling of string property
* feat(component): update styling of boolean property
* feat(component): update styling of enum property
  • Loading branch information
tilmx committed May 11, 2018
1 parent d95a9b4 commit b5c1963
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 119 deletions.
22 changes: 18 additions & 4 deletions src/lsg/patterns/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export enum IconName {
ArrowLeft,
ArrowFillRight,
ArrowFillLeft,
Check,
Uncheck,
Robo,
Plus,
Pattern
Expand Down Expand Up @@ -77,6 +79,22 @@ const icons: { readonly [key: string]: JSX.Element[][] | JSX.Element[] } = {
d="M6 15h5v2H6v-2zm0-8h10v1H6V7zm0 3h7v1H6v-1zM4 5v14h16V5H4zm0-1h16a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1z"
/>
]
],
[IconName.Uncheck]: [
[
<path
key="check"
d="M14.77 12l4.16 4.16a1.96 1.96 0 0 1-2.77 2.77L12 14.77l-4.16 4.16a1.96 1.96 0 0 1-2.77-2.77L9.23 12 5.07 7.84a1.96 1.96 0 1 1 2.77-2.77L12 9.23l4.16-4.16a1.96 1.96 0 0 1 2.77 2.77L14.77 12z"
/>
]
],
[IconName.Check]: [
[
<path
key="check"
d="M8.66 15.2l10.6-10.61A2 2 0 1 1 22.1 7.4L10.07 19.44a2 2 0 0 1-2.83 0L1.6 13.78a2 2 0 1 1 2.82-2.83l4.25 4.24z"
/>
]
]
};

Expand All @@ -92,10 +110,6 @@ const StyledIcon = styled.svg`
fill: currentColor;
stroke: none;
stroke-miterlimit: 10;
@media (max-resolution: 124dpi) {
stroke-width: 1.2px;
}
`;

const IconRegistrySymbol: React.StatelessComponent<IconRegistrySymbolProps> = props => (
Expand Down
11 changes: 2 additions & 9 deletions src/lsg/patterns/property-items/asset-item/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { colors } from '../../colors';
import { fonts } from '../../fonts';
import { PropertyLabel } from '../property-label';
import * as React from 'react';
import { getSpace, SpaceSize } from '../../space';
import styled from 'styled-components';
Expand All @@ -25,14 +26,6 @@ const StyledPreview = styled.div`
margin-bottom: ${getSpace(SpaceSize.XS)}px;
`;

const StyledLabel = styled.span`
display: block;
margin-bottom: ${getSpace(SpaceSize.XS)}px;
font-size: 12px;
font-family: ${fonts().NORMAL_FONT};
color: ${colors.grey36.toString()};
`;

const StyledInput = styled.input`
display: inline-block;
box-sizing: border-box;
Expand Down Expand Up @@ -90,7 +83,7 @@ const StyledButton = styled.button`
export const AssetItem: React.StatelessComponent<AssetItemProps> = props => (
<StyledAssetItem className={props.className}>
<label>
<StyledLabel>{props.label}</StyledLabel>
<PropertyLabel label={props.label} />
<StyledPreview>
<StyledImageBox>
<StyledImage src={props.imageSrc} />
Expand Down
110 changes: 67 additions & 43 deletions src/lsg/patterns/property-items/boolean-item/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { colors } from '../../colors';
import { fonts } from '../../fonts';
import { Icon, IconName, IconSize } from '../../icons';
import { PropertyLabel } from '../property-label';
import * as React from 'react';
import { getSpace, SpaceSize } from '../../space';
import styled from 'styled-components';
Expand All @@ -15,62 +16,81 @@ interface IndicatorProps {
checked?: boolean;
}

const StyledBooleanItem = styled.div`
const StyledBooleanItem = styled.label`
display: flex;
align-items: center;
width: 100%;
margin-bottom: ${getSpace(SpaceSize.S)}px;
`;

const StyledLabelWrapper = styled.label`
display: block;
margin-bottom: ${getSpace(SpaceSize.L)}px;
`;
const indicatorWidth = 48;
const indicatorHeight = 30;

const indicatorWidth = 42;
const indicatorHeight = 24;
const indicatorBorderWidth = 1;
const StyledIndicatorKnob = styled.div`
position: absolute;
display: flex;
align-items: center;
justify-content: center;
width: ${indicatorHeight}px;
height: ${indicatorHeight}px;
margin: -1px 0 0 -1px;
transform: translateX(0);
border-radius: 100%;
background: ${colors.white.toString()};
transition: transform 0.1s, border-color 0.1s, box-shadow 0.1s;
box-sizing: border-box;
border: 1px solid ${colors.grey60.toString()};
@media screen and (-webkit-min-device-pixel-ratio: 2) {
border-width: 0.5px;
}
${(props: IndicatorProps) =>
props.checked
? `
transform: translateX(${indicatorWidth - indicatorHeight}px);
background: ${colors.white.toString()};
border-color: ${colors.blue40.toString()};
`
: ''};
`;

const StyledIndicator = styled.span`
position: relative;
display: block;
display: inline-block;
width: ${indicatorWidth}px;
height: ${indicatorHeight}px;
border-radius: ${indicatorHeight / 2}px;
background: ${colors.grey90.toString()};
box-sizing: border-box;
box-shadow: inset 0 0 0 ${indicatorBorderWidth}px ${colors.grey60.toString()};
border: 1px solid ${colors.grey80.toString()};
transition: background 0.1s, box-shadow 0.1s;
user-select: none;
&:after {
content: '';
display: block;
width: ${indicatorHeight}px;
height: ${indicatorHeight}px;
border: ${indicatorBorderWidth}px solid ${colors.grey60.toString()};
transform: translateX(0px);
border-radius: 100%;
background: ${colors.white.toString()};
transition: all ease-in-out 0.25s;
box-sizing: border-box;
&:hover {
${StyledIndicatorKnob} {
border-color: ${colors.grey60.toString()};
box-shadow: 0.5px 0.5px 3px ${colors.grey60.toString()};
${(props: IndicatorProps) =>
props.checked
? `
border-color: ${colors.blue40.toString()};
box-shadow: 0.5px 0.5px 3px ${colors.blue40.toString()};
`
: ''};
}
}
${(props: IndicatorProps) =>
props.checked
? `
background: ${colors.blue40.toString()};
box-shadow: inset 0 0 0 ${indicatorBorderWidth}px ${colors.blue40.toString()};
&:after {
transform: translateX(${indicatorWidth - indicatorHeight}px);
background: ${colors.white.toString()};
border-color: ${colors.blue40.toString()};
}
`
background: ${colors.blue80.toString()};
border-color: ${colors.blue40.toString()};
`
: ''};
`;

const StyledLabel = styled.span`
display: block;
font-size: 12px;
font-family: ${fonts().NORMAL_FONT};
color: ${colors.grey36.toString()};
margin-bottom: ${getSpace(SpaceSize.XS)}px;
const StyledIcon = styled(Icon)`
transform: translate(-0.5px, -0.5px); // fix to align icon properly
`;

const StyledInput = styled.input`
Expand All @@ -79,14 +99,18 @@ const StyledInput = styled.input`

export const BooleanItem: React.StatelessComponent<BooleanItemProps> = props => {
const { className, label, children, checked, onChange } = props;
const icon = checked ? IconName.Check : IconName.Uncheck;
const color = checked ? colors.blue40 : colors.grey60;

return (
<StyledBooleanItem className={className}>
<StyledLabelWrapper>
<StyledLabel>{label}</StyledLabel>
<StyledInput onChange={onChange} type="checkbox" />
<StyledIndicator checked={checked} />
</StyledLabelWrapper>
<PropertyLabel label={label} />
<StyledInput onChange={onChange} checked={checked} type="checkbox" />
<StyledIndicator checked={checked}>
<StyledIndicatorKnob checked={checked}>
<StyledIcon name={icon} size={IconSize.XS} color={color} />
</StyledIndicatorKnob>
</StyledIndicator>
{children}
</StyledBooleanItem>
);
Expand Down
86 changes: 55 additions & 31 deletions src/lsg/patterns/property-items/enum-item/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { colors } from '../../colors';
import { fonts } from '../../fonts';
import { Icon, IconName, IconSize } from '../../icons';
import { PropertyLabel } from '../property-label';
import * as React from 'react';
import { getSpace, SpaceSize } from '../../space';
import styled from 'styled-components';
Expand All @@ -18,62 +20,84 @@ export interface EnumItemProps {
values: Values[];
}

const StyledEnumItem = styled.div`
const StyledEnumItem = styled.label`
display: flex;
align-items: center;
width: 100%;
margin-bottom: ${getSpace(SpaceSize.S)}px;
`;

const StyledSelectWrapper = styled.div`
width: 70%;
height: 30px;
position: relative;
display: inline-block;
box-sizing: border-box;
border-radius: 3px;
background-color: ${colors.white.toString()};
`;

const StyledSelect = styled.select`
appearance: none;
border: none;
border-radius: 0;
font-size: 1em;
box-sizing: border-box;
width: 100%;
height: 30px;
padding: 0 ${getSpace(SpaceSize.XL)}px 0 ${getSpace(SpaceSize.S)}px;
border: 1px solid ${colors.grey90.toString()};
@media screen and (-webkit-min-device-pixel-ratio: 2) {
border-width: 0.5px;
}
background: none;
border-radius: 3px;
color: ${colors.grey20.toString()};
font-family: ${fonts().NORMAL_FONT};
color: ${colors.grey36.toString()};
font-size: 15px;
border-bottom: 1px solid transparent;
padding-bottom: ${getSpace(SpaceSize.M) / 2}px;
margin-bottom: ${getSpace(SpaceSize.L)}px;
transition: all 0.2s;
text-overflow: ellipsis;
transition: border-color 0.1s, box-shadow 0.1s, color 0.1s;
&:hover {
color: ${colors.black.toString()};
border-color: ${colors.grey60.toString()};
}
&:focus {
outline: none;
border-color: ${colors.blue40.toString()};
color: ${colors.black.toString()};
border-color: ${colors.blue40.toString()};
box-shadow: 0 0 3px ${colors.blue.toString('rgb', { alpha: 0.4 })};
}
`;

const StyledLabel = styled.span`
display: block;
margin-bottom: ${getSpace(SpaceSize.XS)}px;
font-size: 12px;
font-family: ${fonts().NORMAL_FONT};
color: ${colors.grey36.toString()};
const StyledIcon = styled(Icon)`
position: absolute;
right: 0;
fill: ${colors.grey60.toString()};
width: 12px;
height: 12px;
padding: ${getSpace(SpaceSize.XS) + getSpace(SpaceSize.XXS)}px;
transform: rotate(90deg);
pointer-events: none;
`;

export const EnumItem: React.StatelessComponent<EnumItemProps> = props => {
const { className, values, selectedValue, onChange, label, required } = props;

return (
<StyledEnumItem className={className}>
<StyledLabel>{label}</StyledLabel>
<StyledSelect
className={className}
onChange={onChange}
value={selectedValue ? selectedValue : ''}
>
{!required && <option key="empty" value="" />}
{values.map(value => (
<option key={value.id} value={value.id}>
{value.name}
</option>
))};
</StyledSelect>
<PropertyLabel label={label} />
<StyledSelectWrapper>
<StyledSelect
className={className}
onChange={onChange}
value={selectedValue ? selectedValue : ''}
>
{!required && <option key="empty" value="" />}
{values.map(value => (
<option key={value.id} value={value.id}>
{value.name}
</option>
))}
</StyledSelect>
<StyledIcon name={IconName.ArrowFillRight} size={IconSize.XXS} color={colors.grey60} />
</StyledSelectWrapper>
</StyledEnumItem>
);
};
Expand Down
32 changes: 32 additions & 0 deletions src/lsg/patterns/property-items/property-label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { colors } from '../colors';
import { fonts } from '../fonts';
import * as React from 'react';
import { getSpace, SpaceSize } from '../space';
import styled from 'styled-components';

export interface PropertyLabelProps {
label: string;
}

const StyledLabel = styled.span`
display: inline-block;
font-size: 12px;
font-family: ${fonts().NORMAL_FONT};
color: ${colors.grey50.toString()};
width: 30%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis
user-select: none;
cursor: default;
box-sizing: border-box;
padding-right: ${getSpace(SpaceSize.XS)}px;
`;

export const PropertyLabel: React.StatelessComponent<PropertyLabelProps> = props => {
const { label } = props;

return <StyledLabel title={label}>{label}</StyledLabel>;
};

export default PropertyLabel;
Loading

0 comments on commit b5c1963

Please sign in to comment.