From c2645b26b457c66b3adcb98a5c089eba3e72f458 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Wed, 31 Oct 2018 15:09:12 -0700 Subject: feat(instant): add interactive overlay presentation to umd bundle --- packages/instant/src/components/ui/button.tsx | 20 +++++++++-- packages/instant/src/components/ui/icon.tsx | 8 +++++ packages/instant/src/components/ui/index.ts | 5 +-- packages/instant/src/components/ui/overlay.tsx | 49 ++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 packages/instant/src/components/ui/overlay.tsx (limited to 'packages/instant/src/components/ui') diff --git a/packages/instant/src/components/ui/button.tsx b/packages/instant/src/components/ui/button.tsx index 5274d835b..0051482e7 100644 --- a/packages/instant/src/components/ui/button.tsx +++ b/packages/instant/src/components/ui/button.tsx @@ -3,6 +3,11 @@ import * as React from 'react'; import { ColorOption, styled } from '../../style/theme'; +export enum ButtonHoverStyle { + Darken = 0, + Opacity, +} + export interface ButtonProps { backgroundColor?: ColorOption; borderColor?: ColorOption; @@ -12,6 +17,7 @@ export interface ButtonProps { isDisabled?: boolean; onClick?: (event: React.MouseEvent) => void; className?: string; + hoverStyle?: ButtonHoverStyle; } const PlainButton: React.StatelessComponent = ({ children, isDisabled, onClick, type, className }) => ( @@ -32,30 +38,38 @@ export const Button = styled(PlainButton)` width: ${props => props.width}; background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; border: ${props => (props.borderColor ? `1px solid ${props.theme[props.borderColor]}` : 'none')}; + opacity: ${props => (props.hoverStyle === ButtonHoverStyle.Opacity ? 0.7 : 1)}; &:hover { background-color: ${props => - !props.isDisabled + shouldDarken(props) ? darken(darkenOnHoverAmount, props.theme[props.backgroundColor || 'white']) : ''} !important; + opacity: 1; } &:active { background-color: ${props => - !props.isDisabled ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; + shouldDarken(props) ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; + opacity: 1; } &:disabled { - opacity: 0.5; + opacity: ${props => (props.hoverStyle === ButtonHoverStyle.Darken ? 0.5 : 0.2)}; } &:focus { background-color: ${props => saturate(saturateOnFocusAmount, props.theme[props.backgroundColor || 'white'])}; } `; +const shouldDarken = (props: ButtonProps) => { + return !props.isDisabled && props.hoverStyle === ButtonHoverStyle.Darken; +}; + Button.defaultProps = { backgroundColor: ColorOption.primaryColor, borderColor: ColorOption.primaryColor, width: 'auto', isDisabled: false, padding: '1em 2.2em', + hoverStyle: ButtonHoverStyle.Darken, }; Button.displayName = 'Button'; diff --git a/packages/instant/src/components/ui/icon.tsx b/packages/instant/src/components/ui/icon.tsx index 61b382760..a05017ba1 100644 --- a/packages/instant/src/components/ui/icon.tsx +++ b/packages/instant/src/components/ui/icon.tsx @@ -13,11 +13,19 @@ interface IconInfo { strokeLinejoin?: 'miter' | 'round' | 'bevel' | 'inherit'; } interface IconInfoMapping { + closeX: IconInfo; failed: IconInfo; success: IconInfo; chevron: IconInfo; } const ICONS: IconInfoMapping = { + closeX: { + viewBox: '0 0 11 11', + fillRule: 'evenodd', + clipRule: 'evenodd', + path: + 'M10.45 10.449C10.7539 10.1453 10.7539 9.65282 10.45 9.34909L6.60068 5.49999L10.45 1.65093C10.7538 1.3472 10.7538 0.854765 10.45 0.551038C10.1462 0.24731 9.65378 0.24731 9.34995 0.551038L5.50058 4.40006L1.65024 0.549939C1.34641 0.246212 0.853973 0.246212 0.550262 0.549939C0.246429 0.853667 0.246429 1.34611 0.550262 1.64983L4.40073 5.49995L0.55014 9.35019C0.246307 9.65392 0.246307 10.1464 0.55014 10.4501C0.853851 10.7538 1.34628 10.7538 1.65012 10.4501L5.5007 6.59987L9.35007 10.449C9.6539 10.7527 10.1463 10.7527 10.45 10.449Z', + }, failed: { viewBox: '0 0 34 34', fillRule: 'evenodd', diff --git a/packages/instant/src/components/ui/index.ts b/packages/instant/src/components/ui/index.ts index 28f76c262..c60b9640e 100644 --- a/packages/instant/src/components/ui/index.ts +++ b/packages/instant/src/components/ui/index.ts @@ -1,7 +1,8 @@ -export { Text, Title } from './text'; -export { Button, ButtonProps } from './button'; +export { Text, TextProps, Title } from './text'; +export { Button, ButtonProps, ButtonHoverStyle } from './button'; export { Flex, FlexProps } from './flex'; export { Container, ContainerProps } from './container'; export { Input, InputProps } from './input'; export { Icon, IconProps } from './icon'; export { Spinner, SpinnerProps } from './spinner'; +export { Overlay, OverlayProps } from './overlay'; diff --git a/packages/instant/src/components/ui/overlay.tsx b/packages/instant/src/components/ui/overlay.tsx new file mode 100644 index 000000000..94fa10fc5 --- /dev/null +++ b/packages/instant/src/components/ui/overlay.tsx @@ -0,0 +1,49 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { ColorOption, overlayBlack, styled } from '../../style/theme'; +import { util } from '../../util/util'; + +import { Button, ButtonHoverStyle } from './button'; +import { Container } from './container'; +import { Flex } from './flex'; +import { Icon } from './icon'; + +export interface OverlayProps { + className?: string; + onClose?: () => void; + zIndex?: number; +} + +const PlainOverlay: React.StatelessComponent = ({ children, className, onClose }) => ( + + + + +
{children}
+
+); +export const Overlay = styled(PlainOverlay)` + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: ${props => props.zIndex} + background-color: ${overlayBlack}; +`; + +Overlay.defaultProps = { + onClose: util.boundNoop, + zIndex: 100, +}; + +Overlay.displayName = 'Overlay'; -- cgit From d16499da4e0611438df7bfe226bce940beca6918 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 1 Nov 2018 15:23:42 -0700 Subject: Remove alternate hover styling from button and move into icon component --- packages/instant/src/components/ui/button.tsx | 20 ++------ packages/instant/src/components/ui/icon.tsx | 69 ++++++++++++++++++-------- packages/instant/src/components/ui/index.ts | 2 +- packages/instant/src/components/ui/overlay.tsx | 15 +----- 4 files changed, 54 insertions(+), 52 deletions(-) (limited to 'packages/instant/src/components/ui') diff --git a/packages/instant/src/components/ui/button.tsx b/packages/instant/src/components/ui/button.tsx index 0051482e7..5274d835b 100644 --- a/packages/instant/src/components/ui/button.tsx +++ b/packages/instant/src/components/ui/button.tsx @@ -3,11 +3,6 @@ import * as React from 'react'; import { ColorOption, styled } from '../../style/theme'; -export enum ButtonHoverStyle { - Darken = 0, - Opacity, -} - export interface ButtonProps { backgroundColor?: ColorOption; borderColor?: ColorOption; @@ -17,7 +12,6 @@ export interface ButtonProps { isDisabled?: boolean; onClick?: (event: React.MouseEvent) => void; className?: string; - hoverStyle?: ButtonHoverStyle; } const PlainButton: React.StatelessComponent = ({ children, isDisabled, onClick, type, className }) => ( @@ -38,38 +32,30 @@ export const Button = styled(PlainButton)` width: ${props => props.width}; background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; border: ${props => (props.borderColor ? `1px solid ${props.theme[props.borderColor]}` : 'none')}; - opacity: ${props => (props.hoverStyle === ButtonHoverStyle.Opacity ? 0.7 : 1)}; &:hover { background-color: ${props => - shouldDarken(props) + !props.isDisabled ? darken(darkenOnHoverAmount, props.theme[props.backgroundColor || 'white']) : ''} !important; - opacity: 1; } &:active { background-color: ${props => - shouldDarken(props) ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; - opacity: 1; + !props.isDisabled ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; } &:disabled { - opacity: ${props => (props.hoverStyle === ButtonHoverStyle.Darken ? 0.5 : 0.2)}; + opacity: 0.5; } &:focus { background-color: ${props => saturate(saturateOnFocusAmount, props.theme[props.backgroundColor || 'white'])}; } `; -const shouldDarken = (props: ButtonProps) => { - return !props.isDisabled && props.hoverStyle === ButtonHoverStyle.Darken; -}; - Button.defaultProps = { backgroundColor: ColorOption.primaryColor, borderColor: ColorOption.primaryColor, width: 'auto', isDisabled: false, padding: '1em 2.2em', - hoverStyle: ButtonHoverStyle.Darken, }; Button.displayName = 'Button'; diff --git a/packages/instant/src/components/ui/icon.tsx b/packages/instant/src/components/ui/icon.tsx index a05017ba1..f12059cff 100644 --- a/packages/instant/src/components/ui/icon.tsx +++ b/packages/instant/src/components/ui/icon.tsx @@ -1,5 +1,8 @@ +import * as _ from 'lodash'; import * as React from 'react'; +import { styled } from '../../style/theme'; + type svgRule = 'evenodd' | 'nonzero' | 'inherit'; interface IconInfo { viewBox: string; @@ -52,33 +55,57 @@ const ICONS: IconInfoMapping = { }; export interface IconProps { + className?: string; width: number; height?: number; color?: string; icon: keyof IconInfoMapping; + onClick?: (event: React.MouseEvent) => void; + padding?: string; } -export const Icon: React.SFC = props => { +const PlainIcon: React.SFC = props => { const iconInfo = ICONS[props.icon]; - return ( - - - +
+ + + +
); }; + +export const Icon = styled(PlainIcon)` + cursor: ${props => (!_.isUndefined(props.onClick) ? 'pointer' : 'default')}; + transition: opacity 0.5s ease; + padding: ${props => props.padding}; + opacity: ${props => (!_.isUndefined(props.onClick) ? 0.7 : 1)}; + &:hover { + opacity: 1; + } + &:active { + opacity: 1; + } +`; + +Icon.defaultProps = { + color: 'white', + padding: '0em 0em', +}; + +Icon.displayName = 'Icon'; diff --git a/packages/instant/src/components/ui/index.ts b/packages/instant/src/components/ui/index.ts index c60b9640e..0efabdb85 100644 --- a/packages/instant/src/components/ui/index.ts +++ b/packages/instant/src/components/ui/index.ts @@ -1,5 +1,5 @@ export { Text, TextProps, Title } from './text'; -export { Button, ButtonProps, ButtonHoverStyle } from './button'; +export { Button, ButtonProps } from './button'; export { Flex, FlexProps } from './flex'; export { Container, ContainerProps } from './container'; export { Input, InputProps } from './input'; diff --git a/packages/instant/src/components/ui/overlay.tsx b/packages/instant/src/components/ui/overlay.tsx index 94fa10fc5..c5258b031 100644 --- a/packages/instant/src/components/ui/overlay.tsx +++ b/packages/instant/src/components/ui/overlay.tsx @@ -1,10 +1,8 @@ import * as _ from 'lodash'; import * as React from 'react'; -import { ColorOption, overlayBlack, styled } from '../../style/theme'; -import { util } from '../../util/util'; +import { overlayBlack, styled } from '../../style/theme'; -import { Button, ButtonHoverStyle } from './button'; import { Container } from './container'; import { Flex } from './flex'; import { Icon } from './icon'; @@ -18,15 +16,7 @@ export interface OverlayProps { const PlainOverlay: React.StatelessComponent = ({ children, className, onClose }) => ( - +
{children}
@@ -42,7 +32,6 @@ export const Overlay = styled(PlainOverlay)` `; Overlay.defaultProps = { - onClose: util.boundNoop, zIndex: 100, }; -- cgit