Skip to content

Commit

Permalink
bubble buttons work nice
Browse files Browse the repository at this point in the history
  • Loading branch information
vogievetsky committed Apr 8, 2016
1 parent aa7cfa3 commit 21c81ae
Show file tree
Hide file tree
Showing 15 changed files with 172 additions and 96 deletions.
41 changes: 31 additions & 10 deletions src/client/components/bubble-menu/bubble-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ require('./bubble-menu.css');
import * as React from 'react';
import { Fn } from "../../../common/utils/general/general";
import { Stage } from '../../../common/models/index';
import { isInside, escapeKey, uniqueId } from '../../utils/dom/dom';
import { isInside, escapeKey, uniqueId, classNames } from '../../utils/dom/dom';
import { BodyPortal } from '../body-portal/body-portal';

const OFFSET_H = 10;
const OFFSET_V = -1;
const SCREEN_OFFSET = 5;

export type BubbleLayout = 'normal' | 'mini';
export type Align = 'start' | 'center' | 'end';

export interface BubbleMenuProps extends React.Props<any> {
className: string;
Expand All @@ -23,6 +24,7 @@ export interface BubbleMenuProps extends React.Props<any> {
onClose: Fn;
inside?: Element;
layout?: BubbleLayout;
align?: Align;
}

export interface BubbleMenuState {
Expand All @@ -32,6 +34,9 @@ export interface BubbleMenuState {
}

export class BubbleMenu extends React.Component<BubbleMenuProps, BubbleMenuState> {
static defaultProps = {
align: 'center'
};

constructor() {
super();
Expand All @@ -43,7 +48,7 @@ export class BubbleMenu extends React.Component<BubbleMenuProps, BubbleMenuState
}

componentWillMount() {
var { openOn, direction, id } = this.props;
var { openOn, direction, align, id } = this.props;
var rect = openOn.getBoundingClientRect();

var x: number;
Expand All @@ -55,7 +60,13 @@ export class BubbleMenu extends React.Component<BubbleMenuProps, BubbleMenuState
break;

case 'down':
x = rect.left + rect.width / 2;
if (align === 'center') {
x = rect.left + rect.width / 2;
} else if (align === 'start') {
x = rect.left;
} else { // align === 'end'
x = rect.left + rect.width;
}
y = rect.top + rect.height - OFFSET_V;
break;

Expand Down Expand Up @@ -99,7 +110,7 @@ export class BubbleMenu extends React.Component<BubbleMenuProps, BubbleMenuState
}

render(): any {
var { className, direction, stage, fixedSize, containerStage, inside, layout, children } = this.props;
var { className, direction, stage, fixedSize, containerStage, inside, layout, align, children } = this.props;
var { id, x, y } = this.state;

var menuWidth = stage.width;
Expand Down Expand Up @@ -138,7 +149,14 @@ export class BubbleMenu extends React.Component<BubbleMenuProps, BubbleMenuState
break;

case 'down':
var left = x - menuWidth / 2;
var left: number;
if (align === 'center') {
left = x - menuWidth / 2;
} else if (align === 'start') {
left = x;
} else { // align === 'end'
left = x - menuWidth;
}
// constrain
left = Math.min(Math.max(left, containerStage.x), containerStage.x + containerStage.width - menuWidth);
menuLeft = left;
Expand All @@ -157,13 +175,16 @@ export class BubbleMenu extends React.Component<BubbleMenuProps, BubbleMenuState
if (!insideId) throw new Error('inside element must have id');
}

var myClasses = ['bubble-menu', direction];
if (className) myClasses.push(className);
if (layout === 'mini') myClasses.push('mini');
var shpitzElement: JSX.Element = null;
if (align === 'center') {
shpitzElement = <div className="shpitz" style={shpitzStyle}></div>;
}

var myClass = classNames('bubble-menu', direction, className, { mini: layout === 'mini' });
return <BodyPortal left={menuLeft} top={menuTop}>
<div className={myClasses.join(' ')} id={id} data-parent={insideId} style={menuStyle}>
<div className={myClass} id={id} data-parent={insideId} style={menuStyle}>
{children}
<div className="shpitz" style={shpitzStyle}></div>
{shpitzElement}
</div>
</BodyPortal>;
}
Expand Down
17 changes: 17 additions & 0 deletions src/client/components/button/button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,27 @@

.button {
&.primary {
// ToDo: make everything that is a button a button and inline these
@extend %button-primary;
}

&.secondary {
@extend %button-secondary;
}

&.mini {
height: $input-height-mini;
padding-left: 8px;
padding-right: 8px;
min-width: 40px;
}

&.icon {
min-width: 25px;
padding: 2px 0;

svg {
height: 19px;
}
}
}
17 changes: 13 additions & 4 deletions src/client/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { SvgIcon } from '../svg-icon/svg-icon';
export type ButtonType = "primary" | "secondary";

export interface ButtonProps extends React.Props<any> {
title: string;
type: ButtonType;
className?: string;
title?: string;
svg?: string;
onClick?: Fn;
}

Expand All @@ -25,11 +26,19 @@ export class Button extends React.Component<ButtonProps, ButtonState> {
}

render() {
const { title, type, className, onClick } = this.props;
const { title, type, className, svg, onClick } = this.props;

var icon: JSX.Element = null;
if (svg) {
icon = <SvgIcon svg={svg}/>;
}

return <button
className={classNames('button', type, className)}
className={classNames('button', type, className, { icon })}
onClick={onClick}
>{title}</button>;
>
{icon}
{title}
</button>;
}
}
2 changes: 1 addition & 1 deletion src/client/components/cube-header-bar/cube-header-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export class CubeHeaderBar extends React.Component<CubeHeaderBarProps, CubeHeade
}

