Skip to content
This repository was archived by the owner on Sep 26, 2024. It is now read-only.

Commit b3ce9c3

Browse files
committed
bring components back 👼
1 parent 00a5f17 commit b3ce9c3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+25116
-10570
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ node_modules
55
.npm
66
/coverage
77
.DS_Store
8+
yarn-error.log

ArrowPopover/index.jsx

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import { calculateStyles, parseColor } from '../lib/utils';
5+
import { darkPopover } from '../style/color';
6+
import { borderRadius } from '../style/border';
7+
import { tooltip as tooltipZIndex } from '../style/zIndex';
8+
9+
import Text from '../Text';
10+
11+
const arrowHeight = 14;
12+
const arrowWidth = 8;
13+
14+
const ArrowPopover = ({
15+
children,
16+
visible,
17+
offset,
18+
oneLine,
19+
position,
20+
padded,
21+
color,
22+
backgroundColor,
23+
shadow,
24+
width,
25+
isTooltip,
26+
id,
27+
}) => {
28+
const offsetTop = position === 'above' ? -offset.top : offset.top;
29+
const style = calculateStyles({
30+
default: {
31+
transform: `translate(${arrowWidth + offset.left}px, ${offsetTop}px)`,
32+
background: parseColor(backgroundColor),
33+
color: parseColor(color),
34+
display: 'inline-block',
35+
borderRadius,
36+
boxShadow: shadow ? '0 1px 2px 0 rgba(0,0,0,0.50)' : 'none',
37+
textAlign: 'left',
38+
position: 'absolute',
39+
left: '100%',
40+
zIndex: tooltipZIndex,
41+
},
42+
hidden: {
43+
display: 'none',
44+
},
45+
oneLine: {
46+
whiteSpace: 'nowrap',
47+
},
48+
positionAbove: {
49+
bottom: 0,
50+
},
51+
positionBelow: {
52+
top: 0,
53+
},
54+
padded: {
55+
padding: '.25rem .75rem',
56+
},
57+
fixedWidth: {
58+
width,
59+
},
60+
}, {
61+
hidden: !visible,
62+
positionAbove: position === 'above',
63+
positionBelow: position === 'below',
64+
oneLine: oneLine && width === 'none',
65+
padded,
66+
fixedWidth: width !== 'none',
67+
});
68+
69+
const arrowStyle = calculateStyles({
70+
default: {
71+
position: 'absolute',
72+
left: -arrowWidth,
73+
width: 0,
74+
height: 0,
75+
backgroundColor: 'transparent',
76+
borderStyle: 'solid',
77+
borderTopWidth: arrowHeight / 2.0,
78+
borderRightWidth: arrowWidth,
79+
borderBottomWidth: arrowHeight / 2.0,
80+
borderLeftWidth: 0,
81+
borderTopColor: 'transparent',
82+
borderRightColor: backgroundColor,
83+
borderBottomColor: 'transparent',
84+
borderLeftColor: 'transparent',
85+
},
86+
positionNormal: {
87+
top: '50%',
88+
transform: 'translate(0, -50%)',
89+
},
90+
positionAbove: {
91+
top: 'none',
92+
bottom: '6px',
93+
transform: 'none',
94+
},
95+
positionBelow: {
96+
top: '6px',
97+
transform: 'none',
98+
},
99+
}, {
100+
positionNormal: true,
101+
positionAbove: position === 'above',
102+
positionBelow: position === 'below',
103+
});
104+
105+
const aria = isTooltip ? {
106+
role: 'tooltip',
107+
'aria-hidden': !visible,
108+
} : {};
109+
110+
return (
111+
<div style={style} id={id} {...aria}>
112+
<span style={arrowStyle} />
113+
<Text color={color} size="small">{children}</Text>
114+
</div>
115+
);
116+
};
117+
118+
ArrowPopover.propTypes = {
119+
children: PropTypes.node.isRequired,
120+
visible: PropTypes.bool,
121+
oneLine: PropTypes.bool,
122+
offset: PropTypes.shape({
123+
top: PropTypes.number,
124+
left: PropTypes.number,
125+
}),
126+
position: PropTypes.oneOf(['above', 'below', 'none']),
127+
padded: PropTypes.bool,
128+
color: PropTypes.string,
129+
backgroundColor: PropTypes.string,
130+
shadow: PropTypes.bool,
131+
width: PropTypes.string,
132+
isTooltip: PropTypes.bool,
133+
id: PropTypes.string,
134+
};
135+
136+
ArrowPopover.defaultProps = {
137+
visible: false,
138+
oneLine: true,
139+
offset: { left: 0, top: 0 },
140+
position: 'none',
141+
padded: true,
142+
color: 'white',
143+
backgroundColor: darkPopover,
144+
shadow: false,
145+
width: 'none',
146+
isTooltip: false,
147+
id: '',
148+
};
149+
150+
export default ArrowPopover;

