Merge branch 'next' into next-passport

This commit is contained in:
Wyatt Johnson
2018-07-23 16:09:24 +00:00
committed by GitHub
19 changed files with 173 additions and 79 deletions
@@ -2,7 +2,7 @@
exports[`renders correctly on big screens 1`] = `
<div
className="Flex-root TopBar-root Flex-itemGutter Flex-alignCenter Flex-directionRow"
className="Flex-root TopBar-root Flex-itemGutter Flex-alignBaseline Flex-directionRow"
>
<div>
Hello World
@@ -43,12 +43,12 @@ exports[`loads more comments 1`] = `
</form>
<div
aria-live="polite"
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
id="talk-comments-stream-log"
role="log"
>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -77,7 +77,7 @@ exports[`loads more comments 1`] = `
</div>
</div>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -106,7 +106,7 @@ exports[`loads more comments 1`] = `
</div>
</div>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -182,12 +182,12 @@ exports[`renders comment stream 1`] = `
</form>
<div
aria-live="polite"
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
id="talk-comments-stream-log"
role="log"
>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -216,7 +216,7 @@ exports[`renders comment stream 1`] = `
</div>
</div>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -43,12 +43,12 @@ exports[`renders comment stream 1`] = `
</form>
<div
aria-live="polite"
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
id="talk-comments-stream-log"
role="log"
>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -77,7 +77,7 @@ exports[`renders comment stream 1`] = `
</div>
</div>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -108,7 +108,7 @@ exports[`renders comment stream 1`] = `
className="Indent-root Indent-level0"
>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
id="talk-comments-replyList-log--comment-with-replies"
role="log"
>
@@ -43,12 +43,12 @@ exports[`renders comment stream 1`] = `
</form>
<div
aria-live="polite"
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
id="talk-comments-stream-log"
role="log"
>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -77,7 +77,7 @@ exports[`renders comment stream 1`] = `
</div>
</div>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -43,12 +43,12 @@ exports[`renders comment stream 1`] = `
</form>
<div
aria-live="polite"
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
id="talk-comments-stream-log"
role="log"
>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -79,7 +79,7 @@ exports[`renders comment stream 1`] = `
className="Indent-root Indent-level0"
>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
id="talk-comments-replyList-log--comment-0"
role="log"
>
@@ -174,12 +174,12 @@ exports[`show all replies 1`] = `
</form>
<div
aria-live="polite"
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
id="talk-comments-stream-log"
role="log"
>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
>
<div
role="article"
@@ -210,7 +210,7 @@ exports[`show all replies 1`] = `
className="Indent-root Indent-level0"
>
<div
className="Flex-root Flex-itemGutter Flex-directionColumn"
className="Flex-root Flex-itemGutter Flex-alignFlexStart Flex-directionColumn"
id="talk-comments-replyList-log--comment-0"
role="log"
>
@@ -0,0 +1,17 @@
---
name: AriaInfo
menu: UI Kit
---
import { Playground, PropsTable } from 'docz'
import AriaInfo from './AriaInfo'
# AriaInfo
Renders Text that is only seen by screen readers.
## Basic usage
<Playground>
<AriaInfo>This can only be seen by screen readers</AriaInfo>
<div>Above this line is a hidden text that you can't see</div>
</Playground>
@@ -0,0 +1,10 @@
.root {
position: absolute !important;
width: 1px;
height: 1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
@@ -0,0 +1,14 @@
import React from "react";
import TestRenderer from "react-test-renderer";
import { PropTypesOf } from "talk-framework/types";
import AriaInfo from "./AriaInfo";
it("renders correctly", () => {
const props: PropTypesOf<typeof AriaInfo> = {
children: "This text is only for screen readers",
};
const renderer = TestRenderer.create(<AriaInfo {...props} />);
expect(renderer.toJSON()).toMatchSnapshot();
});
@@ -0,0 +1,32 @@
import cn from "classnames";
import React, { HTMLAttributes, StatelessComponent } from "react";
import { withForwardRef, withStyles } from "talk-ui/hocs";
import { PropTypesOf } from "talk-ui/types";
import * as styles from "./AriaInfo.css";
interface InnerProps extends HTMLAttributes<HTMLElement> {
/**
* This prop can be used to add custom classnames.
* It is handled by the `withStyles `HOC.
*/
classes: typeof styles;
component?: string;
children: React.ReactNode;
}
const AriaInfo: StatelessComponent<InnerProps> = props => {
const { component, className, classes, ...rest } = props;
const Component = component!;
const rootClassName = cn(classes.root, className);
return <Component className={rootClassName} {...rest} />;
};
AriaInfo.defaultProps = {
component: "div",
};
const enhanced = withForwardRef(withStyles(styles)(AriaInfo));
export type AriaInfoProps = PropTypesOf<typeof enhanced>;
export default enhanced;
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders correctly 1`] = `
<div
className="AriaInfo-root"
>
This text is only for screen readers
</div>
`;
@@ -0,0 +1 @@
export { default, AriaInfoProps } from "./AriaInfo";
@@ -2,7 +2,7 @@
border-radius: var(--round-corners);
background-color: transparent;
position: relative;
display: flex;
display: inline-flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
+3 -2
View File
@@ -47,8 +47,9 @@ const Flex: StatelessComponent<InnerProps> = props => {
} = props;
let alignItemsWithDefault = alignItems;
if (!direction || !direction.startsWith("column")) {
alignItemsWithDefault = "center";
if (!alignItems) {
alignItemsWithDefault =
direction && direction.startsWith("column") ? "flex-start" : "center";
}
const classObject: Record<string, boolean> = {
@@ -9,7 +9,7 @@ it("renders correctly", () => {
{({ toggleShow, show }) => (
<div>
{show && <div>SHOW ME</div>}
<button onClick={toggleShow}>Click me and I disapear</button>
<button onClick={toggleShow}>Click me and I disappear</button>
</div>
)}
</ToggleShow>
@@ -5,18 +5,22 @@ menu: UI Kit
import { Playground } from 'docz'
import ToggleShow from './ToggleShow'
import Button from '../Button'
import Flex from '../Flex'
# ToggleShow
A Component that provides a render function to display nodes
A render props component to manage visible state.
## Basic usage
<Playground>
<ToggleShow>
{({ toggleShow, show }) => (
<div>
{show && <div>SHOW ME</div>}
<button onClick={toggleShow}>ClickMe and I disapear</button>
</div>
<Flex itemGutter direction="column">
{show && <div>Hello World!</div>}
<Button onClick={toggleShow} variant="filled" color="primary">
Toggle Show
</Button>
</Flex>
)}
</ToggleShow>
</Playground>
@@ -8,7 +8,7 @@ exports[`renders correctly 1`] = `
<button
onClick={[Function]}
>
Click me and I disapear
Click me and I disappear
</button>
</div>
`;
@@ -5,6 +5,7 @@ menu: UI Kit
import { Playground } from 'docz'
import TrapFocus from './TrapFocus'
import Button from '../Button'
# TrapFocus
@@ -12,28 +13,15 @@ Traps focus inside component when using keyboard navigation for accessibility pu
## Basic usage
```ts
import React from "react";
class Dialog extends React.Component {
private firstFocusable: HTMLElement;
private lastFocusable: HTMLElement;
private setFirstFocusable = (ref: HTMLElement) => (this.firstFocusable = ref);
private setLastFocusable = (ref: HTMLElement) => (this.lastFocusable = ref);
public render() {
return (
<Playground>
<div>
<TrapFocus>
{({firstFocusableRef, lastFocusableRef}) =>
<div>
<TrapFocus
firstFocusable={this.firstFocusable}
lastFocusable={this.lastFocusable}
>
<TextField ref={this.setFirstFocusable} />
<Button ref={this.setLastFocusable}>Send</Button>
</TrapFocus>
<Button forwardRef={firstFocusableRef} autoFocus>Cancel</Button>
<Button forwardRef={lastFocusableRef}>Send</Button>
</div>
);
}
}
```
}
</TrapFocus>
</div>
</Playground>
@@ -5,11 +5,16 @@ import Sinon from "sinon";
import { PropTypesOf } from "talk-ui/types";
import TrapFocus from "./TrapFocus";
const FakeFocusable: any = class extends React.Component {
public focus = Sinon.spy();
public render() {
return null;
}
};
it("renders correctly", () => {
const props: PropTypesOf<TrapFocus> = {
firstFocusable: null,
lastFocusable: null,
children: (
children: () => (
<>
<span>child1</span>
<span>child2</span>
@@ -25,15 +30,13 @@ it("renders correctly", () => {
});
it("Change focus to `lastFocusable` when focus reaches beginning", () => {
const fakeHTMLElementBegin = { focus: Sinon.spy() };
const fakeHTMLElementEnd = { focus: Sinon.spy() };
const props: PropTypesOf<TrapFocus> = {
firstFocusable: fakeHTMLElementBegin as any,
lastFocusable: fakeHTMLElementEnd as any,
children: (
children: ({ firstFocusableRef, lastFocusableRef }) => (
<>
<FakeFocusable ref={firstFocusableRef} />
<span>child1</span>
<span>child2</span>
<FakeFocusable ref={lastFocusableRef} />
</>
),
};
@@ -43,20 +46,22 @@ it("Change focus to `lastFocusable` when focus reaches beginning", () => {
</div>
);
renderer.root.findAllByProps({ tabIndex: 0 })[0].props.onFocus();
expect(fakeHTMLElementBegin.focus.called).toBe(false);
expect(fakeHTMLElementEnd.focus.called).toBe(true);
expect(
renderer.root.findAllByType(FakeFocusable)[0].instance.focus.called
).toBe(false);
expect(
renderer.root.findAllByType(FakeFocusable)[1].instance.focus.called
).toBe(true);
});
it("Change focus to `firstFocusable` when focus reaches the end", () => {
const fakeHTMLElementBegin = { focus: Sinon.spy() };
const fakeHTMLElementEnd = { focus: Sinon.spy() };
it("Change focus to `firstFocusable` when focus reaches end", () => {
const props: PropTypesOf<TrapFocus> = {
firstFocusable: fakeHTMLElementBegin as any,
lastFocusable: fakeHTMLElementEnd as any,
children: (
children: ({ firstFocusableRef, lastFocusableRef }) => (
<>
<FakeFocusable ref={firstFocusableRef} />
<span>child1</span>
<span>child2</span>
<FakeFocusable ref={lastFocusableRef} />
</>
),
};
@@ -66,6 +71,10 @@ it("Change focus to `firstFocusable` when focus reaches the end", () => {
</div>
);
renderer.root.findAllByProps({ tabIndex: 0 })[1].props.onFocus();
expect(fakeHTMLElementBegin.focus.called).toBe(true);
expect(fakeHTMLElementEnd.focus.called).toBe(false);
expect(
renderer.root.findAllByType(FakeFocusable)[0].instance.focus.called
).toBe(true);
expect(
renderer.root.findAllByType(FakeFocusable)[1].instance.focus.called
).toBe(false);
});
@@ -1,25 +1,34 @@
import React from "react";
import React, { RefObject } from "react";
export interface Focusable {
focus: () => void;
}
interface RenderProps {
firstFocusableRef: RefObject<Focusable>;
lastFocusableRef: RefObject<Focusable>;
}
export interface TrapFocusProps {
firstFocusable: Focusable | null;
lastFocusable: Focusable | null;
children: React.ReactNode;
children: (props: RenderProps) => React.ReactNode;
}
export default class TrapFocus extends React.Component<TrapFocusProps> {
private firstFocusableRef = React.createRef<Focusable>();
private lastFocusableRef = React.createRef<Focusable>();
// Trap keyboard focus inside the dropdown until a value has been chosen.
public focusBegin = () => this.props.firstFocusable!.focus();
public focusEnd = () => this.props.lastFocusable!.focus();
private focusBegin = () => this.firstFocusableRef.current!.focus();
private focusEnd = () => this.lastFocusableRef.current!.focus();
public render() {
return (
<>
<div tabIndex={0} onFocus={this.focusEnd} />
{this.props.children}
{this.props.children({
firstFocusableRef: this.firstFocusableRef,
lastFocusableRef: this.lastFocusableRef,
})}
<div tabIndex={0} onFocus={this.focusBegin} />
</>
);