Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experiment] feat(react-hooks): add react-hooks #3896

Merged
Binary file added .yarn/offline-mirror/@babel-core-7.5.5.tgz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/offline-mirror/@babel-preset-env-7.5.5.tgz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/offline-mirror/@storybook-addons-5.1.11.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/@storybook-api-5.1.11.tgz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/offline-mirror/@storybook-core-5.1.11.tgz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/offline-mirror/@storybook-react-5.1.11.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/@storybook-router-5.1.11.tgz
Binary file not shown.
Binary file not shown.
Binary file added .yarn/offline-mirror/@storybook-ui-5.1.11.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/@types-node-12.7.3.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/acorn-7.0.0.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/ajv-6.10.2.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/ajv-keywords-3.4.1.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/autoprefixer-9.6.1.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/browserslist-4.7.0.tgz
Binary file not shown.
Binary file not shown.
Binary file added .yarn/offline-mirror/clone-deep-4.0.1.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/css-loader-3.2.0.tgz
Binary file not shown.
Binary file not shown.
Binary file added .yarn/offline-mirror/is-reference-1.1.3.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/node-releases-1.1.29.tgz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/offline-mirror/react-16.9.0.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/react-dom-16.9.0.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/resolve-1.12.0.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/rollup-1.20.3.tgz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/offline-mirror/sass-loader-8.0.0.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/scheduler-0.15.0.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/schema-utils-2.2.0.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/shallow-clone-3.0.1.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/style-loader-1.0.0.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/unfetch-4.1.0.tgz
Binary file not shown.
4 changes: 4 additions & 0 deletions packages/react-hooks/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**/__mocks__/**
**/__tests__/**
**/examples/**
**/tasks/**
9 changes: 9 additions & 0 deletions packages/react-hooks/.storybook/_styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// Copyright IBM Corp. 2016, 2018
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

$css--helpers: true;
@import '~carbon-components/scss/globals/scss/css--helpers';
9 changes: 9 additions & 0 deletions packages/react-hooks/.storybook/addons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
17 changes: 17 additions & 0 deletions packages/react-hooks/.storybook/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import './_styles.scss';
import { configure } from '@storybook/react';

// automatically import all files ending in *.stories.js
const req = require.context('../src', true, /-story\.js$/);
function loadStories() {
req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);
42 changes: 42 additions & 0 deletions packages/react-hooks/.storybook/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

const path = require('path');

module.exports = ({ config, mode }) => {
config.module.rules.push({
test: /\.s?css$/,
sideEffects: true,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
importLoaders: 2,
},
},
{
loader: 'postcss-loader',
options: {
plugins: [require('autoprefixer')],
},
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: [path.resolve(__dirname, '..', 'node_modules')],
},
},
},
],
});

return config;
};
54 changes: 54 additions & 0 deletions packages/react-hooks/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"name": "@carbon/react-hooks",
"private": true,
"version": "10.0.0",
"license": "Apache-2.0",
"main": "lib/index.js",
"module": "es/index.js",
"repository": "https://github.com/carbon-design-system/carbon/tree/master/packages/react-hooks",
"bugs": "https://github.com/carbon-design-system/carbon/issues",
"keywords": [
"ibm",
"carbon",
"carbon-design-system",
"components",
"react"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "yarn clean && rollup -c",
"clean": "rimraf es lib",
"develop": "start-storybook -p 3000",
"watch": "yarn clean && rollup -c -w"
},
"peerDependencies": {
"react": "^16.9.0"
},
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0",
"@storybook/addon-actions": "^5.1.11",
"@storybook/addon-links": "^5.1.11",
"@storybook/addons": "^5.1.11",
"@storybook/react": "^5.1.11",
"autoprefixer": "^9.6.1",
"babel-loader": "^8.0.6",
"browserslist-config-carbon": "10.4.0",
"carbon-components": "10.6.0-rc.0",
"css-loader": "^3.2.0",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"rimraf": "^3.0.0",
"rollup": "^1.20.3",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.0.0"
}
}
55 changes: 55 additions & 0 deletions packages/react-hooks/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

const resolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const babel = require('rollup-plugin-babel');
const packageJson = require('./package.json');

const baseConfig = {
input: './src/index.js',
external: Object.keys(packageJson.peerDependencies),
plugins: [
resolve(),
commonjs({
include: /node_modules/,
}),
babel({
babelrc: false,
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ['extends browserslist-config-carbon'],
},
},
],
'@babel/preset-react',
],
}),
],
};

module.exports = [
{
...baseConfig,
output: {
format: 'esm',
file: 'es/index.js',
},
},
{
...baseConfig,
output: {
format: 'cjs',
file: 'lib/index.js',
},
},
];
94 changes: 94 additions & 0 deletions packages/react-hooks/src/__tests__/useAnnouncer-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

jest.useFakeTimers();

describe('useAnnouncer', () => {
let React;
let ReactDOM;
let act;
let render;
let cleanup;
let useAnnouncer;

beforeEach(() => {
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
act = require('react-dom/test-utils').act;
render = require('../test-helpers').render;
cleanup = require('../test-helpers').cleanup;
useAnnouncer = require('../useAnnouncer').useAnnouncer;
});

afterEach(() => {
if (cleanup) {
cleanup();
}
});

it('should create a live region region for each aria-live mode', () => {
function Component() {
useAnnouncer();
return null;
}

act(() => {
render(<Component />);
});

jest.runAllTimers();

expect(document.querySelector('[aria-live="polite"]')).toBeInstanceOf(
HTMLDivElement
);
expect(document.querySelector('[aria-live="assertive"]')).toBeInstanceOf(
HTMLDivElement
);
});

it('should update a live region for the given mode and announcement', () => {
const testMessage = 'test message';

function Component({ mode, message, testId }) {
const announce = useAnnouncer();
return (
<button data-test-id={testId} onClick={() => announce(mode, message)}>
Announce
</button>
);
}

let testId = 'announce-id-1';
act(() => {
render(<Component mode="polite" message={testMessage} testId={testId} />);
});

let button = document.querySelector(`[data-test-id="${testId}"]`);
button.click();

jest.runAllTimers();

const politeRegion = document.querySelector('[aria-live="polite"]');
expect(politeRegion.textContent).toEqual(testMessage);

testId = 'announce-id-2';
act(() => {
render(
<Component mode="assertive" message={testMessage} testId={testId} />
);
});

button = document.querySelector(`[data-test-id="${testId}"]`);
button.click();

jest.runAllTimers();

const assertiveRegion = document.querySelector('[aria-live="assertive"]');
expect(assertiveRegion.textContent).toEqual(testMessage);
});
});
70 changes: 70 additions & 0 deletions packages/react-hooks/src/__tests__/useId-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Copyright IBM Corp. 2018, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

describe('useId', () => {
let React;
let render;
let cleanup;
let useId;

beforeEach(() => {
jest.resetModules();
React = require('react');
render = require('../test-helpers').render;
cleanup = require('../test-helpers').cleanup;
useId = require('../useId').useId;
});

afterEach(() => {
if (cleanup) {
cleanup();
}
});

it('should generate a unique id for each component', () => {
function Component() {
const id = useId();
return <div id={id} />;
}

const { container } = render(
<>
<Component />
<Component />
</>
);

const ids = Array.from(container.childNodes).map(node => node.id);
const uniqueIds = new Set(ids);
expect(uniqueIds.size).toBe(2);
});

it('should keep the same id for each call to render', () => {
function Component() {
const id = useId();
return <div id={id} />;
}

const { container } = render(<Component />);
const id = container.childNodes[0].id;

render(<Component />);
expect(container.childNodes[0].id).toBe(id);
});

it('should include a prefix in the generated `id`', () => {
const prefix = 'prefix';
function Component() {
const id = useId(prefix);
return <div id={id} />;
}

const { container } = render(<Component />);
const id = container.childNodes[0].id;
expect(id).toEqual(expect.stringContaining(prefix));
});
});
Loading