1.1.0 - The project has been migrated to Typescript.

master
Tudor Stanciu 2023-10-31 02:55:22 +02:00
parent e9528df03b
commit da0a363429
18 changed files with 11925 additions and 2226 deletions

2
.eslintignore Normal file
View File

@ -0,0 +1,2 @@
node_modules
dist

32
.eslintrc Normal file
View File

@ -0,0 +1,32 @@
{
"root": true,
"extends": [
"prettier",
"plugin:prettier/recommended",
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "prettier", "react", "react-hooks"],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off"
},
"settings": {
"react": {
"version": "detect"
}
},
"env": {
"browser": true,
"node": true
},
"globals": {
"JSX": true
}
}

15
.gitignore vendored
View File

@ -1,4 +1,3 @@
# See https://help.github.com/ignore-files/ for more about ignoring files. # See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies # dependencies
@ -6,18 +5,12 @@ node_modules
# builds # builds
build build
lib
dist dist
.rpt2_cache
# misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
example/package-lock.json example/package-lock.json
coverage

View File

@ -1,4 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run precommit

2
.npmrc Normal file
View File

@ -0,0 +1,2 @@
//lab.code-rove.com/:_authToken=${OWN_NPM_TOKEN}
@flare:registry=https://lab.code-rove.com/public-node-registry

8
.prettierrc Normal file
View File

@ -0,0 +1,8 @@
{
"bracketSpacing": true,
"arrowParens": "avoid",
"printWidth": 120,
"trailingComma": "none",
"singleQuote": false,
"endOfLine": "auto"
}

22
LICENSE Normal file
View File

@ -0,0 +1,22 @@
MIT License
Copyright (c) 2023 Tudor Stanciu
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

@ -22,4 +22,6 @@ import { useWindowSize, useLink, useTitle } from "@flare/react-hooks";
## Changelog ## Changelog
**1.0.0** - This version includes the initial version of react-hooks package. **1.0.0** - This version includes the initial version of react-hooks package.
**1.0.1** - Small changes related to appearance (domain and readme updates).
**1.1.0** - The project has been migrated to Typescript.

17
jestconfig.json Normal file
View File

@ -0,0 +1,17 @@
{
"transform": {
"^.+\\.(t|j)sx?$": "ts-jest"
},
"testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
"testEnvironment": "jsdom",
"collectCoverage": true,
"coverageThreshold": {
"global": {
"branches": 50,
"functions": 50,
"lines": 50,
"statements": 50
}
}
}

