diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 35372b9..8eddd26 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,6 +53,7 @@ If you are contributing for the first time, we recommend reading this 5. Add a summary of the hook and a link to the docs to `README.md`. 6. After all the above steps are done, run `yarn format` to ensure that everything is styled by our standards and there are no linting issues. +7. `yarn new-hook myAwesomeHook` will help you to create a proper file structure for the new hook. ## Committing diff --git a/README.md b/README.md index 87f8b6a..ce35a0b 100644 --- a/README.md +++ b/README.md @@ -71,17 +71,6 @@ export default function OnlyInTheClient() { ``` -## Hooks - -- [useMiro](https://github.com/miroapp/miro-react-hooks/tree/main/src/useMiro/useMiro.md) - Access Miro SDK reference from React Context. -- [useCurrentUser](https://github.com/miroapp/miro-react-hooks/tree/main/src/useCurrentUser/useCurrentUser.md) - Get current [Miro user](https://developers.miro.com/docs/websdk-reference-board#getuserinfo). -- [useInfo](https://github.com/miroapp/miro-react-hooks/tree/main/src/useInfo/useInfo.md) - Get [Miro board info](https://developers.miro.com/docs/websdk-reference-board#getinfo). -- [useOnlineUsers](https://github.com/miroapp/miro-react-hooks/tree/main/src/useOnlineUsers/useOnlineUsers.md) - Get [online users](https://developers.miro.com/docs/websdk-reference-board#getonlineusers) in a Miro board. -- [useSelectedItems](https://github.com/miroapp/miro-react-hooks/tree/main/src/useSelectedItems/useSelectedItems.md) - List [selected items](https://developers.miro.com/docs/websdk-reference-board#getselection) with possible predicate filter. -- [useSession](https://github.com/miroapp/miro-react-hooks/tree/main/src/useSession/useSession.md) - Interact with [Miro session](https://developers.miro.com/docs/websdk-reference-session). -- [useStorage](https://github.com/miroapp/miro-react-hooks/tree/main/src/useStorage/useStorage.md) - Interact with [Miro storage](https://developers.miro.com/docs/websdk-reference-storage). -- [useViewport](https://github.com/miroapp/miro-react-hooks/tree/main/src/useViewport/useViewport.md) - Interact with [Miro viewport](https://developers.miro.com/docs/websdk-reference-viewport). - ## Built with - [Miro Platform WebSDK](https://developers.miro.com/docs/miro-web-sdk-introduction) @@ -92,6 +81,20 @@ export default function OnlyInTheClient() { - [React testing library](https://testing-library.com/docs/react-testing-library/intro/) - [React Hooks Testing Library](https://github.com/testing-library/react-hooks-testing-library) +> This library is heavily inspired on https://github.com/react-hookz/web. Pure :sparkling_heart: awesomeness :sparkling_heart:. + ## Contributing Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) guide to get started. + + +## Hooks + +- [useMiro](https://github.com/miroapp/miro-react-hooks/tree/main/src/useMiro.md) - Access Miro SDK reference from React Context. +- [useCurrentUser](https://github.com/miroapp/miro-react-hooks/tree/main/src/useCurrentUser/useCurrentUser.md) - Get current [Miro user](https://developers.miro.com/docs/websdk-reference-board#getuserinfo). +- [useInfo](https://github.com/miroapp/miro-react-hooks/tree/main/src/useInfo/useInfo.md) - Get [Miro board info](https://developers.miro.com/docs/websdk-reference-board#getinfo). +- [useOnlineUsers](https://github.com/miroapp/miro-react-hooks/tree/main/src/useOnlineUsers/useOnlineUsers.md) - Get [online users](https://developers.miro.com/docs/websdk-reference-board#getonlineusers) in a Miro board. +- [useSelectedItems](https://github.com/miroapp/miro-react-hooks/tree/main/src/useSelectedItems/useSelectedItems.md) - List [selected items](https://developers.miro.com/docs/websdk-reference-board#getselection) with possible predicate filter. +- [useSession](https://github.com/miroapp/miro-react-hooks/tree/main/src/useSession/useSession.md) - Interact with [Miro session](https://developers.miro.com/docs/websdk-reference-session). +- [useStorage](https://github.com/miroapp/miro-react-hooks/tree/main/src/useStorage/useStorage.md) - Interact with [Miro storage](https://developers.miro.com/docs/websdk-reference-storage). +- [useViewport](https://github.com/miroapp/miro-react-hooks/tree/main/src/useViewport/useViewport.md) - Interact with [Miro viewport](https://developers.miro.com/docs/websdk-reference-viewport). diff --git a/package.json b/package.json index 1d655aa..f71aefe 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "lint": "eslint \"src/**/*.{ts,tsx}\"", "format": "yarn lint --fix", "lint:types": "tsc --noEmit", + "new-hook": "node ./utils/add-new-hook.mjs", "build:cjs": "tsc", "build:es": "tsc -m esNext --outDir esm", "build": "yarn clean && concurrently yarn:build:cjs yarn:build:es", @@ -105,4 +106,4 @@ "dependencies": { "@react-hookz/web": "^23.1.0" } -} +} \ No newline at end of file diff --git a/src/useCurrentUser/useCurrentUser.ts b/src/useCurrentUser/useCurrentUser.ts index 3ec2e11..86e42f2 100644 --- a/src/useCurrentUser/useCurrentUser.ts +++ b/src/useCurrentUser/useCurrentUser.ts @@ -1,6 +1,6 @@ import { useAsyncAbortable, useMountEffect } from "@react-hookz/web"; -import { useMiro } from "../useMiro/useMiro"; +import { useMiro } from "../useMiro"; /** * Fetches current user from Miro diff --git a/src/useInfo/useInfo.ts b/src/useInfo/useInfo.ts index 8cd8ab5..b361652 100644 --- a/src/useInfo/useInfo.ts +++ b/src/useInfo/useInfo.ts @@ -1,6 +1,6 @@ import { useAsyncAbortable, useMountEffect } from "@react-hookz/web"; -import { useMiro } from "../useMiro/useMiro"; +import { useMiro } from "../useMiro"; /** * Fetches current Miro board info diff --git a/src/useOnlineUsers/useOnlineUsers.ts b/src/useOnlineUsers/useOnlineUsers.ts index 00cc465..d18b639 100644 --- a/src/useOnlineUsers/useOnlineUsers.ts +++ b/src/useOnlineUsers/useOnlineUsers.ts @@ -1,7 +1,7 @@ import { useEffect } from "react"; import { useAsyncAbortable } from "@react-hookz/web"; -import { useMiro } from "../useMiro/useMiro"; +import { useMiro } from "../useMiro"; /** * Fetches list of online users from Miro and reacts to changes diff --git a/src/useSelectedItems/useSelectedItems.ts b/src/useSelectedItems/useSelectedItems.ts index 1e56f57..5b25259 100644 --- a/src/useSelectedItems/useSelectedItems.ts +++ b/src/useSelectedItems/useSelectedItems.ts @@ -2,7 +2,7 @@ import { Item } from "@mirohq/websdk-types"; import { useEffect, useMemo } from "react"; import { useAsyncAbortable } from "@react-hookz/web"; -import { useMiro } from "../useMiro/useMiro"; +import { useMiro } from "../useMiro"; export type SelectItemsOpts = { predicate?: (item: Item) => boolean; diff --git a/src/useSession/useSession.ts b/src/useSession/useSession.ts index 7d495d5..e82db26 100644 --- a/src/useSession/useSession.ts +++ b/src/useSession/useSession.ts @@ -7,7 +7,7 @@ import { UserSessionEvent, } from "@mirohq/websdk-types"; -import { useMiro } from "../useMiro/useMiro"; +import { useMiro } from "../useMiro"; import { useOnlineUsers } from "../useOnlineUsers"; type SessionState = "idle" | "started" | "ended"; diff --git a/src/useStorage/useStorage.ts b/src/useStorage/useStorage.ts index ae85ab0..e57b834 100644 --- a/src/useStorage/useStorage.ts +++ b/src/useStorage/useStorage.ts @@ -2,7 +2,7 @@ import { useAsyncAbortable } from "@react-hookz/web"; import { useCallback, useEffect, useMemo } from "react"; import { Json } from "@mirohq/websdk-types"; -import { useMiro } from "../useMiro/useMiro"; +import { useMiro } from "../useMiro"; /** * Interacts with Miro storage diff --git a/src/useViewport/useViewport.ts b/src/useViewport/useViewport.ts index 190711a..7118d40 100644 --- a/src/useViewport/useViewport.ts +++ b/src/useViewport/useViewport.ts @@ -1,6 +1,6 @@ import { useAsyncAbortable } from "@react-hookz/web"; -import { useMiro } from "../useMiro/useMiro"; +import { useMiro } from "../useMiro"; import { useCallback, useEffect } from "react"; import { BoardViewport } from "@mirohq/websdk-types"; diff --git a/utils/add-new-hook.mjs b/utils/add-new-hook.mjs new file mode 100644 index 0000000..7f25d29 --- /dev/null +++ b/utils/add-new-hook.mjs @@ -0,0 +1,111 @@ +import fs from "node:fs/promises"; +import path from "node:path"; + +const run = async () => { + const scriptPath = process.argv[1].trim(); + const hookName = process.argv[2]?.trim(); + + if (!hookName || hookName.length === 0) { + throw new TypeError("hook name not defined"); + } + + const srcDir = path.resolve(scriptPath, "../../src"); + const hookDir = path.join(srcDir, hookName); + + if ( + await fs + .lstat(hookDir) + .then(() => true) + .catch(() => false) + ) { + throw new TypeError(`directory for hook ${hookName} already exists`); + } + + // Updates entrypoint + await fs.appendFile(path.join(srcDir, "index.ts"), `\nexport * from "./${hookName}";`); + + // Creates hook folder + await fs.mkdir(hookDir); + + // Entrypoint + await fs.writeFile(path.resolve(hookDir, `index.ts`), `export * from "./${hookName}";\n`); + + // Main hook file + await fs.writeFile( + path.resolve(hookDir, `${hookName}.ts`), + `import { useMiro } from "../useMiro"; +/** + * Do something cool + */ +export const ${hookName} = () => { + const miro = useMiro(); + + // Now it's with you +}; + +`, + ); + + // Test file + await fs.writeFile( + path.resolve(hookDir, `${hookName}.test.tsx`), + `import { renderHook } from "@testing-library/react-hooks"; + +import { ${hookName} } from "./${hookName}"; +import { miro, wrapper } from "../test-utils"; + +describe("${hookName}", () => { + it("throws error when Miro SDK instance is not found in the context", () => { + const { result } = renderHook(() => ${hookName}()); + expect(result.error).toEqual(Error("Miro instance needs to be injected with MiroProvider")); + }); + + it.todo("implement me") +}); +`, + ); + + // Docs fole + await fs.writeFile( + path.resolve(hookDir, `${hookName}.md`), + `# ${hookName} + +Your description here + +**Note**: Make sure you are running this code in a configured [Miro WebSDK app](https://developers.miro.com/docs/build-your-first-hello-world-app). + +## Example + +\`\`\`tsx +import * as React from "react"; +import { createRoot } from "react-dom/client"; +import { ${hookName} } from "@mirohq/websdk-react-hooks"; + +export const ${hookName}: React.FC = () => { + const miro = ${hookName}(); + + // Add code sample +}; + +const App = () => { + return ( + + <${hookName} /> + + ) +}; + +const container = document.getElementById("root")!; +const root = createRoot(container); +root.render(); +\`\`\``, + ); + + // Updates entrypoint + await fs.appendFile( + path.join(scriptPath, "../../README.md"), + `\n- [${hookName}](https://github.com/miroapp/miro-react-hooks/tree/main/src/${hookName}/${hookName}.md) - Say something abour your hook here.;\n`, + ); +}; + +run();