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 =