ArrowPopover/story.jsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from 'react';
2+
import { storiesOf } from '@storybook/react';
3+
import { checkA11y } from 'storybook-addon-a11y';
4+
import ArrowPopover from './index';
5+
import Text from '../Text';
6+
7+
storiesOf('ArrowPopover')
8+
.addDecorator(checkA11y)
9+
.add('default tooltip', () => (
10+
<div style={{ display: 'inline-block', margin: '5rem', position: 'relative', overflow: 'visible' }}>
11+
<Text>I have a Popover tooltip!</Text>
12+
<ArrowPopover visible shadow>
13+
This is a simple tooltip style Popover!
14+
</ArrowPopover>
15+
</div>
16+
))
17+
.add('larger popover: below', () => (
18+
<div style={{ display: 'inline-block', margin: '5rem', position: 'relative', overflow: 'visible' }}>
19+
<Text>I have a Popover!</Text>
20+
<ArrowPopover visible oneLine={false} width="300px" position="below">
21+
<div style={{ padding: '.5rem .25rem' }}>
22+
Your posting schedule tells Buffer when to send out posts in your Queue (under the Content tab).<br /><br />
23+
For example, the next 10 posts you add to your Queue will go out in the next 10 upcoming time/date slots you decide below. <br /><br />
24+
You can change this schedule at any time!
25+
</div>
26+
</ArrowPopover>
27+
</div>
28+
))
29+
.add('larger popover: above', () => (
30+
<div style={{ display: 'inline-block', margin: '5rem', position: 'relative', overflow: 'visible' }}>
31+
<Text>I have a Popover!</Text>
32+
<ArrowPopover visible position="above" shadow>
33+
<div style={{ padding: ' .5rem .25rem' }}>
34+
Look at me!<br />
35+
I'm so far above the rest! ✈️<br />
36+
Later! ✌️
37+
</div>
38+
</ArrowPopover>
39+
</div>
40+
));

Button/index.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ import React from 'react';
22
import ButtonStateless from '../ButtonStateless';
33
import PseudoClassComponent from '../PseudoClassComponent';
44

