feat: added support for --only flag

Merge pull request #1731 from coralproject/next-watcher-flags

Watcher --only
Use JSDocs comments (#1727)


Merge branch 'next' into prevent-compile-loop-relay
Merge pull request #1726 from coralproject/prevent-compile-loop-relay

[next] Adapt relay watch config
[next] Remove nodemon (#1725)

* Remove old nodemon configs

* Remove nodemon

[next] Jest implementation for React Components (#1733)

* Make jest testing work with custom path and css modules

* Add first test

* feat: added unit tests to ci

* fix: updated package-lock.json

* Update cssTransform.js

* Update cssTransform.js

* Fix test in ci

Adapt files.exclude (#1736)


Permalink ui

Adding Copy to clipboard functionality

WIP

clean request

wip

progress

progress

work in progress

wip

ui functionality

Translations :/

wip

Merge branch 'permalink' of github.com:coralproject/talk into permalink

* 'permalink' of github.com:coralproject/talk: (42 commits)
  [next] Support server side jest testing (#1747)
  Update snapshots
  Add comments
  Remove precss
  Move react-responsive to dev deps
  Remove comment
  Mobile first approach
  Support standard css variables, dynamically set spacing-unit
  Add docs
  Fully implement Flex and MatchMedia
  Responsive Components <3
  fix: linting
  fix: adjusted pageInfo
  Remove obsoloe snapshot
  Move jsdom to dev deps
  Mark comments as always returning a value
  Add comment
  Fix unit tests
  Translate, concept for translation and id strings
  Add aria props
  ...

Adding Attachment and Popover Component

merge conflicts

progress

Any

Working

Support for refs

Ready

Merge branch 'permalink' of github.com:coralproject/talk into permalink

* 'permalink' of github.com:coralproject/talk: (101 commits)
  Ready
  Support for refs
  Working
  Any
  progress
  merge conflicts
  Make timeagoFormatter optional
  More colors
  Colors
  Short circuit endless respawn
  fix: new mongo parser
  Remove jest from watcher config, as it doesnt run well inside
  Add jest set
  Apply suggestions
  Move react-timeago to dev
  Upgrade docz
  Cleanup docz scripts
  Support watcher sets
  [next] Support server side jest testing (#1747)
  Make filter only a pure function
  ...
This commit is contained in:
Belén Curcio
2018-07-16 18:36:21 -03:00
parent 044e1c2863
commit b9a8fdb77b
183 changed files with 8963 additions and 2233 deletions
@@ -0,0 +1,2 @@
.root {
}
@@ -0,0 +1,62 @@
import React, { CSSProperties } from "react";
import { Manager, Popper, Reference, RefHandler } from "react-popper";
interface RenderProps {
ref: RefHandler;
style?: CSSProperties;
}
interface InnerProps {
body: React.ReactElement<any> | null;
children: (props: RenderProps) => React.ReactElement<any>;
className?: string;
placement?:
| "auto-start"
| "auto"
| "auto-end"
| "top-start"
| "top"
| "top-end"
| "right-start"
| "right"
| "right-end"
| "bottom-end"
| "bottom"
| "bottom-start"
| "left-end"
| "left"
| "left-start";
}
interface Props {
ref: any;
style: CSSProperties;
}
class Attachment extends React.Component<InnerProps> {
public render() {
const { children, body, placement = "top" } = this.props;
return (
<Manager>
<Reference>{(props: Props) => children({ ref: props.ref })}</Reference>
<Popper
placement={placement}
modifiers={{ preventOverflow: { enabled: false } }}
eventsEnabled
positionFixed={false}
>
{(props: Props) =>
body
? React.cloneElement(body, {
innerRef: props.ref,
style: props.style,
})
: null
}
</Popper>
</Manager>
);
}
}
export default Attachment;
@@ -0,0 +1,2 @@
export * from "./Attachment";
export { default } from "./Attachment";
@@ -19,6 +19,8 @@ interface InnerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
/** This is passed by the `withKeyboardFocus` HOC */
keyboardFocus: boolean;
innerRef?: React.RefObject<HTMLDivElement> | any;
}
/**
@@ -31,6 +33,7 @@ const BaseButton: StatelessComponent<InnerProps> = ({
classes,
keyboardFocus,
type: typeProp,
innerRef,
...rest
}) => {
let Element = "button";
@@ -53,7 +56,7 @@ const BaseButton: StatelessComponent<InnerProps> = ({
[classes.keyboardFocus]: keyboardFocus,
});
return <Element {...rest} className={rootClassName} />;
return <Element {...rest} className={rootClassName} ref={innerRef} />;
};
const enhanced = withStyles(styles)(withKeyboardFocus(BaseButton));
+66 -45
View File
@@ -1,78 +1,99 @@
.root {
composes: button from "talk-ui/shared/typography.css";
padding: 5px 20px;
border-radius: $round-corners;
background-color: transparent;
/* TODO: hover styles for the default button */
&:enabled,
&:disabled {
padding: 5px 20px;
border-radius: var(--round-corners);
background-color: transparent;
/* TODO: hover styles for the default button */
}
}
.fullWidth {
.root:disabled {
opacity: 0.4;
cursor: default;
}
.fullWidth:enabled,
.fullWidth:disabled {
display: block;
width: 100%;
box-sizing: border-box;
}
.primary {
background-color: $palette-primary-main;
.primary:enabled,
.primary:disabled {
background-color: var(--palette-primary-main);
color: #fff;
}
.primary:enabled {
&:hover {
background-color: $palette-primary-light;
background-color: var(--palette-primary-light);
}
&:active {
background-color: $palette-primary-lighter;
}
&.invert {
background-color: transparent;
border: 1px solid $palette-primary-main;
color: $palette-primary-main;
&:hover {
border-color: $palette-primary-light;
color: $palette-primary-light;
}
&:active {
border-color: $palette-primary-lighter;
color: $palette-primary-lighter;
}
background-color: var(--palette-primary-lighter);
}
}
.secondary {
background-color: $palette-secondary-main;
color: #fff;
.primary:enabled.invert,
.primary:disabled.invert {
background-color: transparent;
border: 1px solid var(--palette-primary-main);
color: var(--palette-primary-main);
}
.primary:enabled.invert {
&:hover {
background-color: $palette-secondary-light;
border-color: var(--palette-primary-light);
color: var(--palette-primary-light);
}
&:active {
background-color: $palette-secondary-lighter;
border-color: var(--palette-primary-lighter);
color: var(--palette-primary-lighter);
}
}
.secondary:enabled,
.secondary:disabled {
background-color: var(--palette-secondary-main);
color: #fff;
}
.secondary:enabled {
&:hover {
background-color: var(--palette-secondary-light);
}
&:active {
background-color: var(--palette-secondary-lighter);
}
}
.secondary:enabled.invert,
.secondary:disabled.invert {
background-color: transparent;
border: 1px solid var(--palette-secondary-main);
color: var(--palette-secondary-main);
}
.secondary:enabled.invert {
&:hover {
border-color: var(--palette-secondary-light);
color: var(--palette-secondary-light);
}
&.invert {
background-color: transparent;
border: 1px solid $palette-secondary-main;
color: $palette-secondary-main;
&:hover {
border-color: $palette-secondary-light;
color: $palette-secondary-light;
}
&:active {
border-color: $palette-secondary-lighter;
color: $palette-secondary-lighter;
}
&:active {
border-color: var(--palette-secondary-lighter);
color: var(--palette-secondary-lighter);
}
}
/**
* This seems to be the best way to target modern touch device browsers.
*/
@media (-moz-touch-enabled: 1), (pointer:coarse) {
@media (-moz-touch-enabled: 1), (pointer: coarse) {
/* TODO: Remove hover styles */
}
@@ -10,11 +10,18 @@ import Button from './Button'
## Basic usage
<Playground>
<Button style={{marginRight: "10px"}}>Push Me</Button>
<Button style={{marginRight: "10px"}} anchor>I'm an Anchor Tag</Button>
<Button style={{marginRight: "10px"}} primary>Primary</Button>
<Button style={{marginRight: "10px"}} secondary>Secondary</Button>
<Button style={{marginTop: "10px"}} primary fullWidth>Full Width</Button>
<Button style={{marginTop: "10px"}} primary invert fullWidth>Full Width Invert</Button>
<Button style={{margin: "0 10px 10px 0"}}>Push Me</Button>
<Button style={{margin: "0 10px 10px 0"}} disabled>Push Me</Button>
<Button style={{margin: "0 10px 10px 0"}} anchor>I'm an Anchor Tag</Button>
<Button style={{margin: "0 10px 10px 0"}} primary>Primary</Button>
<Button style={{margin: "0 10px 10px 0"}} primary disabled>Primary</Button>
<Button style={{margin: "0 10px 10px 0"}} secondary>Secondary</Button>
<Button style={{margin: "0 10px 10px 0"}} secondary disabled>Secondary</Button>
<Button style={{margin: "0 10px 10px 0"}} primary invert>Primary</Button>
<Button style={{margin: "0 10px 10px 0"}} primary invert disabled>Primary</Button>
<Button style={{margin: "0 10px 10px 0"}} secondary invert>Secondary</Button>
<Button style={{margin: "0 10px 10px 0"}} secondary invert disabled>Secondary</Button>
<Button style={{marginBottom: "10px"}} primary fullWidth>Full Width</Button>
<Button style={{marginBottom: "10px"}} primary invert fullWidth>Full Width Invert</Button>
</Playground>
@@ -28,6 +28,8 @@ interface InnerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
/** If set renders a button with secondary colors */
secondary?: boolean;
innerRef?: React.RefObject<HTMLDivElement> | any;
}
class Button extends React.Component<InnerProps> {
@@ -39,6 +41,7 @@ class Button extends React.Component<InnerProps> {
invert,
primary,
secondary,
innerRef,
...rest
} = this.props;
@@ -53,6 +56,7 @@ class Button extends React.Component<InnerProps> {
<BaseButton
className={rootClassName}
classes={pick(classes, "keyboardFocus")}
innerRef={innerRef}
{...rest}
/>
);
@@ -1,6 +0,0 @@
.root {
display: flex;
align-items: center;
flex-direction: column;
}
@@ -1,30 +0,0 @@
import cn from "classnames";
import * as React from "react";
import { ReactNode, StatelessComponent } from "react";
import { withStyles } from "talk-ui/hocs";
import { PropTypesOf } from "talk-ui/types";
import * as styles from "./Center.css";
interface InnerProps {
/**
* This prop can be used to add custom classnames.
* It is handled by the `withStyles `HOC.
*/
classes: Partial<typeof styles>;
className?: string;
children: ReactNode;
}
const Center: StatelessComponent<InnerProps> = props => {
return (
<div className={cn(props.className, props.classes.root)}>
{props.children}
</div>
);
};
const enhanced = withStyles(styles)(Center);
export type CenterProps = PropTypesOf<typeof enhanced>;
export default enhanced;
@@ -1,2 +0,0 @@
export * from "./Center";
export { default } from "./Center";
@@ -0,0 +1,99 @@
.root {
display: flex;
}
.halfItemGutter {
& > * {
margin: 0 calc(0.5 * var(--spacing-unit)) 0 0;
}
&.directionRowReverse {
& > * {
margin: 0 0 0 calc(0.5 * var(--spacing-unit));
}
}
&.directionColumn {
& > * {
margin: 0 0 calc(0.5 * var(--spacing-unit)) 0;
}
}
&.directionColumnReverese {
& > * {
margin: calc(0.5 * var(--spacing-unit)) 0 0 0;
}
}
& > *:last-child {
margin: 0;
}
}
.itemGutter {
& > * {
margin: 0 var(--spacing-unit) 0 0;
}
&.directionRowReverse {
& > * {
margin: 0 0 0 var(--spacing-unit);
}
}
&.directionColumn {
& > * {
margin: 0 0 var(--spacing-unit) 0;
}
}
&.directionColumnReverese {
& > * {
margin: var(--spacing-unit) 0 0 0;
}
}
& > *:last-child {
margin: 0;
}
}
.justifyFlexStart {
justify-content: flex-start;
}
.justifyFlexEnd {
justify-content: flex-end;
}
.justifyCenter {
justify-content: center;
}
.justifySpaceBetween {
justify-content: space-between;
}
.justifySpaceAround {
justify-content: space-around;
}
.justifySpaceEvenly {
justify-content: space-evenly;
}
.alignFlexStart {
align-items: flex-start;
}
.alignFlexEnd {
align-items: flex-end;
}
.alignCenter {
align-items: center;
}
.alignBaseline {
align-items: baseline;
}
.alignStretch {
align-items: stretch;
}
.directionRow {
flex-direction: row;
}
.directionColumn {
flex-direction: column;
}
.directionRowReverse {
flex-direction: row-reverse;
}
.directionColumnReverse {
flex-direction: column-reverse;
}
@@ -0,0 +1,16 @@
---
name: Flex
menu: UI Kit
---
import { Playground, PropsTable } from 'docz'
import Flex from './Flex'
# Flex
`Flex` is a wrapper around `flexbox`.
## Basic usage
<Playground>
<Flex justifyContent="center">I'm centered</Flex>
</Playground>
@@ -0,0 +1,20 @@
import { shallow } from "enzyme";
import React from "react";
import { PropTypesOf } from "talk-ui/types";
import Flex from "./Flex";
it("renders correctly", () => {
const props: PropTypesOf<typeof Flex> = {
justifyContent: "center",
alignItems: "center",
direction: "row",
};
const wrapper = shallow(
<Flex {...props}>
<div>Hello World</div>
</Flex>
);
expect(wrapper).toMatchSnapshot();
});
@@ -0,0 +1,57 @@
import cn from "classnames";
import React from "react";
import { StatelessComponent } from "react";
import { pascalCase } from "talk-common/utils";
import * as styles from "./Flex.css";
interface InnerProps {
id?: string;
role?: string;
justifyContent?:
| "flex-start"
| "flex-end"
| "center"
| "space-around"
| "space-between"
| "space-evenly";
alignItems?: "flex-start" | "flex-end" | "center" | "baseline" | "stretch";
direction?: "row" | "column" | "row-reverse" | "column-reverse";
itemGutter?: boolean | "half";
className?: string;
}
const Flex: StatelessComponent<InnerProps> = props => {
const {
className,
justifyContent,
alignItems,
direction,
itemGutter,
...rest
} = props;
const classObject: Record<string, boolean> = {
[styles.itemGutter]: itemGutter === true,
[styles.halfItemGutter]: itemGutter === "half",
};
if (justifyContent) {
classObject[(styles as any)[`justify${pascalCase(justifyContent)}`]] = true;
}
if (alignItems) {
classObject[(styles as any)[`align${pascalCase(alignItems)}`]] = true;
}
if (direction) {
classObject[(styles as any)[`direction${pascalCase(direction)}`]] = true;
}
const classNames: string = cn(styles.root, className, classObject);
return <div className={classNames} {...rest} />;
};
export default Flex;
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders correctly 1`] = `
<div
className="Flex-root Flex-justifyCenter Flex-alignCenter Flex-directionRow"
>
<div>
Hello World
</div>
</div>
`;
@@ -0,0 +1,2 @@
export * from "./Flex";
export { default } from "./Flex";
@@ -0,0 +1,40 @@
---
name: MatchMedia
menu: UI Kit
---
import { Playground, PropsTable } from 'docz'
import MatchMedia from './MatchMedia'
# MatchMedia
`MatchMedia` uses media queries to provide responsive rendering.
## Basic usage
<Playground>
<MatchMedia maxWidth="xs">
I'm a very small screen
</MatchMedia>
<MatchMedia minWidth="xs" maxWidth="sm">
I'm a small screen
</MatchMedia>
<MatchMedia minWidth="sm" maxWidth="md">
I'm a medium screen
</MatchMedia>
<MatchMedia minWidth="md" maxWidth="lg">
I'm a large screen
</MatchMedia>
<MatchMedia minWidth="lg" maxWidth="xl">
I'm a very large screen
</MatchMedia>
<MatchMedia minWidth="xl">
I'm a super large screen
</MatchMedia>
</Playground>
## Using render props
<Playground>
<MatchMedia minWidth="lg">
{matches => <span>{matches ? "I'm big" : "I'm small"}</span>}
</MatchMedia>
</Playground>
@@ -0,0 +1,27 @@
import { shallow } from "enzyme";
import React from "react";
import { PropTypesOf } from "talk-ui/types";
import { MatchMedia } from "./MatchMedia";
it("renders correctly", () => {
const props: PropTypesOf<typeof MatchMedia> = {
minWidth: "xs",
maxWidth: "sm",
component: "div",
screen: true,
children: <div>Hello World</div>,
};
const wrapper = shallow(<MatchMedia {...props} />);
expect(wrapper).toMatchSnapshot();
});
it("map new speech prop to older aural prop", () => {
const props: PropTypesOf<typeof MatchMedia> = {
speech: true,
children: <div>Hello World</div>,
};
const wrapper = shallow(<MatchMedia {...props} />);
expect(wrapper).toMatchSnapshot();
});
@@ -0,0 +1,47 @@
import React from "react";
import { ReactNode, StatelessComponent } from "react";
import Responsive, { MediaQueryMatchers } from "react-responsive";
import theme from "../../theme/variables";
import UIContext from "../UIContext";
type Breakpoints = keyof typeof theme.breakpoints;
interface InnerProps {
minWidth?: Breakpoints;
maxWidth?: Breakpoints;
children: ReactNode | ((matches: boolean) => React.ReactNode);
className?: string;
component?:
| string
| React.SFC<any>
| React.ClassType<any, any, any>
| React.ComponentClass<any>;
all?: boolean;
print?: boolean;
screen?: boolean;
speech?: boolean;
values?: Partial<MediaQueryMatchers>;
}
export const MatchMedia: StatelessComponent<InnerProps> = props => {
const { speech, minWidth, maxWidth, ...rest } = props;
const mapped = {
// TODO: Temporarily map newer speech to older aural type until
// react-responsive supports the speech prop.
aural: speech,
minWidth: minWidth ? theme.breakpoints[minWidth] + 1 : undefined,
maxWidth: maxWidth ? theme.breakpoints[maxWidth] : undefined,
};
return <Responsive {...rest} {...mapped} />;
};
const MatchMediaWithContext: StatelessComponent<InnerProps> = props => (
<UIContext.Consumer>
{({ mediaQueryValues }) => (
<MatchMedia {...props} values={mediaQueryValues} />
)}
</UIContext.Consumer>
);
export default MatchMediaWithContext;
@@ -0,0 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`map new speech prop to older aural prop 1`] = `
<MediaQuery
aural={true}
values={Object {}}
>
<div>
Hello World
</div>
</MediaQuery>
`;
exports[`renders correctly 1`] = `
<MediaQuery
component="div"
maxWidth={640}
minWidth={321}
screen={true}
values={Object {}}
>
<div>
Hello World
</div>
</MediaQuery>
`;
@@ -0,0 +1,2 @@
export * from "./MatchMedia";
export { default } from "./MatchMedia";
@@ -0,0 +1,15 @@
.root {
padding: 6px 10px;
background: #ffffff !important;
border: 1px solid #c9cacb;
box-sizing: border-box;
box-shadow: 1px 0px 4px rgba(0, 0, 0, 0.25);
border-radius: 1px;
color: #222 !important;
display: flex !important;
&:after,
&::before {
border-top-color: transparent !important;
}
}
@@ -0,0 +1,42 @@
import React from "react";
import { RefHandler } from "react-popper";
import Attachment from "../Attachment";
import * as styles from "./Popover.css";
interface RenderProps {
toggleShow?: () => void;
ref?: RefHandler;
}
interface InnerProps {
body: React.ReactElement<any> | null;
children: (props: RenderProps) => any;
}
interface State {
show: false;
}
class Popover extends React.Component<InnerProps> {
public state: State = {
show: false,
};
public toggleShow = () => {
this.setState((state: State) => ({
show: !state.show,
}));
};
public render() {
const { body, children } = this.props;
const { show } = this.state;
return (
<Attachment body={show ? body : null} className={styles.root}>
{({ ref }) => children({ toggleShow: this.toggleShow, ref })}
</Attachment>
);
}
}
export default Popover;
@@ -0,0 +1,2 @@
export * from "./Popover";
export { default } from "./Popover";
@@ -0,0 +1,4 @@
.root {
composes: body1 from "talk-ui/shared/typography.css";
background-color: transparent;
}
@@ -0,0 +1,17 @@
---
name: RelativeTime
menu: UI Kit
---
import { Playground } from 'docz'
import RelativeTime from './RelativeTime'
# RelativeTime
Renders relative time until given `date`.
## Basic usage
<Playground>
<RelativeTime date="2018-07-04T12:14"
formatter={(value, unit, suffix, timestamp) => "".concat(value, " ", unit, " ", suffix)} />
</Playground>
@@ -0,0 +1,42 @@
import React from "react";
import { create } from "react-test-renderer";
import { PropTypesOf } from "talk-ui/types";
import UIContext from "../UIContext";
import RelativeTime from "./RelativeTime";
it("uses default formatter", () => {
const props = {
date: "2018-12-17T03:24:00.000Z",
};
const tree = create(<RelativeTime {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});
it("uses formatter from context", () => {
const context: any = {
timeagoFormatter: () => "My Context Formatter",
};
const props: PropTypesOf<typeof RelativeTime> = {
date: "2018-12-17T03:24:00.000Z",
};
const tree = create(
<UIContext.Provider value={context}>
<RelativeTime {...props} />
</UIContext.Provider>
).toJSON();
expect(tree).toMatchSnapshot();
});
it("uses formatter from props", () => {
const props = {
date: "2018-12-17T03:24:00.000Z",
formatter: () => "My Props Formatter",
};
const tree = create(<RelativeTime {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});
@@ -0,0 +1,42 @@
import cn from "classnames";
import React from "react";
import TimeAgo, { Formatter } from "react-timeago";
import { UIContext } from "talk-ui/components";
import { withStyles } from "talk-ui/hocs";
import { PropTypesOf } from "talk-ui/types";
import * as styles from "./RelativeTime.css";
interface InnerProps {
date: string;
live?: boolean;
classes: typeof styles;
className?: string;
formatter?: Formatter;
}
const defaultFormatter: Formatter = (value, unit, suffix, timestamp: string) =>
new Date(timestamp).toISOString();
class RelativeTime extends React.Component<InnerProps> {
public render() {
const { date, classes, live, className, formatter } = this.props;
return (
<UIContext.Consumer>
{({ timeagoFormatter }) => (
<TimeAgo
date={date}
className={cn(className, classes.root)}
live={live}
formatter={timeagoFormatter || formatter || defaultFormatter}
/>
)}
</UIContext.Consumer>
);
}
}
const enhanced = withStyles(styles)(RelativeTime);
export type RelativeTimeProps = PropTypesOf<typeof enhanced>;
export default enhanced;
@@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`uses default formatter 1`] = `
<time
className="RelativeTime-root"
dateTime="2018-12-17T03:24:00.000Z"
title="2018-12-17T03:24:00.000Z"
>
2018-12-17T03:24:00.000Z
</time>
`;
exports[`uses formatter from context 1`] = `
<time
className="RelativeTime-root"
dateTime="2018-12-17T03:24:00.000Z"
title="2018-12-17T03:24:00.000Z"
>
My Context Formatter
</time>
`;
exports[`uses formatter from props 1`] = `
<time
className="RelativeTime-root"
dateTime="2018-12-17T03:24:00.000Z"
title="2018-12-17T03:24:00.000Z"
>
My Context Formatter
</time>
`;
@@ -0,0 +1,2 @@
export * from "./RelativeTime";
export { default } from "./RelativeTime";
@@ -0,0 +1,11 @@
.root {
font-family: "Source Sans Pro";
font-weight: 400;
font-size: 16px;
letter-spacing: calc(0.57em / 16);
background: #ffffff;
border: 1px solid #979797;
box-sizing: border-box;
border-radius: 1px;
padding: 5px 20px;
}
@@ -0,0 +1 @@
export const root: string;
@@ -0,0 +1,14 @@
import cn from "classnames";
import React, { InputHTMLAttributes, StatelessComponent } from "react";
import * as styles from "./TextField.css";
interface InnerProps extends InputHTMLAttributes<HTMLInputElement> {
classes?: typeof styles;
}
const Input: StatelessComponent<InnerProps> = ({ className, ...rest }) => {
return <input {...rest} className={cn(styles.root, className)} />;
};
export default Input;
@@ -0,0 +1,2 @@
export * from "./TextField";
export { default } from "./TextField";
@@ -11,19 +11,19 @@
composes: heading2 from "talk-ui/shared/typography.css";
}
.heading3 {
.heading3 {
composes: heading3 from "talk-ui/shared/typography.css";
}
.heading4 {
.heading4 {
composes: heading4 from "talk-ui/shared/typography.css";
}
.subtitle1 {
.subtitle1 {
composes: subtitle1 from "talk-ui/shared/typography.css";
}
.subtitle2 {
.subtitle2 {
composes: subtitle2 from "talk-ui/shared/typography.css";
}
@@ -31,7 +31,7 @@
composes: body1 from "talk-ui/shared/typography.css";
}
.body2 {
.body2 {
composes: body2 from "talk-ui/shared/typography.css";
}
@@ -43,6 +43,10 @@
composes: overline from "talk-ui/shared/typography.css";
}
.timestamp {
composes: timestamp from "talk-ui/shared/typography.css";
}
.alignLeft {
text-align: left;
}
@@ -70,7 +74,7 @@
}
.paragraph {
margin-bottom: calc(2px * $spacing-unit);
margin-bottom: var(--spacing-unit);
}
.colorInherit {
@@ -78,17 +82,17 @@
}
.colorPrimary {
color: $palette-primary-main;
color: var(--palette-primary-main);
}
.colorSecondary {
color: $palette-secondary-main;
color: var(--palette-secondary-main);
}
.colorTextSecondary {
color: $palette-text-secondary;
color: var(--palette-text-secondary);
}
.colorError {
color: $palette-error-main;
color: var(--palette-error-main);
}
@@ -16,7 +16,8 @@ type Variant =
| "subtitle2"
| "body1"
| "body2"
| "button";
| "button"
| "timestamp";
// Based on Typography Component of Material UI.
// https://github.com/mui-org/material-ui/blob/303199d39b42a321d28347d8440d69166f872f27/packages/material-ui/src/Typography/Typography.js
@@ -99,6 +100,8 @@ const Typography: StatelessComponent<InnerProps> = props => {
{
[classes.colorPrimary]: color === "primary",
[classes.colorSecondary]: color === "secondary",
[classes.colorError]: color === "error",
[classes.colorTextSecondary]: color === "textSecondary",
[classes.noWrap]: noWrap,
[classes.gutterBottom]: gutterBottom,
[classes.paragraph]: paragraph,
@@ -129,6 +132,7 @@ Typography.defaultProps = {
subtitle2: "h3",
body1: "p",
body2: "aside",
timestamp: "span",
},
noWrap: false,
paragraph: false,
@@ -0,0 +1,12 @@
import React from "react";
import { MediaQueryMatchers } from "react-responsive";
import { Formatter } from "react-timeago";
export interface UIContextProps {
timeagoFormatter?: Formatter | null;
mediaQueryValues?: Partial<MediaQueryMatchers>;
}
const UIContext = React.createContext<UIContextProps>({} as any);
export default UIContext;
@@ -0,0 +1 @@
export { default, UIContextProps } from "./UIContext";
+6 -1
View File
@@ -1,4 +1,9 @@
export { default as BaseButton } from "./BaseButton";
export { default as Button } from "./Button";
export { default as Center } from "./Center";
export { default as Typography } from "./Typography";
export { default as Popover } from "./Popover";
export { default as TextField } from "./TextField";
export { default as RelativeTime } from "./RelativeTime";
export { default as UIContext, UIContextProps } from "./UIContext";
export { default as Flex } from "./Flex";
export { default as MatchMedia } from "./MatchMedia";
@@ -0,0 +1,22 @@
import React from "react";
import {
InferableComponentEnhancerWithProps,
withPropsOnChange,
} from "recompose";
/**
* withForwardRef provides a property called `forwardRef` using
* the `React.forwardRef` api.
*/
function withForwardRef<T>(): InferableComponentEnhancerWithProps<
{ forwardRef: Ref<any> },
{}
> {
return WrappedComponent => {
return React.forwardRef((props, ref) => (
<WrappedComponent forwardRef={ref} />
));
};
}
export default withForwardRef;
+34 -21
View File
@@ -1,59 +1,72 @@
.heading1 {
font-size: calc(24rem / $rem-base);
font-weight: $font-weight-medium;
font-size: calc(24rem / var(--rem-base));
font-weight: var(--font-weight-medium);
font-family: "Manuale";
line-height: calc(32em / 24);
letter-spacing: calc(0.2em / 16);
color: $palette-text-primary;
color: var(--palette-text-primary);
}
.heading2 {
font-size: calc(20rem / $rem-base);
font-weight: $font-weight-medium;
font-size: calc(20rem / var(--rem-base));
font-weight: var(--font-weight-medium);
font-family: "Manuale";
line-height: calc(24em / 20);
color: $palette-text-primary;
color: var(--palette-text-primary);
}
.heading3 {
font-size: calc(18rem / $rem-base);
font-weight: $font-weight-medium;
font-size: calc(18rem / var(--rem-base));
font-weight: var(--font-weight-medium);
font-family: "Manuale";
line-height: calc(20em / 18);
letter-spacing: calc(0.2em / 16);
color: $palette-text-primary;
color: var(--palette-text-primary);
}
.heading4 {
font-size: calc(16rem / $rem-base);
font-weight: $font-weight-medium;
font-size: calc(16rem / var(--rem-base));
font-weight: var(--font-weight-medium);
font-family: "Manuale";
line-height: calc(18em / 16);
letter-spacing: calc(0.2em / 16);
color: $palette-text-primary;
color: var(--palette-text-primary);
}
.subtitle1 {}
.subtitle1 {
}
.subtitle2 {}
.subtitle2 {
}
.body2 {}
.body2 {
}
.body1 {
font-size: calc(16rem / $rem-base);
font-weight: $font-weight-regular;
font-size: calc(16rem / var(--rem-base));
font-weight: var(--font-weight-regular);
font-family: "Source Sans Pro";
line-height: calc(18em / 16);
letter-spacing: calc(0.2em / 16);
color: $palette-text-primary;
color: var(--palette-text-primary);
}
.button {
color: $palette-text-secondary;
color: var(--palette-text-secondary);
font-family: "Source Sans Pro";
font-weight: $font-weight-medium;
font-weight: var(--font-weight-medium);
font-size: 16px;
letter-spacing: calc(0.57em / 16);
}
.overline {}
.overline {
}
.timestamp {
color: var(--palette-text-secondary);
font-family: "Source Sans Pro";
font-weight: var(--font-weight-medium);
font-size: 14px;
line-height: calc(18em / 16);
letter-spacing: calc(0.2em / 16);
}
+16
View File
@@ -0,0 +1,16 @@
/*
Variables defined in `variables.ts` are already available
flattened and in kebab case.
These are additionally variables we define.
*/
:root {
--spacing-unit: calc(1px * var(--spacing-unit-small));
}
@media (min-width: $breakpoints-xs) {
:root {
--spacing-unit: calc(1px * var(--spacing-unit-large));
}
}
+15 -6
View File
@@ -7,7 +7,7 @@ const variables = {
palette: {
/* Primary colors */
primary: {
darker: "#0D5B8F",
darkest: "#0D5B8F",
dark: "#2B7EB5",
main: "#3498DB",
light: "#67B2E4",
@@ -15,7 +15,7 @@ const variables = {
},
/* Secondary colors */
secondary: {
darker: "#404345",
darkest: "#404345",
dark: "#65696B",
main: "#787D80",
light: "#9A9DA0",
@@ -23,7 +23,7 @@ const variables = {
},
/* Success colors */
success: {
darker: "#03AB61",
darkest: "#03AB61",
dark: "#02BD6B",
main: "#00CD73",
light: "#40D996",
@@ -31,7 +31,7 @@ const variables = {
},
/* Error colors */
error: {
darker: "#F50F0C",
darkest: "#F50F0C",
dark: "#FF1F1C",
main: "#FA4643",
light: "#F26563",
@@ -58,7 +58,8 @@ const variables = {
},
},
/* gitter and spacing */
spacingUnit: 5,
spacingUnitSmall: 5,
spacingUnitLarge: 10,
/* Borders */
roundCorners: "2px",
/* Typography */
@@ -68,6 +69,14 @@ const variables = {
fontWeightLight: 300,
fontWeightRegular: 400,
fontWeightMedium: 550,
/* Breakpoints */
breakpoints: {
xs: 320,
sm: 640,
md: 1024,
lg: 1400,
xl: 1600,
},
};
module.exports = variables;
export default variables;
+3 -1
View File
@@ -29,4 +29,6 @@ export type Overwrite<T, U> = Pick<T, Diff<keyof T, keyof U>> & U;
*
* E.g. type ButtonProps = ReturnPropTypes<Button>;
*/
export type PropTypesOf<T> = T extends React.ComponentType<infer R> ? R : {};
export type PropTypesOf<T> = T extends React.ComponentType<infer R>
? R
: T extends React.Component<infer S> ? S : {};