return <header className="cube-header-bar">
<div className="left-bar" onClick={onNavClick as any}>
<div className="left-bar" onClick={onNavClick}>
<div className="menu-icon">
<SvgIcon svg={require('../../icons/menu.svg')}/>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/client/components/hiluk-menu/hiluk-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class HilukMenu extends React.Component<HilukMenuProps, HilukMenuState> {
className="copy-url clipboard"
key="copy-url"
data-clipboard-text={url}
onClick={onClose as any}
onClick={onClose}
>{STRINGS.copyUrl}</li>
];

Expand All @@ -61,7 +61,7 @@ export class HilukMenu extends React.Component<HilukMenuProps, HilukMenuState> {
className="copy-specific-url clipboard"
key="copy-specific-url"
data-clipboard-text={specificUrl}
onClick={onClose as any}
onClick={onClose}
>{STRINGS.copySpecificUrl}</li>);
}

Expand Down
2 changes: 1 addition & 1 deletion src/client/components/home-header-bar/home-header-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class HomeHeaderBar extends React.Component<HomeHeaderBarProps, HomeHeade
}

return <header className="home-header-bar">
<div className="left-bar" onClick={onNavClick as any}>
<div className="left-bar" onClick={onNavClick}>
<div className="menu-icon">
<SvgIcon svg={require('../../icons/menu.svg')}/>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/client/components/link-header-bar/link-header-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ export class LinkHeaderBar extends React.Component<LinkHeaderBarProps, LinkHeade
}

return <header className="link-header-bar">
<div className="left-bar" onClick={onNavClick as any}>
<div className="left-bar" onClick={onNavClick}>
<div className="menu-icon">
<SvgIcon svg={require('../../icons/menu.svg')}/>
</div>
<div className="title">{title}</div>
</div>
<div className="right-bar">
<div className="text-button" onClick={onExploreClick as any}>Explore</div>
<div className="text-button" onClick={onExploreClick}>Explore</div>
<a className="icon-button help" href="https://groups.google.com/forum/#!forum/imply-user-group" target="_blank">
<SvgIcon className="help-icon" svg={require('../../icons/help.svg')}/>
</a>
Expand Down
2 changes: 1 addition & 1 deletion src/client/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class Modal extends React.Component<ModalProps, ModalState> {
if (typeof title === 'string') {
titleElement = <div className="modal-title">
<div className="text">{title}</div>
<div className="close" onClick={onClose as any}>
<div className="close" onClick={onClose}>
<SvgIcon svg={require('../../icons/full-remove.svg')}/>
</div>
</div>;
Expand Down
61 changes: 25 additions & 36 deletions src/client/components/segment-bubble/segment-bubble.scss
Original file line number Diff line number Diff line change
@@ -1,53 +1,42 @@
@import '../../imports';

// These max width and height are arbitrary
$segment-bubble-max-width: 30px;
$segment-bubble-max-height: 10px;
$shpitz-size: 7px;

.segment-bubble {
@extend %menu-cont;
position: absolute;
width: $segment-bubble-max-width;
height: $segment-bubble-max-height;
margin-left: -$segment-bubble-max-width / 2;
margin-top: -$segment-bubble-max-height - $shpitz-size;
background: rgba($white, 0.9);
padding: 8px;
text-align: center;
transform: translate(-50%, -100%);
max-width: 400px;

display: flex;
justify-content: center;
align-items: flex-end;

.segment-bubble-inner {
@extend %menu-cont;
background: rgba($white, 0.9);
display: inline-block;
padding: 8px;
text-align: center;
.text {
.segment {
color: $text-lighterish;
display: block;
padding-bottom: 3px;
overflow: hidden;
}

.text {
display: inline-block;
.measure-value {
white-space: nowrap;

.segment {
color: $text-lighterish;
display: block;
margin-bottom: 3px;
}
}
}

.buttons {
white-space: nowrap;
.buttons {
white-space: nowrap;

&:nth-child(n+2) {
margin-top: 7px;
}
&:nth-child(n+2) {
margin-top: 7px;
}

.button {
margin-right: 5px;
}
.button {
margin-right: 5px;
}

.button:last-child {
margin-right: 0;
}
.button:last-child {
margin-right: 0;
}
}

Expand Down
Loading

0 comments on commit 21c81ae

Please sign in to comment.