diff --git a/.changeset/brown-seahorses-melt.md b/.changeset/brown-seahorses-melt.md new file mode 100644 index 00000000000..d4740eaf3a3 --- /dev/null +++ b/.changeset/brown-seahorses-melt.md @@ -0,0 +1,7 @@ +--- +'@primer/react': minor +--- + +Add support for controlling which side `ActionMenu` renders on (via a `side` prop on `ActionMenu.Overlay`) + + diff --git a/.changeset/two-seals-prove.md b/.changeset/two-seals-prove.md new file mode 100644 index 00000000000..5ca8c009f35 --- /dev/null +++ b/.changeset/two-seals-prove.md @@ -0,0 +1,7 @@ +--- +'@primer/react': patch +--- + +use isomorphic layout effects only + + diff --git a/.changeset/wild-snakes-talk.md b/.changeset/wild-snakes-talk.md new file mode 100644 index 00000000000..ab0f4650dba --- /dev/null +++ b/.changeset/wild-snakes-talk.md @@ -0,0 +1,7 @@ +--- +"@primer/react": minor +--- + +Add default `type="button"` to `IconButton` component + + diff --git a/.eslintrc.js b/.eslintrc.js index c9356e66c54..b8784d93e39 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -143,6 +143,12 @@ module.exports = { importNames: ['useSSRSafeId'], message: 'Please use the `useId` hook from `src/hooks/useId.ts` instead', }, + { + name: 'react', + importNames: ['useLayoutEffect'], + message: + 'Please use the `useIsomorphicLayoutEffect` hook from `src/hooks/useIsomorphicLayoutEffect.ts` instead', + }, ], patterns: [ { diff --git a/.github/workflows/assign_release_conductor.yml b/.github/workflows/assign_release_conductor.yml index e6064d8fc26..cc1112dfd15 100644 --- a/.github/workflows/assign_release_conductor.yml +++ b/.github/workflows/assign_release_conductor.yml @@ -8,7 +8,7 @@ jobs: if: github.head_ref == 'changeset-release/main' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: 18 diff --git a/.github/workflows/changesets.yml b/.github/workflows/changesets.yml index 86bb811b682..614167cc9af 100644 --- a/.github/workflows/changesets.yml +++ b/.github/workflows/changesets.yml @@ -7,7 +7,7 @@ jobs: validate: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Node.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a3530b4e2a..d2e7b89c6bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 @@ -61,7 +61,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 @@ -96,7 +96,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 @@ -122,7 +122,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 @@ -151,7 +151,7 @@ jobs: matrix: shard: [1, 2, 3, 4] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Use Node.js 18.x uses: actions/setup-node@v3 with: @@ -188,7 +188,7 @@ jobs: runs-on: ubuntu-latest needs: vrt-runner steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Use Node.js 18.x uses: actions/setup-node@v3 with: @@ -219,7 +219,7 @@ jobs: matrix: shard: [1, 2] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Use Node.js 18.x uses: actions/setup-node@v3 with: @@ -256,7 +256,7 @@ jobs: runs-on: ubuntu-latest needs: aat-runner steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Use Node.js 18.x uses: actions/setup-node@v3 with: @@ -284,7 +284,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Use Node.js 18.x uses: actions/setup-node@v3 with: @@ -299,7 +299,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6bb4aece9d0..88fb0f36ea8 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/consumer_test.yml b/.github/workflows/consumer_test.yml index feaa389ae3b..79fbb0dbee7 100644 --- a/.github/workflows/consumer_test.yml +++ b/.github/workflows/consumer_test.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 diff --git a/.github/workflows/deploy_production.yml b/.github/workflows/deploy_production.yml index 8e7b7a8e4dc..93382bcd390 100644 --- a/.github/workflows/deploy_production.yml +++ b/.github/workflows/deploy_production.yml @@ -20,7 +20,7 @@ jobs: # If it's 0, we deploy. should_deploy: ${{ steps.changeset-count.outputs.change_count == 0 && steps.has-pages.outputs.pages == 1 }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - id: changeset-count run: echo "::set-output name=change_count::$(ls .changeset/*.md | grep -v README | wc -l | xargs)" diff --git a/.github/workflows/environment.yml b/.github/workflows/environment.yml index f7d3398f2d4..4631e338e3e 100644 --- a/.github/workflows/environment.yml +++ b/.github/workflows/environment.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Generate token id: generate_token - uses: tibdex/github-app-token@v1 + uses: tibdex/github-app-token@v2 with: app_id: ${{ secrets.APP_ID }} private_key: ${{ secrets.PRIVATE_KEY }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index e14f6ce8a75..989f0429838 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml index 8ac6f74e3de..51143965fb1 100644 --- a/.github/workflows/size.yml +++ b/.github/workflows/size.yml @@ -7,7 +7,7 @@ jobs: env: CI_JOB_NUMBER: 1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: andresz1/size-limit-action@v1 with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/statuses.yml b/.github/workflows/statuses.yml index b742e8cecca..92d06235c8c 100644 --- a/.github/workflows/statuses.yml +++ b/.github/workflows/statuses.yml @@ -14,7 +14,7 @@ jobs: if: ${{ github.repository == 'primer/react' }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Ruby uses: ruby/setup-ruby@v1 with: diff --git a/.github/workflows/storybook-tests.yml b/.github/workflows/storybook-tests.yml index 9a18780a44b..2cd15f6bfae 100644 --- a/.github/workflows/storybook-tests.yml +++ b/.github/workflows/storybook-tests.yml @@ -10,7 +10,7 @@ jobs: timeout-minutes: 30 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: 18 diff --git a/.github/workflows/update-snapshots.yml b/.github/workflows/update-snapshots.yml index 60df7e97118..6a8614df62d 100644 --- a/.github/workflows/update-snapshots.yml +++ b/.github/workflows/update-snapshots.yml @@ -69,7 +69,7 @@ jobs: # Warning: we are checking out an untrusted source at this point in order # to push to the head pull request. Code from this checkout must not be # used in any of the following steps. - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.workflow_run.head_branch }} diff --git a/.github/workflows/vrt.yml b/.github/workflows/vrt.yml index 6e0b9a6f5a0..8b5d346a729 100644 --- a/.github/workflows/vrt.yml +++ b/.github/workflows/vrt.yml @@ -33,7 +33,7 @@ jobs: matrix: shard: [1, 2, 3, 4] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: diff --git a/package-lock.json b/package-lock.json index 406995744c2..6894e8e8629 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,7 +47,7 @@ "@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6", "@babel/plugin-proposal-optional-chaining": "7.21.0", "@babel/plugin-transform-modules-commonjs": "7.22.5", - "@babel/preset-react": "7.22.5", + "@babel/preset-react": "7.22.15", "@babel/preset-typescript": "7.22.5", "@changesets/changelog-github": "0.4.8", "@github/markdownlint-github": "^0.3.0", @@ -101,7 +101,7 @@ "babel-plugin-dev-expression": "0.2.3", "babel-plugin-macros": "3.1.0", "babel-plugin-open-source": "1.3.4", - "babel-plugin-styled-components": "2.1.1", + "babel-plugin-styled-components": "2.1.4", "babel-plugin-transform-replace-expressions": "0.2.0", "babel-polyfill": "6.26.0", "change-case": "4.1.2", @@ -109,7 +109,7 @@ "copyfiles": "2.4.1", "cross-env": "7.0.3", "eslint": "8.40.0", - "eslint-import-resolver-typescript": "3.5.5", + "eslint-import-resolver-typescript": "3.6.0", "eslint-plugin-github": "4.8.0", "eslint-plugin-jest": "27.2.1", "eslint-plugin-jsx-a11y": "6.7.1", @@ -120,7 +120,7 @@ "eslint-plugin-react": "7.32.2", "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-ssr-friendly": "1.2.0", - "eslint-plugin-storybook": "0.6.12", + "eslint-plugin-storybook": "0.6.13", "eslint-plugin-testing-library": "5.11.0", "fast-glob": "3.2.12", "filesize": "10.0.6", @@ -569,12 +569,12 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -700,18 +700,18 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", + "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1806,16 +1806,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", - "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz", + "integrity": "sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -2180,15 +2180,15 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.5.tgz", - "integrity": "sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.15.tgz", + "integrity": "sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", "@babel/plugin-transform-react-display-name": "^7.22.5", - "@babel/plugin-transform-react-jsx": "^7.22.5", + "@babel/plugin-transform-react-jsx": "^7.22.15", "@babel/plugin-transform-react-jsx-development": "^7.22.5", "@babel/plugin-transform-react-pure-annotations": "^7.22.5" }, @@ -2290,13 +2290,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.22.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", + "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.15", "to-fast-properties": "^2.0.0" }, "engines": { @@ -14197,27 +14197,21 @@ } }, "node_modules/babel-plugin-styled-components": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.1.tgz", - "integrity": "sha512-c8lJlszObVQPguHkI+akXv8+Jgb9Ccujx0EetL7oIvwU100LxO6XAGe45qry37wUL40a5U9f23SYrivro2XKhA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "babel-plugin-syntax-jsx": "^6.18.0", + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", "lodash": "^4.17.21", - "picomatch": "^2.3.0" + "picomatch": "^2.3.1" }, "peerDependencies": { "styled-components": ">= 2" } }, - "node_modules/babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", - "dev": true - }, "node_modules/babel-plugin-transform-replace-expressions": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-replace-expressions/-/babel-plugin-transform-replace-expressions-0.2.0.tgz", @@ -15177,18 +15171,6 @@ "node": ">= 8" } }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", @@ -18175,19 +18157,18 @@ "dev": true }, "node_modules/eslint-import-resolver-typescript": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz", - "integrity": "sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.0.tgz", + "integrity": "sha512-QTHR9ddNnn35RTxlaEnx2gCxqFlF2SEN0SE2d17SqwyM7YOSI2GHWRYp5BiRkObTUNYPupC/3Fq2a0PpT+EKpg==", "dev": true, "dependencies": { "debug": "^4.3.4", "enhanced-resolve": "^5.12.0", "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", "get-tsconfig": "^4.5.0", - "globby": "^13.1.3", "is-core-module": "^2.11.0", - "is-glob": "^4.0.3", - "synckit": "^0.8.5" + "is-glob": "^4.0.3" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -18200,35 +18181,20 @@ "eslint-plugin-import": "*" } }, - "node_modules/eslint-import-resolver-typescript/node_modules/globby": { - "version": "13.1.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", - "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", + "node_modules/eslint-import-resolver-typescript/node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-import-resolver-typescript/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8.6.0" } }, "node_modules/eslint-mdx": { @@ -19177,9 +19143,9 @@ } }, "node_modules/eslint-plugin-storybook": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.6.12.tgz", - "integrity": "sha512-XbIvrq6hNVG6rpdBr+eBw63QhOMLpZneQVSooEDow8aQCWGCk/5vqtap1yxpVydNfSxi3S/3mBBRLQqKUqQRww==", + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.6.13.tgz", + "integrity": "sha512-smd+CS0WH1jBqUEJ3znGS7DU4ayBE9z6lkQAK2yrSUv1+rq8BT/tiI5C/rKE7rmiqiAfojtNYZRhzo5HrulccQ==", "dev": true, "dependencies": { "@storybook/csf": "^0.0.1", @@ -20336,18 +20302,6 @@ "node": ">=8.6.0" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-parse": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz", @@ -21528,6 +21482,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", diff --git a/package.json b/package.json index a57e18f6311..2b23442287b 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6", "@babel/plugin-proposal-optional-chaining": "7.21.0", "@babel/plugin-transform-modules-commonjs": "7.22.5", - "@babel/preset-react": "7.22.5", + "@babel/preset-react": "7.22.15", "@babel/preset-typescript": "7.22.5", "@changesets/changelog-github": "0.4.8", "@github/markdownlint-github": "^0.3.0", @@ -186,7 +186,7 @@ "babel-plugin-dev-expression": "0.2.3", "babel-plugin-macros": "3.1.0", "babel-plugin-open-source": "1.3.4", - "babel-plugin-styled-components": "2.1.1", + "babel-plugin-styled-components": "2.1.4", "babel-plugin-transform-replace-expressions": "0.2.0", "babel-polyfill": "6.26.0", "change-case": "4.1.2", @@ -194,7 +194,7 @@ "copyfiles": "2.4.1", "cross-env": "7.0.3", "eslint": "8.40.0", - "eslint-import-resolver-typescript": "3.5.5", + "eslint-import-resolver-typescript": "3.6.0", "eslint-plugin-github": "4.8.0", "eslint-plugin-jest": "27.2.1", "eslint-plugin-jsx-a11y": "6.7.1", @@ -205,7 +205,7 @@ "eslint-plugin-react": "7.32.2", "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-ssr-friendly": "1.2.0", - "eslint-plugin-storybook": "0.6.12", + "eslint-plugin-storybook": "0.6.13", "eslint-plugin-testing-library": "5.11.0", "fast-glob": "3.2.12", "filesize": "10.0.6", diff --git a/src/ActionMenu/ActionMenu.docs.json b/src/ActionMenu/ActionMenu.docs.json index 0b9c5853191..398386f157b 100644 --- a/src/ActionMenu/ActionMenu.docs.json +++ b/src/ActionMenu/ActionMenu.docs.json @@ -75,6 +75,12 @@ "type": "start | center | end", "defaultValue": "start", "description": "" + }, + { + "name": "side", + "type": "| 'inside-top' | 'inside-bottom' | 'inside-left' | 'inside-right' | 'inside-center' | 'outside-top' | 'outside-bottom' | 'outside-left' | 'outside-right'", + "defaultValue": "'outside-bottom'", + "description": "Controls which side of the anchor the menu will appear" } ], "passthrough": { @@ -83,4 +89,4 @@ } } ] -} \ No newline at end of file +} diff --git a/src/ActionMenu/ActionMenu.examples.stories.tsx b/src/ActionMenu/ActionMenu.examples.stories.tsx index 206f3c36abc..80e929196d8 100644 --- a/src/ActionMenu/ActionMenu.examples.stories.tsx +++ b/src/ActionMenu/ActionMenu.examples.stories.tsx @@ -307,3 +307,30 @@ export const DelayedMenuClose = () => { ) } + +export const OnRightSide = () => ( + + Open menu + + + alert('Copy link clicked')}> + Copy link + ⌘C + + alert('Quote reply clicked')}> + Quote reply + ⌘Q + + alert('Edit comment clicked')}> + Edit comment + ⌘E + + + alert('Delete file clicked')}> + Delete file + ⌘D + + + + +) diff --git a/src/ActionMenu/ActionMenu.tsx b/src/ActionMenu/ActionMenu.tsx index 87ab5f98118..31b68990978 100644 --- a/src/ActionMenu/ActionMenu.tsx +++ b/src/ActionMenu/ActionMenu.tsx @@ -85,7 +85,7 @@ const MenuButton = React.forwardRef(({...props}, anchorRef) => { }) as PolymorphicForwardRefComponent<'button', ActionMenuButtonProps> type MenuOverlayProps = Partial & - Pick & { + Pick & { /** * Recommended: `ActionList` */ @@ -94,6 +94,7 @@ type MenuOverlayProps = Partial & const Overlay: React.FC> = ({ children, align = 'start', + side = 'outside-bottom', 'aria-labelledby': ariaLabelledby, ...overlayProps }) => { @@ -116,6 +117,7 @@ const Overlay: React.FC> = ({ onOpen={onOpen} onClose={onClose} align={align} + side={side} overlayProps={overlayProps} focusZoneSettings={{focusOutBehavior: 'wrap'}} > diff --git a/src/Button/IconButton.tsx b/src/Button/IconButton.tsx index 4a76d45a19b..e313aa1a4e7 100644 --- a/src/Button/IconButton.tsx +++ b/src/Button/IconButton.tsx @@ -16,7 +16,7 @@ const IconButton = forwardRef(({sx: sxProp = defaultSxProp, icon: Icon, ...props return ( // @ts-expect-error StyledButton wants both Anchor and Button refs - + ) }) as PolymorphicForwardRefComponent<'button' | 'a', IconButtonProps> diff --git a/src/drafts/InlineAutocomplete/InlineAutocomplete.test.tsx b/src/drafts/InlineAutocomplete/InlineAutocomplete.test.tsx index 5b090e5eb5d..d7c26c48908 100644 --- a/src/drafts/InlineAutocomplete/InlineAutocomplete.test.tsx +++ b/src/drafts/InlineAutocomplete/InlineAutocomplete.test.tsx @@ -1,4 +1,4 @@ -import React, {useLayoutEffect, useState} from 'react' +import React, {useState} from 'react' import {fireEvent, render, within} from '@testing-library/react' import userEvent from '@testing-library/user-event' import InlineAutocomplete, {ShowSuggestionsEvent, Suggestions, Trigger} from '.' @@ -6,6 +6,7 @@ import FormControl from '../../FormControl' import {ActionList} from '../../ActionList' import Textarea from '../../Textarea' import ThemeProvider from '../../ThemeProvider' +import useIsomorphicLayoutEffect from '../../utils/useIsomorphicLayoutEffect' const label = 'Inline Autocomplete' @@ -82,7 +83,7 @@ const UncontrolledInlineAutocomplete = ({ } } - useLayoutEffect(() => { + useIsomorphicLayoutEffect(() => { // combobox-nav attempts to filter out 'hidden' options by checking if the option has an // offsetHeight or width > 0. In JSDom, all elements have offsetHeight = offsetWidth = 0, // so we need to override at least one to make the class recognize that any options exist. diff --git a/src/drafts/MarkdownEditor/MarkdownEditor.tsx b/src/drafts/MarkdownEditor/MarkdownEditor.tsx index df8b2bd6bc7..50cb614c7e7 100644 --- a/src/drafts/MarkdownEditor/MarkdownEditor.tsx +++ b/src/drafts/MarkdownEditor/MarkdownEditor.tsx @@ -1,13 +1,4 @@ -import React, { - forwardRef, - useCallback, - useEffect, - useImperativeHandle, - useLayoutEffect, - useMemo, - useRef, - useState, -} from 'react' +import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react' import Box from '../../Box' import VisuallyHidden from '../../_VisuallyHidden' import {useId} from '../../hooks/useId' @@ -36,6 +27,7 @@ import {Emoji} from './suggestions/_useEmojiSuggestions' import {Mentionable} from './suggestions/_useMentionSuggestions' import {Reference} from './suggestions/_useReferenceSuggestions' import {isModifierKey} from './utils' +import useIsomorphicLayoutEffect from '../../utils/useIsomorphicLayoutEffect' export type MarkdownEditorProps = SxProp & { /** Current value of the editor as a multiline markdown string. */ @@ -268,7 +260,7 @@ const MarkdownEditor = forwardRef( useResizeObserver(onResize, containerRef) // workaround for Safari bug where layout is otherwise not recalculated - useLayoutEffect(() => { + useIsomorphicLayoutEffect(() => { const container = containerRef.current if (!container) return diff --git a/src/drafts/hooks/useCombobox.ts b/src/drafts/hooks/useCombobox.ts index c821f069cf5..3bb10ba4ec2 100644 --- a/src/drafts/hooks/useCombobox.ts +++ b/src/drafts/hooks/useCombobox.ts @@ -1,6 +1,7 @@ import Combobox from '@github/combobox-nav' -import {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react' +import {useCallback, useEffect, useRef, useState} from 'react' import {useId} from '../../hooks/useId' +import useIsomorphicLayoutEffect from '../../utils/useIsomorphicLayoutEffect' export type ComboboxCommitEvent = { /** The underlying `combobox-commit` event. */ @@ -138,7 +139,7 @@ export const useCombobox = ({ [onCommit, list], ) - useLayoutEffect(() => { + useIsomorphicLayoutEffect(() => { const optionElements = getOptionElements() // Ensure each option has a unique ID (required by the Combobox class), but respect user provided IDs for (const [i, option] of optionElements.entries()) { diff --git a/src/drafts/hooks/useDynamicTextareaHeight.ts b/src/drafts/hooks/useDynamicTextareaHeight.ts index b6a1b2c44e0..f6ce3a55745 100644 --- a/src/drafts/hooks/useDynamicTextareaHeight.ts +++ b/src/drafts/hooks/useDynamicTextareaHeight.ts @@ -1,7 +1,8 @@ -import {RefObject, useCallback, useEffect, useLayoutEffect, useState} from 'react' +import {RefObject, useCallback, useEffect, useState} from 'react' import {SxProp} from '../../sx' import {getCharacterCoordinates} from '../utils/character-coordinates' +import useIsomorphicLayoutEffect from '../../utils/useIsomorphicLayoutEffect' type UseDynamicTextareaHeightSettings = { disabled?: boolean @@ -63,7 +64,7 @@ export const useDynamicTextareaHeight = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [minHeightLines, maxHeightLines, value, elementRef, disabled]) - useLayoutEffect(refreshHeight, [refreshHeight]) + useIsomorphicLayoutEffect(refreshHeight, [refreshHeight]) // With Slots, initial render of the component is delayed and so the initial layout effect can occur // before the target element has actually been calculated in the DOM. But if we only use regular effects, diff --git a/src/drafts/hooks/useSafeAsyncCallback.ts b/src/drafts/hooks/useSafeAsyncCallback.ts index b8f9f1aaa61..78b741dd7c1 100644 --- a/src/drafts/hooks/useSafeAsyncCallback.ts +++ b/src/drafts/hooks/useSafeAsyncCallback.ts @@ -1,4 +1,5 @@ -import {useCallback, useEffect, useLayoutEffect, useRef} from 'react' +import {useCallback, useEffect, useRef} from 'react' +import useIsomorphicLayoutEffect from '../../utils/useIsomorphicLayoutEffect' export const callbackCancelledResult = Symbol('callbackCancelledResult') export type CallbackCancelledResult = typeof callbackCancelledResult @@ -27,7 +28,7 @@ export const useSafeAsyncCallback = ( allowCallingAfterUnmount = false, ): ((...args: A) => R | CallbackCancelledResult) => { const trackingRef = useRef(fn) - useLayoutEffect(() => { + useIsomorphicLayoutEffect(() => { trackingRef.current = fn }, [fn]) diff --git a/src/hooks/useId.ts b/src/hooks/useId.ts index 06e5fcf8d24..b951b256b02 100644 --- a/src/hooks/useId.ts +++ b/src/hooks/useId.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line import/no-namespace +// eslint-disable-next-line no-restricted-imports, import/no-namespace import * as React from 'react' // eslint-disable-next-line no-restricted-imports import {useSSRSafeId} from '@react-aria/ssr' diff --git a/src/utils/useIsomorphicLayoutEffect.ts b/src/utils/useIsomorphicLayoutEffect.ts index b22e79d0da6..acd14253541 100644 --- a/src/utils/useIsomorphicLayoutEffect.ts +++ b/src/utils/useIsomorphicLayoutEffect.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line no-restricted-imports import {useEffect, useLayoutEffect} from 'react' const useIsomorphicLayoutEffect =