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

Commit

Permalink
feat: add feedback after installing libraries (#773)
Browse files Browse the repository at this point in the history
* feat: add user feedback for installing libraries

* feat: scroll to top after installing library via npm

* feat: add show animation for library box

* feat: show library box shadow with box color

* feat: add new spinner component

* feat: show store with internet connection only

* fix: remove unneeded imports

* wip: feat: animate transition of installed packages box in store

* wip: feat: position installed container absolute for better performance

* feat: add feedback after installing libraries

* feat: add feedback after installing npm packages
  • Loading branch information
tilmx authored and yuzl committed Mar 27, 2019
1 parent 5e3a672 commit 6bc58b0
Show file tree
Hide file tree
Showing 13 changed files with 2,261 additions and 271 deletions.
4 changes: 2 additions & 2 deletions packages/analyzer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
"dependencies": {
"@meetalva/types": "1.0.0",
"@meetalva/util": "1.0.0",
"@types/lodash": "4.14.107",
"@types/lodash": "4.14.123",
"@types/node": "^10.12.18",
"@types/npm-package-arg": "^6.1.0",
"@types/webpack": "^4.4.21",
"extract-comments": "^1.1.0",
"find-pkg": "^2.0.0",
"lodash": "4.17.5",
"lodash": "4.17.11",
"memory-fs": "0.4.1",
"npm-package-arg": "^6.1.0",
"pacote": "^9.4.0",
Expand Down
73 changes: 73 additions & 0 deletions packages/components/src/button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { Color } from '../colors';
import * as React from 'react';
import { getSpace, SpaceSize } from '../space';
import styled from 'styled-components';
import { Check } from 'react-feather';
import { Spinner } from '../spinner';
import { IconSize } from '../icons';

export interface ButtonProps {
children?: React.ReactNode;
Expand All @@ -21,6 +24,7 @@ export interface ButtonProps {
style?: React.CSSProperties;
className?: string;
type?: 'submit' | 'button';
state?: ButtonState;
}

export enum ButtonOrder {
Expand All @@ -40,6 +44,12 @@ export enum ButtonSize {
Small
}

export enum ButtonState {
Default,
Progress,
Done
}

const BUTTON_FONT_SIZE = (props: ButtonProps): number => {
switch (props.size) {
case ButtonSize.Small:
Expand Down Expand Up @@ -80,6 +90,7 @@ const StyledBaseButton = styled.button`
border: none;
outline: none;
user-select: none;
position: relative;
`;

const DecoratedBaseButton = styled(StyledBaseButton)`
Expand Down Expand Up @@ -115,6 +126,24 @@ const StyledPrimaryButton =
background: ${props => (props.inverted ? Color.White : primaryFill(props))};
border-color: transparent;
color: ${props => (props.inverted ? primaryFill(props) : Color.White)};
${props =>
(props.state === ButtonState.Progress || props.state === ButtonState.Done) &&
'color: transparent;'}
transition: color 0.1s;
${props =>
props.state === ButtonState.Done &&
`
animation: showText .1s 1.7s ease both;
@keyframes showText {
from {
color: transparent;
}
to {
color: ${props.inverted ? primaryFill(props) : Color.White};
}
}
`}
&:active {
background: ${props => (props.inverted ? '' : primaryFillActive(props))};
Expand Down Expand Up @@ -165,6 +194,17 @@ const StyledTertiaryButton =
}
`;

const StyledWrapper = styled.div`
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
`;

export type AnyButton =
| typeof StyledPrimaryButton
| typeof StyledTertiaryButton
Expand All @@ -182,6 +222,28 @@ const getComponent = (props: ButtonProps): AnyButton => {
}
};

const StyledDoneWrapper = styled(StyledWrapper)`
animation: checkAnimation 1.5s 0.1s ease both;
@keyframes checkAnimation {
0% {
transform: scale(0.5);
opacity: 0;
}
10% {
transform: scale(1);
opacity: 1;
}
90% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(0.5);
opacity: 0;
}
}
`;

export const Button: React.StatelessComponent<ButtonProps> = props => {
const Component = getComponent(props) as any;

Expand All @@ -199,8 +261,19 @@ export const Button: React.StatelessComponent<ButtonProps> = props => {
size={props.size}
style={{ color: props.color, ...props.style }}
color={props.color}
state={props.state}
>
{props.children}
{props.state === ButtonState.Progress && (
<StyledWrapper>
<Spinner size={IconSize.XS} />
</StyledWrapper>
)}
{props.state === ButtonState.Done && (
<StyledDoneWrapper>
<Check size={18} color={Color.White} strokeWidth={3} />
</StyledDoneWrapper>
)}
</Component>
);
};
1 change: 1 addition & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export * from './property-reference';
export * from './search';
export * from './select';
export * from './space';
export * from './spinner';
export * from './splash-screen';
export * from './tab';
export * from './tab-switch';
Expand Down
6 changes: 5 additions & 1 deletion packages/components/src/input-button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import styled from 'styled-components';
import { Button, ButtonSize } from '../button';
import { Button, ButtonSize, ButtonState } from '../button';
import { PropertyInputStyles } from '../property-input';

const StyledWrapper = styled.div`
Expand All @@ -27,7 +27,9 @@ export interface InputButtonProps {
onChange?: React.ChangeEventHandler<HTMLInputElement>;
onSubmit?: React.FormEventHandler<HTMLElement>;
placeholder?: string;
disabled?: boolean;
value?: string;
state?: ButtonState;
isValid: () => boolean;
}

Expand All @@ -39,11 +41,13 @@ export const InputButton: React.SFC<InputButtonProps> = props => (
type="text"
value={props.value || ''}
placeholder={props.placeholder}
disabled={props.disabled}
/>
<StyledButton
type="submit"
disabledAppearance={props.isValid ? !props.isValid() : true}
size={ButtonSize.Medium}
state={props.state}
>
{props.children}
</StyledButton>
Expand Down
71 changes: 36 additions & 35 deletions packages/components/src/library-box/library-box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Headline } from '../headline';
import { Copy, CopySize } from '../copy';
import { getSpace, SpaceSize, Space } from '../space';
import { LibraryImage } from './library-image';
import * as ColorTool from 'color';

export enum LibraryBoxState {
Idle,
Expand Down Expand Up @@ -37,13 +38,46 @@ const StyledBox =
width: 348px;
background: ${props => (props.color ? props.color : Color.Grey20)};
border-radius: 6px;
box-shadow: 0 0 24px 0 ${Color.BlackAlpha15};
box-shadow: 0 0 24px 0 ${props =>
props.color ? new ColorTool(props.color).fade(0.4).toString() : Color.BlackAlpha15};
color: ${Color.White};
text-align: left;
margin: ${getSpace(SpaceSize.S)}px ${getSpace(SpaceSize.XS)}px;
user-select: none;
transition: box-shadow 0.2s;
overflow: hidden;
${props =>
props.size === LibraryBoxSize.Medium &&
`
animation: show .2s ease-out both;
:nth-child(2) {
animation-delay: 0.05s;
}
:nth-child(3) {
animation-delay: 0.1s;
}
:nth-child(4) {
animation-delay: 0.15s;
}
:nth-child(5) {
animation-delay: 0.2s;
}
:nth-child(6) {
animation-delay: 0.25s;
}
`}
@keyframes show {
from {
transform: scale(.95);
opacity: 0;
}
to {
transform: scale(1)
opacity: 1 !important;
}
}
`;

const IMAGE = (props: LibraryBoxProps) => (props.image ? props.image : toDataUrl(<LibraryImage />));
Expand Down Expand Up @@ -80,38 +114,6 @@ const StyledTop = styled.div`
padding: ${getSpace(SpaceSize.L)}px ${getSpace(SpaceSize.XL)}px 0;
`;

const Loader = styled.div`
width: 100%;
height: 2px;
overflow: hidden;
position: absolute;
left: 0;
top: 0;
&:after {
content: '';
display: block;
width: 20px;
height: 100%;
background: ${Color.White};
animation: load 1.5s infinite ease;
transform: scaleX(1);
transform-origin: 0 0;
}
@keyframes load {
0% {
margin-left: -20px;
}
50% {
transform: scaleX(5);
}
100% {
margin-left: 100%;
}
}
`;

const StyledBottom = styled.div`
position: relative;
padding: 0 ${getSpace(SpaceSize.XL)}px;
Expand All @@ -135,7 +137,6 @@ export const LibraryBox: React.StatelessComponent<LibraryBoxProps> = (props): JS
<Space sizeBottom={SpaceSize.S} />
</StyledTop>
<StyledBottom {...props}>
{props.state === LibraryBoxState.Progress && <Loader {...props} />}
<Space sizeTop={SpaceSize.L} />
<StyledInstallContainer>
{props.install}
Expand Down
3 changes: 3 additions & 0 deletions packages/components/src/property-input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export const PropertyInputStyles = css`
color: ${Color.Black};
box-shadow: 0 0 3px ${Color.BlueAlpha40};
}
:disabled {
color: ${Color.Grey60};
}
`;

const StyledWrapper = styled.div`
Expand Down
2 changes: 2 additions & 0 deletions packages/components/src/space/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface SpaceProps {
sizeRight?: SpaceSize;
sizeTop?: SpaceSize;
style?: React.CSSProperties;
onClick?: React.MouseEventHandler;
}

export interface StyledSpaceProps {
Expand Down Expand Up @@ -112,6 +113,7 @@ export const Space: React.StatelessComponent<SpaceProps> = props => {
className={props.className}
spaceSize={size}
inside={Boolean(props.inside)}
onClick={props.onClick}
>
{props.children}
</StyledSpace>
Expand Down
60 changes: 60 additions & 0 deletions packages/components/src/spinner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Color } from '../colors';
import * as React from 'react';
import styled from 'styled-components';
import { IconSize } from '../icons';

export interface SpinnerProps {
size: IconSize;
}

const Wrapper = styled.div`
width: ${(props: SpinnerProps) => props.size}px;
height: ${(props: SpinnerProps) => props.size}px;
animation: intro 0.1s 0.2s ease-out both;
@keyframes intro {
from {
transform: scale(0.5);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
`;

const StyledSpinner = styled.div`
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
animation: spin 2s linear infinite;
@keyframes spin {
to {
transform: rotate(360deg);
}
}
`;

const StyledInnerSpinner = styled.div`
height: 100%;
width: 100%;
box-sizing: border-box;
border-radius: 50%;
border: 1.5px solid ${Color.White};
border-left-color: transparent;
animation: spin 1.5s ease infinite;
`;

export const Spinner: React.StatelessComponent<SpinnerProps> = props => (
<Wrapper size={props.size}>
<StyledSpinner>
<StyledInnerSpinner />
</StyledSpinner>
</Wrapper>
);
Loading

1 comment on commit 6bc58b0

@marionebl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.