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

Add react-contexts package #32

Merged
merged 3 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions packages/hooks/README.dev.md → README.dev.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
# Developer notes

## Testing this package in a local app
## Testing a package in a local app

Using [`yalc`](https://github.com/wclr/yalc) is the best way to test this library in another local package.
Using [`yalc`](https://github.com/wclr/yalc) is the best way to test a library in another
local package.

First, compile and build this package:
First, choose a package to compile and build:

```zsh
% yarn dbuild
% cd packages/hooks
hooks % yarn dbuild
```

And publish to `yalc`:

```zsh
% yalc publish
hooks % yalc publish
```

The `yalc:publish` script will also achieve the above.
Expand All @@ -24,8 +26,10 @@ Then in your app, link to this package:
other-app % yalc link @dolthub/react-hooks
```

And you will see and up-to-date version of this package. When you make a change to this package, you can push the change by running `yarn yalc:push` and you should see it automatically reflected in your app.
And you will see and up-to-date version of the `react-hooks` package. When you make a
change to the package, you can push the change by running `yarn yalc:push` and you should
see it automatically reflected in your app.

To remove the yalc package in your app, run `yalc remove --all`.

**Coming soon**: using `yalc` to watch for changes and automatically push
**Coming soon**: using `yalc` to watch for changes and automatically push.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# react-library

- [`@dolthub/react-contexts`](https://github.com/dolthub/react-library/tree/main/packages/contexts): A library of useful React contexts
- [`@dolthub/react-hooks`](https://github.com/dolthub/react-library/tree/main/packages/hooks): A library of useful React hooks
- [`@dolthub/web-utils`](https://github.com/dolthub/react-library/tree/main/packages/utils): A library of useful utilities for the web
- [`@dolthub/proto-resource-utils`](https://github.com/dolthub/react-library/tree/main/packages/resource-utils): A library of useful utilities for managing Google protobuf resources and names
- [`@dolthub/web-utils`](https://github.com/dolthub/react-library/tree/main/packages/utils): A library of useful utilities for the web
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@
"dbuild": "npm-run-all 'dbuild:*'",
"dbuild:utils": "yarn workspace @dolthub/web-utils dbuild",
"dbuild:hooks": "yarn workspace @dolthub/react-hooks dbuild",
"dbuild:contexts": "yarn workspace @dolthub/react-contexts dbuild",
"dbuild:resource": "yarn workspace @dolthub/proto-resource-utils dbuild",
"lint": "npm-run-all --parallel 'lint:*'",
"lint:hooks": "yarn workspace @dolthub/react-hooks lint",
"lint:contexts": "yarn workspace @dolthub/react-contexts lint",
"lint:utils": "yarn workspace @dolthub/web-utils lint",
"lint:resource": "yarn workspace @dolthub/proto-resource-utils lint",
"prettier": "npm-run-all --parallel 'prettier:*'",
"prettier:hooks": "yarn workspace @dolthub/react-hooks prettier",
"prettier:contexts": "yarn workspace @dolthub/react-contexts prettier",
"prettier:utils": "yarn workspace @dolthub/web-utils prettier",
"prettier:resource": "yarn workspace @dolthub/proto-resource-utils prettier",
"test": "npm-run-all --parallel 'test:*'",
"test:hooks": "yarn workspace @dolthub/react-hooks test",
"test:contexts": "yarn workspace @dolthub/react-contexts test",
"test:utils": "yarn workspace @dolthub/web-utils test",
"test:resource": "yarn workspace @dolthub/proto-resource-utils test"
},
Expand Down
4 changes: 4 additions & 0 deletions packages/contexts/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dist
node_modules
.eslintrc.js
./*.js
3 changes: 3 additions & 0 deletions packages/contexts/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: "../../.eslintrc.cjs",
};
2 changes: 2 additions & 0 deletions packages/contexts/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
src/
tsconfig.*
15 changes: 15 additions & 0 deletions packages/contexts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# @dolthub/react-contexts

A library of useful React contexts.

## Installation

```
% yarn add @dolthub/react-contexts
```

or

```
% npm install @dolthub/react-contexts
```
7 changes: 7 additions & 0 deletions packages/contexts/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
presets: [
["@babel/preset-env", { targets: { node: "current" } }],
"@babel/preset-react",
"@babel/preset-typescript",
],
};
13 changes: 13 additions & 0 deletions packages/contexts/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const TEST_REGEX = "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|js?|tsx?|ts?)$";

module.exports = {
setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
testRegex: TEST_REGEX,
transform: {
"^.+\\.tsx?$": "babel-jest",
},
testPathIgnorePatterns: ["types", "node_modules", ".rollup.cache", "dist"],
moduleFileExtensions: ["ts", "js", "tsx"],
collectCoverage: false,
clearMocks: true,
};
2 changes: 2 additions & 0 deletions packages/contexts/jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import "@testing-library/jest-dom";
import "@testing-library/react";
81 changes: 81 additions & 0 deletions packages/contexts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"name": "@dolthub/react-contexts",
"author": "DoltHub",
"description": "A collection of React contexts for common tasks",
"version": "0.1.0",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"keywords": [
"react",
"contexts",
"react-contexts",
"state",
"frontend"
],
"packageManager": "[email protected]",
"scripts": {
"compile": "tsc -b",
"build": "rollup -c --bundleConfigAsCjs",
"dbuild": "yarn compile && yarn build",
"lint": "eslint --cache --ext .ts,.js,.tsx,.jsx src",
"prettier": "prettier --check 'src/**/*.{js,ts,tsx}'",
"prettier-fix": "prettier --write 'src/**/*.{js,ts,tsx}'",
"npm:publish": "yarn dbuild && npm publish",
"test": "jest --env=jest-environment-jsdom",
"yalc:publish": "yarn dbuild && yalc publish",
"yalc:push": "yarn dbuild && yalc push"
},
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"dependencies": {
"@dolthub/react-hooks": "^0.1.6"
},
"devDependencies": {
"@babel/core": "^7.23.7",
"@babel/preset-env": "^7.23.8",
"@babel/preset-react": "^7.23.3",
"@babel/preset-typescript": "^7.23.3",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.5",
"@testing-library/jest-dom": "^6.2.0",
"@testing-library/react": "^14.1.2",
"@testing-library/react-hooks": "^8.0.1",
"@types/babel__core": "^7",
"@types/babel__preset-env": "^7",
"@types/eslint": "^8",
"@types/jest": "^29.5.11",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/rollup-plugin-peer-deps-external": "^2",
"@typescript-eslint/eslint-plugin": "^6.18.1",
"@typescript-eslint/parser": "^6.18.1",
"babel-jest": "^29.7.0",
"eslint": "^8.56.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"prettier": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rollup": "^4.9.4",
"rollup-plugin-dts": "^6.1.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-terser": "^7.0.2",
"tslib": "^2.6.2",
"typescript": "^5.3.3",
"yalc": "^1.0.0-pre.53"
},
"repository": {
"type": "git",
"url": "git+https://github.com/dolthub/react-library.git"
},
"bugs": {
"url": "https://github.com/dolthub/react-library/issues"
}
}
39 changes: 39 additions & 0 deletions packages/contexts/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import { terser } from "rollup-plugin-terser";
import external from "rollup-plugin-peer-deps-external";
import { dts } from "rollup-plugin-dts";

const packageJson = require("./package.json");

export default [
{
input: "src/index.ts",
output: [
{
file: packageJson.main,
format: "cjs",
sourcemap: true,
name: "react-ts-lib",
},
{
file: packageJson.module,
format: "esm",
sourcemap: true,
},
],
plugins: [
external(),
resolve(),
commonjs(),
typescript({ tsconfig: "./tsconfig.json" }),
terser(),
],
},
{
input: "./types/index.d.ts",
output: [{ file: "dist/index.d.ts", format: "esm" }],
plugins: [dts()],
},
];
109 changes: 109 additions & 0 deletions packages/contexts/src/__tests__/commentForm.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { act, fireEvent, render, screen } from "@testing-library/react";
import React from "react";
import CommentFormProvider, { useCommentFormContext } from "../commentForm";

const MockComponent: React.FC = () => {
const {
comment,
setComment,
onSubmit,
commentFormIsVisible,
commentFormRef,
} = useCommentFormContext();
return (
<div ref={commentFormRef}>
<textarea
value={comment}
onChange={e => setComment(e.target.value)}
data-testid="textarea"
/>
<button onClick={onSubmit}>Submit</button>
{commentFormIsVisible && <div>Form is visible</div>}
</div>
);
};

describe("CommentFormProvider", () => {
beforeEach(() => {
window.HTMLElement.prototype.scrollIntoView = function () {};

Check warning on line 28 in packages/contexts/src/__tests__/commentForm.test.tsx

View workflow job for this annotation

GitHub Actions / ci

Unexpected unnamed function
});

it("initializes with default values", () => {
render(
<CommentFormProvider
containerId="testContainer"
commentId="testComment"
createComment={jest.fn()}
loading={false}
>
<MockComponent />
</CommentFormProvider>,
);

expect(screen.getByText("Submit")).toBeInTheDocument();
expect(screen.getByTestId("textarea")).toHaveValue("");
expect(screen.getByText("Form is visible")).toBeInTheDocument();
});

it("updates comment on input change", () => {
render(
<CommentFormProvider
containerId="testContainer"
commentId="testComment"
createComment={jest.fn()}
loading={false}
>
<MockComponent />
</CommentFormProvider>,
);

const input: HTMLTextAreaElement = screen.getByTestId("textarea");
fireEvent.change(input, { target: { value: "New Comment" } });

expect(input.value).toBe("New Comment");
});

it("submits the form correctly", async () => {
const mockCreateComment = jest.fn().mockResolvedValue(true);
render(
<CommentFormProvider
containerId="testContainer"
commentId="testComment"
createComment={mockCreateComment}
loading={false}
>
<MockComponent />
</CommentFormProvider>,
);

const input: HTMLTextAreaElement = screen.getByTestId("textarea");
fireEvent.change(input, { target: { value: "New Comment" } });
fireEvent.click(screen.getByText("Submit"));

await act(async () => {
expect(mockCreateComment).toHaveBeenCalledWith("New Comment");
});
expect(input.value).toBe("");
});

it("handles form visibility correctly during window resize", () => {
render(
<CommentFormProvider
containerId="testContainer"
commentId="testComment"
createComment={jest.fn()}
loading={false}
>
<MockComponent />
</CommentFormProvider>,
);

act(() => {
// Simulate window resize
global.innerWidth = 500;
global.dispatchEvent(new Event("resize"));
});

expect(screen.getByText("Form is visible")).toBeInTheDocument();
});
});
29 changes: 29 additions & 0 deletions packages/contexts/src/__tests__/feature.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
FeatureMap,
getFeatures,
getFeaturesForShowAll,
} from "../features/feature";

const showAllMap: FeatureMap = new Map([
["bounties", true],
["test", true],
["marketing", true],
]);

const isDev = false;
const initialMap: FeatureMap = new Map([
["bounties", true],
["test", false],
["marketing", isDev],
]);

describe("test getFeatures", () => {
it("returns feature map", () => {
expect(getFeatures(initialMap)).toStrictEqual(initialMap);
expect(getFeatures(initialMap, false)).toStrictEqual(initialMap);
expect(getFeatures(initialMap, true)).toStrictEqual(showAllMap);
expect(getFeatures(initialMap, false)).toStrictEqual(initialMap);
expect(getFeatures(initialMap, true)).toStrictEqual(showAllMap);
expect(getFeaturesForShowAll(initialMap)).toStrictEqual(showAllMap);
});
});
Loading
Loading