5+
const isNativeComponent = component => typeof component.type === 'string';
6+
57
class Button extends PseudoClassComponent {
68
render() {
79
const { children, ...rest } = this.props;
810
let hoveredChildren = children;
911
// string as children isn't clonable
10-
if (React.isValidElement(children)) {
12+
if (React.isValidElement(children) && !isNativeComponent(children)) {
1113
hoveredChildren = React.cloneElement(
1214
children,
1315
{ hovered: this.state.hovered },

Button/test.jsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import React from 'react';
2-
import { mount } from 'enzyme';
2+
import { mount, configure } from 'enzyme';
3+
import Adapter from 'enzyme-adapter-react-16';
34
import ButtonStateless from '../ButtonStateless';
45
import testComponentA11y from '../lib/a11yTestHelper';
56
import Button from './index';
67

8+
configure({ adapter: new Adapter() });
9+
710
describe('Button', () => {
811
it('should pass accessibility audit', () => testComponentA11y(
912
<Button>A Button</Button>,
@@ -16,10 +19,12 @@ describe('Button', () => {
1619
const button = wrapper
1720
.find(ButtonStateless);
1821
button.simulate('mouseEnter');
19-
expect(button.props().hovered)
22+
wrapper.update();
23+
expect(wrapper.find(ButtonStateless).props().hovered)
2024
.toBe(true);
2125
button.simulate('mouseLeave');
22-
expect(button.props().hovered)
26+
wrapper.update();
27+
expect(wrapper.find(ButtonStateless).props().hovered)
2328
.toBe(false);
2429
});
2530

@@ -30,10 +35,12 @@ describe('Button', () => {
3035
const button = wrapper
3136
.find(ButtonStateless);
3237
button.simulate('focus');
33-
expect(button.props().focused)
38+
wrapper.update();
39+
expect(wrapper.find(ButtonStateless).props().focused)
3440
.toBe(true);
3541
button.simulate('blur');
36-
expect(button.props().focused)
42+
wrapper.update();
43+
expect(wrapper.find(ButtonStateless).props().focused)
3744
.toBe(false);
3845
});
3946

@@ -50,10 +57,12 @@ describe('Button', () => {
5057
const button = wrapper
5158
.find(ButtonStateless);
5259
button.simulate('focus');
53-
expect(button.props().focused)
60+
wrapper.update();
61+
expect(wrapper.find(ButtonStateless).props().focused)
5462
.toBe(true);
5563
button.simulate('blur');
56-
expect(button.props().focused)
64+
wrapper.update();
65+
expect(wrapper.find(ButtonStateless).props().focused)
5766
.toBe(false);
5867
});
5968
});

ButtonStateless/index.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const Button = ({
4444
quaternary,
4545
warning,
4646
noStyle,
47+
label,
4748
}) => {
4849
const style = calculateStyles({
4950
default: {
@@ -172,6 +173,7 @@ const Button = ({
172173
onFocus={onFocus}
173174
onBlur={onBlur}
174175
disabled={disabled}
176+
aria-label={label || null}
175177
>
176178
{children}
177179
</button>
@@ -197,6 +199,7 @@ Button.propTypes = {
197199
tertiary: PropTypes.bool,
198200
quaternary: PropTypes.bool,
199201
warning: PropTypes.bool,
202+
label: PropTypes.string,
200203
};
201204

202205
export default Button;

Card/index.jsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from '../style/font';
1010
import {
1111
outerSpace,
12+
outerSpaceLight,
1213
white,
1314
mystic,
1415
geyser,
@@ -25,6 +26,7 @@ import {
2526
} from '../style/animation';
2627
import {
2728
boxShadowLevelOne,
29+
boxShadowLevelTwo,
2830
} from '../style/dropShadow';
2931

3032
const Card = ({
@@ -40,6 +42,8 @@ const Card = ({
4042
onMouseEnter,
4143
onMouseLeave,
4244
reducedPadding,
45+
shadowHeight,
46+
draggingPlaceholder,
4347
}) => {
4448
const style = calculateStyles({
4549
default: {
@@ -66,7 +70,7 @@ const Card = ({
6670
opacity: 0.5,
6771
},
6872
noBorder: {
69-
border: 0,
73+
border: `${borderWidth} solid transparent`,
7074
},
7175
noPadding: {
7276
padding: 0,
@@ -81,6 +85,15 @@ const Card = ({
8185
reducedPadding: {
8286
padding: '1rem',
8387
},
88+
shadowHeightOne: {
89+
boxShadow: boxShadowLevelOne,
90+
},
91+
shadowHeightTwo: {
92+
boxShadow: boxShadowLevelTwo,
93+
},
94+
draggingPlaceholder: {
95+
border: `${borderWidth} dashed ${outerSpaceLight}`,
96+
},
8497
}, {
8598
doublePadding,
8699
empty,
@@ -91,6 +104,9 @@ const Card = ({
91104
hovered,
92105
color,
93106
reducedPadding,
107+
shadowHeightOne: shadowHeight === 1,
108+
shadowHeightTwo: shadowHeight === 2,
109+
draggingPlaceholder,
94110
});
95111
return (
96112
<div
@@ -116,6 +132,13 @@ Card.propTypes = {
116132
onMouseEnter: PropTypes.func,
117133
onMouseLeave: PropTypes.func,
118134
reducedPadding: PropTypes.bool,
135+
shadowHeight: PropTypes.oneOf([0, 1, 2]),
136+
draggingPlaceholder: PropTypes.bool,
137+
};
138+
139+
Card.defaultProps = {
140+
shadowHeight: 0,
141+
draggingPlaceholder: false,
119142
};
120143

121144
export default Card;

Card/story.jsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,10 @@ storiesOf('Card')
4747
))
4848
.add('reducedPadding', () => (
4949
<Card reducedPadding>What is a Product Designer? An awesome story by <Link href={'#'}>@jgadapee</Link> over on Medium! <Link href={'#'}>http://buff.ly/1LTbUqv</Link></Card>
50+
))
51+
.add('shadowHeight=1', () => (
52+
<Card shadowHeight={1}>What is a Product Designer? An awesome story by <Link href={'#'}>@jgadapee</Link> over on Medium! <Link href={'#'}>http://buff.ly/1LTbUqv</Link></Card>
53+
))
54+
.add('shadowHeight=2', () => (
55+
<Card shadowHeight={2}>What is a Product Designer? An awesome story by <Link href={'#'}>@jgadapee</Link> over on Medium! <Link href={'#'}>http://buff.ly/1LTbUqv</Link></Card>
5056
));

0 commit comments

Comments
 (0)