Skip to content

Commit

Permalink
fix: Fix Composite on IE11 (#609)
Browse files Browse the repository at this point in the history
  • Loading branch information
diegohaz committed Apr 6, 2020
1 parent 417b3b3 commit 555b931
Show file tree
Hide file tree
Showing 22 changed files with 660 additions and 215 deletions.
6 changes: 5 additions & 1 deletion packages/reakit-playground/src/__deps/reakit-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export default {
"reakit-utils/toArray": require("reakit-utils/toArray"),
"reakit-utils/tabbable": require("reakit-utils/tabbable"),
"reakit-utils/splitProps": require("reakit-utils/splitProps"),
"reakit-utils/scrollIntoViewIfNeeded": require("reakit-utils/scrollIntoViewIfNeeded"),
"reakit-utils/removeItemFromArray": require("reakit-utils/removeItemFromArray"),
"reakit-utils/removeIndexFromArray": require("reakit-utils/removeIndexFromArray"),
"reakit-utils/pick": require("reakit-utils/pick"),
Expand All @@ -29,10 +28,15 @@ export default {
"reakit-utils/isButton": require("reakit-utils/isButton"),
"reakit-utils/hasFocusWithin": require("reakit-utils/hasFocusWithin"),
"reakit-utils/getDocument": require("reakit-utils/getDocument"),
"reakit-utils/getDefaultView": require("reakit-utils/getDefaultView"),
"reakit-utils/getActiveElement": require("reakit-utils/getActiveElement"),
"reakit-utils/flatten": require("reakit-utils/flatten"),
"reakit-utils/fireKeyboardEvent": require("reakit-utils/fireKeyboardEvent"),
"reakit-utils/fireEvent": require("reakit-utils/fireEvent"),
"reakit-utils/cx": require("reakit-utils/cx"),
"reakit-utils/createOnKeyDown": require("reakit-utils/createOnKeyDown"),
"reakit-utils/createKeyboardEvent": require("reakit-utils/createKeyboardEvent"),
"reakit-utils/createEvent": require("reakit-utils/createEvent"),
"reakit-utils/closest": require("reakit-utils/closest"),
"reakit-utils/applyState": require("reakit-utils/applyState")
};
13 changes: 6 additions & 7 deletions packages/reakit-system/src/createHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ export function createHook<O, P>(options: CreateHookOptions<O, P>) {
if (options.useComposeProps) {
htmlProps = options.useComposeProps(hookOptions, htmlProps);
} else {
composedHooks.forEach(hook => {
for (const hook of composedHooks) {
htmlProps = hook(hookOptions, htmlProps, true);
});
}
}
}
return htmlProps;
return htmlProps || ({} as P);
};

if (process.env.NODE_ENV !== "production" && options.name) {
Expand All @@ -118,10 +118,9 @@ export function createHook<O, P>(options: CreateHookOptions<O, P>) {
...(options.keys || [])
];

const hasPropsAreEqual = Boolean(
options.propsAreEqual ||
composedHooks.find(hook => Boolean(hook.__propsAreEqual))
);
const hasPropsAreEqual =
!!options.propsAreEqual ||
composedHooks.some(hook => !!hook.__propsAreEqual);

if (hasPropsAreEqual) {
useHook.__propsAreEqual = (prev, next) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/reakit-test-utils/src/__tests__/focus-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ test("focus", async () => {
Array [
"focus button1",
"focusin button1",
"blur button1",
"focusout button1",
"blur button1",
"focus button2",
"focusin button2",
]
Expand Down
76 changes: 38 additions & 38 deletions packages/reakit-test-utils/src/__tests__/press-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,30 +226,30 @@ test("press tab", async () => {
expect(button2).toHaveFocus();

expect(stack).toMatchInlineSnapshot(`
Array [
"focus button1",
"focusin button1",
"keyup button1",
"keydown button1",
"blur button1",
"focusout button1",
"focus button2",
"focusin button2",
"keyup button2",
"keydown button2",
"blur button2",
"focusout button2",
"focus button1",
"focusin button1",
"keyup button1",
"keydown button1",
"blur button1",
"focusout button1",
"focus button2",
"focusin button2",
"keyup button2",
]
`);
Array [
"focus button1",
"focusin button1",
"keyup button1",
"keydown button1",
"focusout button1",
"blur button1",
"focus button2",
"focusin button2",
"keyup button2",
"keydown button2",
"focusout button2",
"blur button2",
"focus button1",
"focusin button1",
"keyup button1",
"keydown button1",
"focusout button1",
"blur button1",
"focus button2",
"focusin button2",
"keyup button2",
]
`);
});

test("press tab preventDefault", async () => {
Expand Down Expand Up @@ -288,18 +288,18 @@ test("press tab preventDefault", async () => {
expect(button2).toHaveFocus();

expect(stack).toMatchInlineSnapshot(`
Array [
"focus button1",
"focusin button1",
"keyup button1",
"keydown button1",
"keyup button1",
"keydown button1",
"blur button1",
"focusout button1",
"focus button2",
"focusin button2",
"keyup button2",
]
`);
Array [
"focus button1",
"focusin button1",
"keyup button1",
"keydown button1",
"keyup button1",
"keydown button1",
"focusout button1",
"blur button1",
"focus button2",
"focusin button2",
"keyup button2",
]
`);
});
17 changes: 14 additions & 3 deletions packages/reakit-test-utils/src/focus.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import { isFocusable, getActiveElement } from "reakit-utils";
import { DirtiableElement } from "./__utils/types";
import { fireEvent } from "./fireEvent";
import { act } from "./act";
import { blur } from "./blur";

import "./mockClientRects";

export function focus(element: Element) {
if (getActiveElement(element) === element) return;
if (!isFocusable(element)) return;
blur();

const activeElement = getActiveElement(element) as DirtiableElement | null;

if (activeElement?.dirty) {
fireEvent.change(activeElement);
activeElement.dirty = false;
}

if (activeElement) {
fireEvent.focusOut(activeElement, { relatedTarget: element });
}

act(() => {
if (element instanceof HTMLElement || element instanceof SVGElement) {
element.focus();
}
});
fireEvent.focusIn(element);
fireEvent.focusIn(element, { relatedTarget: activeElement });
}
6 changes: 5 additions & 1 deletion packages/reakit-utils/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
/toArray
/tabbable
/splitProps
/scrollIntoViewIfNeeded
/removeItemFromArray
/removeIndexFromArray
/pick
Expand All @@ -30,9 +29,14 @@
/isButton
/hasFocusWithin
/getDocument
/getDefaultView
/getActiveElement
/flatten
/fireKeyboardEvent
/fireEvent
/cx
/createOnKeyDown
/createKeyboardEvent
/createEvent
/closest
/applyState
121 changes: 101 additions & 20 deletions packages/reakit-utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,15 @@ yarn add reakit-utils

- [applyState](#applystate)
- [closest](#closest)
- [createEvent](#createevent)
- [createKeyboardEvent](#createkeyboardevent)
- [createOnKeyDown](#createonkeydown)
- [cx](#cx)
- [fireEvent](#fireevent)
- [fireKeyboardEvent](#firekeyboardevent)
- [flatten](#flatten)
- [getActiveElement](#getactiveelement)
- [getDefaultView](#getdefaultview)
- [getDocument](#getdocument)
- [hasFocusWithin](#hasfocuswithin)
- [isButton](#isbutton)
Expand All @@ -44,7 +49,6 @@ yarn add reakit-utils
- [pick](#pick)
- [removeIndexFromArray](#removeindexfromarray)
- [removeItemFromArray](#removeitemfromarray)
- [scrollIntoViewIfNeeded](#scrollintoviewifneeded)
- [splitProps](#splitprops)
- [tabbable](#tabbable)
- [toArray](#toarray)
Expand Down Expand Up @@ -95,6 +99,48 @@ closest(document.getElementById("id"), "div");
document.getElementById("id").closest("div");
```

### createEvent

Creates an `Event` in a way that also works on IE 11.

#### Parameters

- `element` **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)**
- `type` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `eventInit` **EventInit** (optional, default `{}`)

#### Examples

```javascript
import { createEvent } from "reakit-utils";

const el = document.getElementById("id");
el.dispatchEvent(createEvent(el, "blur", { bubbles: false }));
```

Returns **[Event](https://developer.mozilla.org/docs/Web/API/Event)**

### createKeyboardEvent

Creates a `KeyboardEvent` in a way that also works on IE 11.

#### Parameters

- `element` **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)**
- `type` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `eventInit` **KeyboardEventInit** (optional, default `{}`)

#### Examples

```javascript
import { createKeyboardEvent } from "reakit-utils";

const el = document.getElementById("id");
el.dispatchEvent(createKeyboardEvent(el, "keydown", { key: "ArrowDown" }));
```

Returns **[KeyboardEvent](https://developer.mozilla.org/docs/Web/API/KeyboardEvent)**

### createOnKeyDown

Returns an `onKeyDown` handler to be passed to a component.
Expand Down Expand Up @@ -129,6 +175,50 @@ const className = cx("a", "b", false, true && "c");

Returns **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))**

### fireEvent

Creates and dispatches `Event` in a way that also works on IE 11.

#### Parameters

- `element` **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)**
- `type` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `eventInit` **EventInit**

#### Examples

```javascript
import { fireEvent } from "reakit-utils";

fireEvent(
document.getElementById("id"),
"blur",
{ bubbles: true, cancelable: true }
);
```

### fireKeyboardEvent

Creates and dispatches `KeyboardEvent` in a way that also works on IE 11.

#### Parameters

- `element` **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)**
- `type` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `eventInit` **KeyboardEventInit**

#### Examples

```javascript
import { fireKeyboardEvent } from "reakit-utils";

fireKeyboardEvent(
document.getElementById("id"),
"keydown",
{ key: "ArrowDown", shiftKey: true }
);
```

### flatten

Transforms an array with multiple levels into a flattened one.
Expand All @@ -154,6 +244,16 @@ Returns `element.ownerDocument.activeElement`.

- `element` **([Element](https://developer.mozilla.org/docs/Web/API/Element) \| [Document](https://developer.mozilla.org/docs/Web/API/Document) | null)?**

### getDefaultView

Returns `element.ownerDocument.defaultView || window`.

#### Parameters

- `element` **[Element](https://developer.mozilla.org/docs/Web/API/Element)?**

Returns **[Window](https://developer.mozilla.org/docs/Web/API/Window)**

### getDocument

Returns `element.ownerDocument || window.document`.
Expand Down Expand Up @@ -382,25 +482,6 @@ removeItemFromArray([obj], obj); // []

Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** A new array without the passed item.

### scrollIntoViewIfNeeded

Ponyfill for `Element.prototype.scrollIntoViewIfNeeded`

#### Parameters

- `element` **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)**
- `center` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?**

#### Examples

```javascript
import { scrollIntoViewIfNeeded } from "reakit-utils";

scrollIntoViewIfNeeded(document.getElementById("id"), true);
// same as
document.getElementById("id").scrollIntoViewIfNeeded(true);
```

### splitProps

Splits an object (`props`) into a tuple where the first item is an object
Expand Down
24 changes: 24 additions & 0 deletions packages/reakit-utils/src/createEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { getDocument } from "./getDocument";

/**
* Creates an `Event` in a way that also works on IE 11.
*
* @example
* import { createEvent } from "reakit-utils";
*
* const el = document.getElementById("id");
* el.dispatchEvent(createEvent(el, "blur", { bubbles: false }));
*/
export function createEvent(
element: HTMLElement,
type: string,
eventInit: EventInit = {}
): Event {
if (typeof Event === "function") {
return new Event(type, eventInit);
}
// IE 11 doesn't support Event constructors
const event = getDocument(element).createEvent("Event");
event.initEvent(type, eventInit?.bubbles, eventInit?.cancelable);
return event;
}

0 comments on commit 555b931

Please sign in to comment.