13699
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,22 @@
{ {
"name": "@flare/react-hooks", "name": "@flare/react-hooks",
"version": "1.0.1", "version": "1.1.0",
"description": "React hooks", "description": "react-hooks is an npm package that brings together multiple react hooks useful both in the development of the ecosystem in my home lab and for the general public.",
"author": { "main": "./dist/cjs/index.js",
"name": "Tudor Stanciu", "module": "./dist/esm/index.js",
"email": "tudor.stanciu94@gmail.com", "types": "./dist/esm/index.d.ts",
"url": "https://lab.code-rove.com/tsp"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://dev.azure.com/tstanciu94/Packages/_git/react-hooks"
},
"private": true,
"keywords": [
"flare",
"react-hooks"
],
"main": "./src/index.js",
"babel": {
"presets": [
"@babel/preset-react"
]
},
"scripts": { "scripts": {
"prebuild": "rimraf build", "build": "npm run build:esm && npm run build:cjs",
"build": "npm run build:cjs && npm run build:copy-files", "build:esm": "tsc",
"build:cjs": "babel src -d build --copy-files", "build:cjs": "tsc --module commonjs --outDir dist/cjs",
"build:copy-files": "node ./scripts/copy-files.js", "test": "jest --config jestconfig.json",
"precommit": "lint-staged", "format": "prettier --write \"{src,tests}/**/*.{js,ts,jsx,tsx}\"",
"prepare": "husky install", "lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\"",
"test": "echo \"Error: no test specified\" && exit 1", "prepublishOnly": "npm test && npm run lint",
"prepush": "npm run build", "prepush": "npm run build",
"push": "cd build && npm publish --registry https://lab.code-rove.com/public-node-registry", "preversion": "npm run lint",
"version": "npm run format",
"push": "npm publish",
"push:major": "npm run version:major && npm run push", "push:major": "npm run version:major && npm run push",
"push:minor": "npm run version:minor && npm run push", "push:minor": "npm run version:minor && npm run push",
"push:patch": "npm run version:patch && npm run push", "push:patch": "npm run version:patch && npm run push",
@ -40,37 +24,52 @@
"version:minor": "npm version minor --no-git-tag-version", "version:minor": "npm version minor --no-git-tag-version",
"version:patch": "npm version patch --no-git-tag-version" "version:patch": "npm version patch --no-git-tag-version"
}, },
"devDependencies": { "repository": {
"@babel/cli": "^7.16.7", "type": "git",
"@babel/core": "^7.16.7", "url": "https://lab.code-rove.com/gitea/bricks/react-hooks"
"@babel/node": "^7.16.7",
"@babel/preset-env": "^7.16.7",
"@babel/preset-react": "^7.8.0",
"rimraf": "^3.0.2",
"fs-extra": "^10.0.0",
"husky": "^7.0.4",
"lint-staged": "^12.2.2",
"prettier": "^2.5.1"
}, },
"keywords": [
"flare",
"react-hooks"
],
"author": {
"name": "Tudor Stanciu",
"email": "tudor.stanciu94@gmail.com",
"url": "https://lab.code-rove.com/tsp"
},
"license": "MIT",
"bugs": {
"url": "https://lab.code-rove.com/gitea/bricks/react-hooks/issues"
},
"homepage": "https://lab.code-rove.com/gitea/bricks/react-hooks#readme",
"files": [
"dist",
"LICENSE",
"README.md"
],
"peerDependencies": { "peerDependencies": {
"prop-types": "^15.8.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0"
"react-scripts": "5.0.1"
}, },
"dependencies": {}, "devDependencies": {
"prettier": { "@testing-library/react": "^12.1.5",
"trailingComma": "none", "@testing-library/react-hooks": "^7.0.2",
"tabWidth": 2, "@types/jest": "^29.4.0",
"semi": true, "@types/react": "^18.0.27",
"singleQuote": false, "@typescript-eslint/eslint-plugin": "^5.51.0",
"arrowParens": "avoid" "@typescript-eslint/parser": "^5.51.0",
}, "eslint": "^8.34.0",
"lint-staged": { "eslint-config-prettier": "^8.6.0",
"**/*.+(js|md|ts|css|sass|less|graphql|scss|json|vue)": [ "eslint-plugin-prettier": "^4.2.1",
"prettier --write", "eslint-plugin-react": "^7.32.2",
"git add" "eslint-plugin-react-hooks": "^4.6.0",
] "jest": "^29.4.2",
"jest-environment-jsdom": "^29.4.2",
"prettier": "^2.8.4",
"react": "^16.14.0",
"react-dom": "16.14.0",
"ts-jest": "^29.0.5",
"typescript": "^4.9.5"
}, },
"publishConfig": { "publishConfig": {
"registry": "https://lab.code-rove.com/public-node-registry" "registry": "https://lab.code-rove.com/public-node-registry"

View File

@ -1,87 +0,0 @@
/* eslint-disable no-console */
const path = require("path");
const fse = require("fs-extra");
const glob = require("glob");
const packagePath = process.cwd();
const buildPath = path.join(packagePath, "./build");
const srcPath = path.join(packagePath, "./src");
/**
* Puts a package.json into every immediate child directory of rootDir.
* That package.json contains information about esm for bundlers so that imports
* like import Typography from '@material-ui/core/Typography' are tree-shakeable.
*
* It also tests that an this import can be used in typescript by checking
* if an index.d.ts is present at that path.
*
* @param {string} rootDir
*/
// async function createModulePackages({ from, to }) {
// const directoryPackages = glob.sync('*/index.js', { cwd: from }).map(path.dirname);
// await Promise.all(
// directoryPackages.map(async directoryPackage => {
// const packageJson = {
// sideEffects: false,
// module: path.join('../esm', directoryPackage, 'index.js'),
// typings: './index.d.ts',
// };
// const packageJsonPath = path.join(to, directoryPackage, 'package.json');
// /*const [typingsExist] =*/ await Promise.all([
// //fse.exists(path.join(to, directoryPackage, 'index.d.ts')),
// fse.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2)),
// ]);
// // if (!typingsExist) {
// // throw new Error(`index.d.ts for ${directoryPackage} is missing`);
// // }
// return packageJsonPath;
// }),
// );
// }
async function createPackageFile() {
const packageData = await fse.readFile(
path.resolve(packagePath, "./package.json"),
"utf8"
);
// eslint-disable-next-line no-unused-vars
const { nyc, scripts, devDependencies, workspaces, ...packageDataOther } =
JSON.parse(packageData);
const newPackageData = {
...packageDataOther,
private: false,
main: "./index.js"
};
const targetPath = path.resolve(buildPath, "./package.json");
await fse.writeFile(
targetPath,
JSON.stringify(newPackageData, null, 2),
"utf8"
);
console.log(`Created package.json in ${targetPath}`);
fse.copy("./README.md", `${buildPath}/README.md`, err => {
if (err) throw err;
console.log("README file was copied to destination");
});
return newPackageData;
}
async function run() {
try {
await createPackageFile();
//await createModulePackages({ from: srcPath, to: buildPath });
} catch (err) {
console.error(err);
process.exit(1);
}
}
run();

View File

@ -1,6 +1,6 @@
import { useEffect } from "react"; import { useEffect } from "react";
const useLink = (href, rel) => { const useLink = (href: string, rel: string) => {
useEffect(() => { useEffect(() => {
const link = document.createElement("link"); const link = document.createElement("link");
link.href = href; link.href = href;

View File

@ -1,6 +1,6 @@
import { useEffect } from "react"; import { useEffect } from "react";
const useTitle = title => { const useTitle = (title: string): void => {
useEffect(() => { useEffect(() => {
const prevTitle = document.title; const prevTitle = document.title;
document.title = title; document.title = title;

View File

@ -1,53 +0,0 @@
import { useState, useEffect } from "react";
const screenSizeLimit = {
mobile: 768,
tablet: 992
};
const useWindowSize = () => {
const [windowSize, setWindowSize] = useState({
width: undefined,
height: undefined
});
useEffect(() => {
// Handler to call on window resize
function handleResize() {
// Set window width/height to state
setWindowSize({
width: window.innerWidth,
height: window.innerHeight
});
}
// Add event listener
window.addEventListener("resize", handleResize);
// Call handler right away so state gets updated with initial window size
handleResize();
// Remove event listener on cleanup
return () => window.removeEventListener("resize", handleResize);
}, []); // Empty array ensures that effect is only run on mount
const isMobile = windowSize.width < screenSizeLimit.mobile;
const isTablet =
windowSize.width >= screenSizeLimit.mobile &&
windowSize.width < screenSizeLimit.tablet;
const isDesktop = windowSize.width >= screenSizeLimit.tablet;
return {
windowSize,
isMobile,
isTablet,
isDesktop
};
};
export default useWindowSize;
/* Test it:
<div>
{windowSize.width}px / {windowSize.height}px
</div>
*/

View File

@ -0,0 +1,62 @@
import { useState, useEffect, useMemo } from "react";
const screenSizeLimits = {
mobile: 768,
tablet: 992
};
type WindowsSize = {
width: number;
height: number;
};
const useWindowSize = (delay = 0) => {
const [windowSize, setWindowSize] = useState<WindowsSize>({
width: window.innerWidth,
height: window.innerHeight
});
useEffect(() => {
let resizeTimeout: NodeJS.Timeout;
// Handler to call on window resize
function handleResize() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
// Set window width/height to state
setWindowSize({
width: window.innerWidth,
height: window.innerHeight
});
}, delay);
}
// Add event listener
window.addEventListener("resize", handleResize);
// Call handler right away so state gets updated with initial window size
handleResize();
return () => {
clearTimeout(resizeTimeout);
// Remove event listener on cleanup
window.removeEventListener("resize", handleResize);
};
}, [delay]);
const isMobile = useMemo(() => !!windowSize && windowSize.width < screenSizeLimits.mobile, [windowSize]);
const isTablet = useMemo(
() => !!windowSize && windowSize.width >= screenSizeLimits.mobile && windowSize.width < screenSizeLimits.tablet,
[windowSize]
);
const isDesktop = useMemo(() => !!windowSize && windowSize.width >= screenSizeLimits.tablet, [windowSize]);
return {
windowSize,
isMobile,
isTablet,
isDesktop
};
};
export default useWindowSize;

25
tsconfig.json Normal file
View File

@ -0,0 +1,25 @@
{
"include": ["src"],
"exclude": ["dist", "node_modules"],
"compilerOptions": {
"target": "es5",
"module": "esnext",
"lib": ["dom", "esnext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./src",
"outDir": "./dist/esm",
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"moduleResolution": "node",
"jsx": "react",
"allowJs": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}