fix: prevent asset conflicts between React and Grid.js versions

Add coexistence checks to all enqueue methods to prevent loading
both React and Grid.js assets simultaneously.

Changes:
- ReactAdmin.php: Only enqueue React assets when ?react=1
- Init.php: Skip Grid.js when React active on admin pages
- Form.php, Coupon.php, Access.php: Restore classic assets when ?react=0
- Customer.php, Product.php, License.php: Add coexistence checks

Now the toggle between Classic and React versions works correctly.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:02:14 +07:00
parent bd9cdac02e
commit e8fbfb14c1
74973 changed files with 6658406 additions and 71 deletions

View File

@@ -0,0 +1,6 @@
dist
es
lib
ts
coverage
node_modules

View File

@@ -0,0 +1,330 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.15.2](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.15.1...reakit-system@0.15.2) (2021-09-06)
**Note:** Version bump only for package reakit-system
## [0.15.1](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.15.0...reakit-system@0.15.1) (2020-12-11)
### Bug Fixes
* Add React 17 to peer dependencies ([#807](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/807)) ([411b5aa](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/411b5aa8adf63f3149b40db6a499e65b58929b29)), closes [#776](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/776)
* Stop passing the `state` prop to custom `as` components ([#800](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/800)) ([e4c67a3](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/e4c67a3de2985684dd1ed918175df3454cd44b81)), closes [#797](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/797)
# [0.15.0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.14.5...reakit-system@0.15.0) (2020-11-12)
### Features
* Add `Role` component ([#728](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/728)) ([5fa51a7](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/5fa51a7891085aeeb6a0e3ea44ef3d294fccc8ba))
* Add `state` prop on all components ([#771](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/771)) ([4ed846d](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/4ed846d0a17e655d726572910b57b9ad3ebc235d)), closes [#744](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/744)
## [0.14.5](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.14.4...reakit-system@0.14.5) (2020-09-22)
**Note:** Version bump only for package reakit-system
## [0.14.4](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.14.3...reakit-system@0.14.4) (2020-09-03)
### Bug Fixes
* Fix internal dependency versions ([3d4cb42](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/3d4cb4217a52ec719e8a2823d21e08c7cc42dd30))
## [0.14.3](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.14.2...reakit-system@0.14.3) (2020-08-24)
**Note:** Version bump only for package reakit-system
## [0.14.2](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.14.1...reakit-system@0.14.2) (2020-08-17)
**Note:** Version bump only for package reakit-system
## [0.14.1](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.14.0...reakit-system@0.14.1) (2020-08-13)
**Note:** Version bump only for package reakit-system
# [0.14.0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.13.1...reakit-system@0.14.0) (2020-08-06)
**Note:** Version bump only for package reakit-system
## [0.13.1](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.13.0...reakit-system@0.13.1) (2020-07-18)
**Note:** Version bump only for package reakit-system
# [0.13.0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.13.0-alpha.0...reakit-system@0.13.0) (2020-06-17)
### Features
* Support render props passed to the `as` prop component ([#668](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/668)) ([214d0e6](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/214d0e6357ea659a05d351fc26f539d186df0404))
## [0.12.2](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.12.1...reakit-system@0.12.2) (2020-06-04)
### Bug Fixes
* **reakit-system:** Fix forwardRef TypeScript types ([2d96447](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/2d9644704f8e9e1f14ecf726ad8d4f7b401817c9))
### Performance Improvements
* Improve `Composite` performance ([#660](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/660)) ([f6656b6](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/f6656b6b765bbec639754aa96a2f08b717413068))
## [0.12.1](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.12.0...reakit-system@0.12.1) (2020-05-12)
### Features
* Remove `undefined` props from props hooks and render props ([d95c9e5](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/d95c9e5311debc59c3e5d137936cc78e95fb8215))
# [0.12.0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.11.0...reakit-system@0.12.0) (2020-04-29)
**Note:** Version bump only for package reakit-system
# [0.11.0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.10.0...reakit-system@0.11.0) (2020-04-20)
### Bug Fixes
* Fix `Composite` on IE11 ([#609](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/609)) ([555b931](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/555b931de003a81a635ed1d980d67f9c62fb91e0))
# [0.10.0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.9.0...reakit-system@0.10.0) (2020-03-30)
### Features
* Automatically check `Radio` on focus ([#599](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/599)) ([6edc689](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/6edc68980de142686bdbdceecc8769e2a6265001))
* Select the first `Tab` by default and don't require `stopId` prop ([#597](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/597)) ([528b016](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/528b016304f381b171cdc96598201deb54fb53c8))
### BREAKING CHANGES
* The first `Tab` is now selected by default. There's no need to pass `selectedId` to `useTabState` anymore.
If you're already using `selectedId` to select a tab in the initial render, you don't need to change anything as this still works. But, if you want to render tabs with none selected, you should now pass `null` to `selectedId`:
```js
// if you're already using selectedId, there's no need to change anything
const tab = useTabState({ selectedId: "tab-1" });
```
```diff
// when there's no tab selected by default, you now need to explicitly specify it
- const tab = useTabState();
+ const tab = useTabState({ selectedId: null });
```
* **Most users will not be affected by this**, but `stops`, `register` and `unregister` on the returned object of state hooks have been renamed to `items`, `registerItem` and `unregisterItem`, respectively.
```diff
const tab = useTabState();
- tab.stops.map(...);
+ tab.items.map(...);
- tab.register(...);
+ tab.registerItem(...);
- tab.unregister(...);
+ tab.unregisterItem(...);
```
# [0.9.0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.8.0...reakit-system@0.9.0) (2020-02-10)
### Features
* Add `Disclosure` module and deprecate `Hidden` ([#541](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/541)) ([4397ab0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/4397ab0ea70e78ed187d6f463a5941f72907afb0))
# [0.8.0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.7.2...reakit-system@0.8.0) (2020-02-05)
### Features
* Add `modal` state to `useDialogState` ([#535](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/535)) ([f3953ad](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/f3953ad)), closes [#404](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/404)
* Replace `unstable_wrap` by `wrapElement` ([#538](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/538)) ([17a12fb](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/17a12fb))
## [0.7.2](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.7.1...reakit-system@0.7.2) (2019-12-18)
**Note:** Version bump only for package reakit-system
## [0.7.1](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.7.0...reakit-system@0.7.1) (2019-11-22)
**Note:** Version bump only for package reakit-system
# [0.7.0](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.6.8...reakit-system@0.7.0) (2019-11-14)
### Features
* **reakit-system:** Replace `useCompose` by `useComposeOptions` on `createHook` ([#493](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/493)) ([50fd7df](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/50fd7df))
## [0.6.8](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.6.7...reakit-system@0.6.8) (2019-11-08)
**Note:** Version bump only for package reakit-system
## [0.6.7](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.6.6...reakit-system@0.6.7) (2019-11-02)
**Note:** Version bump only for package reakit-system
## [0.6.6](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.6.5...reakit-system@0.6.6) (2019-10-12)
### Performance Improvements
* Improve space complexity for `createHook` method ([#453](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/453)) ([6fe7028](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/6fe7028))
## [0.6.5](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.6.4...reakit-system@0.6.5) (2019-09-25)
**Note:** Version bump only for package reakit-system
## [0.6.4](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.6.3...reakit-system@0.6.4) (2019-09-19)
**Note:** Version bump only for package reakit-system
## [0.6.3](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.6.2...reakit-system@0.6.3) (2019-08-25)
### Bug Fixes
* **reakit-system:** Remove dependency on reakit type ([d5ea02c](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/d5ea02c)), closes [#413](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/413)
### Features
* Upgrade `reakit` peer dependency version ([73baeff](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/73baeff))
## [0.6.2](https://github.com/reakit/reakit/tree/master/packages/reakit-system/compare/reakit-system@0.6.1...reakit-system@0.6.2) (2019-06-27)
**Note:** Version bump only for package reakit-system
## 0.6.1 (2019-06-23)
### Features
* Move helpers to separate package (reakit-utils, reakit-system) ([#380](https://github.com/reakit/reakit/tree/master/packages/reakit-system/issues/380)) ([354b874](https://github.com/reakit/reakit/tree/master/packages/reakit-system/commit/354b874))
### BREAKING CHANGES
* Utils aren't exported by `reakit` or `reakit/utils` anymore. Import them from the `reakit-utils` package instead.
* System utils aren't exported by `reakit` or `reakit/system` anymore. Import them from the `reakit-system` package instead.
* `Provider` isn't exported by `reakit/utils` or `reakit/utils/Provider` anymore. Import it from `reakit` or `reakit/Provider` instead.
# Change Log

21
node_modules/reakit/node_modules/reakit-system/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Diego Haz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,322 @@
# reakit-system
<a href="https://npmjs.org/package/reakit-system"><img alt="NPM version" src="https://img.shields.io/npm/v/reakit-system.svg" /></a>
> **This is experimental** and may have breaking changes in minor versions.
## Installation
npm:
```sh
npm i reakit-system
```
Yarn:
```sh
yarn add reakit-system
```
## Usage
```jsx
import { useRole } from "reakit/Role";
import { createHook } from "reakit-system";
const useA = createHook({ name: "A", compose: useRole });
```
## API
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
#### Table of Contents
- [createComponent](#createcomponent)
- [createHook](#createhook)
- [mergeSystem](#mergesystem)
- [SystemProvider](#systemprovider)
- [useCreateElement](#usecreateelement)
- [useOptions](#useoptions)
- [useProps](#useprops)
- [useToken](#usetoken)
### createComponent
Creates a React component.
#### Parameters
- `options` **Options&lt;T, O>**
- `options.as`
- `options.useHook`
- `options.memo`
- `options.propsAreEqual` (optional, default `useHook?.unstable_propsAreEqual`)
- `options.keys` (optional, default `useHook?.__keys||[]`)
- `options.useCreateElement` (optional, default `defaultUseCreateElement`)
#### Examples
```javascript
import { createComponent } from "reakit-system";
const A = createComponent({ as: "a" });
```
### createHook
Creates a React custom hook that will return component props.
#### Parameters
- `options` **CreateHookOptions&lt;O, P>**
#### Examples
```javascript
import { createHook } from "reakit-system";
const useA = createHook({
name: "A",
keys: ["url"], // custom props/options keys
useProps(options, htmlProps) {
return {
...htmlProps,
href: options.url,
};
},
});
function A({ url, ...htmlProps }) {
const props = useA({ url }, htmlProps);
return <a {...props} />;
}
```
### mergeSystem
Merges multiple system objects into a single system object.
#### Parameters
- `systems` **...T**
#### Examples
```javascript
import { Provider } from "reakit";
import { mergeSystem } from "reakit-system";
import * as bootstrapSystem from "reakit-system-bootstrap";
const mySystem = {
useButtonProps() {},
};
const system = mergeSystem(bootstrapSystem, mySystem);
function App() {
return (
<Provider unstable_system={system}>
<div>App</div>
</Provider>
);
}
```
### SystemProvider
Provider component that is used by `reakit`'s `Provider` underneath.
#### Parameters
- `props` **SystemProviderProps**
- `props.children`
- `props.unstable_system`
#### Examples
```javascript
// instead of using
import { Provider } from "reakit";
// you can use this
import { SystemProvider } from "reakit-system";
// reakit's Provider has more features, such as ID generation
import * as system from "reakit-system-bootstrap";
function App() {
return (
<SystemProvider unstable_system={system}>
<div>App</div>
</SystemProvider>
);
}
```
### useCreateElement
Custom hook that will call `children` if it's a function. If
`useCreateElement` has been passed to the context, it'll be used instead.
#### Parameters
- `type` **T**
- `props` **Record&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>**
- `children` **React.ReactNode** (optional, default `props.children`)
#### Examples
```javascript
import React from "react";
import { SystemProvider, useCreateElement } from "reakit-system";
const system = {
useCreateElement(type, props, children = props.children) {
// very similar to what `useCreateElement` does already
if (typeof children === "function") {
const { children: _, ...rest } = props;
return children(rest);
}
return React.createElement(type, props, children);
},
};
function Component(props) {
return useCreateElement("div", props);
}
function App() {
return (
<SystemProvider unstable_system={system}>
<Component url="url">{({ url }) => <a href={url}>link</a>}</Component>
</SystemProvider>
);
}
```
Returns **JSX.Element**
### useOptions
React custom hook that returns the options returned by a given
`use${name}Options` in the SystemContext.
#### Parameters
- `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `options` **T** (optional, default `{}as T`)
- `htmlProps` **any** (optional, default `{}`)
#### Examples
```javascript
import React from "react";
import { SystemProvider, useOptions } from "reakit-system";
const system = {
useAOptions(options, htmlProps) {
return {
...options,
url: htmlProps.href,
};
},
};
function A({ url, ...htmlProps }) {
const options = useOptions("A", { url }, htmlProps);
return <a href={options.url} {...htmlProps} />;
}
function App() {
return (
<SystemProvider unstable_system={system}>
<A href="url">
It will convert href into url in useAOptions and then url into href in A
</A>
</SystemProvider>
);
}
```
Returns **T**
### useProps
React custom hook that returns the props returned by a given
`use${name}Props` in the SystemContext.
#### Parameters
- `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `options` **Record&lt;[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), any>** (optional, default `{}`)
- `htmlProps` **any** (optional, default `{}`)
#### Examples
```javascript
import { SystemProvider, useProps } from "reakit-system";
const system = {
useAProps(options, htmlProps) {
return {
...htmlProps,
href: options.url,
};
},
};
function A({ url, ...htmlProps }) {
const props = useProps("A", { url }, htmlProps);
return <a {...props} />;
}
function App() {
return (
<SystemProvider unstable_system={system}>
<A url="url">It will convert url into href in useAProps</A>
</SystemProvider>
);
}
```
Returns **any**
### useToken
React custom hook that returns the value of any token defined in the
SystemContext. It's mainly used internally in [`useOptions`](#useoptions)
and [`useProps`](#useprops).
#### Parameters
- `token` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
- `defaultValue` **T?**
#### Examples
```javascript
import { SystemProvider, useToken } from "reakit-system";
const system = {
token: "value",
};
function Component(props) {
const token = useToken("token", "default value");
return <div {...props}>{token}</div>;
}
function App() {
return (
<SystemProvider unstable_system={system}>
<Component />
</SystemProvider>
);
}
```
Returns **T**
## License
MIT © [Diego Haz](https://github.com/diegohaz)

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-system/SystemContext",
"private": true,
"sideEffects": false,
"main": "../lib/SystemContext",
"module": "../es/SystemContext",
"types": "../ts/SystemContext"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-system/SystemProvider",
"private": true,
"sideEffects": false,
"main": "../lib/SystemProvider",
"module": "../es/SystemProvider",
"types": "../ts/SystemProvider"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-system/createComponent",
"private": true,
"sideEffects": false,
"main": "../lib/createComponent",
"module": "../es/createComponent",
"types": "../ts/createComponent"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-system/createHook",
"private": true,
"sideEffects": false,
"main": "../lib/createHook",
"module": "../es/createHook",
"types": "../ts/createHook"
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
import { createContext } from 'react';
var SystemContext = /*#__PURE__*/createContext({});
export { SystemContext };

View File

@@ -0,0 +1,33 @@
import { createElement } from 'react';
import { SystemContext } from './SystemContext.js';
/**
* Provider component that is used by `reakit`'s `Provider` underneath.
*
* @example
* // instead of using
* import { Provider } from "reakit";
* // you can use this
* import { SystemProvider } from "reakit-system";
* // reakit's Provider has more features, such as ID generation
* import * as system from "reakit-system-bootstrap";
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <div>App</div>
* </SystemProvider>
* );
* }
*
* @param props
*/
function SystemProvider(_ref) {
var children = _ref.children,
system = _ref.unstable_system;
return /*#__PURE__*/createElement(SystemContext.Provider, {
value: system
}, children);
}
export { SystemProvider };

View File

@@ -0,0 +1,107 @@
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
var it;
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
it = o[Symbol.iterator]();
return it.next.bind(it);
}
export { _objectSpread2 as _, _objectWithoutPropertiesLoose as a, _createForOfIteratorHelperLoose as b };

View File

@@ -0,0 +1,90 @@
import { forwardRef as forwardRef$1, memo as memo$1 } from 'react';
import './SystemContext.js';
import { a as _objectWithoutPropertiesLoose, _ as _objectSpread2 } from './_rollupPluginBabelHelpers-0c84a174.js';
import { useCreateElement } from './useCreateElement.js';
import { splitProps } from 'reakit-utils/splitProps';
import { shallowEqual } from 'reakit-utils/shallowEqual';
import { normalizePropsAreEqual } from 'reakit-utils/normalizePropsAreEqual';
function forwardRef(component) {
return /*#__PURE__*/forwardRef$1(component);
}
function memo(component, propsAreEqual) {
return /*#__PURE__*/memo$1(component, propsAreEqual);
}
/**
* Creates a React component.
*
* @example
* import { createComponent } from "reakit-system";
*
* const A = createComponent({ as: "a" });
*
* @param options
*/
function createComponent(_ref) {
var type = _ref.as,
useHook = _ref.useHook,
shouldMemo = _ref.memo,
_ref$propsAreEqual = _ref.propsAreEqual,
propsAreEqual = _ref$propsAreEqual === void 0 ? useHook === null || useHook === void 0 ? void 0 : useHook.unstable_propsAreEqual : _ref$propsAreEqual,
_ref$keys = _ref.keys,
keys = _ref$keys === void 0 ? (useHook === null || useHook === void 0 ? void 0 : useHook.__keys) || [] : _ref$keys,
_ref$useCreateElement = _ref.useCreateElement,
useCreateElement$1 = _ref$useCreateElement === void 0 ? useCreateElement : _ref$useCreateElement;
var Comp = function Comp(_ref2, ref) {
var _ref2$as = _ref2.as,
as = _ref2$as === void 0 ? type : _ref2$as,
props = _objectWithoutPropertiesLoose(_ref2, ["as"]);
if (useHook) {
var _as$render;
var _splitProps = splitProps(props, keys),
_options = _splitProps[0],
htmlProps = _splitProps[1];
var _useHook = useHook(_options, _objectSpread2({
ref: ref
}, htmlProps)),
wrapElement = _useHook.wrapElement,
elementProps = _objectWithoutPropertiesLoose(_useHook, ["wrapElement"]); // @ts-ignore
var asKeys = ((_as$render = as.render) === null || _as$render === void 0 ? void 0 : _as$render.__keys) || as.__keys;
var asOptions = asKeys && splitProps(props, asKeys)[0];
var allProps = asOptions ? _objectSpread2(_objectSpread2({}, elementProps), asOptions) : elementProps;
var _element = useCreateElement$1(as, allProps);
if (wrapElement) {
return wrapElement(_element);
}
return _element;
}
return useCreateElement$1(as, _objectSpread2({
ref: ref
}, props));
};
if (process.env.NODE_ENV !== "production" && useHook) {
Comp.displayName = useHook.name.replace(/^(unstable_)?use/, "");
}
Comp = forwardRef(Comp);
if (shouldMemo) {
Comp = memo(Comp, propsAreEqual && normalizePropsAreEqual(propsAreEqual));
}
Comp.__keys = keys;
Comp.unstable_propsAreEqual = normalizePropsAreEqual(propsAreEqual || shallowEqual);
return Comp;
}
export { createComponent };

View File

@@ -0,0 +1,135 @@
import 'react';
import './SystemContext.js';
import './useToken.js';
import { useProps } from './useProps.js';
import { b as _createForOfIteratorHelperLoose } from './_rollupPluginBabelHelpers-0c84a174.js';
import { useOptions } from './useOptions.js';
import { shallowEqual } from 'reakit-utils/shallowEqual';
import { toArray } from 'reakit-utils/toArray';
/**
* Creates a React custom hook that will return component props.
*
* @example
* import { createHook } from "reakit-system";
*
* const useA = createHook({
* name: "A",
* keys: ["url"], // custom props/options keys
* useProps(options, htmlProps) {
* return {
* ...htmlProps,
* href: options.url,
* };
* },
* });
*
* function A({ url, ...htmlProps }) {
* const props = useA({ url }, htmlProps);
* return <a {...props} />;
* }
*
* @param options
*/
function createHook(options) {
var _options$useState, _composedHooks$;
var composedHooks = toArray(options.compose);
var __useOptions = function __useOptions(hookOptions, htmlProps) {
// Call the current hook's useOptions first
if (options.useOptions) {
hookOptions = options.useOptions(hookOptions, htmlProps);
} // If there's name, call useOptions from the system context
if (options.name) {
hookOptions = useOptions(options.name, hookOptions, htmlProps);
} // Run composed hooks useOptions
if (options.compose) {
for (var _iterator = _createForOfIteratorHelperLoose(composedHooks), _step; !(_step = _iterator()).done;) {
var hook = _step.value;
hookOptions = hook.__useOptions(hookOptions, htmlProps);
}
}
return hookOptions;
};
var useHook = function useHook(hookOptions, htmlProps, unstable_ignoreUseOptions) {
if (hookOptions === void 0) {
hookOptions = {};
}
if (htmlProps === void 0) {
htmlProps = {};
}
if (unstable_ignoreUseOptions === void 0) {
unstable_ignoreUseOptions = false;
}
// This won't execute when useHook was called from within another useHook
if (!unstable_ignoreUseOptions) {
hookOptions = __useOptions(hookOptions, htmlProps);
} // Call the current hook's useProps
if (options.useProps) {
htmlProps = options.useProps(hookOptions, htmlProps);
} // If there's name, call useProps from the system context
if (options.name) {
htmlProps = useProps(options.name, hookOptions, htmlProps);
}
if (options.compose) {
if (options.useComposeOptions) {
hookOptions = options.useComposeOptions(hookOptions, htmlProps);
}
if (options.useComposeProps) {
htmlProps = options.useComposeProps(hookOptions, htmlProps);
} else {
for (var _iterator2 = _createForOfIteratorHelperLoose(composedHooks), _step2; !(_step2 = _iterator2()).done;) {
var hook = _step2.value;
htmlProps = hook(hookOptions, htmlProps, true);
}
}
} // Remove undefined values from htmlProps
var finalHTMLProps = {};
var definedHTMLProps = htmlProps || {};
for (var prop in definedHTMLProps) {
if (definedHTMLProps[prop] !== undefined) {
finalHTMLProps[prop] = definedHTMLProps[prop];
}
}
return finalHTMLProps;
};
useHook.__useOptions = __useOptions;
var composedKeys = composedHooks.reduce(function (keys, hook) {
keys.push.apply(keys, hook.__keys || []);
return keys;
}, []); // It's used by createComponent to split option props (keys) and html props
useHook.__keys = [].concat(composedKeys, ((_options$useState = options.useState) === null || _options$useState === void 0 ? void 0 : _options$useState.__keys) || [], options.keys || []);
useHook.unstable_propsAreEqual = options.propsAreEqual || ((_composedHooks$ = composedHooks[0]) === null || _composedHooks$ === void 0 ? void 0 : _composedHooks$.unstable_propsAreEqual) || shallowEqual;
if (process.env.NODE_ENV !== "production" && options.name) {
Object.defineProperty(useHook, "name", {
value: "use" + options.name
});
}
return useHook;
}
export { createHook };

View File

@@ -0,0 +1,16 @@
import 'react';
export { SystemContext } from './SystemContext.js';
export { useToken } from './useToken.js';
export { useProps } from './useProps.js';
import './_rollupPluginBabelHelpers-0c84a174.js';
export { useOptions } from './useOptions.js';
export { useCreateElement } from './useCreateElement.js';
import 'reakit-utils/isObject';
export { mergeSystem } from './mergeSystem.js';
import 'reakit-utils/splitProps';
import 'reakit-utils/shallowEqual';
import 'reakit-utils/normalizePropsAreEqual';
export { createComponent } from './createComponent.js';
import 'reakit-utils/toArray';
export { createHook } from './createHook.js';
export { SystemProvider } from './SystemProvider.js';

View File

@@ -0,0 +1,97 @@
import { b as _createForOfIteratorHelperLoose } from './_rollupPluginBabelHelpers-0c84a174.js';
import { isObject } from 'reakit-utils/isObject';
/**
* Transforms [{ a: "a" }, { a: "b" }] into { a: ["a", "b"] }
*/
function reduceObjects(objects, filter) {
var result = {};
for (var _iterator = _createForOfIteratorHelperLoose(objects), _step; !(_step = _iterator()).done;) {
var object = _step.value;
var keys = Object.keys(object);
for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
var _key = _keys[_i];
// eslint-disable-next-line no-continue
if (filter && !filter(object[_key], _key)) continue;
var _value = result[_key] || [];
result[_key] = [].concat(_value, [object[_key]]);
}
}
return result;
}
function mergeFunctionsInObjects(objects) {
var object = reduceObjects(objects, function (value) {
return typeof value === "function";
});
var keys = Object.keys(object);
var result = {};
for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
var key = _keys[_i];
var fns = object[key];
result[key] = fns.length === 1 ? fns[0] : fns.reduce(function (lastHook, currHook) {
return function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return currHook.apply(void 0, args.slice(0, -1).concat([lastHook.apply(void 0, args)]));
};
});
}
return result;
}
function mergeObjectsInObjects(systems) {
var object = reduceObjects(systems, isObject);
var keys = Object.keys(object);
var result = {};
for (var _i2 = 0, _keys2 = keys; _i2 < _keys2.length; _i2++) {
var key = _keys2[_i2];
var values = object[key];
result[key] = Object.assign.apply(Object, [{}].concat(values));
}
return result;
}
/**
* Merges multiple system objects into a single system object.
*
* @example
* import { Provider } from "reakit";
* import { mergeSystem } from "reakit-system";
* import * as bootstrapSystem from "reakit-system-bootstrap";
*
* const mySystem = {
* useButtonProps() {},
* };
*
* const system = mergeSystem(bootstrapSystem, mySystem);
*
* function App() {
* return (
* <Provider unstable_system={system}>
* <div>App</div>
* </Provider>
* );
* }
*/
function mergeSystem() {
for (var _len2 = arguments.length, systems = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
systems[_key2] = arguments[_key2];
}
return Object.assign.apply(Object, [{}].concat(systems, [mergeObjectsInObjects(systems), mergeFunctionsInObjects(systems)]));
}
export { mergeSystem };

View File

@@ -0,0 +1,62 @@
import { useContext, createElement } from 'react';
import { SystemContext } from './SystemContext.js';
import { a as _objectWithoutPropertiesLoose } from './_rollupPluginBabelHelpers-0c84a174.js';
function isRenderProp(children) {
return typeof children === "function";
}
/**
* Custom hook that will call `children` if it's a function. If
* `useCreateElement` has been passed to the context, it'll be used instead.
*
* @example
* import React from "react";
* import { SystemProvider, useCreateElement } from "reakit-system";
*
* const system = {
* useCreateElement(type, props, children = props.children) {
* // very similar to what `useCreateElement` does already
* if (typeof children === "function") {
* const { children: _, ...rest } = props;
* return children(rest);
* }
* return React.createElement(type, props, children);
* },
* };
*
* function Component(props) {
* return useCreateElement("div", props);
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <Component url="url">{({ url }) => <a href={url}>link</a>}</Component>
* </SystemProvider>
* );
* }
*/
var useCreateElement = function useCreateElement(type, props, children) {
if (children === void 0) {
children = props.children;
}
var context = useContext(SystemContext);
if (context.useCreateElement) {
return context.useCreateElement(type, props, children);
}
if (typeof type === "string" && isRenderProp(children)) {
var _ = props.children,
rest = _objectWithoutPropertiesLoose(props, ["children"]);
return children(rest);
}
return /*#__PURE__*/createElement(type, props, children);
};
export { useCreateElement };

View File

@@ -0,0 +1,59 @@
import { useDebugValue } from 'react';
import './SystemContext.js';
import { useToken } from './useToken.js';
import { _ as _objectSpread2 } from './_rollupPluginBabelHelpers-0c84a174.js';
/**
* React custom hook that returns the options returned by a given
* `use${name}Options` in the SystemContext.
*
* @example
* import React from "react";
* import { SystemProvider, useOptions } from "reakit-system";
*
* const system = {
* useAOptions(options, htmlProps) {
* return {
* ...options,
* url: htmlProps.href,
* };
* },
* };
*
* function A({ url, ...htmlProps }) {
* const options = useOptions("A", { url }, htmlProps);
* return <a href={options.url} {...htmlProps} />;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <A href="url">
* It will convert href into url in useAOptions and then url into href in A
* </A>
* </SystemProvider>
* );
* }
*/
function useOptions(name, options, htmlProps) {
if (options === void 0) {
options = {};
}
if (htmlProps === void 0) {
htmlProps = {};
}
var hookName = "use" + name + "Options";
useDebugValue(hookName);
var useHook = useToken(hookName);
if (useHook) {
return _objectSpread2(_objectSpread2({}, options), useHook(options, htmlProps));
}
return options;
}
export { useOptions };

View File

@@ -0,0 +1,55 @@
import { useDebugValue } from 'react';
import './SystemContext.js';
import { useToken } from './useToken.js';
/**
* React custom hook that returns the props returned by a given
* `use${name}Props` in the SystemContext.
*
* @example
* import { SystemProvider, useProps } from "reakit-system";
*
* const system = {
* useAProps(options, htmlProps) {
* return {
* ...htmlProps,
* href: options.url,
* };
* },
* };
*
* function A({ url, ...htmlProps }) {
* const props = useProps("A", { url }, htmlProps);
* return <a {...props} />;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <A url="url">It will convert url into href in useAProps</A>
* </SystemProvider>
* );
* }
*/
function useProps(name, options, htmlProps) {
if (options === void 0) {
options = {};
}
if (htmlProps === void 0) {
htmlProps = {};
}
var hookName = "use" + name + "Props";
useDebugValue(hookName);
var useHook = useToken(hookName);
if (useHook) {
return useHook(options, htmlProps);
}
return htmlProps;
}
export { useProps };

View File

@@ -0,0 +1,36 @@
import { useDebugValue, useContext } from 'react';
import { SystemContext } from './SystemContext.js';
/**
* React custom hook that returns the value of any token defined in the
* SystemContext. It's mainly used internally in [`useOptions`](#useoptions)
* and [`useProps`](#useprops).
*
* @example
* import { SystemProvider, useToken } from "reakit-system";
*
* const system = {
* token: "value",
* };
*
* function Component(props) {
* const token = useToken("token", "default value");
* return <div {...props}>{token}</div>;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <Component />
* </SystemProvider>
* );
* }
*/
function useToken(token, defaultValue) {
useDebugValue(token);
var context = useContext(SystemContext);
return context[token] != null ? context[token] : defaultValue;
}
export { useToken };

View File

@@ -0,0 +1,9 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var SystemContext = /*#__PURE__*/React.createContext({});
exports.SystemContext = SystemContext;

View File

@@ -0,0 +1,37 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var SystemContext = require('./SystemContext.js');
/**
* Provider component that is used by `reakit`'s `Provider` underneath.
*
* @example
* // instead of using
* import { Provider } from "reakit";
* // you can use this
* import { SystemProvider } from "reakit-system";
* // reakit's Provider has more features, such as ID generation
* import * as system from "reakit-system-bootstrap";
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <div>App</div>
* </SystemProvider>
* );
* }
*
* @param props
*/
function SystemProvider(_ref) {
var children = _ref.children,
system = _ref.unstable_system;
return /*#__PURE__*/React.createElement(SystemContext.SystemContext.Provider, {
value: system
}, children);
}
exports.SystemProvider = SystemProvider;

View File

@@ -0,0 +1,111 @@
'use strict';
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
var it;
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
it = o[Symbol.iterator]();
return it.next.bind(it);
}
exports._createForOfIteratorHelperLoose = _createForOfIteratorHelperLoose;
exports._objectSpread2 = _objectSpread2;
exports._objectWithoutPropertiesLoose = _objectWithoutPropertiesLoose;

View File

@@ -0,0 +1,94 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
require('./SystemContext.js');
var _rollupPluginBabelHelpers = require('./_rollupPluginBabelHelpers-8f9a8751.js');
var useCreateElement = require('./useCreateElement.js');
var splitProps = require('reakit-utils/splitProps');
var shallowEqual = require('reakit-utils/shallowEqual');
var normalizePropsAreEqual = require('reakit-utils/normalizePropsAreEqual');
function forwardRef(component) {
return /*#__PURE__*/React.forwardRef(component);
}
function memo(component, propsAreEqual) {
return /*#__PURE__*/React.memo(component, propsAreEqual);
}
/**
* Creates a React component.
*
* @example
* import { createComponent } from "reakit-system";
*
* const A = createComponent({ as: "a" });
*
* @param options
*/
function createComponent(_ref) {
var type = _ref.as,
useHook = _ref.useHook,
shouldMemo = _ref.memo,
_ref$propsAreEqual = _ref.propsAreEqual,
propsAreEqual = _ref$propsAreEqual === void 0 ? useHook === null || useHook === void 0 ? void 0 : useHook.unstable_propsAreEqual : _ref$propsAreEqual,
_ref$keys = _ref.keys,
keys = _ref$keys === void 0 ? (useHook === null || useHook === void 0 ? void 0 : useHook.__keys) || [] : _ref$keys,
_ref$useCreateElement = _ref.useCreateElement,
useCreateElement$1 = _ref$useCreateElement === void 0 ? useCreateElement.useCreateElement : _ref$useCreateElement;
var Comp = function Comp(_ref2, ref) {
var _ref2$as = _ref2.as,
as = _ref2$as === void 0 ? type : _ref2$as,
props = _rollupPluginBabelHelpers._objectWithoutPropertiesLoose(_ref2, ["as"]);
if (useHook) {
var _as$render;
var _splitProps = splitProps.splitProps(props, keys),
_options = _splitProps[0],
htmlProps = _splitProps[1];
var _useHook = useHook(_options, _rollupPluginBabelHelpers._objectSpread2({
ref: ref
}, htmlProps)),
wrapElement = _useHook.wrapElement,
elementProps = _rollupPluginBabelHelpers._objectWithoutPropertiesLoose(_useHook, ["wrapElement"]); // @ts-ignore
var asKeys = ((_as$render = as.render) === null || _as$render === void 0 ? void 0 : _as$render.__keys) || as.__keys;
var asOptions = asKeys && splitProps.splitProps(props, asKeys)[0];
var allProps = asOptions ? _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, elementProps), asOptions) : elementProps;
var _element = useCreateElement$1(as, allProps);
if (wrapElement) {
return wrapElement(_element);
}
return _element;
}
return useCreateElement$1(as, _rollupPluginBabelHelpers._objectSpread2({
ref: ref
}, props));
};
if (process.env.NODE_ENV !== "production" && useHook) {
Comp.displayName = useHook.name.replace(/^(unstable_)?use/, "");
}
Comp = forwardRef(Comp);
if (shouldMemo) {
Comp = memo(Comp, propsAreEqual && normalizePropsAreEqual.normalizePropsAreEqual(propsAreEqual));
}
Comp.__keys = keys;
Comp.unstable_propsAreEqual = normalizePropsAreEqual.normalizePropsAreEqual(propsAreEqual || shallowEqual.shallowEqual);
return Comp;
}
exports.createComponent = createComponent;

View File

@@ -0,0 +1,139 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
require('react');
require('./SystemContext.js');
require('./useToken.js');
var useProps = require('./useProps.js');
var _rollupPluginBabelHelpers = require('./_rollupPluginBabelHelpers-8f9a8751.js');
var useOptions = require('./useOptions.js');
var shallowEqual = require('reakit-utils/shallowEqual');
var toArray = require('reakit-utils/toArray');
/**
* Creates a React custom hook that will return component props.
*
* @example
* import { createHook } from "reakit-system";
*
* const useA = createHook({
* name: "A",
* keys: ["url"], // custom props/options keys
* useProps(options, htmlProps) {
* return {
* ...htmlProps,
* href: options.url,
* };
* },
* });
*
* function A({ url, ...htmlProps }) {
* const props = useA({ url }, htmlProps);
* return <a {...props} />;
* }
*
* @param options
*/
function createHook(options) {
var _options$useState, _composedHooks$;
var composedHooks = toArray.toArray(options.compose);
var __useOptions = function __useOptions(hookOptions, htmlProps) {
// Call the current hook's useOptions first
if (options.useOptions) {
hookOptions = options.useOptions(hookOptions, htmlProps);
} // If there's name, call useOptions from the system context
if (options.name) {
hookOptions = useOptions.useOptions(options.name, hookOptions, htmlProps);
} // Run composed hooks useOptions
if (options.compose) {
for (var _iterator = _rollupPluginBabelHelpers._createForOfIteratorHelperLoose(composedHooks), _step; !(_step = _iterator()).done;) {
var hook = _step.value;
hookOptions = hook.__useOptions(hookOptions, htmlProps);
}
}
return hookOptions;
};
var useHook = function useHook(hookOptions, htmlProps, unstable_ignoreUseOptions) {
if (hookOptions === void 0) {
hookOptions = {};
}
if (htmlProps === void 0) {
htmlProps = {};
}
if (unstable_ignoreUseOptions === void 0) {
unstable_ignoreUseOptions = false;
}
// This won't execute when useHook was called from within another useHook
if (!unstable_ignoreUseOptions) {
hookOptions = __useOptions(hookOptions, htmlProps);
} // Call the current hook's useProps
if (options.useProps) {
htmlProps = options.useProps(hookOptions, htmlProps);
} // If there's name, call useProps from the system context
if (options.name) {
htmlProps = useProps.useProps(options.name, hookOptions, htmlProps);
}
if (options.compose) {
if (options.useComposeOptions) {
hookOptions = options.useComposeOptions(hookOptions, htmlProps);
}
if (options.useComposeProps) {
htmlProps = options.useComposeProps(hookOptions, htmlProps);
} else {
for (var _iterator2 = _rollupPluginBabelHelpers._createForOfIteratorHelperLoose(composedHooks), _step2; !(_step2 = _iterator2()).done;) {
var hook = _step2.value;
htmlProps = hook(hookOptions, htmlProps, true);
}
}
} // Remove undefined values from htmlProps
var finalHTMLProps = {};
var definedHTMLProps = htmlProps || {};
for (var prop in definedHTMLProps) {
if (definedHTMLProps[prop] !== undefined) {
finalHTMLProps[prop] = definedHTMLProps[prop];
}
}
return finalHTMLProps;
};
useHook.__useOptions = __useOptions;
var composedKeys = composedHooks.reduce(function (keys, hook) {
keys.push.apply(keys, hook.__keys || []);
return keys;
}, []); // It's used by createComponent to split option props (keys) and html props
useHook.__keys = [].concat(composedKeys, ((_options$useState = options.useState) === null || _options$useState === void 0 ? void 0 : _options$useState.__keys) || [], options.keys || []);
useHook.unstable_propsAreEqual = options.propsAreEqual || ((_composedHooks$ = composedHooks[0]) === null || _composedHooks$ === void 0 ? void 0 : _composedHooks$.unstable_propsAreEqual) || shallowEqual.shallowEqual;
if (process.env.NODE_ENV !== "production" && options.name) {
Object.defineProperty(useHook, "name", {
value: "use" + options.name
});
}
return useHook;
}
exports.createHook = createHook;

View File

@@ -0,0 +1,32 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
require('react');
var SystemContext = require('./SystemContext.js');
var useToken = require('./useToken.js');
var useProps = require('./useProps.js');
require('./_rollupPluginBabelHelpers-8f9a8751.js');
var useOptions = require('./useOptions.js');
var useCreateElement = require('./useCreateElement.js');
require('reakit-utils/isObject');
var mergeSystem = require('./mergeSystem.js');
require('reakit-utils/splitProps');
require('reakit-utils/shallowEqual');
require('reakit-utils/normalizePropsAreEqual');
var createComponent = require('./createComponent.js');
require('reakit-utils/toArray');
var createHook = require('./createHook.js');
var SystemProvider = require('./SystemProvider.js');
exports.SystemContext = SystemContext.SystemContext;
exports.useToken = useToken.useToken;
exports.useProps = useProps.useProps;
exports.useOptions = useOptions.useOptions;
exports.useCreateElement = useCreateElement.useCreateElement;
exports.mergeSystem = mergeSystem.mergeSystem;
exports.createComponent = createComponent.createComponent;
exports.createHook = createHook.createHook;
exports.SystemProvider = SystemProvider.SystemProvider;

View File

@@ -0,0 +1,101 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('./_rollupPluginBabelHelpers-8f9a8751.js');
var isObject = require('reakit-utils/isObject');
/**
* Transforms [{ a: "a" }, { a: "b" }] into { a: ["a", "b"] }
*/
function reduceObjects(objects, filter) {
var result = {};
for (var _iterator = _rollupPluginBabelHelpers._createForOfIteratorHelperLoose(objects), _step; !(_step = _iterator()).done;) {
var object = _step.value;
var keys = Object.keys(object);
for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
var _key = _keys[_i];
// eslint-disable-next-line no-continue
if (filter && !filter(object[_key], _key)) continue;
var _value = result[_key] || [];
result[_key] = [].concat(_value, [object[_key]]);
}
}
return result;
}
function mergeFunctionsInObjects(objects) {
var object = reduceObjects(objects, function (value) {
return typeof value === "function";
});
var keys = Object.keys(object);
var result = {};
for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
var key = _keys[_i];
var fns = object[key];
result[key] = fns.length === 1 ? fns[0] : fns.reduce(function (lastHook, currHook) {
return function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return currHook.apply(void 0, args.slice(0, -1).concat([lastHook.apply(void 0, args)]));
};
});
}
return result;
}
function mergeObjectsInObjects(systems) {
var object = reduceObjects(systems, isObject.isObject);
var keys = Object.keys(object);
var result = {};
for (var _i2 = 0, _keys2 = keys; _i2 < _keys2.length; _i2++) {
var key = _keys2[_i2];
var values = object[key];
result[key] = Object.assign.apply(Object, [{}].concat(values));
}
return result;
}
/**
* Merges multiple system objects into a single system object.
*
* @example
* import { Provider } from "reakit";
* import { mergeSystem } from "reakit-system";
* import * as bootstrapSystem from "reakit-system-bootstrap";
*
* const mySystem = {
* useButtonProps() {},
* };
*
* const system = mergeSystem(bootstrapSystem, mySystem);
*
* function App() {
* return (
* <Provider unstable_system={system}>
* <div>App</div>
* </Provider>
* );
* }
*/
function mergeSystem() {
for (var _len2 = arguments.length, systems = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
systems[_key2] = arguments[_key2];
}
return Object.assign.apply(Object, [{}].concat(systems, [mergeObjectsInObjects(systems), mergeFunctionsInObjects(systems)]));
}
exports.mergeSystem = mergeSystem;

View File

@@ -0,0 +1,66 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var SystemContext = require('./SystemContext.js');
var _rollupPluginBabelHelpers = require('./_rollupPluginBabelHelpers-8f9a8751.js');
function isRenderProp(children) {
return typeof children === "function";
}
/**
* Custom hook that will call `children` if it's a function. If
* `useCreateElement` has been passed to the context, it'll be used instead.
*
* @example
* import React from "react";
* import { SystemProvider, useCreateElement } from "reakit-system";
*
* const system = {
* useCreateElement(type, props, children = props.children) {
* // very similar to what `useCreateElement` does already
* if (typeof children === "function") {
* const { children: _, ...rest } = props;
* return children(rest);
* }
* return React.createElement(type, props, children);
* },
* };
*
* function Component(props) {
* return useCreateElement("div", props);
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <Component url="url">{({ url }) => <a href={url}>link</a>}</Component>
* </SystemProvider>
* );
* }
*/
var useCreateElement = function useCreateElement(type, props, children) {
if (children === void 0) {
children = props.children;
}
var context = React.useContext(SystemContext.SystemContext);
if (context.useCreateElement) {
return context.useCreateElement(type, props, children);
}
if (typeof type === "string" && isRenderProp(children)) {
var _ = props.children,
rest = _rollupPluginBabelHelpers._objectWithoutPropertiesLoose(props, ["children"]);
return children(rest);
}
return /*#__PURE__*/React.createElement(type, props, children);
};
exports.useCreateElement = useCreateElement;

View File

@@ -0,0 +1,63 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
require('./SystemContext.js');
var useToken = require('./useToken.js');
var _rollupPluginBabelHelpers = require('./_rollupPluginBabelHelpers-8f9a8751.js');
/**
* React custom hook that returns the options returned by a given
* `use${name}Options` in the SystemContext.
*
* @example
* import React from "react";
* import { SystemProvider, useOptions } from "reakit-system";
*
* const system = {
* useAOptions(options, htmlProps) {
* return {
* ...options,
* url: htmlProps.href,
* };
* },
* };
*
* function A({ url, ...htmlProps }) {
* const options = useOptions("A", { url }, htmlProps);
* return <a href={options.url} {...htmlProps} />;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <A href="url">
* It will convert href into url in useAOptions and then url into href in A
* </A>
* </SystemProvider>
* );
* }
*/
function useOptions(name, options, htmlProps) {
if (options === void 0) {
options = {};
}
if (htmlProps === void 0) {
htmlProps = {};
}
var hookName = "use" + name + "Options";
React.useDebugValue(hookName);
var useHook = useToken.useToken(hookName);
if (useHook) {
return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, options), useHook(options, htmlProps));
}
return options;
}
exports.useOptions = useOptions;

View File

@@ -0,0 +1,59 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
require('./SystemContext.js');
var useToken = require('./useToken.js');
/**
* React custom hook that returns the props returned by a given
* `use${name}Props` in the SystemContext.
*
* @example
* import { SystemProvider, useProps } from "reakit-system";
*
* const system = {
* useAProps(options, htmlProps) {
* return {
* ...htmlProps,
* href: options.url,
* };
* },
* };
*
* function A({ url, ...htmlProps }) {
* const props = useProps("A", { url }, htmlProps);
* return <a {...props} />;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <A url="url">It will convert url into href in useAProps</A>
* </SystemProvider>
* );
* }
*/
function useProps(name, options, htmlProps) {
if (options === void 0) {
options = {};
}
if (htmlProps === void 0) {
htmlProps = {};
}
var hookName = "use" + name + "Props";
React.useDebugValue(hookName);
var useHook = useToken.useToken(hookName);
if (useHook) {
return useHook(options, htmlProps);
}
return htmlProps;
}
exports.useProps = useProps;

View File

@@ -0,0 +1,40 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var SystemContext = require('./SystemContext.js');
/**
* React custom hook that returns the value of any token defined in the
* SystemContext. It's mainly used internally in [`useOptions`](#useoptions)
* and [`useProps`](#useprops).
*
* @example
* import { SystemProvider, useToken } from "reakit-system";
*
* const system = {
* token: "value",
* };
*
* function Component(props) {
* const token = useToken("token", "default value");
* return <div {...props}>{token}</div>;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <Component />
* </SystemProvider>
* );
* }
*/
function useToken(token, defaultValue) {
React.useDebugValue(token);
var context = React.useContext(SystemContext.SystemContext);
return context[token] != null ? context[token] : defaultValue;
}
exports.useToken = useToken;

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-system/mergeSystem",
"private": true,
"sideEffects": false,
"main": "../lib/mergeSystem",
"module": "../es/mergeSystem",
"types": "../ts/mergeSystem"
}

View File

@@ -0,0 +1,41 @@
{
"name": "reakit-system",
"version": "0.15.2",
"description": "Reakit System utils",
"sideEffects": false,
"license": "MIT",
"repository": "https://github.com/reakit/reakit/tree/master/packages/reakit-system",
"main": "lib/index.js",
"module": "es/index.js",
"unpkg": "dist/reakit-system.min.js",
"types": "ts",
"author": {
"name": "Diego Haz",
"email": "hazdiego@gmail.com",
"url": "https://github.com/diegohaz"
},
"scripts": {
"test": "jest",
"coverage": "yarn test --coverage",
"postcoverage": "open-cli coverage/lcov-report/index.html",
"lint": "eslint . --ext js,ts,tsx",
"clean": "node ../../scripts/build/clean.js",
"build": "node ../../scripts/build/build.js",
"docs": "documentation readme src/*.{ts,tsx} --markdown-toc-max-depth=2 --section=API --parse-extension ts --parse-extension tsx",
"preversion": "yarn lint && yarn test && yarn docs && yarn build",
"postpublish": "yarn clean"
},
"keywords": [
"reakit",
"react",
"system"
],
"dependencies": {
"reakit-utils": "^0.15.2"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
},
"gitHead": "e30e656b303f014fb841893c003aac2a5a5ac6fa"
}

View File

@@ -0,0 +1,9 @@
import * as React from "react";
import { useCreateElement } from "./useCreateElement";
export type SystemContextType = {
useCreateElement?: typeof useCreateElement;
[key: string]: any;
};
export const SystemContext = React.createContext<SystemContextType>({});

View File

@@ -0,0 +1,37 @@
import * as React from "react";
import { SystemContextType, SystemContext } from "./SystemContext";
export type SystemProviderProps = {
children: React.ReactNode;
unstable_system: SystemContextType;
};
/**
* Provider component that is used by `reakit`'s `Provider` underneath.
*
* @example
* // instead of using
* import { Provider } from "reakit";
* // you can use this
* import { SystemProvider } from "reakit-system";
* // reakit's Provider has more features, such as ID generation
* import * as system from "reakit-system-bootstrap";
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <div>App</div>
* </SystemProvider>
* );
* }
*
* @param props
*/
export function SystemProvider({
children,
unstable_system: system,
}: SystemProviderProps) {
return (
<SystemContext.Provider value={system}>{children}</SystemContext.Provider>
);
}

View File

@@ -0,0 +1,106 @@
import * as React from "react";
import { render } from "reakit-test-utils";
import { createComponent } from "../createComponent";
test("keys", () => {
const useHook = ({ children }: { children: string }) => ({ children });
useHook.__keys = ["children"] as const;
const Component = createComponent({ as: "div", useHook });
const { getByText } = render(<Component>component</Component>);
expect(getByText("component")).toBeDefined();
});
test("as string", () => {
const useA = ({ a }: { a: string }) => ({ children: a });
useA.__keys = ["a"] as const;
const A = createComponent({ as: "div", useHook: useA });
const { getByText } = render(<A as="span" a="a" />);
expect(getByText("a")).toMatchInlineSnapshot(`
<span>
a
</span>
`);
});
test("as component", () => {
const useA = ({ a }: { a: string }, htmlProps: any) => ({
children: a,
...htmlProps,
});
useA.__keys = ["a"] as const;
const A = createComponent({ as: "div", useHook: useA });
const B = ({ b, ...props }: { b: string }) => <div id={b} {...props} />;
const { getByText } = render(<A as={B} a="a" b="b" />);
expect(getByText("a")).toMatchInlineSnapshot(`
<div
id="b"
>
a
</div>
`);
});
test("as generic component", () => {
const useA = ({ a }: { a: string }, htmlProps: any) => ({
children: a,
...htmlProps,
});
useA.__keys = ["a"] as const;
const A = createComponent({ as: "div", useHook: useA });
function B<T extends string>({ b, ...props }: { b: T }) {
return <div id={b} {...props} />;
}
const { getByText } = render(<A as={B} a="a" b="b" />);
expect(getByText("a")).toMatchInlineSnapshot(`
<div
id="b"
>
a
</div>
`);
});
test("as other component created with createComponent", () => {
const useA = ({ a }: { a: string }, h: any) => ({ children: a, ...h });
useA.__keys = ["a"] as const;
const A = createComponent({ as: "div", useHook: useA });
const useB = ({ b }: { b: string }, h: any) => ({ id: b, ...h });
useB.__keys = ["b"] as const;
const B = createComponent({ as: "div", useHook: useB });
const { getByText } = render(<A as={B} a="a" b="b" />);
expect(getByText("a")).toMatchInlineSnapshot(`
<div
id="b"
>
a
</div>
`);
});
test("wrap", () => {
const useA = (_: any, h: any) => ({
wrapElement: (element: React.ReactNode) => (
<div id="wrapper">{element}</div>
),
...h,
});
const A = createComponent({ as: "span", useHook: useA });
const { baseElement } = render(<A id="a">a</A>);
expect(baseElement).toMatchInlineSnapshot(`
<body>
<div>
<div
id="wrapper"
>
<span
id="a"
>
a
</span>
</div>
</div>
</body>
`);
});

View File

@@ -0,0 +1,234 @@
import * as React from "react";
import { render } from "reakit-test-utils";
import { createHook } from "../createHook";
import { SystemProvider } from "../SystemProvider";
type Options = {
a: string;
};
test("useProps", () => {
const useHook = createHook<Options, React.HTMLAttributes<any>>({
useProps(options, htmlProps) {
return {
...htmlProps,
"data-a": options.a,
};
},
});
expect(useHook({ a: "a" }, { id: "a" })).toMatchInlineSnapshot(`
Object {
"data-a": "a",
"id": "a",
}
`);
});
test("useProps undefined props", () => {
const useHook = createHook<{}, React.HTMLAttributes<any>>({
useProps(_, htmlProps) {
return {
...htmlProps,
"data-a": undefined,
};
},
});
expect(useHook({}, { id: "a" })).toMatchInlineSnapshot(`
Object {
"id": "a",
}
`);
});
test("compose useProps", () => {
const useHook = createHook<Options, React.HTMLAttributes<any>>({
useProps(options, htmlProps) {
return {
...htmlProps,
"data-a": options.a,
};
},
});
type Options2 = Options & {
b: string;
};
const useHook2 = createHook<Options2, React.HTMLAttributes<any>>({
compose: [useHook],
useProps(options, htmlProps) {
return {
...htmlProps,
"data-b": options.b,
};
},
});
expect(useHook2({ a: "a", b: "b" }, { id: "a" })).toMatchInlineSnapshot(`
Object {
"data-a": "a",
"data-b": "b",
"id": "a",
}
`);
});
test("useOptions", () => {
const useHook = createHook<Options, React.HTMLAttributes<any>>({
useOptions(options) {
return {
...options,
a: "a",
};
},
useProps(options, htmlProps) {
return {
...htmlProps,
id: options.a,
};
},
});
expect(useHook()).toEqual({ id: "a" });
});
test("compose useOptions", () => {
const useHook = createHook<Options, React.HTMLAttributes<any>>({
useOptions(options) {
return {
...options,
a: `${options.a}b`,
};
},
});
const useHook2 = createHook<Options, React.HTMLAttributes<any>>({
compose: [useHook],
useOptions(options) {
return {
...options,
a: "a",
};
},
useProps(options, htmlProps) {
return {
...htmlProps,
id: options.a,
};
},
});
expect(useHook2()).toEqual({ id: "ab" });
});
test("useComposeOptions", () => {
const useHook = createHook<Options, React.HTMLAttributes<any>>({
useProps(options, htmlProps) {
return {
...htmlProps,
id: `${options.a}b`,
};
},
});
const useHook2 = createHook<Options, React.HTMLAttributes<any>>({
compose: [useHook],
useComposeOptions(options) {
return { ...options, a: "a" };
},
});
expect(useHook2()).toEqual({ id: "ab" });
});
test("name", () => {
const useHook = createHook<Options, React.HTMLAttributes<any>>({ name: "A" });
expect(useHook.name).toBe("useA");
});
test("name and context", () => {
const useHook = createHook<Options, React.HTMLAttributes<any>>({ name: "A" });
const Test = () => {
return <div {...useHook()} />;
};
const system = {
useAProps: (_: Options, htmlProps: React.HTMLAttributes<any>) => ({
...htmlProps,
id: "a",
}),
};
const { baseElement } = render(
<SystemProvider unstable_system={system}>
<Test />
</SystemProvider>
);
expect(baseElement).toMatchInlineSnapshot(`
<body>
<div>
<div
id="a"
/>
</div>
</body>
`);
});
test("name and context with useProps", () => {
const useHook = createHook<Options, React.HTMLAttributes<any>>({
name: "A",
useProps(_, htmlProps) {
return { className: "a", ...htmlProps };
},
});
const Test = () => {
return <div {...useHook()} />;
};
const system = {
useAProps: (_: Options, htmlProps: React.HTMLAttributes<any>) => ({
...htmlProps,
id: "a",
}),
};
const { baseElement } = render(
<SystemProvider unstable_system={system}>
<Test />
</SystemProvider>
);
expect(baseElement).toMatchInlineSnapshot(`
<body>
<div>
<div
class="a"
id="a"
/>
</div>
</body>
`);
});
test("name and context with useOptions", () => {
const useHook = createHook<Options, React.HTMLAttributes<any>>({
name: "A",
useOptions(options) {
return {
...options,
a: "a",
};
},
});
const Test = () => {
return <div {...useHook()} />;
};
const system = {
useAProps: (options: Options, htmlProps: React.HTMLAttributes<any>) => ({
...htmlProps,
id: options.a,
}),
};
const { baseElement } = render(
<SystemProvider unstable_system={system}>
<Test />
</SystemProvider>
);
expect(baseElement).toMatchInlineSnapshot(`
<body>
<div>
<div
id="a"
/>
</div>
</body>
`);
});

View File

@@ -0,0 +1,82 @@
import { mergeSystem } from "../mergeSystem";
test("single primitive prop", () => {
const system = { a: "a" };
const merged = mergeSystem(system, {});
expect(merged.a).toBe("a");
});
test("different primitive props", () => {
const system1 = { a: "a" };
const system2 = { b: "b" };
const merged = mergeSystem(system1, system2);
expect(merged.a).toBe("a");
expect(merged.b).toBe("b");
});
test("same primitive props with different values", () => {
const system1 = { a: "a" };
const system2 = { a: "b" };
const merged = mergeSystem(system1, system2);
expect(merged.a).toBe("b");
});
test("single object prop", () => {
const system = { a: { a: "a" } };
const merged = mergeSystem(system, {});
expect(merged.a.a).toBe("a");
});
test("different object props", () => {
const system1 = { a: { a: "a" } };
const system2 = { b: { b: "b" } };
const merged = mergeSystem(system1, system2);
expect(merged.a.a).toBe("a");
expect(merged.b.b).toBe("b");
});
test("same object props with different values", () => {
const system1 = { a: { a: "a" } };
const system2 = { a: { b: "b" } };
const merged = mergeSystem(system1, system2);
expect(merged.a.a).toBe("a");
expect(merged.a.b).toBe("b");
});
test("same object props with intersection values", () => {
const system1 = { a: { a: "a" } };
const system2 = { a: { a: "b", b: "b" } };
const merged = mergeSystem(system1, system2);
expect(merged.a.a).toBe("b");
expect(merged.a.b).toBe("b");
});
test("single function props", () => {
const system = { fn: jest.fn() };
const merged = mergeSystem(system, {});
expect(merged.fn).toBe(system.fn);
merged.fn(1, 2, 3, 4, 5);
expect(system.fn).toBeCalledWith(1, 2, 3, 4, 5);
});
test("different function props", () => {
const system1 = { fn1: jest.fn() };
const system2 = { fn2: jest.fn() };
const merged = mergeSystem(system1, system2);
expect(merged.fn1).toBe(system1.fn1);
expect(merged.fn2).toBe(system2.fn2);
merged.fn1(1, 2, 3, 4, 5);
merged.fn2(1, 2, 3, 4, 5);
expect(system1.fn1).toBeCalledWith(1, 2, 3, 4, 5);
expect(system2.fn2).toBeCalledWith(1, 2, 3, 4, 5);
});
test("same function props with different values", () => {
const impl = (a: number, b: number, c: number) => a + b + c;
const system1 = { fn: jest.fn(impl) };
const system2 = { fn: jest.fn(impl) };
const merged = mergeSystem(system1, system2);
merged.fn(1, 2, 3);
expect(system1.fn).toBeCalledWith(1, 2, 3);
expect(system2.fn).toBeCalledWith(1, 2, 6);
});

View File

@@ -0,0 +1,78 @@
import * as React from "react";
import { render } from "reakit-test-utils";
import { createComponent } from "../createComponent";
test("as string", () => {
const useA = ({ a }: { a: string }) => ({ children: a });
const A = createComponent({ as: "div", useHook: useA });
const { getByText } = render(<A as="span" state={{ a: "a" }} />);
expect(getByText("a")).toMatchInlineSnapshot(`
<span>
a
</span>
`);
});
test("as component", () => {
const useA = ({ a }: { a: string }, htmlProps: any) => ({
children: a,
...htmlProps,
});
const A = createComponent({ as: "div", useHook: useA });
const B = ({ b, state, ...props }: { state: any; b: string }) => (
<div id={b} {...props} />
);
const { getByText } = render(<A as={B} state={{ a: "a" }} b="b" />);
expect(getByText("a")).toMatchInlineSnapshot(`
<div
id="b"
>
a
</div>
`);
});
test("as generic component", () => {
const useA = ({ a }: { a: string }, htmlProps: any) => ({
children: a,
...htmlProps,
});
const A = createComponent({ as: "div", useHook: useA });
function B<T extends string>({ b, state, ...props }: { state: any; b: T }) {
return <div id={b} {...props} />;
}
const { getByText } = render(<A as={B} state={{ a: "a" }} b="b" />);
expect(getByText("a")).toMatchInlineSnapshot(`
<div
id="b"
>
a
</div>
`);
});
test("wrap", () => {
const useA = (_: any, h: any) => ({
wrapElement: (element: React.ReactNode) => (
<div id="wrapper">{element}</div>
),
...h,
});
const A = createComponent({ as: "span", useHook: useA });
const { baseElement } = render(<A id="a">a</A>);
expect(baseElement).toMatchInlineSnapshot(`
<body>
<div>
<div
id="wrapper"
>
<span
id="a"
>
a
</span>
</div>
</div>
</body>
`);
});

View File

@@ -0,0 +1,78 @@
import * as React from "react";
import { render } from "reakit-test-utils";
import { renderHook } from "reakit-test-utils/hooks";
import { Provider } from "reakit/Provider";
import { useCreateElement } from "../useCreateElement";
test("useCreateElement", () => {
const { result } = renderHook(() =>
useCreateElement("div", { a: "a" }, "div")
);
expect(result.current).toMatchInlineSnapshot(`
<div
a="a"
>
div
</div>
`);
});
test("render props", () => {
const { result } = renderHook(() =>
useCreateElement("div", { a: "a" }, ({ a }: { a: string }) => (
<div id={a}>div</div>
))
);
expect(result.current).toMatchInlineSnapshot(`
<div
id="a"
>
div
</div>
`);
});
test("render props with component type", () => {
type HTMLProps = React.HTMLAttributes<any>;
type AProps = { children: (props: HTMLProps) => React.ReactElement };
const A = ({ children }: AProps) => children({ className: "a" });
const B = () =>
useCreateElement(A, {}, (props: HTMLProps) => <div {...props}>a</div>);
const { container } = render(<B />);
expect(container).toMatchInlineSnapshot(`
<div>
<div
class="a"
>
a
</div>
</div>
`);
});
test("context", () => {
const { result } = renderHook(
() => useCreateElement("div", { a: "a" }, "div"),
{
wrapper: ({ children }) => (
<Provider
unstable_system={{
useCreateElement: (_, props, c) => <p {...props}>{c}</p>,
}}
>
{children}
</Provider>
),
}
);
expect(result.current).toMatchInlineSnapshot(`
<p
a="a"
>
div
</p>
`);
});

View File

@@ -0,0 +1,35 @@
import * as React from "react";
import { renderHook } from "reakit-test-utils/hooks";
import { useProps } from "../useProps";
import { SystemProvider, SystemProviderProps } from "../SystemProvider";
import { SystemContextType } from "../SystemContext";
function render(
system: SystemContextType,
...args: Parameters<typeof useProps>
) {
return renderHook(() => useProps(...args), {
wrapper: (props: SystemProviderProps) => (
<SystemProvider
{...props}
unstable_system={props.unstable_system || system}
/>
),
}).result;
}
test("useProps", () => {
const result = render(
{
useAProps: (options: { a: string }) => options.a,
},
"A",
{ a: "a" }
);
expect(result.current).toBe("a");
});
test("default return", () => {
const result = render({}, "A", undefined, { id: "id" });
expect(result.current).toEqual({ id: "id" });
});

View File

@@ -0,0 +1,29 @@
import * as React from "react";
import { renderHook } from "reakit-test-utils/hooks";
import { useToken } from "../useToken";
import { SystemProvider, SystemProviderProps } from "../SystemProvider";
import { SystemContextType } from "../SystemContext";
function render(
system: SystemContextType,
...args: Parameters<typeof useToken>
) {
return renderHook(() => useToken(...args), {
wrapper: (props: SystemProviderProps) => (
<SystemProvider
{...props}
unstable_system={props.unstable_system || system}
/>
),
}).result;
}
test("useToken", () => {
const result = render({ a: "a" }, "a");
expect(result.current).toBe("a");
});
test("default value", () => {
const result = render({ a: "a" }, "b", "b");
expect(result.current).toBe("b");
});

View File

@@ -0,0 +1,6 @@
import { isRenderProp } from "../isRenderProp";
test("isRenderProp", () => {
expect(isRenderProp("a")).toBe(false);
expect(isRenderProp(() => {})).toBe(true);
});

View File

@@ -0,0 +1,13 @@
import { reduceObjects } from "../reduceObjects";
test("reduceObjects", () => {
expect(reduceObjects([{ a: "a" }, { a: "b" }])).toEqual({ a: ["a", "b"] });
expect(
reduceObjects(
[{ a: "a" }, { a: "b" }],
(val, key) => key === "a" && val === "a"
)
).toEqual({
a: ["a"],
});
});

View File

@@ -0,0 +1,7 @@
import * as React from "react";
export function forwardRef<T extends React.ForwardRefRenderFunction<any, any>>(
component: T
) {
return (React.forwardRef(component) as unknown) as T;
}

View File

@@ -0,0 +1,5 @@
import { RenderProp } from "reakit-utils/types";
export function isRenderProp(children: any): children is RenderProp {
return typeof children === "function";
}

View File

@@ -0,0 +1,11 @@
import * as React from "react";
export function memo<T extends React.ComponentType<any>>(
component: T,
propsAreEqual?: (
prevProps: Readonly<React.ComponentProps<T>>,
nextProps: Readonly<React.ComponentProps<T>>
) => boolean
) {
return (React.memo(component, propsAreEqual) as unknown) as T;
}

View File

@@ -0,0 +1,21 @@
/**
* Transforms [{ a: "a" }, { a: "b" }] into { a: ["a", "b"] }
*/
export function reduceObjects<T extends Record<string, any>>(
objects: T[],
filter?: (value: T[keyof T], key: keyof T) => boolean
) {
const result = {} as { [K in keyof T]?: Array<T[K]> };
for (const object of objects) {
const keys = Object.keys(object) as Array<keyof T>;
for (const key of keys) {
// eslint-disable-next-line no-continue
if (filter && !filter(object[key], key)) continue;
const value = (result[key] || []) as Array<T[keyof T]>;
result[key] = [...value, object[key]];
}
}
return result;
}

View File

@@ -0,0 +1,105 @@
import * as React from "react";
import { As, PropsWithAs } from "reakit-utils/types";
import { splitProps } from "reakit-utils/splitProps";
import { shallowEqual } from "reakit-utils/shallowEqual";
import { normalizePropsAreEqual } from "reakit-utils/normalizePropsAreEqual";
import { forwardRef } from "./__utils/forwardRef";
import { useCreateElement as defaultUseCreateElement } from "./useCreateElement";
import { memo } from "./__utils/memo";
type RoleHTMLProps = React.HTMLAttributes<any> &
React.RefAttributes<any> & {
wrapElement?: (element: React.ReactNode) => React.ReactNode;
};
type Hook<O> = {
(options?: O, props?: RoleHTMLProps): RoleHTMLProps;
unstable_propsAreEqual?: (prev: O, next: O) => boolean;
__keys?: ReadonlyArray<any>;
};
type Options<T extends As, O> = {
as: T;
useHook?: Hook<O>;
keys?: ReadonlyArray<any>;
memo?: boolean;
propsAreEqual?: (prev: O, next: O) => boolean;
useCreateElement?: (
type: T,
props: Omit<PropsWithAs<O, T>, "as">,
children?: React.ReactNode
) => JSX.Element;
};
export type Component<T extends As, O> = {
<TT extends As>(props: PropsWithAs<O, TT> & { as: TT }): JSX.Element;
(props: PropsWithAs<O, T>): JSX.Element;
displayName?: string;
unstable_propsAreEqual: (
prev: PropsWithAs<O, T>,
next: PropsWithAs<O, T>
) => boolean;
__keys?: ReadonlyArray<any>;
};
/**
* Creates a React component.
*
* @example
* import { createComponent } from "reakit-system";
*
* const A = createComponent({ as: "a" });
*
* @param options
*/
export function createComponent<T extends As, O>({
as: type,
useHook,
memo: shouldMemo,
propsAreEqual = useHook?.unstable_propsAreEqual,
keys = useHook?.__keys || [],
useCreateElement = defaultUseCreateElement,
}: Options<T, O>) {
let Comp = ((
{ as = type, ...props }: PropsWithAs<O, T>,
ref: React.Ref<T>
) => {
if (useHook) {
const [options, htmlProps] = splitProps(props, keys);
const { wrapElement, ...elementProps } = useHook(options, {
ref,
...htmlProps,
});
// @ts-ignore
const asKeys = as.render?.__keys || as.__keys;
const asOptions = asKeys && splitProps(props, asKeys)[0];
const allProps = asOptions
? { ...elementProps, ...asOptions }
: elementProps;
const element = useCreateElement(as, allProps as typeof props);
if (wrapElement) {
return wrapElement(element);
}
return element;
}
return useCreateElement(as, { ref, ...props });
}) as Component<T, O>;
if (process.env.NODE_ENV !== "production" && useHook) {
Comp.displayName = useHook.name.replace(/^(unstable_)?use/, "");
}
Comp = forwardRef(Comp);
if (shouldMemo) {
Comp = memo(Comp, propsAreEqual && normalizePropsAreEqual(propsAreEqual));
}
Comp.__keys = keys;
Comp.unstable_propsAreEqual = normalizePropsAreEqual(
propsAreEqual || shallowEqual
);
return Comp;
}

View File

@@ -0,0 +1,136 @@
import { toArray } from "reakit-utils/toArray";
import { shallowEqual } from "reakit-utils/shallowEqual";
import { useOptions } from "./useOptions";
import { useProps } from "./useProps";
type Hook<O = any, P = any> = {
(options?: O, htmlProps?: P, unstable_ignoreUseOptions?: boolean): P;
unstable_propsAreEqual: (prev: O & P, next: O & P) => boolean;
__keys: ReadonlyArray<any>;
__useOptions: (options: O, htmlProps: P) => O;
};
type CreateHookOptions<O, P> = {
name?: string;
compose?: Hook | Hook[];
useState?: { (): any; __keys: ReadonlyArray<any> };
useOptions?: (options: O, htmlProps: P) => O;
useProps?: (options: O, htmlProps: P) => P;
useComposeOptions?: (options: O, htmlProps: P) => O;
useComposeProps?: (options: O, htmlProps: P) => P;
propsAreEqual?: (prev: O & P, next: O & P) => boolean;
keys?: ReadonlyArray<string>;
};
/**
* Creates a React custom hook that will return component props.
*
* @example
* import { createHook } from "reakit-system";
*
* const useA = createHook({
* name: "A",
* keys: ["url"], // custom props/options keys
* useProps(options, htmlProps) {
* return {
* ...htmlProps,
* href: options.url,
* };
* },
* });
*
* function A({ url, ...htmlProps }) {
* const props = useA({ url }, htmlProps);
* return <a {...props} />;
* }
*
* @param options
*/
export function createHook<O, P>(options: CreateHookOptions<O, P>) {
const composedHooks = toArray(options.compose) as Hook[];
const __useOptions = (hookOptions: O, htmlProps: P) => {
// Call the current hook's useOptions first
if (options.useOptions) {
hookOptions = options.useOptions(hookOptions, htmlProps);
}
// If there's name, call useOptions from the system context
if (options.name) {
hookOptions = useOptions(options.name, hookOptions, htmlProps);
}
// Run composed hooks useOptions
if (options.compose) {
for (const hook of composedHooks) {
hookOptions = hook.__useOptions(hookOptions, htmlProps);
}
}
return hookOptions;
};
const useHook: Hook<O, P> = (
hookOptions = {} as O,
htmlProps = {} as P,
unstable_ignoreUseOptions = false
) => {
// This won't execute when useHook was called from within another useHook
if (!unstable_ignoreUseOptions) {
hookOptions = __useOptions(hookOptions, htmlProps);
}
// Call the current hook's useProps
if (options.useProps) {
htmlProps = options.useProps(hookOptions, htmlProps);
}
// If there's name, call useProps from the system context
if (options.name) {
htmlProps = useProps(options.name, hookOptions, htmlProps) as P;
}
if (options.compose) {
if (options.useComposeOptions) {
hookOptions = options.useComposeOptions(hookOptions, htmlProps);
}
if (options.useComposeProps) {
htmlProps = options.useComposeProps(hookOptions, htmlProps);
} else {
for (const hook of composedHooks) {
htmlProps = hook(hookOptions, htmlProps, true);
}
}
}
// Remove undefined values from htmlProps
const finalHTMLProps = {} as P;
const definedHTMLProps = htmlProps || ({} as P);
for (const prop in definedHTMLProps) {
if (definedHTMLProps[prop] !== undefined) {
finalHTMLProps[prop] = definedHTMLProps[prop];
}
}
return finalHTMLProps;
};
useHook.__useOptions = __useOptions;
const composedKeys = composedHooks.reduce((keys, hook) => {
keys.push(...(hook.__keys || []));
return keys;
}, [] as string[]);
// It's used by createComponent to split option props (keys) and html props
useHook.__keys = [
...composedKeys,
...(options.useState?.__keys || []),
...(options.keys || []),
];
useHook.unstable_propsAreEqual =
options.propsAreEqual ||
composedHooks[0]?.unstable_propsAreEqual ||
shallowEqual;
if (process.env.NODE_ENV !== "production" && options.name) {
Object.defineProperty(useHook, "name", {
value: `use${options.name}`,
});
}
return useHook;
}

View File

@@ -0,0 +1,9 @@
export * from "./createComponent";
export * from "./createHook";
export * from "./mergeSystem";
export * from "./SystemContext";
export * from "./SystemProvider";
export * from "./useCreateElement";
export * from "./useOptions";
export * from "./useProps";
export * from "./useToken";

View File

@@ -0,0 +1,66 @@
import { isObject } from "reakit-utils/isObject";
import { UnionToIntersection } from "reakit-utils/types";
import { reduceObjects } from "./__utils/reduceObjects";
import { SystemContextType } from "./SystemContext";
function mergeFunctionsInObjects(objects: Array<Record<string, any>>) {
const object = reduceObjects(objects, (value) => typeof value === "function");
const keys = Object.keys(object);
const result: Record<string, any> = {};
for (const key of keys) {
const fns = object[key]!;
result[key] =
fns.length === 1
? fns[0]
: fns.reduce((lastHook, currHook) => (...args: any[]) =>
currHook(...args.slice(0, -1), lastHook(...args))
);
}
return result;
}
function mergeObjectsInObjects(systems: Array<Record<string, any>>) {
const object = reduceObjects(systems, isObject);
const keys = Object.keys(object);
const result: Record<string, any> = {};
for (const key of keys) {
const values = object[key]!;
result[key] = Object.assign({}, ...values);
}
return result;
}
/**
* Merges multiple system objects into a single system object.
*
* @example
* import { Provider } from "reakit";
* import { mergeSystem } from "reakit-system";
* import * as bootstrapSystem from "reakit-system-bootstrap";
*
* const mySystem = {
* useButtonProps() {},
* };
*
* const system = mergeSystem(bootstrapSystem, mySystem);
*
* function App() {
* return (
* <Provider unstable_system={system}>
* <div>App</div>
* </Provider>
* );
* }
*/
export function mergeSystem<T extends SystemContextType[]>(...systems: T) {
return Object.assign(
{},
...systems,
mergeObjectsInObjects(systems),
mergeFunctionsInObjects(systems)
) as UnionToIntersection<T[number]>;
}

View File

@@ -0,0 +1,54 @@
import * as React from "react";
import { As } from "reakit-utils/types";
import { isRenderProp } from "./__utils/isRenderProp";
import { SystemContext } from "./SystemContext";
/**
* Custom hook that will call `children` if it's a function. If
* `useCreateElement` has been passed to the context, it'll be used instead.
*
* @example
* import React from "react";
* import { SystemProvider, useCreateElement } from "reakit-system";
*
* const system = {
* useCreateElement(type, props, children = props.children) {
* // very similar to what `useCreateElement` does already
* if (typeof children === "function") {
* const { children: _, ...rest } = props;
* return children(rest);
* }
* return React.createElement(type, props, children);
* },
* };
*
* function Component(props) {
* return useCreateElement("div", props);
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <Component url="url">{({ url }) => <a href={url}>link</a>}</Component>
* </SystemProvider>
* );
* }
*/
export const useCreateElement = <T extends As>(
type: T,
props: Record<string, any>,
children: React.ReactNode = props.children
): JSX.Element => {
const context = React.useContext(SystemContext);
if (context.useCreateElement) {
return context.useCreateElement(type, props, children);
}
if (typeof type === "string" && isRenderProp(children)) {
const { children: _, ...rest } = props;
return children(rest);
}
return React.createElement(type, props, children);
};

View File

@@ -0,0 +1,48 @@
import * as React from "react";
import { useToken } from "./useToken";
/**
* React custom hook that returns the options returned by a given
* `use${name}Options` in the SystemContext.
*
* @example
* import React from "react";
* import { SystemProvider, useOptions } from "reakit-system";
*
* const system = {
* useAOptions(options, htmlProps) {
* return {
* ...options,
* url: htmlProps.href,
* };
* },
* };
*
* function A({ url, ...htmlProps }) {
* const options = useOptions("A", { url }, htmlProps);
* return <a href={options.url} {...htmlProps} />;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <A href="url">
* It will convert href into url in useAOptions and then url into href in A
* </A>
* </SystemProvider>
* );
* }
*/
export function useOptions<T = {}>(
name: string,
options: T = {} as T,
htmlProps: React.HTMLAttributes<any> & React.RefAttributes<any> = {}
): T {
const hookName = `use${name}Options`;
React.useDebugValue(hookName);
const useHook = useToken(hookName);
if (useHook) {
return { ...options, ...useHook(options, htmlProps) };
}
return options;
}

View File

@@ -0,0 +1,45 @@
import * as React from "react";
import { useToken } from "./useToken";
/**
* React custom hook that returns the props returned by a given
* `use${name}Props` in the SystemContext.
*
* @example
* import { SystemProvider, useProps } from "reakit-system";
*
* const system = {
* useAProps(options, htmlProps) {
* return {
* ...htmlProps,
* href: options.url,
* };
* },
* };
*
* function A({ url, ...htmlProps }) {
* const props = useProps("A", { url }, htmlProps);
* return <a {...props} />;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <A url="url">It will convert url into href in useAProps</A>
* </SystemProvider>
* );
* }
*/
export function useProps(
name: string,
options: Record<string, any> = {},
htmlProps: React.HTMLAttributes<any> & React.RefAttributes<any> = {}
): React.HTMLAttributes<any> & React.RefAttributes<any> {
const hookName = `use${name}Props`;
React.useDebugValue(hookName);
const useHook = useToken(hookName);
if (useHook) {
return useHook(options, htmlProps);
}
return htmlProps;
}

View File

@@ -0,0 +1,33 @@
import * as React from "react";
import { SystemContext } from "./SystemContext";
/**
* React custom hook that returns the value of any token defined in the
* SystemContext. It's mainly used internally in [`useOptions`](#useoptions)
* and [`useProps`](#useprops).
*
* @example
* import { SystemProvider, useToken } from "reakit-system";
*
* const system = {
* token: "value",
* };
*
* function Component(props) {
* const token = useToken("token", "default value");
* return <div {...props}>{token}</div>;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <Component />
* </SystemProvider>
* );
* }
*/
export function useToken<T = any>(token: string, defaultValue?: T): T {
React.useDebugValue(token);
const context = React.useContext(SystemContext);
return context[token] != null ? context[token] : defaultValue;
}

View File

@@ -0,0 +1,7 @@
import * as React from "react";
import { useCreateElement } from "./useCreateElement";
export declare type SystemContextType = {
useCreateElement?: typeof useCreateElement;
[key: string]: any;
};
export declare const SystemContext: React.Context<SystemContextType>;

View File

@@ -0,0 +1,28 @@
import * as React from "react";
import { SystemContextType } from "./SystemContext";
export declare type SystemProviderProps = {
children: React.ReactNode;
unstable_system: SystemContextType;
};
/**
* Provider component that is used by `reakit`'s `Provider` underneath.
*
* @example
* // instead of using
* import { Provider } from "reakit";
* // you can use this
* import { SystemProvider } from "reakit-system";
* // reakit's Provider has more features, such as ID generation
* import * as system from "reakit-system-bootstrap";
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <div>App</div>
* </SystemProvider>
* );
* }
*
* @param props
*/
export declare function SystemProvider({ children, unstable_system: system, }: SystemProviderProps): JSX.Element;

View File

@@ -0,0 +1,2 @@
import * as React from "react";
export declare function forwardRef<T extends React.ForwardRefRenderFunction<any, any>>(component: T): T;

View File

@@ -0,0 +1,2 @@
import { RenderProp } from "reakit-utils/types";
export declare function isRenderProp(children: any): children is RenderProp;

View File

@@ -0,0 +1,2 @@
import * as React from "react";
export declare function memo<T extends React.ComponentType<any>>(component: T, propsAreEqual?: (prevProps: Readonly<React.ComponentProps<T>>, nextProps: Readonly<React.ComponentProps<T>>) => boolean): T;

View File

@@ -0,0 +1,4 @@
/**
* Transforms [{ a: "a" }, { a: "b" }] into { a: ["a", "b"] }
*/
export declare function reduceObjects<T extends Record<string, any>>(objects: T[], filter?: (value: T[keyof T], key: keyof T) => boolean): { [K in keyof T]?: T[K][] | undefined; };

View File

@@ -0,0 +1,39 @@
import * as React from "react";
import { As, PropsWithAs } from "reakit-utils/types";
declare type RoleHTMLProps = React.HTMLAttributes<any> & React.RefAttributes<any> & {
wrapElement?: (element: React.ReactNode) => React.ReactNode;
};
declare type Hook<O> = {
(options?: O, props?: RoleHTMLProps): RoleHTMLProps;
unstable_propsAreEqual?: (prev: O, next: O) => boolean;
__keys?: ReadonlyArray<any>;
};
declare type Options<T extends As, O> = {
as: T;
useHook?: Hook<O>;
keys?: ReadonlyArray<any>;
memo?: boolean;
propsAreEqual?: (prev: O, next: O) => boolean;
useCreateElement?: (type: T, props: Omit<PropsWithAs<O, T>, "as">, children?: React.ReactNode) => JSX.Element;
};
export declare type Component<T extends As, O> = {
<TT extends As>(props: PropsWithAs<O, TT> & {
as: TT;
}): JSX.Element;
(props: PropsWithAs<O, T>): JSX.Element;
displayName?: string;
unstable_propsAreEqual: (prev: PropsWithAs<O, T>, next: PropsWithAs<O, T>) => boolean;
__keys?: ReadonlyArray<any>;
};
/**
* Creates a React component.
*
* @example
* import { createComponent } from "reakit-system";
*
* const A = createComponent({ as: "a" });
*
* @param options
*/
export declare function createComponent<T extends As, O>({ as: type, useHook, memo: shouldMemo, propsAreEqual, keys, useCreateElement, }: Options<T, O>): Component<T, O>;
export {};

View File

@@ -0,0 +1,46 @@
declare type Hook<O = any, P = any> = {
(options?: O, htmlProps?: P, unstable_ignoreUseOptions?: boolean): P;
unstable_propsAreEqual: (prev: O & P, next: O & P) => boolean;
__keys: ReadonlyArray<any>;
__useOptions: (options: O, htmlProps: P) => O;
};
declare type CreateHookOptions<O, P> = {
name?: string;
compose?: Hook | Hook[];
useState?: {
(): any;
__keys: ReadonlyArray<any>;
};
useOptions?: (options: O, htmlProps: P) => O;
useProps?: (options: O, htmlProps: P) => P;
useComposeOptions?: (options: O, htmlProps: P) => O;
useComposeProps?: (options: O, htmlProps: P) => P;
propsAreEqual?: (prev: O & P, next: O & P) => boolean;
keys?: ReadonlyArray<string>;
};
/**
* Creates a React custom hook that will return component props.
*
* @example
* import { createHook } from "reakit-system";
*
* const useA = createHook({
* name: "A",
* keys: ["url"], // custom props/options keys
* useProps(options, htmlProps) {
* return {
* ...htmlProps,
* href: options.url,
* };
* },
* });
*
* function A({ url, ...htmlProps }) {
* const props = useA({ url }, htmlProps);
* return <a {...props} />;
* }
*
* @param options
*/
export declare function createHook<O, P>(options: CreateHookOptions<O, P>): Hook<O, P>;
export {};

View File

@@ -0,0 +1,9 @@
export * from "./createComponent";
export * from "./createHook";
export * from "./mergeSystem";
export * from "./SystemContext";
export * from "./SystemProvider";
export * from "./useCreateElement";
export * from "./useOptions";
export * from "./useProps";
export * from "./useToken";

View File

@@ -0,0 +1,25 @@
import { UnionToIntersection } from "reakit-utils/types";
import { SystemContextType } from "./SystemContext";
/**
* Merges multiple system objects into a single system object.
*
* @example
* import { Provider } from "reakit";
* import { mergeSystem } from "reakit-system";
* import * as bootstrapSystem from "reakit-system-bootstrap";
*
* const mySystem = {
* useButtonProps() {},
* };
*
* const system = mergeSystem(bootstrapSystem, mySystem);
*
* function App() {
* return (
* <Provider unstable_system={system}>
* <div>App</div>
* </Provider>
* );
* }
*/
export declare function mergeSystem<T extends SystemContextType[]>(...systems: T): UnionToIntersection<T[number]>;

View File

@@ -0,0 +1,33 @@
import * as React from "react";
/**
* Custom hook that will call `children` if it's a function. If
* `useCreateElement` has been passed to the context, it'll be used instead.
*
* @example
* import React from "react";
* import { SystemProvider, useCreateElement } from "reakit-system";
*
* const system = {
* useCreateElement(type, props, children = props.children) {
* // very similar to what `useCreateElement` does already
* if (typeof children === "function") {
* const { children: _, ...rest } = props;
* return children(rest);
* }
* return React.createElement(type, props, children);
* },
* };
*
* function Component(props) {
* return useCreateElement("div", props);
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <Component url="url">{({ url }) => <a href={url}>link</a>}</Component>
* </SystemProvider>
* );
* }
*/
export declare const useCreateElement: <T extends React.ElementType<any>>(type: T, props: Record<string, any>, children?: React.ReactNode) => JSX.Element;

View File

@@ -0,0 +1,34 @@
import * as React from "react";
/**
* React custom hook that returns the options returned by a given
* `use${name}Options` in the SystemContext.
*
* @example
* import React from "react";
* import { SystemProvider, useOptions } from "reakit-system";
*
* const system = {
* useAOptions(options, htmlProps) {
* return {
* ...options,
* url: htmlProps.href,
* };
* },
* };
*
* function A({ url, ...htmlProps }) {
* const options = useOptions("A", { url }, htmlProps);
* return <a href={options.url} {...htmlProps} />;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <A href="url">
* It will convert href into url in useAOptions and then url into href in A
* </A>
* </SystemProvider>
* );
* }
*/
export declare function useOptions<T = {}>(name: string, options?: T, htmlProps?: React.HTMLAttributes<any> & React.RefAttributes<any>): T;

View File

@@ -0,0 +1,31 @@
import * as React from "react";
/**
* React custom hook that returns the props returned by a given
* `use${name}Props` in the SystemContext.
*
* @example
* import { SystemProvider, useProps } from "reakit-system";
*
* const system = {
* useAProps(options, htmlProps) {
* return {
* ...htmlProps,
* href: options.url,
* };
* },
* };
*
* function A({ url, ...htmlProps }) {
* const props = useProps("A", { url }, htmlProps);
* return <a {...props} />;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <A url="url">It will convert url into href in useAProps</A>
* </SystemProvider>
* );
* }
*/
export declare function useProps(name: string, options?: Record<string, any>, htmlProps?: React.HTMLAttributes<any> & React.RefAttributes<any>): React.HTMLAttributes<any> & React.RefAttributes<any>;

View File

@@ -0,0 +1,26 @@
/**
* React custom hook that returns the value of any token defined in the
* SystemContext. It's mainly used internally in [`useOptions`](#useoptions)
* and [`useProps`](#useprops).
*
* @example
* import { SystemProvider, useToken } from "reakit-system";
*
* const system = {
* token: "value",
* };
*
* function Component(props) {
* const token = useToken("token", "default value");
* return <div {...props}>{token}</div>;
* }
*
* function App() {
* return (
* <SystemProvider unstable_system={system}>
* <Component />
* </SystemProvider>
* );
* }
*/
export declare function useToken<T = any>(token: string, defaultValue?: T): T;

View File

@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "ts"
},
"include": [
"src",
"../../types"
]
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-system/useCreateElement",
"private": true,
"sideEffects": false,
"main": "../lib/useCreateElement",
"module": "../es/useCreateElement",
"types": "../ts/useCreateElement"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-system/useOptions",
"private": true,
"sideEffects": false,
"main": "../lib/useOptions",
"module": "../es/useOptions",
"types": "../ts/useOptions"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-system/useProps",
"private": true,
"sideEffects": false,
"main": "../lib/useProps",
"module": "../es/useProps",
"types": "../ts/useProps"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-system/useToken",
"private": true,
"sideEffects": false,
"main": "../lib/useToken",
"module": "../es/useToken",
"types": "../ts/useToken"
}

View File

@@ -0,0 +1,6 @@
dist
es
lib
ts
coverage
node_modules

View File

@@ -0,0 +1,356 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.15.2](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.15.1...reakit-utils@0.15.2) (2021-09-06)
**Note:** Version bump only for package reakit-utils
## [0.15.1](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.15.0...reakit-utils@0.15.1) (2020-12-11)
### Bug Fixes
* Accept other option props together with the `state` prop ([#799](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/799)) ([a21bb2b](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/a21bb2b22780121125bbf3dfc6160ac29e1a0741)), closes [#798](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/798)
* Add React 17 to peer dependencies ([#807](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/807)) ([411b5aa](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/411b5aa8adf63f3149b40db6a499e65b58929b29)), closes [#776](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/776)
* Fix `Menu` scroll jump ([#801](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/801)) ([96f5dd5](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/96f5dd52704444862d16167db3c82fb89838e3ae)), closes [#751](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/751)
# [0.15.0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.14.4...reakit-utils@0.15.0) (2020-11-12)
### Features
* Add `state` prop on all components ([#771](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/771)) ([4ed846d](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/4ed846d0a17e655d726572910b57b9ad3ebc235d)), closes [#744](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/744)
## [0.14.4](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.14.3...reakit-utils@0.14.4) (2020-09-22)
### Bug Fixes
* **reakit-utils:** Fix `getActiveElement` returning an empty object on IE 11 ([b7516c0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/b7516c01cc923d8e179743a07eba74a083132229))
## [0.14.3](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.14.2...reakit-utils@0.14.3) (2020-08-24)
### Bug Fixes
* **reakit-utils:** Fix `canUseDOM` to support IE11 window object ([#720](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/720)) ([ca9d94a](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/ca9d94aae947e88aae872ce15d7bc82712e1056f))
* Fix SSR check ([#717](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/717)) ([1f09fc9](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/1f09fc9879ecd9516d514c7a848b7a62a1b93358))
## [0.14.2](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.14.1...reakit-utils@0.14.2) (2020-08-17)
### Bug Fixes
* Fix blur event on `Composite` for React 17 ([#711](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/711)) ([0ad76e6](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/0ad76e61560da5f25e99a01d9842bf53e18d7993))
## [0.14.1](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.14.0...reakit-utils@0.14.1) (2020-08-13)
**Note:** Version bump only for package reakit-utils
# [0.14.0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.13.1...reakit-utils@0.14.0) (2020-08-06)
**Note:** Version bump only for package reakit-utils
## [0.13.1](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.13.0...reakit-utils@0.13.1) (2020-07-18)
### Bug Fixes
* Fix `Dialog` focus loss ([#682](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/682)) ([8ae0da7](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/8ae0da741ca45fed6bc1a7c25a3fc9aa60340b44)), closes [#677](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/677)
# [0.13.0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.13.0-alpha.0...reakit-utils@0.13.0) (2020-06-17)
**Note:** Version bump only for package reakit-utils
## [0.12.1](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.12.0...reakit-utils@0.12.1) (2020-06-04)
### Features
* **reakit-utils:** Accept undefined arguments on `shallowEqual` ([c710c93](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/c710c93a5afe0aed1cae157d5766f36eb9730fba))
# [0.12.0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.11.0...reakit-utils@0.12.0) (2020-04-29)
### Features
* **reakit-utils:** Add `shallowEqual` util ([c3e7a71](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/c3e7a717b182f1e0f9c734d2bc058787f091ce82))
# [0.11.0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.10.0...reakit-utils@0.11.0) (2020-04-20)
### Bug Fixes
* **reakit-utils:** Fix `getClosestFocusable` iteration ([b72c623](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/b72c6235a60d5ac624e30ba3acd808b937b06002))
* Fix `Composite` on IE11 ([#609](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/609)) ([555b931](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/555b931de003a81a635ed1d980d67f9c62fb91e0))
### Features
* Replace `unstable_animated` by `animated` with improvements on the API ([#616](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/616)) ([16f843f](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/16f843f8dc4b97a552d629bd41cf20107e307a77)), closes [#528](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/528)
### BREAKING CHANGES
* **This should affect only people who were using the `unstable_animated` API**: `DisclosureContent` and its derivative components don't add `hidden` class anymore. You should now use `[data-enter]` and `[data-leave]` selectors. For more details, see [Animating](https://reakit.io/docs/disclosure/#animating).
# [0.10.0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.9.0...reakit-utils@0.10.0) (2020-03-30)
### Bug Fixes
* Add ie11 ponyfill for Element.matches ([#555](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/555)) ([07488aa](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/07488aa1142ffba652c4582890f52bda9953966a)), closes [#556](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/556)
### Features
* **reakit-utils:** Add `flatten` util ([57ac450](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/57ac4503da4604bae5a18dc6d7e6644ec152daad))
* **reakit-utils:** Remove `warning` util ([ff98d43](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/ff98d43568790cc191fde1ee9b56a35311a3a10f))
### BREAKING CHANGES
* **reakit-utils:** `warning` has been removed from `reakit-utils`. Use the `reakit-warning` package instead.
# [0.9.0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.8.0...reakit-utils@0.9.0) (2020-02-10)
### Features
* **reakit-utils:** Add `useForkRef` method ([8366545](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/8366545bf372cb8fb7c61bd18785c780c3794361))
### BREAKING CHANGES
* **reakit-utils:** `mergeRefs` has been replaced by `useForkRef`. It's now a custom hook, so it should follow the rules of hooks.
*Before*:
```jsx
import React from "react";
import { mergeRefs } from "reakit-utils";
const Component = React.forwardRef((props, ref) => {
const internalRef = React.useRef();
return <div ref={mergeRefs(internalRef, ref)} {...props} />;
});
```
*After*:
```jsx
import React from "react";
import { useForkRef } from "reakit-utils";
const Component = React.forwardRef((props, ref) => {
const internalRef = React.useRef();
return <div ref={useForkRef(internalRef, ref)} {...props} />;
});
```
# [0.8.0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.7.3...reakit-utils@0.8.0) (2020-02-05)
### Features
* **reakit-utils:** Add `getActiveElement` method ([a252fcd](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/a252fcd))
* **reakit-utils:** Add `isButton` method ([8ff86fc](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/8ff86fc))
* **reakit-utils:** Add `isPlainObject` function ([faeb26f](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/faeb26f))
* **reakit-utils:** Remove `Omit` type ([24797e0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/24797e0))
### BREAKING CHANGES
* **reakit-utils:** `Omit` has been removed from `reakit-utils/types`. [TypeScript now supports it natively](https://www.typescriptlang.org/docs/handbook/utility-types.html#omittk).
## [0.7.3](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.7.2...reakit-utils@0.7.3) (2019-12-18)
**Note:** Version bump only for package reakit-utils
## [0.7.2](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.7.1...reakit-utils@0.7.2) (2019-11-22)
### Bug Fixes
* **reakit-utils:** Support iframes ([b6b3340](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/b6b3340))
## [0.7.1](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.7.0...reakit-utils@0.7.1) (2019-11-14)
**Note:** Version bump only for package reakit-utils
# [0.7.0](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.6.7...reakit-utils@0.7.0) (2019-11-08)
**Note:** Version bump only for package reakit-utils
## [0.6.7](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.6.6...reakit-utils@0.6.7) (2019-11-02)
### Bug Fixes
* Fix `Tabbable` focus behavior on Mac Safari/Firefox ([#458](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/458)) ([8306241](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/8306241))
## [0.6.6](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.6.5...reakit-utils@0.6.6) (2019-10-12)
### Bug Fixes
* Add a `useIsomorphicEffect` hook to allow proper SSR rendering ([#461](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/461)) ([47434b2](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/47434b2)), closes [#438](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/438)
## [0.6.5](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.6.4...reakit-utils@0.6.5) (2019-09-25)
### Bug Fixes
* Replace IE11 incompatible DOM features ([#443](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/443)) ([8837557](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/8837557)), closes [#360](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/360)
### Features
* Show warnings on console whenever it gets called, not only once ([efaa95e](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/efaa95e))
## [0.6.4](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.6.3...reakit-utils@0.6.4) (2019-09-19)
### Bug Fixes
* Fix `Dialog` initial focus ([#433](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/433)) ([a0916c7](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/a0916c7))
* Fix `Dialog` with `tabIndex={0}` not being included in the tab order ([#426](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/426)) ([bfb1d05](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/bfb1d05))
## [0.6.3](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.6.2...reakit-utils@0.6.3) (2019-08-25)
### Features
* **reakit-utils:** Move `tabbable` internal module to `reakit-utils` package ([b84acce](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/b84acce))
* Support nested `Tabbable` and `Rover` components ([#417](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/417)) ([ee9623e](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/ee9623e)), closes [#376](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/376)
## [0.6.2](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/compare/reakit-utils@0.6.1...reakit-utils@0.6.2) (2019-06-27)
### Bug Fixes
* Fix missing React Hooks deps ([b08b62c](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/b08b62c))
## 0.6.1 (2019-06-23)
### Features
* Move helpers to separate package (reakit-utils, reakit-system) ([#380](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/issues/380)) ([354b874](https://github.com/reakit/reakit/tree/master/packages/reakit-utils/commit/354b874))
### BREAKING CHANGES
* Utils aren't exported by `reakit` or `reakit/utils` anymore. Import them from the `reakit-utils` package instead.
* System utils aren't exported by `reakit` or `reakit/system` anymore. Import them from the `reakit-system` package instead.
* `Provider` isn't exported by `reakit/utils` or `reakit/utils/Provider` anymore. Import it from `reakit` or `reakit/Provider` instead.
# Change Log

21
node_modules/reakit/node_modules/reakit-utils/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Diego Haz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

981
node_modules/reakit/node_modules/reakit-utils/README.md generated vendored Normal file
View File

@@ -0,0 +1,981 @@
# reakit-utils
<a href="https://npmjs.org/package/reakit-utils"><img alt="NPM version" src="https://img.shields.io/npm/v/reakit-utils.svg" /></a>
> **This is experimental** and may have breaking changes in minor versions.
## Installation
npm:
```sh
npm i reakit-utils
```
Yarn:
```sh
yarn add reakit-utils
```
## API
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
#### Table of Contents
- [applyState](#applystate)
- [canUseDOM](#canusedom)
- [closest](#closest)
- [contains](#contains)
- [createEvent](#createevent)
- [createOnKeyDown](#createonkeydown)
- [isUA](#isua)
- [ensureFocus](#ensurefocus)
- [fireBlurEvent](#fireblurevent)
- [fireEvent](#fireevent)
- [fireKeyboardEvent](#firekeyboardevent)
- [flatten](#flatten)
- [getActiveElement](#getactiveelement)
- [getDocument](#getdocument)
- [getNextActiveElementOnBlur](#getnextactiveelementonblur)
- [getWindow](#getwindow)
- [hasFocus](#hasfocus)
- [hasFocusWithin](#hasfocuswithin)
- [isButton](#isbutton)
- [isEmpty](#isempty)
- [isInteger](#isinteger)
- [isObject](#isobject)
- [isPlainObject](#isplainobject)
- [isPortalEvent](#isportalevent)
- [isPromise](#ispromise)
- [isSelfTarget](#isselftarget)
- [isTextField](#istextfield)
- [matches](#matches)
- [normalizePropsAreEqual](#normalizepropsareequal)
- [omit](#omit)
- [pick](#pick)
- [removeIndexFromArray](#removeindexfromarray)
- [removeItemFromArray](#removeitemfromarray)
- [shallowEqual](#shallowequal)
- [\_\_deprecatedSplitProps](#__deprecatedsplitprops)
- [splitProps](#splitprops)
- [tabbable](#tabbable)
- [toArray](#toarray)
- [types](#types)
- [useForkRef](#useforkref)
- [useIsomorphicEffect](#useisomorphiceffect)
- [useLiveRef](#useliveref)
- [useSealedState](#usesealedstate)
- [useUpdateEffect](#useupdateeffect)
### applyState
Receives a `setState` argument and calls it with `currentValue` if it's a
function. Otherwise return the argument as the new value.
#### Parameters
- `argument` **React.SetStateAction&lt;T>**
- `currentValue` **T**
#### Examples
```javascript
import { applyState } from "reakit-utils";
applyState((value) => value + 1, 1); // 2
applyState(2, 1); // 2
```
### canUseDOM
It's `true` if it is running in a browser environment or `false` if it is not (SSR).
#### Examples
```javascript
import { canUseDOM } from "reakit-utils";
const title = canUseDOM ? document.title : "";
```
### closest
Ponyfill for `Element.prototype.closest`
#### Parameters
- `element` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
- `selectors` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
#### Examples
```javascript
import { closest } from "reakit-utils";
closest(document.getElementById("id"), "div");
// same as
document.getElementById("id").closest("div");
```
### contains
Similar to `Element.prototype.contains`, but a little bit faster when
`element` is the same as `child`.
#### Parameters
- `parent` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
- `child` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
#### Examples
```javascript
import { contains } from "reakit-utils";
contains(document.getElementById("parent"), document.getElementById("child"));
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### 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?**
#### 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)**
### createOnKeyDown
Returns an `onKeyDown` handler to be passed to a component.
#### Parameters
- `options` **Options** (optional, default `{}`)
- `options.keyMap`
- `options.onKey`
- `options.stopPropagation`
- `options.onKeyDown`
- `options.shouldKeyDown` (optional, default `()=>true`)
- `options.preventDefault` (optional, default `true`)
Returns **React.KeyboardEventHandler**
### isUA
Checks if a given string exists in the user agent string.
#### Parameters
- `string` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
### ensureFocus
Ensures `element` will receive focus if it's not already.
#### Parameters
- `element` **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)**
- `$1` **EnsureFocusOptions** (optional, default `{}`)
- `$1.preventScroll`
- `$1.isActive` (optional, default `hasFocus`)
#### Examples
```javascript
import { ensureFocus } from "reakit-utils";
ensureFocus(document.activeElement); // does nothing
const element = document.querySelector("input");
ensureFocus(element); // focuses element
ensureFocus(element, { preventScroll: true }); // focuses element preventing scroll jump
function isActive(el) {
return el.dataset.active === "true";
}
ensureFocus(document.querySelector("[data-active='true']"), { isActive }); // does nothing
```
Returns **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** `requestAnimationFrame` call ID so it can be passed to `cancelAnimationFrame` if needed.
### fireBlurEvent
Creates and dispatches a blur event in a way that also works on IE 11.
#### Parameters
- `element` **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)**
- `eventInit` **FocusEventInit?**
#### Examples
```javascript
import { fireBlurEvent } from "reakit-utils";
fireBlurEvent(document.getElementById("id"));
```
### 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.
#### Parameters
- `array` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;T>**
#### Examples
```javascript
import { flatten } from "reakit-utils";
flatten([0, 1, [2, [3, 4], 5], 6]);
// => [0, 1, 2, 3, 4, 5, 6]
```
### getActiveElement
Returns `element.ownerDocument.activeElement`.
#### Parameters
- `element` **([Element](https://developer.mozilla.org/docs/Web/API/Element) \| [Document](https://developer.mozilla.org/docs/Web/API/Document) | null)?**
### getDocument
Returns `element.ownerDocument || document`.
#### Parameters
- `element` **([Element](https://developer.mozilla.org/docs/Web/API/Element) \| [Document](https://developer.mozilla.org/docs/Web/API/Document) | null)?**
Returns **[Document](https://developer.mozilla.org/docs/Web/API/Document)**
### getNextActiveElementOnBlur
Cross-browser method that returns the next active element (the element that
is receiving focus) after a blur event is dispatched. It receives the blur
event object as the argument.
#### Parameters
- `event` **(React.FocusEvent | [FocusEvent](https://developer.mozilla.org/docs/Web/API/FocusEvent))**
#### Examples
```javascript
import { getNextActiveElementOnBlur } from "reakit-utils";
const element = document.getElementById("id");
element.addEventListener("blur", (event) => {
const nextActiveElement = getNextActiveElementOnBlur(event);
});
```
### getWindow
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)**
### hasFocus
Checks if `element` has focus. Elements that are referenced by
`aria-activedescendant` are also considered.
#### Parameters
- `element` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
#### Examples
```javascript
import { hasFocus } from "reakit-utils";
hasFocus(document.getElementById("id"));
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### hasFocusWithin
Checks if `element` has focus within. Elements that are referenced by
`aria-activedescendant` are also considered.
#### Parameters
- `element` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
#### Examples
```javascript
import { hasFocusWithin } from "reakit-utils";
hasFocusWithin(document.getElementById("id"));
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### isButton
Checks whether `element` is a native HTML button element.
#### Parameters
- `element` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
#### Examples
```javascript
import { isButton } from "reakit-utils";
isButton(document.querySelector("button")); // true
isButton(document.querySelector("input[type='button']")); // true
isButton(document.querySelector("div")); // false
isButton(document.querySelector("input[type='text']")); // false
isButton(document.querySelector("div[role='button']")); // false
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### isEmpty
Checks whether `arg` is empty or not.
#### Parameters
- `arg` **any**
#### Examples
```javascript
import { isEmpty } from "reakit-utils";
isEmpty([]); // true
isEmpty(["a"]); // false
isEmpty({}); // true
isEmpty({ a: "a" }); // false
isEmpty(); // true
isEmpty(null); // true
isEmpty(undefined); // true
isEmpty(""); // true
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### isInteger
Checks whether `arg` is an integer or not.
#### Parameters
- `arg` **any**
#### Examples
```javascript
import { isInteger } from "reakit-utils";
isInteger(1); // true
isInteger(1.5); // false
isInteger("1"); // true
isInteger("1.5"); // false
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### isObject
Checks whether `arg` is an object or not.
#### Parameters
- `arg` **any**
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### isPlainObject
Checks whether `arg` is a plain object or not.
#### Parameters
- `arg` **any**
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### isPortalEvent
Returns `true` if `event` has been fired within a React Portal element.
#### Parameters
- `event` **React.SyntheticEvent&lt;[Element](https://developer.mozilla.org/docs/Web/API/Element), [Event](https://developer.mozilla.org/docs/Web/API/Event)>**
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### isPromise
Checks whether `arg` is a promise or not.
#### Parameters
- `arg` **(T | [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)&lt;T>)**
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### isSelfTarget
Returns `true` if `event.target` and `event.currentTarget` are the same.
#### Parameters
- `event` **React.SyntheticEvent**
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### isTextField
Check whether the given element is a text field, where text field is defined
by the ability to select within the input, or that it is contenteditable.
#### Parameters
- `element` **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)**
#### Examples
```javascript
import { isTextField } from "reakit-utils";
isTextField(document.querySelector("div")); // false
isTextField(document.querySelector("input")); // true
isTextField(document.querySelector("input[type='button']")); // false
isTextField(document.querySelector("textarea")); // true
isTextField(document.querySelector("div[contenteditable='true']")); // true
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### matches
- **See: <https://developer.mozilla.org/en-US/docs/Web/API/Element/matches>
**
Ponyfill for `Element.prototype.matches`
#### Parameters
- `element` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
- `selectors` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### normalizePropsAreEqual
This higher order functions take `propsAreEqual` function and
returns a new function which normalizes the props.
Normalizing in our case is making sure the `propsAreEqual` works with
both version 1 (object spreading) and version 2 (state object) state passing.
To achieve this, the returned function in case of a state object
will spread the state object in both `prev` and \`next props.
Other case it just returns the function as is which makes sure
that we are still backward compatible
#### Parameters
- `propsAreEqual` **function (prev: O, next: O): [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
Returns **function (prev: PropsWithAs&lt;O, T>, next: PropsWithAs&lt;O, T>): [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### omit
Omits specific keys from an object.
#### Parameters
- `object` **T**
- `paths` **(ReadonlyArray&lt;K> | [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;K>)**
#### Examples
```javascript
import { omit } from "reakit-utils";
omit({ a: "a", b: "b" }, ["a"]); // { b: "b" }
```
Returns **Omit&lt;T, K>**
### pick
Picks specific keys from an object.
#### Parameters
- `object` **T**
- `paths` **(ReadonlyArray&lt;K> | [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;K>)**
#### Examples
```javascript
import { pick } from "reakit-utils";
pick({ a: "a", b: "b" }, ["a"]); // { a: "a" }
```
### removeIndexFromArray
Immutably removes an index from an array.
#### Parameters
- `array` **T**
- `index` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)**
#### Examples
```javascript
import { removeIndexFromArray } from "reakit-utils";
removeIndexFromArray(["a", "b", "c"], 1); // ["a", "c"]
```
Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** A new array without the item in the passed index.
### removeItemFromArray
Immutably removes an item from an array.
#### Parameters
- `array` **A**
- `item` **any**
#### Examples
```javascript
import { removeItemFromArray } from "reakit-utils";
removeItemFromArray(["a", "b", "c"], "b"); // ["a", "c"]
// This only works by reference
const obj = {};
removeItemFromArray([obj], {}); // [obj]
removeItemFromArray([obj], obj); // []
```
Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** A new array without the passed item.
### shallowEqual
Compares two objects.
#### Parameters
- `objA` **Record&lt;any, any>?**
- `objB` **Record&lt;any, any>?**
#### Examples
```javascript
import { shallowEqual } from "reakit-utils";
shallowEqual({ a: "a" }, {}); // false
shallowEqual({ a: "a" }, { b: "b" }); // false
shallowEqual({ a: "a" }, { a: "a" }); // true
shallowEqual({ a: "a" }, { a: "a", b: "b" }); // false
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
### \_\_deprecatedSplitProps
Splits an object (`props`) into a tuple where the first item is an object
with the passed `keys`, and the second item is an object with these keys
omitted.
#### Parameters
- `props` **T**
- `keys` **(ReadonlyArray&lt;K> | [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;K>)**
#### Examples
```javascript
import { splitProps } from "reakit-utils";
splitProps({ a: "a", b: "b" }, ["a"]); // [{ a: "a" }, { b: "b" }]
```
Returns **\[any, Omit&lt;T, K>]**
**Meta**
- **deprecated**: will be removed in version 2
### splitProps
Splits an object (`props`) into a tuple where the first item
is the `state` property, and the second item is the rest of the properties.
It is also backward compatible with version 1. If `keys` are passed then
splits an object (`props`) into a tuple where the first item is an object
with the passed `keys`, and the second item is an object with these keys
omitted.
#### Parameters
- `props` **T**
- `keys` **(ReadonlyArray&lt;K> | [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;K>)** (optional, default `[]`)
#### Examples
```javascript
import { splitProps } from "reakit-utils";
splitProps({ a: "a", b: "b" }, ["a"]); // [{ a: "a" }, { b: "b" }]
```
```javascript
import { splitProps } from "reakit-utils";
splitProps({ state: { a: "a" }, b: "b" }); // [{ a: "a" }, { b: "b" }]
```
Returns **\[any, Omit&lt;T, K>]**
### tabbable
#### isFocusable
Checks whether `element` is focusable or not.
##### Parameters
- `element` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
##### Examples
```javascript
import { isFocusable } from "reakit-utils";
isFocusable(document.querySelector("input")); // true
isFocusable(document.querySelector("input[tabindex='-1']")); // true
isFocusable(document.querySelector("input[hidden]")); // false
isFocusable(document.querySelector("input:disabled")); // false
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
#### isTabbable
Checks whether `element` is tabbable or not.
##### Parameters
- `element` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
##### Examples
```javascript
import { isTabbable } from "reakit-utils";
isTabbable(document.querySelector("input")); // true
isTabbable(document.querySelector("input[tabindex='-1']")); // false
isTabbable(document.querySelector("input[hidden]")); // false
isTabbable(document.querySelector("input:disabled")); // false
```
Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**
#### getAllFocusableIn
Returns all the focusable elements in `container`.
##### Parameters
- `container` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Element](https://developer.mozilla.org/docs/Web/API/Element)>**
#### getFirstFocusableIn
Returns the first focusable element in `container`.
##### Parameters
- `container` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
Returns **([Element](https://developer.mozilla.org/docs/Web/API/Element) | null)**
#### getAllTabbableIn
Returns all the tabbable elements in `container`, including the container
itself.
##### Parameters
- `container` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
- `fallbackToFocusable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** If `true`, it'll return focusable elements if there are no tabbable ones.
Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Element](https://developer.mozilla.org/docs/Web/API/Element)>**
#### getFirstTabbableIn
Returns the first tabbable element in `container`, including the container
itself if it's tabbable.
##### Parameters
- `container` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
- `fallbackToFocusable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** If `true`, it'll return the first focusable element if there are no tabbable ones.
Returns **([Element](https://developer.mozilla.org/docs/Web/API/Element) | null)**
#### getLastTabbableIn
Returns the last tabbable element in `container`, including the container
itself if it's tabbable.
##### Parameters
- `container` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
- `fallbackToFocusable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** If `true`, it'll return the last focusable element if there are no tabbable ones.
Returns **([Element](https://developer.mozilla.org/docs/Web/API/Element) | null)**
#### getNextTabbableIn
Returns the next tabbable element in `container`.
##### Parameters
- `container` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
- `fallbackToFocusable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** If `true`, it'll return the next focusable element if there are no tabbable ones.
Returns **([Element](https://developer.mozilla.org/docs/Web/API/Element) | null)**
#### getPreviousTabbableIn
Returns the previous tabbable element in `container`.
##### Parameters
- `container` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
- `fallbackToFocusable` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** If `true`, it'll return the previous focusable element if there are no tabbable ones.
Returns **([Element](https://developer.mozilla.org/docs/Web/API/Element) | null)**
#### getClosestFocusable
Returns the closest focusable element.
##### Parameters
- `element` **(T | null)?**
- `container` **[Element](https://developer.mozilla.org/docs/Web/API/Element)**
Returns **([Element](https://developer.mozilla.org/docs/Web/API/Element) | null)**
### toArray
Transforms `arg` into an array if it's not already.
#### Parameters
- `arg` **T**
#### Examples
```javascript
import { toArray } from "reakit-utils";
toArray("a"); // ["a"]
toArray(["a"]); // ["a"]
```
### types
#### RenderProp
Render prop type
Type: function (props: P): React.ReactElement&lt;any>
#### As
"as" prop
Type: React.ElementType&lt;P>
#### HTMLAttributesWithRef
Type: any
#### ExtractHTMLAttributes
Returns only the HTML attributes inside P
```ts
type OnlyId = ExtractHTMLAttributes<{ id: string; foo: string }>;
type HTMLAttributes = ExtractHTMLAttributes<any>;
```
Type: Pick&lt;HTMLAttributesWithRef, Extract&lt;any, any>>
#### UnionToIntersection
Transforms `"a" | "b"` into `"a" & "b"`
Type: any
#### PropsWithAs
Generic component props with "as" prop
Type: any
#### ArrayValue
Returns the type of the items in an array
Type: any
#### AnyFunction
Any function
Type: function (...args: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>): any
#### SetState
State hook setter.
Type: React.Dispatch&lt;React.SetStateAction&lt;T>>
### useForkRef
Merges up to two React Refs into a single memoized function React Ref so you
can pass it to an element.
#### Parameters
- `refA` **React.Ref&lt;any>?**
- `refB` **React.Ref&lt;any>?**
#### Examples
```javascript
import React from "react";
import { useForkRef } from "reakit-utils";
const Component = React.forwardRef((props, ref) => {
const internalRef = React.useRef();
return <div {...props} ref={useForkRef(internalRef, ref)} />;
});
```
### useIsomorphicEffect
`React.useLayoutEffect` that fallbacks to `React.useEffect` on server side
rendering.
### useLiveRef
A `React.Ref` that keeps track of the passed `value`.
#### Parameters
- `value` **T**
Returns **React.MutableRefObject&lt;T>**
### useSealedState
React custom hook that returns the very first value passed to `initialState`,
even if it changes between re-renders.
#### Parameters
- `initialState` **SealedInitialState&lt;T>**
### useUpdateEffect
A `React.useEffect` that will not run on the first render.
#### Parameters
- `effect` **React.EffectCallback**
- `deps` **(ReadonlyArray&lt;any> | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))?**
## License
MIT © [Diego Haz](https://github.com/diegohaz)

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-utils/applyState",
"private": true,
"sideEffects": false,
"main": "../lib/applyState",
"module": "../es/applyState",
"types": "../ts/applyState"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-utils/canUseDOM",
"private": true,
"sideEffects": false,
"main": "../lib/canUseDOM",
"module": "../es/canUseDOM",
"types": "../ts/canUseDOM"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-utils/closest",
"private": true,
"sideEffects": false,
"main": "../lib/closest",
"module": "../es/closest",
"types": "../ts/closest"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-utils/contains",
"private": true,
"sideEffects": false,
"main": "../lib/contains",
"module": "../es/contains",
"types": "../ts/contains"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-utils/createEvent",
"private": true,
"sideEffects": false,
"main": "../lib/createEvent",
"module": "../es/createEvent",
"types": "../ts/createEvent"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-utils/createOnKeyDown",
"private": true,
"sideEffects": false,
"main": "../lib/createOnKeyDown",
"module": "../es/createOnKeyDown",
"types": "../ts/createOnKeyDown"
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-utils/dom",
"private": true,
"sideEffects": false,
"main": "../lib/dom",
"module": "../es/dom",
"types": "../ts/dom"
}

View File

@@ -0,0 +1,8 @@
{
"name": "reakit-utils/ensureFocus",
"private": true,
"sideEffects": false,
"main": "../lib/ensureFocus",
"module": "../es/ensureFocus",
"types": "../ts/ensureFocus"
}

View File

@@ -0,0 +1,107 @@
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
var it;
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
it = o[Symbol.iterator]();
return it.next.bind(it);
}
export { _objectWithoutPropertiesLoose as _, _objectSpread2 as a, _createForOfIteratorHelperLoose as b };

View File

@@ -0,0 +1,24 @@
function isUpdater(argument) {
return typeof argument === "function";
}
/**
* Receives a `setState` argument and calls it with `currentValue` if it's a
* function. Otherwise return the argument as the new value.
*
* @example
* import { applyState } from "reakit-utils";
*
* applyState((value) => value + 1, 1); // 2
* applyState(2, 1); // 2
*/
function applyState(argument, currentValue) {
if (isUpdater(argument)) {
return argument(currentValue);
}
return argument;
}
export { applyState };

View File

@@ -0,0 +1,21 @@
import './getDocument.js';
import { getWindow } from './getWindow.js';
function checkIsBrowser() {
var _window = getWindow();
return Boolean(typeof _window !== "undefined" && _window.document && _window.document.createElement);
}
/**
* It's `true` if it is running in a browser environment or `false` if it is not (SSR).
*
* @example
* import { canUseDOM } from "reakit-utils";
*
* const title = canUseDOM ? document.title : "";
*/
var canUseDOM = checkIsBrowser();
export { canUseDOM };

View File

@@ -0,0 +1,24 @@
import { matches } from './matches.js';
/**
* Ponyfill for `Element.prototype.closest`
*
* @example
* import { closest } from "reakit-utils";
*
* closest(document.getElementById("id"), "div");
* // same as
* document.getElementById("id").closest("div");
*/
function closest(element, selectors) {
if ("closest" in element) return element.closest(selectors);
do {
if (matches(element, selectors)) return element;
element = element.parentElement || element.parentNode;
} while (element !== null && element.nodeType === 1);
return null;
}
export { closest };

View File

@@ -0,0 +1,14 @@
/**
* Similar to `Element.prototype.contains`, but a little bit faster when
* `element` is the same as `child`.
*
* @example
* import { contains } from "reakit-utils";
*
* contains(document.getElementById("parent"), document.getElementById("child"));
*/
function contains(parent, child) {
return parent === child || parent.contains(child);
}
export { contains };

View File

@@ -0,0 +1,24 @@
import { getDocument } from './getDocument.js';
/**
* 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 }));
*/
function createEvent(element, type, eventInit) {
if (typeof Event === "function") {
return new Event(type, eventInit);
} // IE 11 doesn't support Event constructors
var event = getDocument(element).createEvent("Event");
event.initEvent(type, eventInit === null || eventInit === void 0 ? void 0 : eventInit.bubbles, eventInit === null || eventInit === void 0 ? void 0 : eventInit.cancelable);
return event;
}
export { createEvent };

View File

@@ -0,0 +1,48 @@
/**
* Returns an `onKeyDown` handler to be passed to a component.
*
* @param options
*/
function createOnKeyDown(_temp) {
var _ref = _temp === void 0 ? {} : _temp,
keyMap = _ref.keyMap,
onKey = _ref.onKey,
stopPropagation = _ref.stopPropagation,
onKeyDown = _ref.onKeyDown,
_ref$shouldKeyDown = _ref.shouldKeyDown,
shouldKeyDown = _ref$shouldKeyDown === void 0 ? function () {
return true;
} : _ref$shouldKeyDown,
_ref$preventDefault = _ref.preventDefault,
preventDefault = _ref$preventDefault === void 0 ? true : _ref$preventDefault;
return function (event) {
if (!keyMap) return;
var finalKeyMap = typeof keyMap === "function" ? keyMap(event) : keyMap;
var shouldPreventDefault = typeof preventDefault === "function" ? preventDefault(event) : preventDefault;
var shouldStopPropagation = typeof stopPropagation === "function" ? stopPropagation(event) : stopPropagation;
if (event.key in finalKeyMap) {
var action = finalKeyMap[event.key];
if (typeof action === "function" && shouldKeyDown(event)) {
if (shouldPreventDefault) event.preventDefault();
if (shouldStopPropagation) event.stopPropagation();
if (onKey) onKey(event);
action(event); // Prevent onKeyDown from being called twice for the same keys
return;
}
}
if (onKeyDown && "current" in onKeyDown) {
var _onKeyDown$current;
(_onKeyDown$current = onKeyDown.current) === null || _onKeyDown$current === void 0 ? void 0 : _onKeyDown$current.call(onKeyDown, event);
} else {
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
}
};
}
export { createOnKeyDown };

View File

@@ -0,0 +1,14 @@
import './getDocument.js';
import './getWindow.js';
import { canUseDOM } from './canUseDOM.js';
/**
* Checks if a given string exists in the user agent string.
*/
function isUA(string) {
if (!canUseDOM) return false;
return window.navigator.userAgent.indexOf(string) !== -1;
}
export { isUA };

View File

@@ -0,0 +1,44 @@
import './getDocument.js';
import './getActiveElement.js';
import { hasFocus } from './hasFocus.js';
/**
* Ensures `element` will receive focus if it's not already.
*
* @example
* import { ensureFocus } from "reakit-utils";
*
* ensureFocus(document.activeElement); // does nothing
*
* const element = document.querySelector("input");
*
* ensureFocus(element); // focuses element
* ensureFocus(element, { preventScroll: true }); // focuses element preventing scroll jump
*
* function isActive(el) {
* return el.dataset.active === "true";
* }
*
* ensureFocus(document.querySelector("[data-active='true']"), { isActive }); // does nothing
*
* @returns {number} `requestAnimationFrame` call ID so it can be passed to `cancelAnimationFrame` if needed.
*/
function ensureFocus(element, _temp) {
var _ref = _temp === void 0 ? {} : _temp,
preventScroll = _ref.preventScroll,
_ref$isActive = _ref.isActive,
isActive = _ref$isActive === void 0 ? hasFocus : _ref$isActive;
if (isActive(element)) return -1;
element.focus({
preventScroll: preventScroll
});
if (isActive(element)) return -1;
return requestAnimationFrame(function () {
element.focus({
preventScroll: preventScroll
});
});
}
export { ensureFocus };

View File

@@ -0,0 +1,38 @@
import './getDocument.js';
import { a as _objectSpread2 } from './_rollupPluginBabelHelpers-1f0bf8c2.js';
import { createEvent } from './createEvent.js';
function createFocusEvent(element, type, eventInit) {
if (eventInit === void 0) {
eventInit = {};
}
if (typeof FocusEvent === "function") {
return new FocusEvent(type, eventInit);
}
return createEvent(element, type, eventInit);
}
/**
* Creates and dispatches a blur event in a way that also works on IE 11.
*
* @example
* import { fireBlurEvent } from "reakit-utils";
*
* fireBlurEvent(document.getElementById("id"));
*/
function fireBlurEvent(element, eventInit) {
var event = createFocusEvent(element, "blur", eventInit);
var defaultAllowed = element.dispatchEvent(event);
var bubbleInit = _objectSpread2(_objectSpread2({}, eventInit), {}, {
bubbles: true
});
element.dispatchEvent(createFocusEvent(element, "focusout", bubbleInit));
return defaultAllowed;
}
export { fireBlurEvent };

View File

@@ -0,0 +1,20 @@
import './getDocument.js';
import { createEvent } from './createEvent.js';
/**
* Creates and dispatches `Event` in a way that also works on IE 11.
*
* @example
* import { fireEvent } from "reakit-utils";
*
* fireEvent(document.getElementById("id"), "blur", {
* bubbles: true,
* cancelable: true,
* });
*/
function fireEvent(element, type, eventInit) {
return element.dispatchEvent(createEvent(element, type, eventInit));
}
export { fireEvent };

View File

@@ -0,0 +1,35 @@
import { getDocument } from './getDocument.js';
import { getWindow } from './getWindow.js';
function createKeyboardEvent(element, type, eventInit) {
if (eventInit === void 0) {
eventInit = {};
}
if (typeof KeyboardEvent === "function") {
return new KeyboardEvent(type, eventInit);
} // IE 11 doesn't support Event constructors
var event = getDocument(element).createEvent("KeyboardEvent");
event.initKeyboardEvent(type, eventInit.bubbles, eventInit.cancelable, getWindow(element), eventInit.key, eventInit.location, eventInit.ctrlKey, eventInit.altKey, eventInit.shiftKey, eventInit.metaKey);
return event;
}
/**
* Creates and dispatches `KeyboardEvent` in a way that also works on IE 11.
*
* @example
* import { fireKeyboardEvent } from "reakit-utils";
*
* fireKeyboardEvent(document.getElementById("id"), "keydown", {
* key: "ArrowDown",
* shiftKey: true,
* });
*/
function fireKeyboardEvent(element, type, eventInit) {
return element.dispatchEvent(createKeyboardEvent(element, type, eventInit));
}
export { fireKeyboardEvent };

Some files were not shown because too many files have changed in this diff Show More