From adcd2ec116d6e74aca447eb2881031aa953a15b3 Mon Sep 17 00:00:00 2001 From: Thinh Trinh Duc Date: Sat, 24 Aug 2024 18:51:23 +0700 Subject: [PATCH 1/2] Added autosizer --- apps/docs/package.json | 2 +- .../src/components/examples/Autosizer.tsx | 16 +++++ apps/docs/src/components/examples/index.ts | 1 + apps/docs/src/pages/docs/_meta.json | 3 + apps/docs/src/pages/docs/autosizer.mdx | 60 +++++++++++++++++++ packages/autosizer/.eslintrc.js | 8 +++ packages/autosizer/README.md | 32 ++++++++++ packages/autosizer/package.json | 45 ++++++++++++++ packages/autosizer/src/autosizer.spec.tsx | 34 +++++++++++ packages/autosizer/src/autosizer.tsx | 58 ++++++++++++++++++ packages/autosizer/src/index.ts | 1 + packages/autosizer/tsconfig.json | 8 +++ packages/components/CHANGELOG.md | 6 ++ packages/components/package.json | 5 +- packages/components/src/index.ts | 1 + turbo.json | 3 +- yarn.lock | 5 ++ 17 files changed, 284 insertions(+), 4 deletions(-) create mode 100644 apps/docs/src/components/examples/Autosizer.tsx create mode 100644 apps/docs/src/pages/docs/autosizer.mdx create mode 100644 packages/autosizer/.eslintrc.js create mode 100644 packages/autosizer/README.md create mode 100644 packages/autosizer/package.json create mode 100644 packages/autosizer/src/autosizer.spec.tsx create mode 100644 packages/autosizer/src/autosizer.tsx create mode 100644 packages/autosizer/src/index.ts create mode 100644 packages/autosizer/tsconfig.json diff --git a/apps/docs/package.json b/apps/docs/package.json index e95587c..d75f4cb 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -10,7 +10,7 @@ "clean": "rimraf .turbo && rimraf node_modules && rimraf .next" }, "dependencies": { - "@react-awesome/components": "1.0.20", + "@react-awesome/components": "1.0.21", "@vercel/speed-insights": "^1.0.10", "classnames": "^2.5.1", "lodash": "^4.17.21", diff --git a/apps/docs/src/components/examples/Autosizer.tsx b/apps/docs/src/components/examples/Autosizer.tsx new file mode 100644 index 0000000..a7c9527 --- /dev/null +++ b/apps/docs/src/components/examples/Autosizer.tsx @@ -0,0 +1,16 @@ +import { Autosizer } from '@react-awesome/components' + +export const AutosizerExample = () => { + return ( +
+ + {({ width, height }) => ( +
+
Width: {width}px
+
Height: {height}px
+
+ )} +
+
+ ) +} diff --git a/apps/docs/src/components/examples/index.ts b/apps/docs/src/components/examples/index.ts index 14d2d97..d288f31 100644 --- a/apps/docs/src/components/examples/index.ts +++ b/apps/docs/src/components/examples/index.ts @@ -1,2 +1,3 @@ export * from './PhoneInput/Default' export * from './PhoneInput/SupportCountry' +export * from './Autosizer' diff --git a/apps/docs/src/pages/docs/_meta.json b/apps/docs/src/pages/docs/_meta.json index 9ff5ce4..0848a24 100644 --- a/apps/docs/src/pages/docs/_meta.json +++ b/apps/docs/src/pages/docs/_meta.json @@ -7,6 +7,9 @@ "phone-input": { "title": "PhoneInput" }, + "autosizer": { + "title": "Autosizer" + }, "-- Hooks": { "type": "separator", "title": "Hooks" diff --git a/apps/docs/src/pages/docs/autosizer.mdx b/apps/docs/src/pages/docs/autosizer.mdx new file mode 100644 index 0000000..b7f5583 --- /dev/null +++ b/apps/docs/src/pages/docs/autosizer.mdx @@ -0,0 +1,60 @@ +--- +title: Autosizer +--- + +# Autosizer + +**Autosizer** keeps tracking of the parent size and reports it to the children. + +## Install + +To start using **Autosizer** component, you can install the `@react-awesome/autosizer` library or you can import it directly from `@react-awesome/components` if you have installed it before. In your project directory, run +the following command to install the dependencies: + +```sh npm2yarn +npm i @react-awesome/autosizer +``` + +import { Container } from '../../components/Container' +import { AutosizerExample } from '../../components/examples' + +```jsx +import { Autosizer } from '@react-awesome/components' + +const Example = () => { + return ( +
+ + {({ width, height }) => ( +
+
Width: {width}px
+
Height: {height}px
+
+ )} +
+
+ ) +} +``` + + + + + +## API + +**Autosizer** accepts the following props: + +#### `children` (optional) + +Children of `Autosizer` is rendered as render props. + +- Type: `(size : { width: number, height: number }) => React.ReactNode` +- Default: `undefined` + +#### `initialSize` (optional) + +Initial size of the parent component. + +- Type: `{ width: number, height: number }` +- Default: `undefined` diff --git a/packages/autosizer/.eslintrc.js b/packages/autosizer/.eslintrc.js new file mode 100644 index 0000000..19f3ed1 --- /dev/null +++ b/packages/autosizer/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + root: true, + extends: ["@react-awesome/eslint-config/library.js"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, +}; diff --git a/packages/autosizer/README.md b/packages/autosizer/README.md new file mode 100644 index 0000000..62491ec --- /dev/null +++ b/packages/autosizer/README.md @@ -0,0 +1,32 @@ +# @react-awesome/autosizer + +

+ version + coverage + license + build status + size +

+ +**autosizer** tracks the previous value of a variable. + +Please refer to the [documentation](https://react-awesome-components.vercel.app/docs/autosizer) for more information. + +## Installation + +```sh +yarn add @react-awesome/autosizer +# or +npm i @react-awesome/autosizer +``` + +## Contribution + +Yes please! See the +[contributing guidelines](https://github.com/trinhthinh388/react-awesome-components/blob/master/CONTRIBUTING.md) +for details. + +## Licence + +This project is licensed under the terms of the +[MIT license](https://github.com/trinhthinh388/react-awesome-components/blob/master/LICENSE). diff --git a/packages/autosizer/package.json b/packages/autosizer/package.json new file mode 100644 index 0000000..e31931a --- /dev/null +++ b/packages/autosizer/package.json @@ -0,0 +1,45 @@ +{ + "name": "@react-awesome/autosizer", + "version": "0.0.0", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "sideEffects": false, + "license": "MIT", + "description": "Autosizer keeps tracking the parent size and report back to its children.", + "keywords": [ + "react", + "autosizer", + "resize" + ], + "repository": { + "url": "https://github.com/trinhthinh388/react-awesome-components" + }, + "files": [ + "dist/**" + ], + "scripts": { + "build": "vite --config ../../vite.config.ts build", + "dev": "vite --watch --config ../../vite.config.ts build", + "lint": "eslint \"src/**/*.ts*\"", + "clean": "rimraf .turbo && rimraf node_modules && rimraf dist", + "test": "vitest --config ../../vite.config.ts --coverage --run", + "test:ui": "vitest --config ../../vite.config.ts --coverage --ui", + "typecheck": "tsc --noEmit" + }, + "devDependencies": { + "@react-awesome/eslint-config": "*", + "@react-awesome/tsconfig": "*", + "@types/react": "^18.2.46", + "@types/react-dom": "^18.2.18", + "eslint": "^8.56.0", + "react": "^18.2.0", + "typescript": "^5.3.3" + }, + "publishConfig": { + "access": "public" + }, + "dependencies": { + "react-merge-refs": "^2.1.1" + } +} diff --git a/packages/autosizer/src/autosizer.spec.tsx b/packages/autosizer/src/autosizer.spec.tsx new file mode 100644 index 0000000..bd604ef --- /dev/null +++ b/packages/autosizer/src/autosizer.spec.tsx @@ -0,0 +1,34 @@ +import { Mock } from 'vitest' +import { Autosizer } from './autosizer' +import { render } from '@testing-library/react' + +describe('useBreakpoint', () => { + let MockObserverInstance: ResizeObserver + let GlobalResizeObserver: Mock + + beforeEach(() => { + MockObserverInstance = { + observe: vitest.fn(), + unobserve: vitest.fn(), + disconnect: vitest.fn(), + } + GlobalResizeObserver = vitest + .fn() + .mockImplementation(() => MockObserverInstance) + global.ResizeObserver = GlobalResizeObserver + }) + + afterEach(() => { + vitest.resetAllMocks() + }) + + it('Should observe resize event', async () => { + const { unmount } = render() + + expect(MockObserverInstance.observe).toHaveBeenCalled() + + unmount() + + expect(MockObserverInstance.disconnect).toHaveBeenCalled() + }) +}) diff --git a/packages/autosizer/src/autosizer.tsx b/packages/autosizer/src/autosizer.tsx new file mode 100644 index 0000000..bacdb0c --- /dev/null +++ b/packages/autosizer/src/autosizer.tsx @@ -0,0 +1,58 @@ +import React, { + forwardRef, + useCallback, + useEffect, + useRef, + useState, +} from 'react' +import { mergeRefs } from 'react-merge-refs' + +export type AutosizerProps = { + children?: (_: { width: number; height: number }) => React.ReactNode + initialSize?: { + width?: number + height?: number + } +} & Omit, 'children'> + +export const Autosizer = forwardRef( + ({ children = () => void 0, initialSize = {}, ...props }, ref) => { + const elRef = useRef(null) + const [size, setSize] = useState({ + width: initialSize.width || 0, + height: initialSize.height || 0, + }) + + const watch = useCallback( + /* istanbul ignore next */ () => { + if (!elRef.current) return + + const observer = new ResizeObserver( + /* istanbul ignore next */ (entries) => { + if (!entries.length) return + const [entry] = entries + setSize({ + width: entry.contentRect.width, + height: entry.contentRect.height, + }) + }, + ) + + observer.observe(elRef.current) + + return () => { + observer.disconnect() + } + }, + [], + ) + + useEffect(() => watch(), [watch]) + + return ( +
+ {children(size)} +
+ ) + }, +) diff --git a/packages/autosizer/src/index.ts b/packages/autosizer/src/index.ts new file mode 100644 index 0000000..c7868db --- /dev/null +++ b/packages/autosizer/src/index.ts @@ -0,0 +1 @@ +export * from './autosizer' diff --git a/packages/autosizer/tsconfig.json b/packages/autosizer/tsconfig.json new file mode 100644 index 0000000..a09969e --- /dev/null +++ b/packages/autosizer/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@react-awesome/tsconfig/react-library.json", + "compilerOptions": { + "types": ["vitest/globals"], + }, + "include": ["."], + "exclude": ["dist", "build", "node_modules"], +} diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 05d85b2..d0435ff 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -1,5 +1,11 @@ # @react-awesome/components +## 1.0.21 + +### Patch Changes + +- Added autosizer + ## 1.0.20 ### Patch Changes diff --git a/packages/components/package.json b/packages/components/package.json index d79c634..1901ea8 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@react-awesome/components", - "version": "1.0.20", + "version": "1.0.21", "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/index.d.ts", @@ -45,6 +45,7 @@ "@react-awesome/use-selection-range": "0.0.3", "@react-awesome/use-previous": "0.0.3", "@react-awesome/use-toggle": "1.0.0", - "@react-awesome/use-breakpoint": "1.0.0" + "@react-awesome/use-breakpoint": "1.0.0", + "@react-awesome/autosizer": "0.0.0" } } diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index f823fcd..0f26b3a 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -1,4 +1,5 @@ export * from '@react-awesome/phone-input' +export * from '@react-awesome/autosizer' /** * Hooks diff --git a/turbo.json b/turbo.json index 9cc6146..bed7f0b 100644 --- a/turbo.json +++ b/turbo.json @@ -14,7 +14,8 @@ "@react-awesome/use-selection-range#build", "@react-awesome/use-preserve-input-caret-position#build", "@react-awesome/use-click-outside#build", - "@react-awesome/phone-input#build" + "@react-awesome/phone-input#build", + "@react-awesome/autosizer#build" ] }, "test": { diff --git a/yarn.lock b/yarn.lock index 28fb6bf..eb31ad1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7034,6 +7034,11 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +react-merge-refs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-2.1.1.tgz#e46763f8f1b881c0226ee54a1a2a10ffefba0233" + integrity sha512-jLQXJ/URln51zskhgppGJ2ub7b2WFKGq3cl3NYKtlHoTG+dN2q7EzWrn3hN3EgPsTMvpR9tpq5ijdp7YwFZkag== + react-refresh@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" From e62cb486897e4442dba48043b53c751e52f2eb48 Mon Sep 17 00:00:00 2001 From: Thinh Trinh Duc Date: Sat, 24 Aug 2024 18:53:19 +0700 Subject: [PATCH 2/2] updated pipeline --- .github/workflows/test.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ce0a144..3f9bf89 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -85,3 +85,10 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} flags: useBreakpoint files: ./packages/use-breakpoint/coverage/coverage-final.json + + - name: Upload `Autosizer` coverage reports to Codecov + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + flags: Autosizer + files: ./packages/autosizer/coverage/coverage-final.json