├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .huskyrc.js ├── .prettierignore ├── .prettierrc.js ├── README.md ├── babel-jest.config.js ├── jest.config.js ├── package.json ├── src ├── FeedbackFish.tsx ├── index.ts ├── setupTests.ts ├── test │ └── index.test.tsx └── useFeedbackFish.ts ├── tsconfig.json └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: push 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - name: Install modules 9 | run: yarn 10 | - name: Run tests 11 | run: yarn test 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /.huskyrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | hooks: { 3 | "pre-commit": "pretty-quick --staged", 4 | }, 5 | } 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | proseWrap: "always", 3 | semi: false, 4 | } 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @feedback-fish/react 2 | 3 | The [Feedback Fish](https://feedback.fish) widget for React apps. 4 | 5 | ## Usage 6 | 7 | See [the documentation](https://feedback.fish/help/react) for usage 8 | instructions! 9 | 10 | ## License 11 | 12 | Licensed under the MIT license. 13 | -------------------------------------------------------------------------------- /babel-jest.config.js: -------------------------------------------------------------------------------- 1 | // Only used by Jest for tests 2 | module.exports = { 3 | presets: [ 4 | "@babel/preset-env", 5 | "@babel/preset-react", 6 | "@babel/preset-typescript", 7 | ], 8 | } 9 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | setupFilesAfterEnv: ["/src/setupTests.ts"], 3 | transform: { 4 | "\\.tsx?$": ["babel-jest", { configFile: "./babel-jest.config.js" }], 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@feedback-fish/react", 3 | "version": "1.2.2", 4 | "private": false, 5 | "description": "Embed the Feedback Fish widget into your React app to collect user feedback.", 6 | "homepage": "https://feedback.fish", 7 | "bugs": "https://github.com/feedback-fish/feedback-fish-react/issues", 8 | "repository": "https://github.com/feedback-fish/feedback-fish-react", 9 | "license": "MIT", 10 | "types": "dist/index.d.ts", 11 | "source": "src/index.ts", 12 | "main": "dist/feedback-fish.js", 13 | "module": "dist/feedback-fish.module.js", 14 | "unpkg": "dist/feedback-fish.umd.js", 15 | "scripts": { 16 | "prepare": "yarn run build", 17 | "build": "microbundle", 18 | "dev": "microbundle watch", 19 | "test": "jest" 20 | }, 21 | "files": [ 22 | "dist", 23 | "src", 24 | "tsconfig.json" 25 | ], 26 | "devDependencies": { 27 | "@babel/preset-env": "^7.11.5", 28 | "@babel/preset-react": "^7.10.4", 29 | "@babel/preset-typescript": "^7.10.4", 30 | "@testing-library/jest-dom": "^5.11.4", 31 | "@testing-library/react": "^11.0.4", 32 | "@types/jest": "^26.0.14", 33 | "@types/react": "^16.9.49", 34 | "babel-jest": "^26.3.0", 35 | "husky": "^4.3.0", 36 | "jest": "^26.4.2", 37 | "microbundle": "^0.12.3", 38 | "prettier": "2.1.2", 39 | "pretty-quick": "^3.0.2", 40 | "react": "^16.8.0", 41 | "react-dom": "^16.13.1", 42 | "typescript": "^4.0.3" 43 | }, 44 | "peerDependencies": { 45 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0" 46 | }, 47 | "engines": { 48 | "node": ">=10.16.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/FeedbackFish.tsx: -------------------------------------------------------------------------------- 1 | import React, { FunctionComponent, ReactElement } from "react" 2 | 3 | import { useFeedbackFish } from "./useFeedbackFish" 4 | 5 | type Props = { 6 | projectId: Parameters[0] 7 | children?: ReactElement | ((props: object) => ReactElement) 8 | userId?: string 9 | metadata?: { 10 | [key: string]: string 11 | } 12 | } 13 | 14 | export const FeedbackFish: FunctionComponent = (props) => { 15 | useFeedbackFish(props.projectId) 16 | 17 | if (!props.children) return null 18 | 19 | const childrenProps = { 20 | "data-feedback-fish": true, 21 | "data-feedback-fish-userid": props.userId, 22 | ...Object.keys(props.metadata || {}).reduce((acc, key) => { 23 | return { 24 | ...acc, 25 | [`data-feedback-fish-${key}`]: props?.metadata?.[key], 26 | } 27 | }, {}), 28 | } 29 | 30 | if (React.isValidElement(props.children)) { 31 | return React.cloneElement(props.children, childrenProps) 32 | } 33 | 34 | if (typeof props.children === "function") { 35 | return props.children(childrenProps) 36 | } 37 | 38 | return null 39 | } 40 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./FeedbackFish" 2 | export * from "./useFeedbackFish" 3 | -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom/extend-expect" 2 | -------------------------------------------------------------------------------- /src/test/index.test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen } from "@testing-library/react" 2 | import * as React from "react" 3 | 4 | import { FeedbackFish } from "../" 5 | 6 | const defaultChild = 7 | 8 | const renderFeedbackFish = (propsOverwrite = {}) => { 9 | const props = { 10 | children: defaultChild, 11 | projectId: "bla", 12 | ...propsOverwrite, 13 | } 14 | 15 | return render() 16 | } 17 | const getButton = () => screen.getByRole("button", { name: /send feedback/i }) 18 | 19 | it(`injects the feedback fish script tag`, () => { 20 | const { baseElement } = renderFeedbackFish({ projectId: "bla" }) 21 | 22 | expect(baseElement).toMatchInlineSnapshot(` 23 | 24 |
25 | 30 |
31 |