From c8aace9c1860f806f830817ca0222eca47af30fc Mon Sep 17 00:00:00 2001 From: Oleksandr Fediashov Date: Tue, 13 Dec 2022 13:40:41 +0100 Subject: [PATCH 01/30] chore: replace ta-scripts with release-it (#4410) * chore: replace ta-scripts with release-it * chore: bump Node versions on CI --- .circleci/config.yml | 2 +- .github/workflows/size-limit.yml | 2 +- .release-it.json | 9 + package.json | 6 +- yarn.lock | 1891 +++++++++++++++++++++++++----- 5 files changed, 1607 insertions(+), 303 deletions(-) create mode 100644 .release-it.json diff --git a/.circleci/config.yml b/.circleci/config.yml index 8ea763b310..2c972a3ff1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ general: docker_defaults: &docker_defaults docker: - - image: circleci/node:12-browsers + - image: circleci/node:16-browsers working_directory: ~/project/semantic-ui-react environment: diff --git a/.github/workflows/size-limit.yml b/.github/workflows/size-limit.yml index 1897cbd5da..913c8a0c81 100644 --- a/.github/workflows/size-limit.yml +++ b/.github/workflows/size-limit.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/setup-node@v1 with: - node-version: 12.x + node-version: 16.x - name: Cache node_modules uses: actions/cache@v1 diff --git a/.release-it.json b/.release-it.json new file mode 100644 index 0000000000..8ede38bf97 --- /dev/null +++ b/.release-it.json @@ -0,0 +1,9 @@ +{ + "github": { + "release": false + }, + "npm": { + "publishArgs": "--registry=https://registry.npmjs.org", + "skipChecks": true + } +} diff --git a/package.json b/package.json index ec63118c97..0908136904 100644 --- a/package.json +++ b/package.json @@ -29,9 +29,7 @@ "prettier:fix": "prettier --write \"**/*.{js,jsx,ts,tsx}\"", "prerelease": "yarn lint && yarn tsd:test && yarn test && cross-env NODE_ENV=production yarn build", "postrelease": "yarn deploy:docs", - "release:major": "yarn prerelease && ta-script npm/release major && yarn postrelease", - "release:minor": "yarn prerelease && ta-script npm/release minor && yarn postrelease", - "release:patch": "yarn prerelease && ta-script npm/release patch && yarn postrelease", + "release": "release-it", "prestart": "yarn satisfied --fix yarn", "start": "cross-env NODE_ENV=development gulp --series start:docs", "satisfied": "satisfied --ignore \"webpack|react|react-dom\" --skip-invalid", @@ -166,6 +164,7 @@ "react-static-routes": "^1.0.0", "react-test-renderer": "^17.0.0", "react-universal-component": "^3.0.3", + "release-it": "^15.5.1", "rimraf": "^3.0.2", "satisfied": "^1.1.2", "semantic-ui-css": "^2.4.1", @@ -174,7 +173,6 @@ "sinon-chai": "^3.5.0", "size-limit": "^4.5.5", "start-server-and-test": "^1.11.5", - "ta-scripts": "^2.5.2", "terser-webpack-plugin": "^3.0.8", "terser-webpack-plugin-legacy": "^1.2.3", "through2": "^3.0.1", diff --git a/yarn.lock b/yarn.lock index ce63ba4867..145a05eb9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1137,6 +1137,11 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@iarna/toml@2.2.5": + version "2.2.5" + resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" + integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1213,6 +1218,107 @@ dependencies: mkdirp "^1.0.4" +"@octokit/auth-token@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.2.tgz#a0fc8de149fd15876e1ac78f6525c1c5ab48435f" + integrity sha512-pq7CwIMV1kmzkFTimdwjAINCXKTajZErLB4wMLYapR2nuB/Jpr66+05wOTZMSCBXP6n4DdDWT2W19Bm17vU69Q== + dependencies: + "@octokit/types" "^8.0.0" + +"@octokit/core@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.1.0.tgz#b6b03a478f1716de92b3f4ec4fd64d05ba5a9251" + integrity sha512-Czz/59VefU+kKDy+ZfDwtOIYIkFjExOKf+HA92aiTZJ6EfWpFzYQWw0l54ji8bVmyhc+mGaLUbSUmXazG7z5OQ== + dependencies: + "@octokit/auth-token" "^3.0.0" + "@octokit/graphql" "^5.0.0" + "@octokit/request" "^6.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + before-after-hook "^2.2.0" + universal-user-agent "^6.0.0" + +"@octokit/endpoint@^7.0.0": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.3.tgz#0b96035673a9e3bedf8bab8f7335de424a2147ed" + integrity sha512-57gRlb28bwTsdNXq+O3JTQ7ERmBTuik9+LelgcLIVfYwf235VHbN9QNo4kXExtp/h8T423cR5iJThKtFYxC7Lw== + dependencies: + "@octokit/types" "^8.0.0" + is-plain-object "^5.0.0" + universal-user-agent "^6.0.0" + +"@octokit/graphql@^5.0.0": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.4.tgz#519dd5c05123868276f3ae4e50ad565ed7dff8c8" + integrity sha512-amO1M5QUQgYQo09aStR/XO7KAl13xpigcy/kI8/N1PnZYSS69fgte+xA4+c2DISKqUZfsh0wwjc2FaCt99L41A== + dependencies: + "@octokit/request" "^6.0.0" + "@octokit/types" "^8.0.0" + universal-user-agent "^6.0.0" + +"@octokit/openapi-types@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-14.0.0.tgz#949c5019028c93f189abbc2fb42f333290f7134a" + integrity sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw== + +"@octokit/plugin-paginate-rest@^5.0.0": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz#93d7e74f1f69d68ba554fa6b888c2a9cf1f99a83" + integrity sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw== + dependencies: + "@octokit/types" "^8.0.0" + +"@octokit/plugin-request-log@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" + integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== + +"@octokit/plugin-rest-endpoint-methods@^6.7.0": + version "6.7.0" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.7.0.tgz#2f6f17f25b6babbc8b41d2bb0a95a8839672ce7c" + integrity sha512-orxQ0fAHA7IpYhG2flD2AygztPlGYNAdlzYz8yrD8NDgelPfOYoRPROfEyIe035PlxvbYrgkfUZIhSBKju/Cvw== + dependencies: + "@octokit/types" "^8.0.0" + deprecation "^2.3.1" + +"@octokit/request-error@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.2.tgz#f74c0f163d19463b87528efe877216c41d6deb0a" + integrity sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg== + dependencies: + "@octokit/types" "^8.0.0" + deprecation "^2.0.0" + once "^1.4.0" + +"@octokit/request@^6.0.0": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.2.tgz#a2ba5ac22bddd5dcb3f539b618faa05115c5a255" + integrity sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw== + dependencies: + "@octokit/endpoint" "^7.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^8.0.0" + is-plain-object "^5.0.0" + node-fetch "^2.6.7" + universal-user-agent "^6.0.0" + +"@octokit/rest@19.0.5": + version "19.0.5" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.5.tgz#4dbde8ae69b27dca04b5f1d8119d282575818f6c" + integrity sha512-+4qdrUFq2lk7Va+Qff3ofREQWGBeoTKNqlJO+FGjFP35ZahP+nBenhZiGdu8USSgmq4Ky3IJ/i4u0xbLqHaeow== + dependencies: + "@octokit/core" "^4.1.0" + "@octokit/plugin-paginate-rest" "^5.0.0" + "@octokit/plugin-request-log" "^1.0.4" + "@octokit/plugin-rest-endpoint-methods" "^6.7.0" + +"@octokit/types@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-8.0.0.tgz#93f0b865786c4153f0f6924da067fe0bb7426a9f" + integrity sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg== + dependencies: + "@octokit/openapi-types" "^14.0.0" + "@percy/cli-build@1.0.0-beta.73": version "1.0.0-beta.73" resolved "https://registry.yarnpkg.com/@percy/cli-build/-/cli-build-1.0.0-beta.73.tgz#f282747984327982628aeee16ccacf7d885b53aa" @@ -1348,6 +1454,21 @@ dependencies: "@percy/logger" "1.0.0-beta.73" +"@pnpm/network.ca-file@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz#2ab05e09c1af0cdf2fcf5035bea1484e222f7983" + integrity sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA== + dependencies: + graceful-fs "4.2.10" + +"@pnpm/npm-conf@^1.0.4": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@pnpm/npm-conf/-/npm-conf-1.0.5.tgz#3475541fb71d7b6ce68acaaa3392eae9fedf3276" + integrity sha512-hD8ml183638O3R6/Txrh0L8VzGOrFXgRtRDG4qQC4tONdZ5Z1M+tlUUDUvrjYdmK6G+JTBTeaCLMna11cXzi8A== + dependencies: + "@pnpm/network.ca-file" "^1.0.1" + config-chain "^1.1.11" + "@popperjs/core@^2.6.0": version "2.6.0" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.6.0.tgz#f022195afdfc942e088ee2101285a1d31c7d727f" @@ -1368,6 +1489,11 @@ exenv "^1.2.2" prop-types "^15.6.2" +"@sindresorhus/is@^5.2.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.3.0.tgz#0ec9264cf54a527671d990eb874e030b55b70dcc" + integrity sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw== + "@sinonjs/commons@^1", "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.7.2": version "1.8.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217" @@ -1411,6 +1537,13 @@ dependencies: semver "7.3.2" +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + "@textlint/ast-node-types@^4.0.3": version "4.2.1" resolved "https://registry.yarnpkg.com/@textlint/ast-node-types/-/ast-node-types-4.2.1.tgz#978fa10e23468114462fc08ef29f96980c12a8ef" @@ -1429,6 +1562,11 @@ traverse "^0.6.6" unified "^6.1.6" +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -1443,6 +1581,11 @@ version "4.6.2" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.6.2.tgz#12cfaba693ba20f114ed5765467ff25fdf67ddb0" +"@types/http-cache-semantics@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4": version "7.0.5" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" @@ -1819,6 +1962,11 @@ acorn-walk@^7.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== +acorn-walk@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" @@ -1842,6 +1990,11 @@ acorn@^7.1.1, acorn@^7.3.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA== +acorn@^8.7.0: + version "8.8.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + address@1.0.3, address@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" @@ -1850,7 +2003,7 @@ after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" -agent-base@6: +agent-base@6, agent-base@^6.0.0, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== @@ -1963,6 +2116,13 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" +ansi-align@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + ansi-colors@4.1.1, ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -1995,6 +2155,13 @@ ansi-escapes@^4.3.0: dependencies: type-fest "^0.11.0" +ansi-escapes@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-6.0.0.tgz#68c580e87a489f6df3d761028bb93093fde6bd8a" + integrity sha512-IG23inYII3dWlU2EyiAiGj6Bwal5GzsgPMwjYGvc1HPE2dgbj4ZB5ToWBKSquKw74nB3TIuOwaI6/jSULzfgrw== + dependencies: + type-fest "^3.0.0" + ansi-gray@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" @@ -2023,6 +2190,11 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -2041,6 +2213,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + ansi-wrap@0.1.0, ansi-wrap@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" @@ -2050,10 +2227,6 @@ any-observable@^0.3.0: resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - anymatch@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" @@ -2112,6 +2285,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + args@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/args/-/args-4.0.0.tgz#5ca24cdba43d4b17111c56616f5f2e9d91933954" @@ -2278,15 +2456,16 @@ array.prototype.flatmap@^1.2.3: es-abstract "^1.17.0-next.1" function-bind "^1.1.1" -array.prototype.map@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.2.tgz#9a4159f416458a23e9483078de1106b2ef68f8ec" - integrity sha512-Az3OYxgsa1g7xDYp86l0nnN4bcmuEITGe1rbdEBVkrqkzMgDcbdQ2R7r41pNzti+4NMces3H8gMmuioZUilLgw== +array.prototype.map@^1.0.1, array.prototype.map@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.5.tgz#6e43c2fee6c0fb5e4806da2dc92eb00970809e55" + integrity sha512-gfaKntvwqYIuC7mLLyv2wzZIJqrRhn5PZ9EfFejSx6a78sV7iDsGpG9P+3oUPtm1Rerqm6nrKS4FYuTIvWfo3g== dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.4" + is-string "^1.0.7" arraybuffer.slice@~0.0.7: version "0.0.7" @@ -2344,6 +2523,13 @@ ast-types@0.12.2: resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.12.2.tgz#341656049ee328ac03fc805c156b49ebab1e4462" integrity sha512-8c83xDLJM/dLDyXNLiR6afRRm4dPKN6KAnKqytRK3DBJul9lA+atxdQkNDkSVPdTqea5HiRq3lnnOIZ0MBpvdg== +ast-types@^0.13.2: + version "0.13.4" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782" + integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w== + dependencies: + tslib "^2.0.1" + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -2372,6 +2558,13 @@ async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" +async-retry@1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" + integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw== + dependencies: + retry "0.13.1" + async-sema@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/async-sema/-/async-sema-1.4.1.tgz#6b01d56b4bfbd5364a2cada0a6569516d57a5cbb" @@ -2451,12 +2644,6 @@ axe-core@^3.5.4: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.5.5.tgz#84315073b53fa3c0c51676c588d59da09a192227" integrity sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q== -axios@^0.15.2: - version "0.15.3" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.15.3.tgz#2c9d638b2e191a08ea1d6cc988eadd6ba5bdc053" - dependencies: - follow-redirects "1.0.0" - axios@^0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d" @@ -3325,9 +3512,10 @@ base64-arraybuffer@0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" -base64-js@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base64id@2.0.0: version "2.0.0" @@ -3367,6 +3555,11 @@ beeper@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" +before-after-hook@^2.2.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" + integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== + better-assert@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" @@ -3425,6 +3618,15 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" +bl@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-5.1.0.tgz#183715f678c7188ecef9fe475d90209400624273" + integrity sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ== + dependencies: + buffer "^6.0.3" + inherits "^2.0.4" + readable-stream "^3.4.0" + blob-util@2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" @@ -3439,7 +3641,7 @@ bluebird@3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" -bluebird@3.7.2, bluebird@^3.3.3, bluebird@^3.4.7, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.2: +bluebird@3.7.2, bluebird@^3.4.7, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -3495,6 +3697,20 @@ boxen@1.3.0, boxen@^1.2.1: term-size "^1.2.0" widest-line "^2.0.0" +boxen@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.0.0.tgz#9e5f8c26e716793fc96edcf7cf754cdf5e3fbf32" + integrity sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg== + dependencies: + ansi-align "^3.0.1" + camelcase "^7.0.0" + chalk "^5.0.1" + cli-boxes "^3.0.0" + string-width "^5.1.2" + type-fest "^2.13.0" + widest-line "^4.0.1" + wrap-ansi "^8.0.1" + brace-expansion@^1.0.0, brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -3679,6 +3895,14 @@ buffer@^5.2.1, buffer@^5.5.0: base64-js "^1.0.2" ieee754 "^1.1.4" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -3687,11 +3911,16 @@ bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" -bytes@3.1.0, bytes@^3.1.0: +bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +bytes@3.1.2, bytes@^3.1.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + cacache@^11.0.2: version "11.3.2" resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" @@ -3770,11 +3999,37 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cacheable-lookup@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" + integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== + +cacheable-request@^10.2.1: + version "10.2.3" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.3.tgz#25277efe121308ab722c28b4164e51382b4adeb1" + integrity sha512-6BehRBOs7iurNjAYN9iPazTwFDaMQavJO8W1MEm3s2pH8q/tkPTtLDRUZaweWK87WFGf2Y5wLAlaCJlR5kOz3w== + dependencies: + "@types/http-cache-semantics" "^4.0.1" + get-stream "^6.0.1" + http-cache-semantics "^4.1.0" + keyv "^4.5.2" + mimic-response "^4.0.0" + normalize-url "^8.0.0" + responselike "^3.0.0" + cachedir@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -3833,6 +4088,11 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelcase@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-7.0.0.tgz#fd112621b212126741f998d614cbc2a8623fd174" + integrity sha512-JToIvOmz6nhGsUhAYScbo2d6Py5wojjNfoxoc2mEVLUdJ70gJK2gnd+ABY1Tc3sVMyK7QDPtN0T/XdlCQWITyQ== + caniuse-api@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" @@ -3938,6 +4198,11 @@ chalk@2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.1.2.tgz#d957f370038b75ac572471e83be4c5ca9f8e8c45" + integrity sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ== + chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -3963,6 +4228,11 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^5.0.0, chalk@^5.0.1, chalk@^5.1.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" + integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== + change-case@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.0.2.tgz#fd48746cce02f03f0a672577d1d3a8dc2eceb037" @@ -4002,6 +4272,11 @@ chardet@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.0.tgz#0bbe1355ac44d7a3ed4a925707c4ef70f8190f6c" +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + check-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" @@ -4123,6 +4398,11 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.2.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.7.0.tgz#6d01b3696c59915b6ce057e4aa4adfc2fa25f5ef" + integrity sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog== + ci-job-number@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/ci-job-number/-/ci-job-number-1.2.2.tgz#f4e5918fcaeeda95b604f214be7d7d4a961fe0c0" @@ -4173,6 +4453,11 @@ cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" +cli-boxes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145" + integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g== + cli-cursor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" @@ -4193,10 +4478,17 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-spinners@^2.2.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.4.0.tgz#c6256db216b878cfba4720e719cec7cf72685d7f" - integrity sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA== +cli-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" + integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg== + dependencies: + restore-cursor "^4.0.0" + +cli-spinners@^2.2.0, cli-spinners@^2.6.1: + version "2.7.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" + integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== cli-table3@~0.6.0: version "0.6.0" @@ -4228,6 +4520,11 @@ cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" +cli-width@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.0.0.tgz#a5622f6a3b0a9e3e711a25f099bf2399f608caf6" + integrity sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw== + clipboard@^2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376" @@ -4431,7 +4728,7 @@ colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -4551,6 +4848,17 @@ configstore@^3.0.0: write-file-atomic "^2.0.0" xdg-basedir "^3.0.0" +configstore@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-6.0.0.tgz#49eca2ebc80983f77e09394a1a56e0aca8235566" + integrity sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA== + dependencies: + dot-prop "^6.0.1" + graceful-fs "^4.2.6" + unique-string "^3.0.0" + write-file-atomic "^3.0.3" + xdg-basedir "^5.0.1" + confusing-browser-globals@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd" @@ -4693,6 +5001,16 @@ cors@^2.8.4: object-assign "^4" vary "^1" +cosmiconfig@8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.0.0.tgz#e9feae014eab580f858f8a0288f38997a7bebe97" + integrity sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: version "2.2.2" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.2.2.tgz#6173cebd56fac042c1f4390edf7af6c07c7cb892" @@ -4821,6 +5139,13 @@ crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" +crypto-random-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-4.0.0.tgz#5a3cc53d7dd86183df5da0312816ceeeb5bb1fc2" + integrity sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA== + dependencies: + type-fest "^1.0.1" + css-color-names@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" @@ -5009,6 +5334,16 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +data-uri-to-buffer@3: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" + integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== + +data-uri-to-buffer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" + integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA== + date-fns@^1.27.2: version "1.30.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" @@ -5080,6 +5415,13 @@ decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" @@ -5182,12 +5524,23 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== +defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== dependencies: - object-keys "^1.0.12" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" define-property@^0.2.5: version "0.2.5" @@ -5212,7 +5565,17 @@ defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" -del@^2.0.2, del@^2.2.0: +degenerator@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-3.0.2.tgz#6a61fcc42a702d6e50ff6023fe17bff435f68235" + integrity sha512-c0mef3SNQo56t6urUU6tdQAs+ThoD0o9B9MJ8HEt7NQcGEILCRFqQb7ZbP9JAv+QF1Ky5plydhMR/IrqWDm+TQ== + dependencies: + ast-types "^0.13.2" + escodegen "^1.8.1" + esprima "^4.0.0" + vm2 "^3.9.8" + +del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" dependencies: @@ -5252,10 +5615,20 @@ depd@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" +deprecation@^2.0.0, deprecation@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" + integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== + des.js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" @@ -5480,6 +5853,13 @@ dot-prop@^4.1.0: dependencies: is-obj "^1.0.0" +dot-prop@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" + integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== + dependencies: + is-obj "^2.0.0" + double-ended-queue@2.1.0-0: version "2.1.0-0" resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" @@ -5536,6 +5916,11 @@ each-props@^1.3.0: is-plain-object "^2.0.1" object.defaults "^1.1.0" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -5590,10 +5975,10 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.0.0.tgz#48a2309cc8a1d2e9d23bc6a67c39b63032e76ea4" - integrity sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w== +emoji-regex@^9.0.0, emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== emoji-regex@~6.1.0: version "6.1.3" @@ -5759,22 +6144,36 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== +es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5, es-abstract@^1.19.0, es-abstract@^1.20.4: + version "1.20.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.5.tgz#e6dc99177be37cacda5988e692c3fa8b218e95d2" + integrity sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ== dependencies: + call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.3" + get-symbol-description "^1.0.0" + gopd "^1.0.1" has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.2" object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + unbox-primitive "^1.0.2" es-array-method-boxes-properly@^1.0.0: version "1.0.0" @@ -5860,6 +6259,11 @@ escalade@^3.0.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== +escape-goat@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-4.0.0.tgz#9424820331b510b0666b98f7873fe11ac4aa8081" + integrity sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -5868,6 +6272,23 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + +escodegen@^1.8.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + escope@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" @@ -6163,9 +6584,10 @@ esprima@^2.6.0: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" -esprima@^4.0.0, esprima@~4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" +esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.0, esquery@^1.2.0: version "1.3.1" @@ -6181,9 +6603,10 @@ esrecurse@^4.1.0: estraverse "^4.1.0" object-assign "^4.0.1" -estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0: version "5.1.0" @@ -6262,6 +6685,21 @@ execa@3.4.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-6.1.0.tgz#cea16dee211ff011246556388effa0818394fb20" + integrity sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^3.0.1" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -6301,6 +6739,21 @@ execa@^4.0.1, execa@^4.0.2: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + executable@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" @@ -6409,6 +6862,15 @@ external-editor@^2.0.4: iconv-lite "^0.4.17" tmp "^0.0.33" +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" @@ -6508,10 +6970,10 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.9: - version "3.2.10" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.10.tgz#2734f83baa7f43b7fd41e13bc34438f4ffe284ee" - integrity sha512-s9nFhFnvR63wls6/kM88kQqDhMu0AfdjqouE2l5GVQPbqLgyFjjU5ry/r2yKsJxpb9Py1EYNqieFrmMaX4v++A== +fast-glob@^3.2.11, fast-glob@^3.2.9: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -6523,7 +6985,7 @@ fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -6582,6 +7044,14 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" +fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + figgy-pudding@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" @@ -6608,6 +7078,14 @@ figures@^3.2.0: dependencies: escape-string-regexp "^1.0.5" +figures@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-5.0.0.tgz#126cd055052dea699f8a54e8c9450e6ecfc44d5f" + integrity sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg== + dependencies: + escape-string-regexp "^5.0.0" + is-unicode-supported "^1.2.0" + file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" @@ -6641,6 +7119,11 @@ file-type@^6.1.0: version "6.2.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" +file-uri-to-path@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz#7b415aeba227d575851e0a5b0c640d7656403fba" + integrity sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg== + filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -6870,12 +7353,6 @@ flush-write-stream@^1.0.0, flush-write-stream@^1.0.2: inherits "^2.0.1" readable-stream "^2.0.4" -follow-redirects@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.0.0.tgz#8e34298cbd2e176f254effec75a1c78cc849fd37" - dependencies: - debug "^2.2.0" - follow-redirects@1.5.10: version "1.5.10" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" @@ -6909,6 +7386,20 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +form-data-encoder@^2.1.2: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" + integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== + +form-data@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@^2.3.2, form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -6923,6 +7414,13 @@ format@^0.2.2: resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -6962,16 +7460,6 @@ fs-extra@6.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^0.26.5: - version "0.26.7" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - fs-extra@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b" @@ -7019,15 +7507,6 @@ fs-mkdirp-stream@^1.0.0: graceful-fs "^4.1.11" through2 "^2.0.3" -fs-promise@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-0.5.0.tgz#4347d6bf624655a7061a4319213c393276ad3ef3" - dependencies: - any-promise "^1.0.0" - fs-extra "^0.26.5" - mz "^2.3.1" - thenify-all "^1.6.0" - fs-readdir-recursive@^1.0.0, fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" @@ -7060,27 +7539,36 @@ fsevents@~2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +ftp@^0.3.10: + version "0.3.10" + resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" + integrity sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ== + dependencies: + readable-stream "1.1.x" + xregexp "2.0.0" + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" -function.prototype.name@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.2.tgz#5cdf79d7c05db401591dfde83e3b70c5123e9a45" - integrity sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg== +function.prototype.name@^1.1.2, function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - functions-have-names "^1.2.0" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" -functions-have-names@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.1.tgz#a981ac397fa0c9964551402cdc5533d7a4d52f91" - integrity sha512-j48B/ZI7VKs3sgeI2cZp7WXWmZXu7Iq5pl5/vptV5N2mq+DGFuS/ulaDjtaoLpYzuD6u8UgrUKHfgo7fDTSiBA== +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== gauge@~2.7.3: version "2.7.4" @@ -7113,6 +7601,15 @@ get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -7156,6 +7653,31 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-uri@3: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-3.0.2.tgz#f0ef1356faabc70e1f9404fa3b66b2ba9bfc725c" + integrity sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg== + dependencies: + "@tootallnate/once" "1" + data-uri-to-buffer "3" + debug "4" + file-uri-to-path "2" + fs-extra "^8.1.0" + ftp "^0.3.10" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -7198,6 +7720,21 @@ git-promise@^0.3.1: q "~1.4.1" shelljs "~0.5.3" +git-up@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-7.0.0.tgz#bace30786e36f56ea341b6f69adfd83286337467" + integrity sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ== + dependencies: + is-ssh "^1.4.0" + parse-url "^8.1.0" + +git-url-parse@13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.1.0.tgz#07e136b5baa08d59fabdf0e33170de425adf07b4" + integrity sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA== + dependencies: + git-up "^7.0.0" + glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -7278,6 +7815,13 @@ global-dirs@^2.0.1: dependencies: ini "^1.3.5" +global-dirs@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" + integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== + dependencies: + ini "2.0.0" + global-modules@1.0.0, global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -7335,6 +7879,17 @@ globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" +globby@13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.2.tgz#29047105582427ab6eca4f905200667b056da515" + integrity sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^4.0.0" + globby@^11.0.1, globby@^11.0.4: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -7381,6 +7936,30 @@ good-listener@^1.2.2: dependencies: delegate "^3.1.2" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +got@12.5.3, got@^12.1.0: + version "12.5.3" + resolved "https://registry.yarnpkg.com/got/-/got-12.5.3.tgz#82bdca2dd61258a02e24d668ea6e7abb70ac3598" + integrity sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w== + dependencies: + "@sindresorhus/is" "^5.2.0" + "@szmarczak/http-timer" "^5.0.1" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.1" + decompress-response "^6.0.0" + form-data-encoder "^2.1.2" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^3.0.0" + got@^6.3.0, got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -7397,10 +7976,10 @@ got@^6.3.0, got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" -graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== +graceful-fs@4.2.10, graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== "graceful-readlink@>= 1.0.0": version "1.0.1" @@ -7548,6 +8127,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-binary2@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" @@ -7581,14 +8165,21 @@ has-gulplog@^0.1.0: dependencies: sparkles "^1.0.0" -has-symbol-support-x@^1.4.1: - version "1.4.2" +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-symbol-support-x@^1.4.1: + version "1.4.2" resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== has-to-string-tag-x@^1.2.0: version "1.4.1" @@ -7596,6 +8187,13 @@ has-to-string-tag-x@^1.2.0: dependencies: has-symbol-support-x "^1.4.1" +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -7627,6 +8225,11 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" +has-yarn@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-3.0.0.tgz#c3c21e559730d1d3b57e28af1f30d06fac38147d" + integrity sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA== + has@^1.0.1, has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -7869,6 +8472,11 @@ htmlparser2@~3.3.0: domutils "1.1" readable-stream "1.0" +http-cache-semantics@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" @@ -7893,6 +8501,17 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + http-errors@~1.7.2: version "1.7.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" @@ -7908,6 +8527,15 @@ http-parser-js@>=0.4.0: version "0.4.13" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.13.tgz#3bd6d6fde6e3172c9334c3b33b6c193d80fe1137" +http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + http-proxy-middleware@~0.17.4: version "0.17.4" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" @@ -7935,10 +8563,26 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +http2-wrapper@^2.1.10: + version "2.2.0" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.0.tgz#b80ad199d216b7d3680195077bd7b9060fa9d7f3" + integrity sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" +https-proxy-agent@5, https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + https-proxy-agent@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" @@ -7952,6 +8596,16 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +human-signals@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" + integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ== + humanize-url@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/humanize-url/-/humanize-url-1.0.1.tgz#f4ab99e0d288174ca4e1e50407c55fbae464efff" @@ -7980,7 +8634,7 @@ iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" -iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -7997,9 +8651,10 @@ icss-utils@^2.1.0: dependencies: postcss "^6.0.1" -ieee754@^1.1.4: - version "1.1.8" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" +ieee754@^1.1.4, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== iferr@^0.1.5: version "0.1.5" @@ -8051,6 +8706,11 @@ import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" +import-lazy@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" + integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== + import-local@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" @@ -8130,6 +8790,11 @@ inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" @@ -8184,20 +8849,41 @@ inquirer@3.3.0, inquirer@^3.0.6, inquirer@^3.3.0: strip-ansi "^4.0.0" through "^2.3.6" +inquirer@9.1.4: + version "9.1.4" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.1.4.tgz#482da8803670a64bd942bc5166a9547a19d41474" + integrity sha512-9hiJxE5gkK/cM2d1mTEnuurGTAoHebbkX0BYl3h7iEg7FYfuNIom+nDfBCSWtvSnoSrWCeBxqqBZu26xdlJlXA== + dependencies: + ansi-escapes "^6.0.0" + chalk "^5.1.2" + cli-cursor "^4.0.0" + cli-width "^4.0.0" + external-editor "^3.0.3" + figures "^5.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^6.1.2" + run-async "^2.4.0" + rxjs "^7.5.7" + string-width "^5.1.2" + strip-ansi "^7.0.1" + through "^2.3.6" + wrap-ansi "^8.0.1" + internal-ip@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" dependencies: meow "^3.3.0" -internal-slot@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3" - integrity sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g== +internal-slot@^1.0.2, internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== dependencies: - es-abstract "^1.17.0-next.1" + get-intrinsic "^1.1.0" has "^1.0.3" - side-channel "^1.0.2" + side-channel "^1.0.4" interpret@^1.0.0, interpret@^1.4.0: version "1.4.0" @@ -8218,6 +8904,11 @@ ip@1.1.5, ip@^1.1.0, ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -8273,6 +8964,13 @@ is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -8286,10 +8984,13 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e" - integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ== +is-boolean-object@^1.0.1, is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" is-buffer@^1.1.4, is-buffer@^1.1.5: version "1.1.6" @@ -8300,10 +9001,17 @@ is-buffer@^2.0.0, is-buffer@~2.0.3: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== -is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" - integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== +is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-ci@3.0.1, is-ci@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== + dependencies: + ci-info "^3.2.0" is-ci@^1.0.10: version "1.1.0" @@ -8358,6 +9066,11 @@ is-directory@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -8445,11 +9158,24 @@ is-installed-globally@^0.3.2: global-dirs "^2.0.1" is-path-inside "^3.0.1" +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-interactive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-2.0.0.tgz#40c57614593826da1100ade6059778d597f16e90" + integrity sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ== + is-lower-case@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393" @@ -8469,10 +9195,20 @@ is-negated-glob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" +is-npm@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-6.0.0.tgz#b59e75e8915543ca5d881ecff864077cba095261" + integrity sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ== + is-number-object@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" @@ -8503,6 +9239,11 @@ is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + is-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" @@ -8536,10 +9277,10 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-path-inside@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" - integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== +is-path-inside@^3.0.1, is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" @@ -8551,6 +9292,11 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -8567,12 +9313,13 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" -is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" - integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== +is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: - has-symbols "^1.0.1" + call-bind "^1.0.2" + has-tostringtag "^1.0.0" is-regexp@^1.0.0: version "1.0.0" @@ -8609,6 +9356,20 @@ is-set@^2.0.1: resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-ssh@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.0.tgz#4f8220601d2839d8fa624b3106f8e8884f01b8b2" + integrity sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ== + dependencies: + protocols "^2.0.1" + is-stream@1.1.0, is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -8618,10 +9379,17 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-string@^1.0.4, is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" is-subset@^0.1.1: version "0.1.1" @@ -8633,14 +9401,14 @@ is-svg@^2.0.0: dependencies: html-comment-regex "^1.1.0" -is-symbol@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: - has-symbols "^1.0.0" + has-symbols "^1.0.2" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -8657,6 +9425,11 @@ is-unc-path@^1.0.0: dependencies: unc-path-regex "^0.1.2" +is-unicode-supported@^1.1.0, is-unicode-supported@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz#d824984b616c292a2e198207d4a609983842f714" + integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== + is-upper-case@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f" @@ -8671,6 +9444,13 @@ is-valid-glob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + is-whitespace-character@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz#ede53b4c6f6fb3874533751ec9280d01928d03ed" @@ -8691,6 +9471,18 @@ is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +is-yarn-global@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.4.1.tgz#b312d902b313f81e4eaf98b6361ba2b45cd694bb" + integrity sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ== + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -8800,7 +9592,7 @@ iterate-iterator@^1.0.1: resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" integrity sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw== -iterate-value@^1.0.0: +iterate-value@^1.0.0, iterate-value@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== @@ -8859,6 +9651,13 @@ js-yaml@^3.13.1, js-yaml@^3.4.3, js-yaml@^3.9.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + js-yaml@~3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" @@ -8883,6 +9682,11 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-loader@^0.5.4: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" @@ -8946,12 +9750,6 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - optionalDependencies: - graceful-fs "^4.1.6" - jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -9086,6 +9884,13 @@ keyboard-key@^1.1.0: resolved "https://registry.yarnpkg.com/keyboard-key/-/keyboard-key-1.1.0.tgz#6f2e8e37fa11475bb1f1d65d5174f1b35653f5b7" integrity sha512-qkBzPTi3rlAKvX7k0/ub44sqOfXeLc/jcnGGmj5c7BJpU8eDrEVPyhCvNYAaoubbsLm9uGWwQJO1ytQK1a9/dQ== +keyv@^4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" + integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== + dependencies: + json-buffer "3.0.1" + killable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b" @@ -9110,12 +9915,6 @@ kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - optionalDependencies: - graceful-fs "^4.1.9" - language-subtag-registry@~0.3.2: version "0.3.20" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.20.tgz#a00a37121894f224f763268e431c55556b0c0755" @@ -9141,6 +9940,13 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" +latest-version@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-7.0.0.tgz#843201591ea81a4d404932eeb61240fe04e9e5da" + integrity sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg== + dependencies: + package-json "^8.1.0" + lazy-ass@1.6.0, lazy-ass@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" @@ -9410,10 +10216,6 @@ lodash._root@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" -lodash.assign@^4.0.3, lodash.assign@^4.0.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -9499,7 +10301,7 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: +lodash@4.17.21, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -9530,6 +10332,14 @@ log-symbols@^4.0.0: dependencies: chalk "^4.0.0" +log-symbols@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-5.1.0.tgz#a20e3b9a5f53fac6aeb8e2bb22c07cf2c8f16d93" + integrity sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA== + dependencies: + chalk "^5.0.0" + is-unicode-supported "^1.1.0" + log-update@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" @@ -9595,6 +10405,11 @@ lowercase-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -9622,6 +10437,11 @@ lz-string@^1.4.4: resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= +macos-release@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-3.1.0.tgz#6165bb0736ae567ed6649e36ce6a24d87cbb7aca" + integrity sha512-/M/R0gCDgM+Cv1IuBG1XGdfTFnMEG6PZeT+KGWHO/OG+imqmaD9CH5vHBTycEM3+Kc4uG2Il+tFAuUWLqQOeUA== + make-dir@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51" @@ -9857,10 +10677,10 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.44.0, "mime-db@>= 1.34.0 < 2": - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== +mime-db@1.52.0, "mime-db@>= 1.34.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-db@~1.33.0: version "1.33.0" @@ -9872,12 +10692,12 @@ mime-types@2.1.18: dependencies: mime-db "~1.33.0" -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== +mime-types@2.1.35, mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - mime-db "1.44.0" + mime-db "1.52.0" mime@1.4.1: version "1.4.1" @@ -9901,6 +10721,21 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +mimic-response@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" + integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== + min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" @@ -10122,14 +10957,6 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -mz@^2.3.1: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - nan@^2.12.1: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" @@ -10189,6 +11016,18 @@ neo-async@^2.5.0, neo-async@^2.6.1: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +netmask@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" + integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== + +new-github-release-url@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/new-github-release-url/-/new-github-release-url-2.0.0.tgz#335189b91f52bbb9569042a7485900a205a0500b" + integrity sha512-NHDDGYudnvRutt/VhKFlX26IotXe1w0cmkDm6JGquh5bz/bDTw0LufSmH/GxTjEdpHEO+bVKFTwdrcGa/9XlKQ== + dependencies: + type-fest "^2.5.1" + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -10216,13 +11055,27 @@ node-dir@^0.1.10: dependencies: minimatch "^3.0.2" -node-fetch@2.6.5, node-fetch@^2.1.2: +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + +node-fetch@2.6.5: version "2.6.5" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== dependencies: whatwg-url "^5.0.0" +node-fetch@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.0.tgz#37e71db4ecc257057af828d523a7243d651d91e4" + integrity sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + node-fetch@^1.0.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -10230,6 +11083,13 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" +node-fetch@^2.1.2, node-fetch@^2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + node-forge@0.7.5: version "0.7.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" @@ -10340,6 +11200,11 @@ normalize-url@^1.0.0, normalize-url@^1.4.0: query-string "^4.1.0" sort-keys "^1.0.0" +normalize-url@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.0.tgz#593dbd284f743e8dcf6a5ddf8fadff149c82701a" + integrity sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw== + now-and-later@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.0.tgz#bc61cbb456d79cb32207ce47ca05136ff2e7d6ee" @@ -10370,13 +11235,20 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^4.0.0: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -10426,10 +11298,10 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== +object-inspect@^1.12.2, object-inspect@^1.7.0, object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2: version "1.1.2" @@ -10439,7 +11311,7 @@ object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2: define-properties "^1.1.3" es-abstract "^1.17.5" -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.0.11, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -10450,7 +11322,7 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@4.1.0, object.assign@^4.0.4, object.assign@^4.1.0: +object.assign@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" dependencies: @@ -10459,6 +11331,16 @@ object.assign@4.1.0, object.assign@^4.0.4, object.assign@^4.1.0: has-symbols "^1.0.0" object-keys "^1.0.11" +object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + object.defaults@^1.0.0, object.defaults@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" @@ -10556,13 +11438,29 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -onetime@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" - integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +open@8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + opencollective-postinstall@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" @@ -10600,16 +11498,17 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== dependencies: deep-is "~0.1.3" - fast-levenshtein "~2.0.4" + fast-levenshtein "~2.0.6" levn "~0.3.0" prelude-ls "~1.1.2" type-check "~0.3.2" - wordwrap "~1.0.0" + word-wrap "~1.2.3" optionator@^0.9.1: version "0.9.1" @@ -10623,6 +11522,21 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +ora@6.1.2, ora@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ora/-/ora-6.1.2.tgz#7b3c1356b42fd90fb1dad043d5dbe649388a0bf5" + integrity sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw== + dependencies: + bl "^5.0.0" + chalk "^5.0.0" + cli-cursor "^4.0.0" + cli-spinners "^2.6.1" + is-interactive "^2.0.0" + is-unicode-supported "^1.1.0" + log-symbols "^5.1.0" + strip-ansi "^7.0.1" + wcwidth "^1.0.1" + ora@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/ora/-/ora-4.0.5.tgz#7410b5cc2d99fa637fd5099bbb9f02bfbb5a361e" @@ -10671,6 +11585,14 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" +os-name@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-5.0.1.tgz#acb4f996ec5bd86c41755fef9d6d31905c47172e" + integrity sha512-0EQpaHUHq7olp2/YFUr+0vZi9tMpDTblHGz+Ch5RntKxiRXOAY0JOz1UlxhSjMSksHvkm13eD6elJj3M8Ht/kw== + dependencies: + macos-release "^3.0.1" + windows-release "^5.0.1" + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -10695,6 +11617,11 @@ output-file-sync@^1.1.2: mkdirp "^0.5.1" object-assign "^4.1.0" +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -10761,6 +11688,30 @@ p-try@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" +pac-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz#b718f76475a6a5415c2efbe256c1c971c84f635e" + integrity sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + get-uri "3" + http-proxy-agent "^4.0.1" + https-proxy-agent "5" + pac-resolver "^5.0.0" + raw-body "^2.2.0" + socks-proxy-agent "5" + +pac-resolver@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-5.0.1.tgz#c91efa3a9af9f669104fa2f51102839d01cde8e7" + integrity sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q== + dependencies: + degenerator "^3.0.2" + ip "^1.1.5" + netmask "^2.0.2" + package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -10770,6 +11721,16 @@ package-json@^4.0.0: registry-url "^3.0.3" semver "^5.1.0" +package-json@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-8.1.0.tgz#2a22806f1ed7c786c8e6ff26cfe20003bf4c6850" + integrity sha512-hySwcV8RAWeAfPsXb9/HGSPn8lwDnv6fabH+obUZKX169QknRkRhPxd1yMubpKDskLFATkl3jHpNtVtDPFA0Wg== + dependencies: + got "^12.1.0" + registry-auth-token "^5.0.1" + registry-url "^6.0.0" + semver "^7.3.7" + pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" @@ -10854,6 +11815,20 @@ parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" +parse-path@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.0.0.tgz#605a2d58d0a749c8594405d8cc3a2bf76d16099b" + integrity sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog== + dependencies: + protocols "^2.0.0" + +parse-url@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-8.1.0.tgz#972e0827ed4b57fc85f0ea6b0d839f0d8a57a57d" + integrity sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w== + dependencies: + parse-path "^7.0.0" + parse5@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" @@ -10946,6 +11921,11 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -11511,6 +12491,18 @@ promise.allsettled@1.0.2: function-bind "^1.1.1" iterate-value "^1.0.0" +promise.allsettled@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.6.tgz#8dc8ba8edf429feb60f8e81335b920e109c94b6e" + integrity sha512-22wJUOD3zswWFqgwjNHa1965LvqTX87WPu/lreY2KSd7SVcERfuZ4GfUaOnJNnvtoIv2yXT/W00YIGMetXtFXg== + dependencies: + array.prototype.map "^1.0.5" + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + iterate-value "^1.0.2" + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -11546,6 +12538,11 @@ proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" +protocols@^2.0.0, protocols@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" + integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== + proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" @@ -11554,7 +12551,21 @@ proxy-addr@~2.0.5: forwarded "~0.1.2" ipaddr.js "1.9.1" -proxy-from-env@1.1.0: +proxy-agent@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-5.0.0.tgz#d31405c10d6e8431fde96cba7a0c027ce01d633b" + integrity sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g== + dependencies: + agent-base "^6.0.0" + debug "4" + http-proxy-agent "^4.0.0" + https-proxy-agent "^5.0.0" + lru-cache "^5.1.1" + pac-proxy-agent "^5.0.0" + proxy-from-env "^1.0.0" + socks-proxy-agent "^5.0.0" + +proxy-from-env@1.1.0, proxy-from-env@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== @@ -11626,6 +12637,13 @@ punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" +pupa@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-3.1.0.tgz#f15610274376bbcc70c9a3aa8b505ea23f41c579" + integrity sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug== + dependencies: + escape-goat "^4.0.0" + puppeteer@^13.0.1: version "13.0.1" resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-13.0.1.tgz#9cd9bb8ec090bade183ca186bf342396bdffa135" @@ -11693,6 +12711,11 @@ queue@6.0.2: dependencies: inherits "~2.0.3" +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + raf@^3.4.0, raf@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" @@ -11771,6 +12794,16 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@^2.2.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + raw-loader@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa" @@ -11783,7 +12816,7 @@ raw-loader@^4.0.1: loader-utils "^2.0.0" schema-utils "^2.6.5" -rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: +rc@1.2.8, rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -12163,6 +13196,15 @@ readable-stream@1.0: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@1.1.x, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + "readable-stream@2 || 3", readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" @@ -12172,15 +13214,6 @@ readable-stream@1.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - readdirp@^2.0.0, readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -12304,13 +13337,14 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0, regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + functions-have-names "^1.2.2" regexpp@^1.0.1: version "1.1.0" @@ -12356,12 +13390,26 @@ registry-auth-token@3.3.2, registry-auth-token@^3.0.1: rc "^1.1.6" safe-buffer "^5.0.1" +registry-auth-token@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.1.tgz#5e6cd106e6c251135a046650c58476fc03e92833" + integrity sha512-UfxVOj8seK1yaIOiieV4FIP01vfBDLsY0H9sQzi9EbbUdJiuuBjJgLa1DpImXMNPnVkBD4eVxTEXcrZA6kfpJA== + dependencies: + "@pnpm/npm-conf" "^1.0.4" + registry-url@3.1.0, registry-url@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" dependencies: rc "^1.0.1" +registry-url@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-6.0.1.tgz#056d9343680f2f64400032b1e199faa692286c58" + integrity sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q== + dependencies: + rc "1.2.8" + regjsgen@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" @@ -12388,6 +13436,39 @@ relateurl@0.2.x: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" +release-it@^15.5.1: + version "15.5.1" + resolved "https://registry.yarnpkg.com/release-it/-/release-it-15.5.1.tgz#bce504bef6fefd42bf54c84320ed1145f72a2681" + integrity sha512-1X1oyqay/amJh/V+xkSU9zN6LqGmLQJ0Q40+FaHE6+Pu6QCmgX9HbrpHxvF0HZeXkB5cdhHjmYsPbHnUQLRnYg== + dependencies: + "@iarna/toml" "2.2.5" + "@octokit/rest" "19.0.5" + async-retry "1.3.3" + chalk "5.1.2" + cosmiconfig "8.0.0" + execa "6.1.0" + form-data "4.0.0" + git-url-parse "13.1.0" + globby "13.1.2" + got "12.5.3" + inquirer "9.1.4" + is-ci "3.0.1" + lodash "4.17.21" + mime-types "2.1.35" + new-github-release-url "2.0.0" + node-fetch "3.3.0" + open "8.4.0" + ora "6.1.2" + os-name "5.0.1" + promise.allsettled "1.0.6" + proxy-agent "5.0.0" + semver "7.3.8" + shelljs "0.8.5" + update-notifier "6.0.2" + url-join "5.0.0" + wildcard-match "5.1.2" + yargs-parser "21.1.1" + remark-frontmatter@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/remark-frontmatter/-/remark-frontmatter-1.3.1.tgz#bc28c0c913fa0b9dd26f17304bc47b856b2ea2de" @@ -12546,6 +13627,11 @@ requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" +resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -12598,6 +13684,13 @@ resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13. dependencies: path-parse "^1.0.6" +responselike@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" + integrity sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg== + dependencies: + lowercase-keys "^3.0.0" + restore-cursor@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" @@ -12621,10 +13714,23 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" +restore-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9" + integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" +retry@0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -12669,11 +13775,10 @@ rst-selector-parser@^2.2.3: lodash.flattendeep "^4.4.0" nearley "^2.7.10" -run-async@^2.2.0, run-async@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - dependencies: - is-promise "^2.1.0" +run-async@^2.2.0, run-async@^2.3.0, run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== run-parallel@^1.1.9: version "1.1.9" @@ -12704,6 +13809,13 @@ rxjs@^6.3.3, rxjs@^6.5.5, rxjs@^6.6.0: dependencies: tslib "^1.9.0" +rxjs@^7.5.7: + version "7.6.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.6.0.tgz#361da5362b6ddaa691a2de0b4f2d32028f1eb5a2" + integrity sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ== + dependencies: + tslib "^2.1.0" + safe-buffer@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -12712,6 +13824,15 @@ safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, s version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -12814,6 +13935,13 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" +semver-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-4.0.0.tgz#3afcf5ed6d62259f5c72d0d5d50dffbdc9680df5" + integrity sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA== + dependencies: + semver "^7.3.5" + semver-greatest-satisfied-range@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" @@ -12835,11 +13963,18 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.2, semver@^7.2.1, semver@^7.3.2: +semver@7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== +semver@7.3.8, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -13011,6 +14146,11 @@ setprototypeof@1.1.1: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.9" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.9.tgz#98f64880474b74f4a38b8da9d3c0f2d104633e7d" @@ -13060,9 +14200,10 @@ shell-quote@1.6.1: array-reduce "~0.0.0" jsonify "~0.0.0" -shelljs@^0.7.0: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" +shelljs@0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -13076,17 +14217,19 @@ shorthash@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/shorthash/-/shorthash-0.0.2.tgz#59b268eecbde59038b30da202bcfbddeb2c4a4eb" -side-channel@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947" - integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA== +side-channel@^1.0.2, side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: - es-abstract "^1.17.0-next.1" - object-inspect "^1.7.0" + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== simulant@^0.2.2: version "0.2.2" @@ -13137,6 +14280,11 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" @@ -13175,6 +14323,11 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + snake-case@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f" @@ -13280,6 +14433,23 @@ sockjs@0.3.19: faye-websocket "^0.10.0" uuid "^3.0.1" +socks-proxy-agent@5, socks-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e" + integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== + dependencies: + agent-base "^6.0.2" + debug "4" + socks "^2.3.3" + +socks@^2.3.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + sort-keys@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" @@ -13467,6 +14637,11 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + "statuses@>= 1.3.1 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" @@ -13567,6 +14742,15 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string.prototype.matchall@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz#48bb510326fb9fdeb6a33ceaa81a6ea04ef7648e" @@ -13588,21 +14772,23 @@ string.prototype.trim@^1.2.1: es-abstract "^1.17.0-next.1" function-bind "^1.1.1" -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== +string.prototype.trimstart@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.2.0" @@ -13656,6 +14842,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" @@ -13686,6 +14879,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + strip-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" @@ -13815,17 +15013,6 @@ symbol-observable@^1.1.0: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -ta-scripts@^2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/ta-scripts/-/ta-scripts-2.5.2.tgz#d06ab4d019299952d0b82cb577d13d1a8b24e4e9" - dependencies: - axios "^0.15.2" - bluebird "^3.3.3" - del "^2.2.0" - fs-promise "^0.5.0" - shelljs "^0.7.0" - yargs "^4.7.1" - table@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" @@ -13994,18 +15181,6 @@ text-table@0.2.0, text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -thenify-all@^1.0.0, thenify-all@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.0" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" - dependencies: - any-promise "^1.0.0" - throttleit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" @@ -14169,6 +15344,11 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + toposort@^1.0.0: version "1.0.6" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" @@ -14244,6 +15424,11 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.0.1, tslib@^2.1.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" + integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== + tsutils@^3.17.1: version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" @@ -14299,6 +15484,21 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^1.0.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== + +type-fest@^2.13.0, type-fest@^2.5.1: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + +type-fest@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.3.0.tgz#3378c9664eecfd1eb4f0522b13cb0630bc1ec044" + integrity sha512-gezeeOIZyQLGW5uuCeEnXF1aXmtt2afKspXz3YqoOcZ3l/YMJq1pujvgT+cz/Nw1O/7q/kSav5fihJHsC/AOUg== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -14307,6 +15507,13 @@ type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -14349,6 +15556,16 @@ uglifyjs-webpack-plugin@^0.4.6: uglify-js "^2.8.29" webpack-sources "^1.0.1" +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + unbzip2-stream@1.4.3, unbzip2-stream@^1.0.9: version "1.4.3" resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" @@ -14489,6 +15706,13 @@ unique-string@^1.0.0: dependencies: crypto-random-string "^1.0.0" +unique-string@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-3.0.0.tgz#84a1c377aff5fd7a8bc6b55d8244b2bd90d75b9a" + integrity sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ== + dependencies: + crypto-random-string "^4.0.0" + unist-builder@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-1.0.3.tgz#ab0f9d0f10936b74f3e913521955b0478e0ff036" @@ -14535,6 +15759,11 @@ unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.3.0: dependencies: unist-util-visit-parents "^2.0.0" +universal-user-agent@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" + integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== + universalify@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" @@ -14576,6 +15805,26 @@ update-check@1.5.1: registry-auth-token "3.3.2" registry-url "3.1.0" +update-notifier@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-6.0.2.tgz#a6990253dfe6d5a02bd04fbb6a61543f55026b60" + integrity sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og== + dependencies: + boxen "^7.0.0" + chalk "^5.0.1" + configstore "^6.0.0" + has-yarn "^3.0.0" + import-lazy "^4.0.0" + is-ci "^3.0.1" + is-installed-globally "^0.4.0" + is-npm "^6.0.0" + is-yarn-global "^0.4.0" + latest-version "^7.0.0" + pupa "^3.1.0" + semver "^7.3.7" + semver-diff "^4.0.0" + xdg-basedir "^5.1.0" + update-notifier@^2.1.0, update-notifier@^2.4.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" @@ -14615,6 +15864,11 @@ urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" +url-join@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-5.0.0.tgz#c2f1e5cbd95fa91082a93b58a1f42fecb4bdbcf1" + integrity sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA== + url-loader@^0.6.1: version "0.6.2" resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-0.6.2.tgz#a007a7109620e9d988d14bce677a1decb9a993f7" @@ -14828,6 +16082,14 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +vm2@^3.9.8: + version "3.9.13" + resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.13.tgz#774a1a3d73b9b90b1aa45bcc5f25e349f2eef649" + integrity sha512-0rvxpB8P8Shm4wX2EKOiMp7H2zq+HUE/UwodY0pCZXs9IffIKZq6vUti5OgkVCTakKo9e/fgO4X1fkwfjWxE3Q== + dependencies: + acorn "^8.7.0" + acorn-walk "^8.2.0" + void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" @@ -14886,6 +16148,11 @@ web-namespaces@^1.0.0, web-namespaces@^1.1.2: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.2.tgz#c8dc267ab639505276bae19e129dbd6ae72b22b4" integrity sha512-II+n2ms4mPxK+RnIxRPOw3zwF2jRscdJIUE9BfkKHm4FYEg9+biIoTMnaZF5MpemE3T+VhMLrhbyD4ilkPCSbg== +web-streams-polyfill@^3.0.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -15104,6 +16371,17 @@ whet.extend@~0.9.9: version "0.9.9" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" @@ -15145,15 +16423,30 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" +widest-line@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2" + integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig== + dependencies: + string-width "^5.0.1" + +wildcard-match@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/wildcard-match/-/wildcard-match-5.1.2.tgz#66b438001391674d8599b45da051e0bd9f33cd2a" + integrity sha512-qNXwI591Z88c8bWxp+yjV60Ch4F8Riawe3iGxbzquhy8Xs9m+0+SLFBGb/0yCTIDElawtaImC37fYZ+dr32KqQ== + window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" -window-size@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" +windows-release@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-5.0.1.tgz#d1f7cd1f25660ba05cac6359711844dce909a8ed" + integrity sha512-y1xFdFvdMiDXI3xiOhMbJwt1Y7dUxidha0CWPs1NgjZIjZANTcX7+7bMqNjuezhzb8s5JGEiBAbQjQQYYy7ulw== + dependencies: + execa "^5.1.1" -word-wrap@^1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== @@ -15166,10 +16459,6 @@ wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - worker-farm@^1.5.2, worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -15215,6 +16504,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.0.1.tgz#2101e861777fec527d0ea90c57c6b03aac56a5b3" + integrity sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -15228,6 +16526,16 @@ write-file-atomic@^2.0.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write-file-atomic@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + write@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" @@ -15285,6 +16593,11 @@ xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" +xdg-basedir@^5.0.1, xdg-basedir@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-5.1.0.tgz#1efba19425e73be1bc6f2a6ceb52a3d2c884c0c9" + integrity sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ== + xml-char-classes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/xml-char-classes/-/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d" @@ -15293,6 +16606,11 @@ xmlhttprequest-ssl@~1.5.4: version "1.5.5" resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" +xregexp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" + integrity sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA== + xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" @@ -15332,6 +16650,11 @@ yargs-parser@13.1.2, yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" @@ -15340,13 +16663,6 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" - dependencies: - camelcase "^3.0.0" - lodash.assign "^4.0.6" - yargs-parser@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" @@ -15425,25 +16741,6 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^4.7.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" - dependencies: - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - lodash.assign "^4.0.3" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.1" - which-module "^1.0.0" - window-size "^0.2.0" - y18n "^3.2.1" - yargs-parser "^2.4.1" - yargs@^7.0.2, yargs@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" From 95ec8191b2e712d3f6dcbdd34f728cbd9819c194 Mon Sep 17 00:00:00 2001 From: Oleksandr Fediashov Date: Tue, 28 Feb 2023 18:04:46 +0100 Subject: [PATCH 02/30] feat: use React.forwardRef in all components (#4233) * chore: remove .state() assertions in tests (#4232) * Ember: remove .state() usage in Enzyme * AccordionAccordion: remove .state() usage in Enzyme * Checkbox: remove .state() usage in Enzyme * TransitionablePortal: remove .state() usage in Enzyme * Transition: remove .state() usage in Enzyme * Dropdown: remove .state() usage in Enzyme * chore(Image): use React.forwardRef() (#4234) * chore(Placeholder): use React.forwardRef() (#4236) * chore(Header): use React.forwardRef() (#4237) * chore(Segment): use React.forwardRef() (#4238) * chore(Table): use React.forwardRef() (#4239) * chore(Table): use React.forwardRef() * fix naming * chore(Step): use React.forwardRef() (#4240) * chore: disable ESLint rule for function names (#4241) * chore(Comment): use React.forwardRef() (#4242) * chore(Comment): use React.forwardRef() * fix displayName * fix tests * chore(Card): use React.forwardRef() (#4243) * chore(Feed): use React.forwardRef() (#4244) * chore(Statistic): use React.forwardRef() (#4245) * chore(Item): use React.forwardRef() (#4247) * chore(Container|Divider|Loader|Rail): use React.forwardRef() (#4248) * chore(Accordion): use React.forwardRef() (#4249) * chore(Advertisement|Breadcrumb): use React.forwardRef() (#4250) * chore(Message): use React.forwardRef() (#4251) * chore(Label|List): use React.forwardRef() (#4252) * chore(Menu): use React.forwardRef() (#4254) * chore(Pagination): use React.forwardRef() (#4255) * chore(Button): use React.forwardRef() (#4256) * chore(Modal|Portal|Popup): use React.forwardRef() (#4253) * chore(Modal|Portal): use React.forwardRef() * remove redundant statics * migrate Popup * chore(Rating|Reveal): use React.forwardRef() (#4258) * chore(Dimmer|Grid|Sidebar): use React.forwardRef() (#4260) * chore(Modal*|Popup*): use React.forwardRef() (#4261) * chore(Confirm|Checkbox|Embed|Radio|TextArea): use React.forwardRef() (#4262) * chore(Flag|Icon|ImageGroup): use React.forwardRef() (#4264) * chore(Tab): use React.forwardRef() (#4265) * chore(TransitionGroup): use React.forwardRef() (#4266) * chore(Input): use React.forwardRef() (#4267) * chore(Sticky): use React.forwardRef() (#4263) * chore(TransitionablePortal): convert to be functional component (#4269) * chore(Search*): use React.forwardRef() (#4270) * chore(Dropdown*): use React.forwardRef() (#4273) * chore(Dropdown*): use React.forwardRef() * fix examples-test * chore(Visibility): remove component (#4257) * chore(Visibility): remove component * remove behaviors section * chore(Ref): remove component (#4286) * chore(Ref): remove component * fix tests * chore(Search): use React.forwardRef() (#4330) * chore(Search): use React.forwardRef() * add test for ref forwarding * fix tests, add comments * chore: refactor Modal tests (#4339) * chore: remove unused test utils (#4340) * chore: refactor tests for classnames to use mount() (#4341) * chore: refactor tests for shorthands to use mount() (#4342) * chore: refactor tests for shorthands to use mount() * add comment * fix tests with unmount * fix(Dropdown): use ref forwarding (#4338) * Add forward ref to Form (#4364) * Convert form to function component * Add ref forwarding to Form component * Update test/specs/collections/Form/Form-test.js Co-authored-by: Oleksandr Fediashov Co-authored-by: Oleksandr Fediashov * Add ref to components (#4373) * Add ref to FormButton * Add ref to FormCheckbox * Add forwardRef to FormGroup * Remove accidental `only` calls * chore(FormField): use React.forwardRef() (#4359) * Add ref to form field component * Move ref to controlProps * Add more forwardsRef tests * Remove unnecessary describe wrapper * update tests Co-authored-by: Oleksandr Fediashov * chore(FormTextArea): use React.forwardRef() (#4405) * chore(FormRadio): use React.forwardRef() (#4406) * chore(FormInput): use React.forwardRef() (#4407) * chore(Select,FormSelect,FormDropdown): use React.forwardRef() (#4408) * chore(Select): use React.forwardRef() * chore(FormSelect): use React.forwardRef() * chore(FormDropdown): use React.forwardRef() * fix tests, fix Dropdown component Co-authored-by: Oleksandr Fediashov --------- Co-authored-by: Brandon Olivier Co-authored-by: Felix Mosheev <9304194+felixmosh@users.noreply.github.com> --- .eslintrc | 1 + docs/src/components/Sidebar/Sidebar.js | 21 +- .../addons/Ref/Types/RefExampleRef.js | 67 -- .../addons/Ref/Types/RefForwardingExample.js | 54 -- docs/src/examples/addons/Ref/Types/index.js | 30 - docs/src/examples/addons/Ref/index.js | 38 - .../VisibilityExampleCallbackFrequency.js | 134 ---- .../Settings/VisibilityExampleFireOnMount.js | 126 ---- .../VisibilityExampleGroupedCallbacks.js | 130 ---- .../Settings/VisibilityExampleOffset.js | 102 --- .../Settings/VisibilityExampleUpdateOn.js | 114 --- .../behaviors/Visibility/Settings/index.js | 52 -- .../Types/VisibilityExampleVisibility.js | 151 ---- .../behaviors/Visibility/Types/index.js | 16 - .../examples/behaviors/Visibility/index.js | 30 - .../Sidebar/Usage/SidebarExampleTarget.js | 11 +- .../Types/StickyExampleAdjacentContext.js | 50 +- .../Sticky/Types/StickyExamplePushing.js | 52 +- .../Sticky/Usage/StickyExampleOffset.js | 60 +- .../Sticky/Variations/StickyExampleActive.js | 49 +- .../Variations/StickyExampleOversized.js | 61 +- docs/src/layouts/HomepageLayout.js | 13 +- docs/src/layouts/StickyLayout.js | 30 +- docs/src/utils/constants.js | 2 +- docs/src/utils/docTypes/componentInfoShape.js | 1 - docs/static/utils/getComponentMenu.js | 14 +- gulp/plugins/util/getComponentInfo.js | 20 +- gulp/tasks/docs.js | 1 - index.d.ts | 14 - package.json | 1 - src/addons/Confirm/Confirm.js | 73 +- src/addons/Pagination/Pagination.js | 106 +-- src/addons/Pagination/PaginationItem.js | 57 +- src/addons/Portal/Portal.js | 354 ++++----- src/addons/Portal/PortalInner.d.ts | 3 - src/addons/Portal/PortalInner.js | 47 +- src/addons/Portal/usePortalElement.js | 30 + src/addons/Portal/utils/useTrigger.js | 25 + src/addons/Portal/utils/validateTrigger.js | 8 +- src/addons/Radio/Radio.js | 8 +- src/addons/Select/Select.js | 7 +- src/addons/TextArea/TextArea.js | 59 +- .../TransitionablePortal.js | 138 ++-- src/behaviors/Visibility/Visibility.d.ts | 176 ----- src/behaviors/Visibility/Visibility.js | 428 ----------- src/behaviors/Visibility/index.d.ts | 8 - src/behaviors/Visibility/index.js | 1 - src/collections/Breadcrumb/Breadcrumb.js | 9 +- .../Breadcrumb/BreadcrumbDivider.js | 10 +- .../Breadcrumb/BreadcrumbSection.js | 38 +- src/collections/Form/Form.js | 91 ++- src/collections/Form/FormButton.js | 8 +- src/collections/Form/FormCheckbox.js | 8 +- src/collections/Form/FormDropdown.js | 7 +- src/collections/Form/FormField.js | 13 +- src/collections/Form/FormGroup.js | 8 +- src/collections/Form/FormInput.js | 7 +- src/collections/Form/FormRadio.js | 7 +- src/collections/Form/FormSelect.js | 7 +- src/collections/Form/FormTextArea.js | 7 +- src/collections/Grid/Grid.js | 7 +- src/collections/Grid/GridColumn.js | 7 +- src/collections/Grid/GridRow.js | 7 +- src/collections/Menu/Menu.js | 163 ++--- src/collections/Menu/MenuHeader.js | 7 +- src/collections/Menu/MenuItem.js | 106 +-- src/collections/Menu/MenuMenu.js | 7 +- src/collections/Message/Message.js | 149 ++-- src/collections/Message/MessageContent.js | 7 +- src/collections/Message/MessageHeader.js | 8 +- src/collections/Message/MessageItem.js | 8 +- src/collections/Message/MessageList.js | 8 +- src/collections/Table/Table.js | 9 +- src/collections/Table/TableBody.js | 7 +- src/collections/Table/TableCell.js | 9 +- src/collections/Table/TableFooter.js | 7 +- src/collections/Table/TableHeader.js | 7 +- src/collections/Table/TableHeaderCell.js | 7 +- src/collections/Table/TableRow.js | 9 +- src/elements/Button/Button.js | 281 ++++---- src/elements/Button/ButtonContent.js | 8 +- src/elements/Button/ButtonGroup.js | 9 +- src/elements/Button/ButtonOr.js | 7 +- src/elements/Container/Container.js | 7 +- src/elements/Divider/Divider.js | 7 +- src/elements/Flag/Flag.js | 30 +- src/elements/Header/Header.js | 11 +- src/elements/Header/HeaderContent.js | 7 +- src/elements/Header/HeaderSubheader.js | 7 +- src/elements/Icon/Icon.js | 146 ++-- src/elements/Icon/IconGroup.js | 8 +- src/elements/Image/Image.js | 17 +- src/elements/Image/ImageGroup.js | 8 +- src/elements/Input/Input.js | 226 +++--- src/elements/Label/Label.js | 174 +++-- src/elements/Label/LabelDetail.js | 8 +- src/elements/Label/LabelGroup.js | 7 +- src/elements/List/List.js | 137 ++-- src/elements/List/ListContent.js | 9 +- src/elements/List/ListDescription.js | 7 +- src/elements/List/ListHeader.js | 8 +- src/elements/List/ListIcon.js | 7 +- src/elements/List/ListItem.js | 187 ++--- src/elements/List/ListList.js | 7 +- src/elements/Loader/Loader.js | 7 +- src/elements/Placeholder/Placeholder.js | 7 +- src/elements/Placeholder/PlaceholderHeader.js | 7 +- src/elements/Placeholder/PlaceholderImage.js | 7 +- src/elements/Placeholder/PlaceholderLine.js | 7 +- .../Placeholder/PlaceholderParagraph.js | 7 +- src/elements/Rail/Rail.js | 7 +- src/elements/Reveal/Reveal.js | 7 +- src/elements/Reveal/RevealContent.js | 7 +- src/elements/Segment/Segment.js | 7 +- src/elements/Segment/SegmentGroup.js | 7 +- src/elements/Segment/SegmentInline.js | 7 +- src/elements/Step/Step.js | 114 +-- src/elements/Step/StepContent.js | 12 +- src/elements/Step/StepDescription.js | 7 +- src/elements/Step/StepGroup.js | 11 +- src/elements/Step/StepTitle.js | 7 +- src/index.js | 7 +- src/lib/doesNodeContainClick.js | 28 +- src/lib/factories.js | 9 +- src/lib/getUnhandledProps.js | 4 +- src/lib/hooks/useAutoControlledValue.js | 45 ++ src/lib/hooks/useClassNamesOnNode.js | 2 +- src/lib/hooks/useEventCallback.js | 35 + src/lib/hooks/useForceUpdate.js | 8 + src/lib/hooks/useMergedRefs.js | 40 ++ src/lib/hooks/usePrevious.js | 18 + src/lib/index.js | 8 +- src/lib/isRefObject.js | 6 + src/lib/normalizeOffset.js | 7 - src/modules/Accordion/Accordion.js | 8 +- src/modules/Accordion/AccordionAccordion.js | 144 ++-- src/modules/Accordion/AccordionContent.js | 8 +- src/modules/Accordion/AccordionTitle.js | 46 +- src/modules/Checkbox/Checkbox.js | 286 ++++---- src/modules/Dimmer/Dimmer.js | 71 +- src/modules/Dimmer/DimmerDimmable.js | 7 +- src/modules/Dimmer/DimmerInner.js | 138 ++-- src/modules/Dropdown/Dropdown.js | 102 +-- src/modules/Dropdown/DropdownDivider.js | 8 +- src/modules/Dropdown/DropdownHeader.js | 9 +- src/modules/Dropdown/DropdownItem.js | 139 ++-- src/modules/Dropdown/DropdownMenu.js | 8 +- src/modules/Dropdown/DropdownSearchInput.js | 51 +- src/modules/Dropdown/DropdownText.js | 14 +- src/modules/Embed/Embed.js | 107 +-- src/modules/Modal/Modal.js | 386 +++++----- src/modules/Modal/ModalActions.js | 66 +- src/modules/Modal/ModalContent.js | 7 +- src/modules/Modal/ModalDescription.js | 7 +- src/modules/Modal/ModalDimmer.js | 22 +- src/modules/Modal/ModalHeader.js | 7 +- src/modules/Popup/Popup.js | 421 ++++++----- src/modules/Popup/PopupContent.js | 9 +- src/modules/Popup/PopupHeader.js | 10 +- src/modules/Popup/lib/createReferenceProxy.js | 2 +- src/modules/Progress/Progress.js | 199 +++-- src/modules/Rating/Rating.js | 137 ++-- src/modules/Rating/RatingIcon.js | 69 +- src/modules/Search/Search.js | 23 +- src/modules/Search/SearchCategory.js | 8 +- src/modules/Search/SearchCategoryLayout.d.ts | 3 - src/modules/Search/SearchCategoryLayout.js | 1 + src/modules/Search/SearchResult.js | 48 +- src/modules/Search/SearchResults.js | 7 +- src/modules/Sidebar/Sidebar.js | 178 +++-- src/modules/Sidebar/SidebarPushable.js | 7 +- src/modules/Sidebar/SidebarPusher.js | 7 +- src/modules/Sticky/Sticky.js | 383 +++++----- src/modules/Tab/Tab.js | 77 +- src/modules/Tab/TabPane.js | 8 +- src/modules/Transition/Transition.js | 26 +- src/modules/Transition/TransitionGroup.js | 137 ++-- src/views/Advertisement/Advertisement.js | 7 +- src/views/Card/Card.js | 137 ++-- src/views/Card/CardContent.js | 11 +- src/views/Card/CardDescription.js | 7 +- src/views/Card/CardGroup.js | 11 +- src/views/Card/CardHeader.js | 7 +- src/views/Card/CardMeta.js | 7 +- src/views/Comment/Comment.js | 7 +- src/views/Comment/CommentAction.js | 7 +- src/views/Comment/CommentActions.js | 7 +- src/views/Comment/CommentAuthor.js | 7 +- src/views/Comment/CommentAvatar.js | 7 +- src/views/Comment/CommentContent.js | 7 +- src/views/Comment/CommentGroup.js | 7 +- src/views/Comment/CommentMetadata.js | 7 +- src/views/Comment/CommentText.js | 7 +- src/views/Feed/Feed.js | 10 +- src/views/Feed/FeedContent.js | 9 +- src/views/Feed/FeedDate.js | 7 +- src/views/Feed/FeedEvent.js | 7 +- src/views/Feed/FeedExtra.js | 9 +- src/views/Feed/FeedLabel.js | 9 +- src/views/Feed/FeedLike.js | 9 +- src/views/Feed/FeedMeta.js | 9 +- src/views/Feed/FeedSummary.js | 9 +- src/views/Feed/FeedUser.js | 7 +- src/views/Item/Item.js | 9 +- src/views/Item/ItemContent.js | 9 +- src/views/Item/ItemDescription.js | 7 +- src/views/Item/ItemExtra.js | 7 +- src/views/Item/ItemGroup.js | 11 +- src/views/Item/ItemHeader.js | 7 +- src/views/Item/ItemImage.d.ts | 14 +- src/views/Item/ItemImage.js | 7 +- src/views/Item/ItemMeta.js | 7 +- src/views/Statistic/Statistic.js | 11 +- src/views/Statistic/StatisticGroup.js | 11 +- src/views/Statistic/StatisticLabel.js | 7 +- src/views/Statistic/StatisticValue.js | 7 +- static.routes.js | 77 +- test/specs/addons/Confirm/Confirm-test.js | 6 +- .../addons/Pagination/Pagination-test.js | 23 +- .../addons/Pagination/PaginationItem-test.js | 1 + test/specs/addons/Portal/Portal-test.js | 72 +- test/specs/addons/Portal/PortalInner-test.js | 64 +- test/specs/addons/Radio/Radio-test.js | 1 + test/specs/addons/Select/Select-test.js | 1 + test/specs/addons/TextArea/TextArea-test.js | 13 +- .../TransitionablePortal-test.js | 120 ++-- .../behaviors/Visibility/Visibility-test.js | 630 ---------------- .../collections/Breadcrumb/Breadcrumb-test.js | 2 + .../Breadcrumb/BreadcrumbDivider-test.js | 3 + .../Breadcrumb/BreadcrumbSection-test.js | 3 +- test/specs/collections/Form/Form-test.js | 4 + .../specs/collections/Form/FormButton-test.js | 2 + .../collections/Form/FormCheckbox-test.js | 2 + .../collections/Form/FormDropdown-test.js | 1 + test/specs/collections/Form/FormField-test.js | 35 + test/specs/collections/Form/FormGroup-test.js | 2 + test/specs/collections/Form/FormInput-test.js | 43 ++ test/specs/collections/Form/FormRadio-test.js | 1 + .../specs/collections/Form/FormSelect-test.js | 1 + .../collections/Form/FormTextArea-test.js | 1 + test/specs/collections/Grid/Grid-test.js | 1 + .../specs/collections/Grid/GridColumn-test.js | 1 + test/specs/collections/Grid/GridRow-test.js | 1 + test/specs/collections/Menu/Menu-test.js | 32 +- .../specs/collections/Menu/MenuHeader-test.js | 1 + test/specs/collections/Menu/MenuItem-test.js | 23 +- test/specs/collections/Menu/MenuMenu-test.js | 1 + .../specs/collections/Message/Message-test.js | 2 + .../Message/MessageContent-test.js | 1 + .../collections/Message/MessageHeader-test.js | 1 + .../collections/Message/MessageItem-test.js | 1 + .../collections/Message/MessageList-test.js | 1 + test/specs/collections/Table/Table-test.js | 2 + .../specs/collections/Table/TableBody-test.js | 1 + .../specs/collections/Table/TableCell-test.js | 2 + .../collections/Table/TableFooter-test.js | 1 + .../collections/Table/TableHeader-test.js | 1 + .../collections/Table/TableHeaderCell-test.js | 1 + test/specs/collections/Table/TableRow-test.js | 2 + test/specs/commonTests/classNameHelpers.js | 25 +- test/specs/commonTests/forwardsRef.js | 36 + test/specs/commonTests/hasUIClassName.js | 9 +- test/specs/commonTests/hasValidTypings.js | 7 +- .../commonTests/implementsClassNameProps.js | 37 +- .../commonTests/implementsCommonProps.js | 1 + .../commonTests/implementsCreateMethod.js | 9 +- .../commonTests/implementsShorthandProp.js | 61 +- test/specs/commonTests/index.js | 2 + test/specs/commonTests/isConformant.js | 221 +++--- test/specs/docs/examples-test.js | 13 +- test/specs/elements/Button/Button-test.js | 48 +- .../elements/Button/ButtonContent-test.js | 1 + .../specs/elements/Button/ButtonGroup-test.js | 1 + test/specs/elements/Button/ButtonOr-test.js | 1 + .../elements/Container/Container-test.js | 1 + test/specs/elements/Divider/Divider-test.js | 1 + test/specs/elements/Flag/Flag-test.js | 1 + test/specs/elements/Header/Header-test.js | 2 + .../elements/Header/HeaderContent-test.js | 1 + .../elements/Header/HeaderSubheader-test.js | 1 + test/specs/elements/Icon/Icon-test.js | 1 + test/specs/elements/Image/Image-test.js | 22 +- test/specs/elements/Image/ImageGroup-test.js | 1 + test/specs/elements/Input/Input-test.js | 139 ++-- test/specs/elements/Label/Label-test.js | 24 +- test/specs/elements/Label/LabelDetail-test.js | 1 + test/specs/elements/Label/LabelGroup-test.js | 1 + test/specs/elements/List/List-test.js | 12 +- test/specs/elements/List/ListContent-test.js | 3 +- .../elements/List/ListDescription-test.js | 1 + test/specs/elements/List/ListHeader-test.js | 1 + test/specs/elements/List/ListItem-test.js | 10 +- test/specs/elements/List/ListList-test.js | 1 + test/specs/elements/Loader/Loader-test.js | 1 + .../elements/Placeholder/Placeholder-test.js | 1 + .../Placeholder/PlaceholderHeader-test.js | 1 + .../Placeholder/PlaceholderImage-test.js | 1 + .../Placeholder/PlaceholderLine-test.js | 2 + .../Placeholder/PlaceholderParagraph-test.js | 1 + test/specs/elements/Rail/Rail-test.js | 1 + test/specs/elements/Reveal/Reveal-test.js | 1 + .../elements/Reveal/RevealContent-test.js | 1 + test/specs/elements/Segment/Segment-test.js | 1 + .../elements/Segment/SegmentGroup-test.js | 1 + .../elements/Segment/SegmentInline-test.js | 1 + test/specs/elements/Step/Step-test.js | 7 +- test/specs/elements/Step/StepContent-test.js | 5 + .../elements/Step/StepDescription-test.js | 1 + test/specs/elements/Step/StepGroup-test.js | 4 + test/specs/elements/Step/StepTitle-test.js | 1 + .../specs/modules/Accordion/Accordion-test.js | 1 + .../Accordion/AccordionAccordion-test.js | 122 ++-- .../Accordion/AccordionContent-test.js | 1 + .../modules/Accordion/AccordionTitle-test.js | 9 +- test/specs/modules/Checkbox/Checkbox-test.js | 30 +- test/specs/modules/Dimmer/Dimmer-test.js | 1 + .../modules/Dimmer/DimmerDimmable-test.js | 1 + test/specs/modules/Dimmer/DimmerInner-test.js | 10 +- test/specs/modules/Dropdown/Dropdown-test.js | 680 +++++++++--------- .../modules/Dropdown/DropdownDivider-test.js | 1 + .../modules/Dropdown/DropdownHeader-test.js | 1 + .../modules/Dropdown/DropdownItem-test.js | 2 + .../modules/Dropdown/DropdownMenu-test.js | 1 + .../Dropdown/DropdownSearchInput-test.js | 3 +- .../modules/Dropdown/DropdownText-test.js | 1 + test/specs/modules/Embed/Embed-test.js | 37 +- test/specs/modules/Modal/Modal-test.js | 154 +--- test/specs/modules/Modal/ModalActions-test.js | 2 + test/specs/modules/Modal/ModalContent-test.js | 1 + .../modules/Modal/ModalDescription-test.js | 1 + test/specs/modules/Modal/ModalDimmer-test.js | 16 +- test/specs/modules/Modal/ModalHeader-test.js | 1 + test/specs/modules/Popup/Popup-test.js | 31 +- test/specs/modules/Popup/PopupContent-test.js | 1 + test/specs/modules/Popup/PopupHeader-test.js | 1 + test/specs/modules/Progress/Progress-test.js | 25 +- test/specs/modules/Rating/Rating-test.js | 1 + test/specs/modules/Rating/RatingIcon-test.js | 1 + test/specs/modules/Search/Search-test.js | 85 ++- .../modules/Search/SearchCategory-test.js | 1 + .../Search/SearchCategoryLayout-test.js | 13 + .../specs/modules/Search/SearchResult-test.js | 14 + .../modules/Search/SearchResults-test.js | 1 + test/specs/modules/Sidebar/Sidebar-test.js | 12 +- .../modules/Sidebar/SidebarPushable-test.js | 1 + .../modules/Sidebar/SidebarPusher-test.js | 1 + test/specs/modules/Sticky/Sticky-test.js | 157 ++-- test/specs/modules/Tab/Tab-test.js | 2 + test/specs/modules/Tab/TabPane-test.js | 1 + .../modules/Transition/Transition-test.js | 137 ++-- .../Transition/TransitionGroup-test.js | 38 +- test/specs/views/Card/Card-test.js | 13 + test/specs/views/Card/CardContent-test.js | 5 + test/specs/views/Card/CardDescription-test.js | 1 + test/specs/views/Card/CardGroup-test.js | 5 + test/specs/views/Card/CardHeader-test.js | 1 + test/specs/views/Card/CardMeta-test.js | 1 + test/specs/views/Comment/Comment-test.js | 1 + .../specs/views/Comment/CommentAction-test.js | 1 + .../views/Comment/CommentActions-test.js | 1 + .../specs/views/Comment/CommentAuthor-test.js | 1 + .../specs/views/Comment/CommentAvatar-test.js | 1 + .../views/Comment/CommentContent-test.js | 1 + test/specs/views/Comment/CommentGroup-test.js | 1 + .../views/Comment/CommentMetadata-test.js | 1 + test/specs/views/Comment/CommentText-test.js | 1 + test/specs/views/Feed/Feed-test.js | 2 + test/specs/views/Feed/FeedContent-test.js | 4 + test/specs/views/Feed/FeedDate-test.js | 1 + test/specs/views/Feed/FeedEvent-test.js | 1 + test/specs/views/Feed/FeedExtra-test.js | 2 + test/specs/views/Feed/FeedLabel-test.js | 2 + test/specs/views/Feed/FeedLike-test.js | 4 + test/specs/views/Feed/FeedMeta-test.js | 4 + test/specs/views/Feed/FeedSummary-test.js | 2 + test/specs/views/Feed/FeedUser-test.js | 1 + test/specs/views/Item/Item-test.js | 3 + test/specs/views/Item/ItemContent-test.js | 6 + test/specs/views/Item/ItemDescription-test.js | 1 + test/specs/views/Item/ItemExtra-test.js | 1 + test/specs/views/Item/ItemGroup-test.js | 5 +- test/specs/views/Item/ItemHeader-test.js | 1 + test/specs/views/Item/ItemImage-test.js | 2 + test/specs/views/Item/ItemMeta-test.js | 1 + test/specs/views/Stastistic/Statistic-test.js | 4 + .../views/Stastistic/StatisticGroup-test.js | 4 + .../views/Stastistic/StatisticLabel-test.js | 1 + .../views/Stastistic/StatisticValue-test.js | 1 + test/utils/assertBodyClasses.js | 22 - test/utils/getComponentName.js | 19 + test/utils/getComponentProps.js | 20 + test/utils/index.js | 3 +- test/utils/nestedShallow.js | 5 - yarn.lock | 8 - 394 files changed, 5795 insertions(+), 7244 deletions(-) delete mode 100644 docs/src/examples/addons/Ref/Types/RefExampleRef.js delete mode 100644 docs/src/examples/addons/Ref/Types/RefForwardingExample.js delete mode 100644 docs/src/examples/addons/Ref/Types/index.js delete mode 100644 docs/src/examples/addons/Ref/index.js delete mode 100644 docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleCallbackFrequency.js delete mode 100644 docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleFireOnMount.js delete mode 100644 docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleGroupedCallbacks.js delete mode 100644 docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleOffset.js delete mode 100644 docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleUpdateOn.js delete mode 100644 docs/src/examples/behaviors/Visibility/Settings/index.js delete mode 100644 docs/src/examples/behaviors/Visibility/Types/VisibilityExampleVisibility.js delete mode 100644 docs/src/examples/behaviors/Visibility/Types/index.js delete mode 100644 docs/src/examples/behaviors/Visibility/index.js create mode 100644 src/addons/Portal/usePortalElement.js create mode 100644 src/addons/Portal/utils/useTrigger.js delete mode 100644 src/behaviors/Visibility/Visibility.d.ts delete mode 100644 src/behaviors/Visibility/Visibility.js delete mode 100644 src/behaviors/Visibility/index.d.ts delete mode 100644 src/behaviors/Visibility/index.js create mode 100644 src/lib/hooks/useAutoControlledValue.js create mode 100644 src/lib/hooks/useEventCallback.js create mode 100644 src/lib/hooks/useForceUpdate.js create mode 100644 src/lib/hooks/useMergedRefs.js create mode 100644 src/lib/hooks/usePrevious.js create mode 100644 src/lib/isRefObject.js delete mode 100644 src/lib/normalizeOffset.js delete mode 100644 test/specs/behaviors/Visibility/Visibility-test.js create mode 100644 test/specs/commonTests/forwardsRef.js create mode 100644 test/specs/modules/Search/SearchCategoryLayout-test.js delete mode 100644 test/utils/assertBodyClasses.js create mode 100644 test/utils/getComponentName.js create mode 100644 test/utils/getComponentProps.js diff --git a/.eslintrc b/.eslintrc index 14d66ad96c..151942c8b8 100644 --- a/.eslintrc +++ b/.eslintrc @@ -11,6 +11,7 @@ "consistent-return": "off", "complexity": ["warn", 10], "global-require": "off", + "func-names": "off", "lines-between-class-members": "off", "no-console": "error", "no-multi-spaces": ["error", { "ignoreEOLComments": true }], diff --git a/docs/src/components/Sidebar/Sidebar.js b/docs/src/components/Sidebar/Sidebar.js index 72baa4dff1..d8797ff909 100644 --- a/docs/src/components/Sidebar/Sidebar.js +++ b/docs/src/components/Sidebar/Sidebar.js @@ -3,7 +3,7 @@ import _ from 'lodash/fp' import PropTypes from 'prop-types' import React, { Component } from 'react' import { Link } from 'react-static' -import { Menu, Icon, Input, Ref } from 'semantic-ui-react' +import { Menu, Icon, Input } from 'semantic-ui-react' import CarbonAd from 'docs/src/components/CarbonAd/CarbonAd' import Logo from 'docs/src/components/Logo/Logo' @@ -229,16 +229,15 @@ class Sidebar extends Component { - - - + {query ? this.renderSearchItems() : this.menuItemsByType} diff --git a/docs/src/examples/addons/Ref/Types/RefExampleRef.js b/docs/src/examples/addons/Ref/Types/RefExampleRef.js deleted file mode 100644 index e6370f8158..0000000000 --- a/docs/src/examples/addons/Ref/Types/RefExampleRef.js +++ /dev/null @@ -1,67 +0,0 @@ -import React from 'react' -import { Grid, Table, Ref, Segment } from 'semantic-ui-react' - -function RefExampleRef() { - const objectRef = React.useRef(null) - const [functionalRef, setFunctionalRef] = React.useState(null) - const [isMounted, setIsMounted] = React.useState(false) - - React.useEffect(() => { - setIsMounted(true) - return () => setIsMounted(false) - }, []) - - return ( - - - - - An example node with functional ref - - - - An example node with ref via React.useRef() - - - - - - {isMounted && ( - - - - Type - - nodeName - - - textContent - - - - - - - - Functional ref via React.useState() hook - - {functionalRef.nodeName} - {functionalRef.textContent} - - - - - From React.useRef() hook - - {objectRef.current.nodeName} - {objectRef.current.textContent} - - -
- )} -
-
- ) -} - -export default RefExampleRef diff --git a/docs/src/examples/addons/Ref/Types/RefForwardingExample.js b/docs/src/examples/addons/Ref/Types/RefForwardingExample.js deleted file mode 100644 index 1e8ba6953d..0000000000 --- a/docs/src/examples/addons/Ref/Types/RefForwardingExample.js +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react' -import { Grid, Ref, Segment } from 'semantic-ui-react' - -const ExampleButton = React.forwardRef((props, ref) => ( -
-
-)) - -function RefForwardingExample() { - const forwardedRef = React.useRef(null) - const [isMounted, setIsMounted] = React.useState(false) - - React.useEffect(() => { - setIsMounted(true) - return () => setIsMounted(false) - }, []) - - return ( - - - -

- A button below uses React.forwardRef() API. -

- - - A button - -
-
- - - {isMounted && ( - -
-              {JSON.stringify(
-                {
-                  nodeName: forwardedRef.current.nodeName,
-                  nodeType: forwardedRef.current.nodeType,
-                  textContent: forwardedRef.current.textContent,
-                },
-                null,
-                2,
-              )}
-            
-
- )} -
-
- ) -} - -export default RefForwardingExample diff --git a/docs/src/examples/addons/Ref/Types/index.js b/docs/src/examples/addons/Ref/Types/index.js deleted file mode 100644 index 6431b2eefa..0000000000 --- a/docs/src/examples/addons/Ref/Types/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' - -import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample' -import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection' - -const RefTypesExamples = () => ( - - - A component exposes the innerRef prop that always returns - the DOM node of both functional and class component children. - - } - examplePath='addons/Ref/Types/RefExampleRef' - /> - - React.forwardRef() API is also handled by this component. - - } - examplePath='addons/Ref/Types/RefForwardingExample' - /> - -) - -export default RefTypesExamples diff --git a/docs/src/examples/addons/Ref/index.js b/docs/src/examples/addons/Ref/index.js deleted file mode 100644 index a5821a1393..0000000000 --- a/docs/src/examples/addons/Ref/index.js +++ /dev/null @@ -1,38 +0,0 @@ -import React from 'react' -import { Message, Icon } from 'semantic-ui-react' - -import Types from './Types' - -const RefExamples = () => ( - <> - - - - - Deprecation notice -

- Ref component is deprecated and will be removed in the - next major release. Please follow our{' '} - - upgrade guide - {' '} - to avoid breaks during upgrade to v3. -

-

- It's still recommended to use Ref component with v2 to - get refs to HTML elements from Semantic UI React components, but as it - uses deprecated ReactDOM.findDOMNode() you may receive - warnings in React's StrictMode. We are working on it in{' '} - - Semantic-Org/Semantic-UI-React#3819 - - . -

-
-
- - - -) - -export default RefExamples diff --git a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleCallbackFrequency.js b/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleCallbackFrequency.js deleted file mode 100644 index e6bbf62c13..0000000000 --- a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleCallbackFrequency.js +++ /dev/null @@ -1,134 +0,0 @@ -import _ from 'lodash' -import React, { Component, createRef } from 'react' -import { - Button, - Checkbox, - Divider, - Grid, - Image, - Label, - Ref, - Segment, - Sticky, - Visibility, -} from 'semantic-ui-react' - -export default class VisibilityExampleCallbackFrequency extends Component { - state = { - continuous: false, - log: [], - logCount: 0, - once: true, - } - contextRef = createRef() - - updateLog = (eventName) => () => - this.setState((prevState) => ({ - log: [ - `${new Date().toLocaleTimeString()}: ${eventName}`, - ...prevState.log, - ].slice(0, 20), - logCount: prevState.logCount + 1, - })) - - clearLog = () => this.setState({ log: [], logCount: 0 }) - - toggleOnce = () => this.setState((prevState) => ({ once: !prevState.once })) - - toggleContinuous = () => - this.setState((prevState) => ({ continuous: !prevState.continuous })) - - render() { - const { continuous, log, logCount, once } = this.state - - return ( - - - - - - {_.map( - [ - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - ], - (src, index, images) => ( - - - {index !== images.length - 1 && } - - ), - )} - - - - - - - - - - - - - - - Event Log - - -
-                    {log.map((e, i) => (
-                      
{e}
- ))} -
-
-
-
-
-
-
- ) - } -} diff --git a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleFireOnMount.js b/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleFireOnMount.js deleted file mode 100644 index 467116bf73..0000000000 --- a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleFireOnMount.js +++ /dev/null @@ -1,126 +0,0 @@ -import React, { Component } from 'react' -import { - Divider, - Grid, - Image, - Table, - Segment, - Visibility, -} from 'semantic-ui-react' - -export default class VisibilityExampleFireOnMount extends Component { - state = { - calculations: { - direction: 'none', - height: 0, - width: 0, - topPassed: false, - bottomPassed: false, - pixelsPassed: 0, - percentagePassed: 0, - topVisible: false, - bottomVisible: false, - fits: false, - passing: false, - onScreen: false, - offScreen: false, - }, - } - - handleOnScreen = (e, { calculations }) => this.setState({ calculations }) - - handleOffScreen = (e, { calculations }) => this.setState({ calculations }) - - render() { - const { calculations } = this.state - - return ( - - - - - - - - - - - - - - - - - - - - Calculation - Value - - - - - direction - {calculations.direction} - - - pixelsPassed - {calculations.pixelsPassed.toFixed()}px - - - percentagePassed - - {(calculations.percentagePassed * 100).toFixed()}% - - - - fits - {calculations.fits.toString()} - - - width - {calculations.width.toFixed()}px - - - height - {calculations.height.toFixed()}px - - - onScreen - {calculations.onScreen.toString()} - - - offScreen - {calculations.offScreen.toString()} - - - passing - {calculations.passing.toString()} - - - topVisible - {calculations.topVisible.toString()} - - - bottomVisible - {calculations.bottomVisible.toString()} - - - topPassed - {calculations.topPassed.toString()} - - - bottomPassed - {calculations.bottomPassed.toString()} - - -
-
-
- ) - } -} diff --git a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleGroupedCallbacks.js b/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleGroupedCallbacks.js deleted file mode 100644 index f671ba1ded..0000000000 --- a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleGroupedCallbacks.js +++ /dev/null @@ -1,130 +0,0 @@ -import _ from 'lodash' -import React, { Component, createRef } from 'react' -import { - Button, - Checkbox, - Divider, - Grid, - Image, - Label, - Ref, - Segment, - Sticky, - Visibility, -} from 'semantic-ui-react' - -export default class VisibilityExampleGroupedCallbacks extends Component { - state = { - continuous: false, - log: [], - logCount: 0, - once: true, - } - contextRef = createRef() - - updateLog = (eventName) => () => - this.setState((prevState) => ({ - log: [ - `${new Date().toLocaleTimeString()}: ${eventName}`, - ...prevState.log, - ].slice(0, 20), - logCount: prevState.logCount + 1, - })) - - clearLog = () => this.setState({ log: [], logCount: 0 }) - - toggleOnce = () => this.setState((prevState) => ({ once: !prevState.once })) - - toggleContinuous = () => - this.setState((prevState) => ({ continuous: !prevState.continuous })) - - render() { - const { continuous, log, logCount, once } = this.state - - return ( - - - - - - {_.map( - [ - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - ], - (src, index, images) => ( - - - {index !== images.length - 1 && } - - ), - )} - - - - - - - - - - - - - - - Event Log - - -
-                    {log.map((e, i) => (
-                      
{e}
- ))} -
-
-
-
-
-
-
- ) - } -} diff --git a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleOffset.js b/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleOffset.js deleted file mode 100644 index 19b51b5e30..0000000000 --- a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleOffset.js +++ /dev/null @@ -1,102 +0,0 @@ -import _ from 'lodash' -import React, { Component, createRef } from 'react' -import { - Divider, - Grid, - Image, - Segment, - Sticky, - Table, - Ref, - Visibility, -} from 'semantic-ui-react' - -export default class VisibilityExampleOffset extends Component { - state = { - calculations: { - topPassed: false, - bottomPassed: false, - topVisible: false, - bottomVisible: false, - }, - } - contextRef = createRef() - - handleUpdate = (e, { calculations }) => this.setState({ calculations }) - - render() { - const { calculations } = this.state - - return ( - - - - - - {_.map( - [ - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - ], - (src, index, images) => ( - - - {index !== images.length - 1 && } - - ), - )} - - - - - - - - - - Calculation - Value - - - - - topVisible - - {calculations.topVisible.toString()} - - - - bottomVisible - - {calculations.bottomVisible.toString()} - - - - topPassed - {calculations.topPassed.toString()} - - - bottomPassed - - {calculations.bottomPassed.toString()} - - - -
-
-
-
-
- ) - } -} diff --git a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleUpdateOn.js b/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleUpdateOn.js deleted file mode 100644 index 329680ddff..0000000000 --- a/docs/src/examples/behaviors/Visibility/Settings/VisibilityExampleUpdateOn.js +++ /dev/null @@ -1,114 +0,0 @@ -import _ from 'lodash' -import React, { Component, createRef } from 'react' -import { - Checkbox, - Divider, - Grid, - Image, - Segment, - Sticky, - Table, - Ref, - Visibility, -} from 'semantic-ui-react' - -export default class VisibilityExampleUpdateOn extends Component { - state = { - calculations: { - topVisible: false, - bottomVisible: false, - }, - showWireframe: true, - } - contextRef = createRef() - - handleUpdate = (e, { calculations }) => this.setState({ calculations }) - - handleWireframe = (e, { checked }) => - this.setState({ showWireframe: checked }) - - render() { - const { calculations, showWireframe } = this.state - - return ( - - - - {showWireframe ? ( - - {_.map( - [ - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - ], - (src, index, images) => ( - - - {index !== images.length - 1 && } - - ), - )} - - ) : null} - - - - It's a tricky Segment - - - - - - - - - - - - - Calculation - Value - - - - - topVisible - - {calculations.topVisible.toString()} - - - - bottomVisible - - {calculations.bottomVisible.toString()} - - - -
-
-
-
-
-
- ) - } -} diff --git a/docs/src/examples/behaviors/Visibility/Settings/index.js b/docs/src/examples/behaviors/Visibility/Settings/index.js deleted file mode 100644 index 2e79c9da4a..0000000000 --- a/docs/src/examples/behaviors/Visibility/Settings/index.js +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react' -import { Message } from 'semantic-ui-react' - -import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample' -import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection' - -const VisibilitySettingsExamples = () => ( - - - - - - - You can specify updateOn='repaint', it will allow to - update and fire callbacks on browser repaint (animation frames). - - } - examplePath='behaviors/Visibility/Settings/VisibilityExampleUpdateOn' - > - - By default Visibility handles events only on browser - events. It means that if you will hide a large block an event will not - be triggered and Visibility will not perform calculations. - This problem can be easily solved with updateOn='repaint'. - - - -) - -export default VisibilitySettingsExamples diff --git a/docs/src/examples/behaviors/Visibility/Types/VisibilityExampleVisibility.js b/docs/src/examples/behaviors/Visibility/Types/VisibilityExampleVisibility.js deleted file mode 100644 index f030c71811..0000000000 --- a/docs/src/examples/behaviors/Visibility/Types/VisibilityExampleVisibility.js +++ /dev/null @@ -1,151 +0,0 @@ -import _ from 'lodash' -import React, { Component, createRef } from 'react' -import { - Divider, - Grid, - Image, - Segment, - Sticky, - Table, - Ref, - Visibility, -} from 'semantic-ui-react' - -export default class VisibilityExampleVisibility extends Component { - state = { - calculations: { - direction: 'none', - height: 0, - width: 0, - topPassed: false, - bottomPassed: false, - pixelsPassed: 0, - percentagePassed: 0, - topVisible: false, - bottomVisible: false, - fits: false, - passing: false, - onScreen: false, - offScreen: false, - }, - } - contextRef = createRef() - - handleUpdate = (e, { calculations }) => this.setState({ calculations }) - - render() { - const { calculations } = this.state - - return ( - - - - - - {_.map( - [ - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - '/images/wireframe/centered-paragraph.png', - '/images/wireframe/short-paragraph.png', - '/images/wireframe/media-paragraph.png', - '/images/wireframe/paragraph.png', - ], - (src, index, images) => ( - - - {index !== images.length - 1 && } - - ), - )} - - - - - - - - - - Calculation - Value - - - - - direction - {calculations.direction} - - - pixelsPassed - - {calculations.pixelsPassed.toFixed()}px - - - - percentagePassed - - {(calculations.percentagePassed * 100).toFixed()}% - - - - fits - {calculations.fits.toString()} - - - width - {calculations.width.toFixed()}px - - - height - {calculations.height.toFixed()}px - - - onScreen - {calculations.onScreen.toString()} - - - offScreen - {calculations.offScreen.toString()} - - - passing - {calculations.passing.toString()} - - - topVisible - - {calculations.topVisible.toString()} - - - - bottomVisible - - {calculations.bottomVisible.toString()} - - - - topPassed - {calculations.topPassed.toString()} - - - bottomPassed - - {calculations.bottomPassed.toString()} - - - -
-
-
-
-
- ) - } -} diff --git a/docs/src/examples/behaviors/Visibility/Types/index.js b/docs/src/examples/behaviors/Visibility/Types/index.js deleted file mode 100644 index 9995e3e147..0000000000 --- a/docs/src/examples/behaviors/Visibility/Types/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' - -import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample' -import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection' - -const VisibilityTypesExamples = () => ( - - - -) - -export default VisibilityTypesExamples diff --git a/docs/src/examples/behaviors/Visibility/index.js b/docs/src/examples/behaviors/Visibility/index.js deleted file mode 100644 index 251c3879c1..0000000000 --- a/docs/src/examples/behaviors/Visibility/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' -import { Message, Icon } from 'semantic-ui-react' - -import Types from './Types' -import Settings from './Settings' - -const VisibilityExamples = () => ( - <> - - - - - Deprecation notice -

- Visibility component is deprecated and will be removed in - the next major release. Please follow our{' '} - - upgrade guide - {' '} - to avoid breaks during upgrade to v3. -

-
-
- - - - -) - -export default VisibilityExamples diff --git a/docs/src/examples/modules/Sidebar/Usage/SidebarExampleTarget.js b/docs/src/examples/modules/Sidebar/Usage/SidebarExampleTarget.js index a63b258191..d5448d3d7c 100644 --- a/docs/src/examples/modules/Sidebar/Usage/SidebarExampleTarget.js +++ b/docs/src/examples/modules/Sidebar/Usage/SidebarExampleTarget.js @@ -5,7 +5,6 @@ import { Header, Image, Menu, - Ref, Segment, Sidebar, } from 'semantic-ui-react' @@ -42,12 +41,10 @@ const SidebarExampleTarget = () => { Channels - - -
Clickable area
-

When you will click there, the sidebar will be closed.

-
-
+ +
Clickable area
+

When you will click there, the sidebar will be closed.

+
Application Content
diff --git a/docs/src/examples/modules/Sticky/Types/StickyExampleAdjacentContext.js b/docs/src/examples/modules/Sticky/Types/StickyExampleAdjacentContext.js index 9576b8ac9c..20fb405486 100644 --- a/docs/src/examples/modules/Sticky/Types/StickyExampleAdjacentContext.js +++ b/docs/src/examples/modules/Sticky/Types/StickyExampleAdjacentContext.js @@ -1,14 +1,6 @@ import _ from 'lodash' import React, { Component, createRef } from 'react' -import { - Grid, - Header, - Image, - Rail, - Ref, - Segment, - Sticky, -} from 'semantic-ui-react' +import { Grid, Header, Image, Rail, Segment, Sticky } from 'semantic-ui-react' const Placeholder = () => @@ -19,31 +11,29 @@ export default class StickyExampleAdjacentContext extends Component { return ( - - - {_.times(10, (i) => ( + + {_.times(10, (i) => ( + + ))} + + + {_.times(3, (i) => ( ))} - - {_.times(3, (i) => ( - - ))} - - -
Stuck Content
- -
-
+ +
Stuck Content
+ +
+
- - -
Stuck Content
- -
-
-
-
+ + +
Stuck Content
+ +
+
+
) diff --git a/docs/src/examples/modules/Sticky/Types/StickyExamplePushing.js b/docs/src/examples/modules/Sticky/Types/StickyExamplePushing.js index 588d5c5e3f..113bd01aff 100644 --- a/docs/src/examples/modules/Sticky/Types/StickyExamplePushing.js +++ b/docs/src/examples/modules/Sticky/Types/StickyExamplePushing.js @@ -1,14 +1,6 @@ import _ from 'lodash' import React, { Component, createRef } from 'react' -import { - Grid, - Header, - Image, - Rail, - Ref, - Segment, - Sticky, -} from 'semantic-ui-react' +import { Grid, Header, Image, Rail, Segment, Sticky } from 'semantic-ui-react' const Placeholder = () => @@ -19,31 +11,29 @@ export default class StickyExamplePushing extends Component { return ( - - - {_.times(10, (i) => ( - - ))} + + {_.times(10, (i) => ( + + ))} - - -
Stuck Content
- -
-
+ + +
Stuck Content
+ +
+
- - {_.times(3, (i) => ( - - ))} + + {_.times(3, (i) => ( + + ))} - -
Stuck Content
- -
-
-
-
+ +
Stuck Content
+ +
+ +
) diff --git a/docs/src/examples/modules/Sticky/Usage/StickyExampleOffset.js b/docs/src/examples/modules/Sticky/Usage/StickyExampleOffset.js index c8471df3ed..bc6d312b98 100644 --- a/docs/src/examples/modules/Sticky/Usage/StickyExampleOffset.js +++ b/docs/src/examples/modules/Sticky/Usage/StickyExampleOffset.js @@ -1,14 +1,6 @@ import _ from 'lodash' import React, { Component, createRef } from 'react' -import { - Grid, - Header, - Image, - Rail, - Ref, - Segment, - Sticky, -} from 'semantic-ui-react' +import { Grid, Header, Image, Rail, Segment, Sticky } from 'semantic-ui-react' const Placeholder = () => @@ -19,36 +11,34 @@ export default class StickyExampleOffset extends Component { return ( - - - {_.times(10, (i) => ( + + {_.times(10, (i) => ( + + ))} + + + {_.times(3, (i) => ( ))} - - {_.times(3, (i) => ( - - ))} - - -
Stuck Content
- -
-
+ +
Stuck Content
+ +
+
- - -
Stuck Content
- -
-
-
-
+ + +
Stuck Content
+ +
+
+
) diff --git a/docs/src/examples/modules/Sticky/Variations/StickyExampleActive.js b/docs/src/examples/modules/Sticky/Variations/StickyExampleActive.js index 46ca05dc32..de20e55745 100644 --- a/docs/src/examples/modules/Sticky/Variations/StickyExampleActive.js +++ b/docs/src/examples/modules/Sticky/Variations/StickyExampleActive.js @@ -6,7 +6,6 @@ import { Header, Image, Rail, - Ref, Segment, Sticky, } from 'semantic-ui-react' @@ -26,33 +25,31 @@ export default class StickyExampleActive extends Component { return ( - - - {_.times(10, (i) => ( - - ))} + + {_.times(10, (i) => ( + + ))} - - - - - - - + + + + + + + - - -
Stuck Content
- -
-
-
-
+ + +
Stuck Content
+ +
+
+
) diff --git a/docs/src/examples/modules/Sticky/Variations/StickyExampleOversized.js b/docs/src/examples/modules/Sticky/Variations/StickyExampleOversized.js index 6c209a3fbc..5801139ffe 100644 --- a/docs/src/examples/modules/Sticky/Variations/StickyExampleOversized.js +++ b/docs/src/examples/modules/Sticky/Variations/StickyExampleOversized.js @@ -6,7 +6,6 @@ import { Image, Item, Rail, - Ref, Segment, Sticky, } from 'semantic-ui-react' @@ -21,39 +20,37 @@ export default class StickyExampleOversized extends Component { return ( - - - {_.times(15, (i) => ( - - ))} + + {_.times(15, (i) => ( + + ))} - - - - {_.times(12, (i) => ( - - - - Followup Article - By Author - - - ))} - - - + + + + {_.times(12, (i) => ( + + + + Followup Article + By Author + + + ))} + + + - - -
Stuck Content
- -
-
-
-
+ + +
Stuck Content
+ +
+
+
) diff --git a/docs/src/layouts/HomepageLayout.js b/docs/src/layouts/HomepageLayout.js index 9d94fbc69c..26b3ee9bcc 100644 --- a/docs/src/layouts/HomepageLayout.js +++ b/docs/src/layouts/HomepageLayout.js @@ -4,6 +4,7 @@ import { createMedia } from '@artsy/fresnel' import PropTypes from 'prop-types' import React, { Component } from 'react' +import { InView } from 'react-intersection-observer' import { Button, Container, @@ -16,7 +17,6 @@ import { Menu, Segment, Sidebar, - Visibility, } from 'semantic-ui-react' const { MediaContextProvider, Media } = createMedia({ @@ -72,8 +72,7 @@ HomepageHeading.propTypes = { class DesktopContainer extends Component { state = {} - hideFixedMenu = () => this.setState({ fixed: false }) - showFixedMenu = () => this.setState({ fixed: true }) + toggleFixedMenu = (inView) => this.setState({ fixed: !inView }) render() { const { children } = this.props @@ -81,11 +80,7 @@ class DesktopContainer extends Component { return ( - + - + {children} diff --git a/docs/src/layouts/StickyLayout.js b/docs/src/layouts/StickyLayout.js index b3a0dfe8d6..f86a98b087 100644 --- a/docs/src/layouts/StickyLayout.js +++ b/docs/src/layouts/StickyLayout.js @@ -1,5 +1,6 @@ import _ from 'lodash' import React, { Component } from 'react' +import { InView } from 'react-intersection-observer' import { Container, Divider, @@ -11,7 +12,6 @@ import { List, Menu, Segment, - Visibility, } from 'semantic-ui-react' const menuStyle = { @@ -99,13 +99,8 @@ export default class StickyLayout extends Component { } } - stickOverlay = () => this.setState({ overlayFixed: true }) - - stickTopMenu = () => this.setState({ menuFixed: true }) - - unStickOverlay = () => this.setState({ overlayFixed: false }) - - unStickTopMenu = () => this.setState({ menuFixed: false }) + toggleOverlay = (inView) => this.setState({ overlayFixed: !inView }) + toggleTopMenu = (inView) => this.setState({ menuFixed: !inView }) render() { const { menuFixed, overlayFixed, overlayRect } = this.state @@ -134,11 +129,8 @@ export default class StickyLayout extends Component { {/* Attaching the top menu is a simple operation, we only switch `fixed` prop and add another style if it has gone beyond the scope of visibility */} - + + - + {_.times(3, (i) => ( @@ -186,13 +178,9 @@ export default class StickyLayout extends Component { An empty Visibility element controls the need to change the fixing of element below, it also uses height and width params received from its ref for correct display. */} - + +
+
- _.sortBy( - [ - ...componentMenu, - { - displayName: 'Ref', - type: 'addon', - external: true, - }, - ], - 'displayName', - ) +const getComponentMenu = () => componentMenu export default getComponentMenu diff --git a/gulp/plugins/util/getComponentInfo.js b/gulp/plugins/util/getComponentInfo.js index 07c2dabeb5..39df9d5357 100644 --- a/gulp/plugins/util/getComponentInfo.js +++ b/gulp/plugins/util/getComponentInfo.js @@ -18,6 +18,7 @@ const getComponentInfo = (filepath) => { const filename = path.basename(absPath) const filenameWithoutExt = path.basename(absPath, path.extname(absPath)) + const componentName = path.parse(filename).name // singular form of the component's ../../ directory // "element" for "src/elements/Button/Button.js" const componentType = path.basename(path.dirname(dir)).replace(/s$/, '') @@ -27,25 +28,30 @@ const getComponentInfo = (filepath) => { ...defaultHandlers, parserCustomHandler, ]) + if (!components.length) { throw new Error(`Could not find a component definition in "${filepath}".`) } - if (components.length > 1) { + + const info = components.find((component) => component.displayName === componentName) + + if (!info) { throw new Error( [ - `Found more than one component definition in "${filepath}".`, - 'This is currently not supported, please ensure your module only defines a single React component.', + `Failed to find a component definition for "${componentName}" in "${filepath}".`, + 'Please ensure your module defines matching React component.', ].join(' '), ) } - const info = components[0] // remove keys we don't use delete info.methods - // add exported Component info - const Component = require(absPath).default - info.constructorName = _.get(Component, 'prototype.constructor.name', null) + if (!info.displayName) { + throw new Error( + `Please check that static property "displayName" is defined on a component in "${filepath}".`, + ) + } // add component type info.type = componentType diff --git a/gulp/tasks/docs.js b/gulp/tasks/docs.js index 1be6ecbe1c..becde6c912 100644 --- a/gulp/tasks/docs.js +++ b/gulp/tasks/docs.js @@ -92,7 +92,6 @@ task('build:docs:static:start', (cb) => { const componentsSrc = [ toUniversalGlob(paths.src(), 'addons/*/*.js'), - toUniversalGlob(paths.src(), 'behaviors/*/*.js'), toUniversalGlob(paths.src(), 'elements/*/*.js'), toUniversalGlob(paths.src(), 'collections/*/*.js'), toUniversalGlob(paths.src(), 'modules/*/*.js'), diff --git a/index.d.ts b/index.d.ts index bc45d993a4..fe160ab975 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,7 +1,3 @@ -// Third party - -export { Ref, RefProps } from '@fluentui/react-component-ref' - // Addons export { @@ -39,16 +35,6 @@ export { StrictTransitionablePortalProps, } from './dist/commonjs/addons/TransitionablePortal' -// Behaviors -export { - default as Visibility, - VisibilityCalculations, - VisibilityEventData, - VisibilityOnPassed, - VisibilityProps, - StrictVisibilityProps, -} from './dist/commonjs/behaviors/Visibility' - // Collections export { default as Breadcrumb, diff --git a/package.json b/package.json index 0908136904..b1814c0773 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,6 @@ "dependencies": { "@babel/runtime": "^7.10.5", "@fluentui/react-component-event-listener": "~0.63.0", - "@fluentui/react-component-ref": "~0.63.0", "@popperjs/core": "^2.6.0", "@semantic-ui-react/event-stack": "^3.1.3", "clsx": "^1.1.1", diff --git a/src/addons/Confirm/Confirm.js b/src/addons/Confirm/Confirm.js index 8d2463de34..2b3e7c004e 100644 --- a/src/addons/Confirm/Confirm.js +++ b/src/addons/Confirm/Confirm.js @@ -1,6 +1,6 @@ import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { customPropTypes, getUnhandledProps } from '../../lib' import Button from '../../elements/Button' @@ -10,55 +10,56 @@ import Modal from '../../modules/Modal' * A Confirm modal gives the user a choice to confirm or cancel an action. * @see Modal */ -class Confirm extends Component { - handleCancel = (e) => { - _.invoke(this.props, 'onCancel', e, this.props) +const Confirm = React.forwardRef(function (props, ref) { + const { cancelButton, confirmButton, content, header, open, size } = props + const rest = getUnhandledProps(Confirm, props) + + const handleCancel = (e) => { + _.invoke(props, 'onCancel', e, props) } - handleCancelOverrides = (predefinedProps) => ({ + const handleCancelOverrides = (predefinedProps) => ({ onClick: (e, buttonProps) => { _.invoke(predefinedProps, 'onClick', e, buttonProps) - this.handleCancel(e) + handleCancel(e) }, }) - handleConfirmOverrides = (predefinedProps) => ({ + const handleConfirmOverrides = (predefinedProps) => ({ onClick: (e, buttonProps) => { _.invoke(predefinedProps, 'onClick', e, buttonProps) - _.invoke(this.props, 'onConfirm', e, this.props) + _.invoke(props, 'onConfirm', e, props) }, }) - render() { - const { cancelButton, confirmButton, content, header, open, size } = this.props - const rest = getUnhandledProps(Confirm, this.props) - - // `open` is auto controlled by the Modal - // It cannot be present (even undefined) with `defaultOpen` - // only apply it if the user provided an open prop - const openProp = {} - if (_.has(this.props, 'open')) openProp.open = open - - return ( - - {Modal.Header.create(header, { autoGenerateKey: false })} - {Modal.Content.create(content, { autoGenerateKey: false })} - - {Button.create(cancelButton, { - autoGenerateKey: false, - overrideProps: this.handleCancelOverrides, - })} - {Button.create(confirmButton, { - autoGenerateKey: false, - defaultProps: { primary: true }, - overrideProps: this.handleConfirmOverrides, - })} - - - ) + // `open` is auto controlled by the Modal + // It cannot be present (even undefined) with `defaultOpen` + // only apply it if the user provided an open prop + const openProp = {} + if (_.has(props, 'open')) { + openProp.open = open } -} + return ( + + {Modal.Header.create(header, { autoGenerateKey: false })} + {Modal.Content.create(content, { autoGenerateKey: false })} + + {Button.create(cancelButton, { + autoGenerateKey: false, + overrideProps: handleCancelOverrides, + })} + {Button.create(confirmButton, { + autoGenerateKey: false, + defaultProps: { primary: true }, + overrideProps: handleConfirmOverrides, + })} + + + ) +}) + +Confirm.displayName = 'Confirm' Confirm.propTypes = { /** The cancel button text. */ cancelButton: customPropTypes.itemShorthand, diff --git a/src/addons/Pagination/Pagination.js b/src/addons/Pagination/Pagination.js index bcaf394c5f..078389ab26 100644 --- a/src/addons/Pagination/Pagination.js +++ b/src/addons/Pagination/Pagination.js @@ -3,10 +3,10 @@ import PropTypes from 'prop-types' import React from 'react' import { - ModernAutoControlledComponent as Component, createPaginationItems, customPropTypes, getUnhandledProps, + useAutoControlledValue, } from '../../lib' import Menu from '../../collections/Menu' import PaginationItem from './PaginationItem' @@ -14,68 +14,72 @@ import PaginationItem from './PaginationItem' /** * A component to render a pagination. */ -export default class Pagination extends Component { - getInitialAutoControlledState() { - return { activePage: 1 } - } +const Pagination = React.forwardRef(function (props, ref) { + const { + 'aria-label': ariaLabel, + boundaryRange, + disabled, + ellipsisItem, + siblingRange, + totalPages, + } = props + const [activePage, setActivePage] = useAutoControlledValue({ + state: props.activePage, + defaultState: props.defaultActivePage, + initialState: 1, + }) - handleItemClick = (e, { value: nextActivePage }) => { - const { activePage: prevActivePage } = this.state + const handleItemClick = (e, { value: nextActivePage }) => { + const prevActivePage = activePage // Heads up! We need the cast to the "number" type there, as `activePage` can be a string - if (+prevActivePage === +nextActivePage) return + if (+prevActivePage === +nextActivePage) { + return + } - this.setState({ activePage: nextActivePage }) - _.invoke(this.props, 'onPageChange', e, { ...this.props, activePage: nextActivePage }) + setActivePage(nextActivePage) + _.invoke(props, 'onPageChange', e, { ...props, activePage: nextActivePage }) } - handleItemOverrides = (active, type, value) => (predefinedProps) => ({ + const handleItemOverrides = (active, type, value) => (predefinedProps) => ({ active, type, key: `${type}-${value}`, onClick: (e, itemProps) => { _.invoke(predefinedProps, 'onClick', e, itemProps) - if (itemProps.type !== 'ellipsisItem') this.handleItemClick(e, itemProps) + + if (itemProps.type !== 'ellipsisItem') { + handleItemClick(e, itemProps) + } }, }) - render() { - const { - 'aria-label': ariaLabel, - boundaryRange, - disabled, - ellipsisItem, - siblingRange, - totalPages, - } = this.props - const { activePage } = this.state - - const items = createPaginationItems({ - activePage, - boundaryRange, - hideEllipsis: _.isNil(ellipsisItem), - siblingRange, - totalPages, - }) - const rest = getUnhandledProps(Pagination, this.props) - - return ( - - {_.map(items, ({ active, type, value }) => - PaginationItem.create(this.props[type], { - defaultProps: { - content: value, - disabled, - value, - }, - overrideProps: this.handleItemOverrides(active, type, value), - }), - )} - - ) - } -} - + const items = createPaginationItems({ + activePage, + boundaryRange, + hideEllipsis: _.isNil(ellipsisItem), + siblingRange, + totalPages, + }) + const rest = getUnhandledProps(Pagination, props) + + return ( + + {_.map(items, ({ active, type, value }) => + PaginationItem.create(props[type], { + defaultProps: { + content: value, + disabled, + value, + }, + overrideProps: handleItemOverrides(active, type, value), + }), + )} + + ) +}) + +Pagination.displayName = 'Pagination' Pagination.propTypes = { /** A pagination item can have an aria label. */ 'aria-label': PropTypes.string, @@ -125,8 +129,6 @@ Pagination.propTypes = { totalPages: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, } -Pagination.autoControlledProps = ['activePage'] - Pagination.defaultProps = { 'aria-label': 'Pagination Navigation', boundaryRange: 1, @@ -152,3 +154,5 @@ Pagination.defaultProps = { } Pagination.Item = PaginationItem + +export default Pagination diff --git a/src/addons/Pagination/PaginationItem.js b/src/addons/Pagination/PaginationItem.js index 27efdf8884..6cb9af2b91 100644 --- a/src/addons/Pagination/PaginationItem.js +++ b/src/addons/Pagination/PaginationItem.js @@ -1,7 +1,7 @@ import keyboardKey from 'keyboard-key' import _ from 'lodash' import PropTypes from 'prop-types' -import { Component } from 'react' +import * as React from 'react' import { createShorthandFactory } from '../../lib' import MenuItem from '../../collections/Menu/MenuItem' @@ -9,40 +9,39 @@ import MenuItem from '../../collections/Menu/MenuItem' /** * An item of a pagination. */ -class PaginationItem extends Component { - handleClick = (e) => { - _.invoke(this.props, 'onClick', e, this.props) - } +const PaginationItem = React.forwardRef(function (props, ref) { + const { active, type } = props + const disabled = props.disabled || type === 'ellipsisItem' - handleKeyDown = (e) => { - _.invoke(this.props, 'onKeyDown', e, this.props) - if (keyboardKey.getCode(e) === keyboardKey.Enter) _.invoke(this.props, 'onClick', e, this.props) + const handleClick = (e) => { + _.invoke(props, 'onClick', e, props) } - handleOverrides = () => ({ - onClick: this.handleClick, - onKeyDown: this.handleKeyDown, - }) - - render() { - const { active, type } = this.props - const disabled = this.props.disabled || type === 'ellipsisItem' + const handleKeyDown = (e) => { + _.invoke(props, 'onKeyDown', e, props) - return MenuItem.create(this.props, { - defaultProps: { - active, - 'aria-current': active, - 'aria-disabled': disabled, - disabled, - onClick: this.handleClick, - onKeyDown: this.handleKeyDown, - tabIndex: disabled ? -1 : 0, - }, - overrideProps: this.handleOverrides, - }) + if (keyboardKey.getCode(e) === keyboardKey.Enter) { + _.invoke(props, 'onClick', e, props) + } } -} + return MenuItem.create(props, { + defaultProps: { + active, + 'aria-current': active, + 'aria-disabled': disabled, + disabled, + tabIndex: disabled ? -1 : 0, + }, + overrideProps: () => ({ + onClick: handleClick, + onKeyDown: handleKeyDown, + ref, + }), + }) +}) + +PaginationItem.displayName = 'PaginationItem' PaginationItem.propTypes = { /** A pagination item can be active. */ active: PropTypes.bool, diff --git a/src/addons/Portal/Portal.js b/src/addons/Portal/Portal.js index e987e36f95..4f49874189 100644 --- a/src/addons/Portal/Portal.js +++ b/src/addons/Portal/Portal.js @@ -1,17 +1,16 @@ import EventStack from '@semantic-ui-react/event-stack' -import { handleRef, Ref } from '@fluentui/react-component-ref' import keyboardKey from 'keyboard-key' import _ from 'lodash' import PropTypes from 'prop-types' import React from 'react' import { - ModernAutoControlledComponent as Component, customPropTypes, doesNodeContainClick, makeDebugger, + useAutoControlledValue, } from '../../lib' -import validateTrigger from './utils/validateTrigger' +import useTrigger from './utils/useTrigger' import PortalInner from './PortalInner' const debug = makeDebugger('portal') @@ -23,263 +22,270 @@ const debug = makeDebugger('portal') * @see Dimmer * @see Confirm */ -class Portal extends Component { - contentRef = React.createRef() - triggerRef = React.createRef() - latestDocumentMouseDownEvent = null +function Portal(props) { + const { + children, + closeOnDocumentClick, + closeOnEscape, + closeOnPortalMouseLeave, + closeOnTriggerBlur, + closeOnTriggerClick, + closeOnTriggerMouseLeave, + eventPool, + mountNode, + mouseEnterDelay, + mouseLeaveDelay, + openOnTriggerClick, + openOnTriggerFocus, + openOnTriggerMouseEnter, + } = props + + const [open, setOpen] = useAutoControlledValue({ + state: props.open, + defaultState: props.defaultOpen, + initialState: false, + }) + + const contentRef = React.useRef() + const [triggerRef, trigger] = useTrigger(props.trigger, props.triggerRef) + + const mouseEnterTimer = React.useRef() + const mouseLeaveTimer = React.useRef() + const latestDocumentMouseDownEvent = React.useRef() - componentWillUnmount() { - // Clean up timers - clearTimeout(this.mouseEnterTimer) - clearTimeout(this.mouseLeaveTimer) + // ---------------------------------------- + // Behavior + // ---------------------------------------- + + const openPortal = (e) => { + debug('open()') + + setOpen(true) + _.invoke(props, 'onOpen', e, { ...props, open: true }) + } + + const openPortalWithTimeout = (e, delay) => { + debug('openWithTimeout()', delay) + // React wipes the entire event object and suggests using e.persist() if + // you need the event for async access. However, even with e.persist + // certain required props (e.g. currentTarget) are null so we're forced to clone. + const eventClone = { ...e } + return setTimeout(() => openPortal(eventClone), delay || 0) + } + + const closePortal = (e) => { + debug('close()') + + setOpen(false) + _.invoke(props, 'onClose', e, { ...props, open: false }) + } + + const closePortalWithTimeout = (e, delay) => { + debug('closeWithTimeout()', delay) + // React wipes the entire event object and suggests using e.persist() if + // you need the event for async access. However, even with e.persist + // certain required props (e.g. currentTarget) are null so we're forced to clone. + const eventClone = { ...e } + return setTimeout(() => closePortal(eventClone), delay || 0) } // ---------------------------------------- // Document Event Handlers // ---------------------------------------- - handleDocumentMouseDown = (e) => { - this.latestDocumentMouseDownEvent = e + React.useEffect(() => { + // Clean up timers + clearTimeout(mouseEnterTimer.current) + clearTimeout(mouseLeaveTimer.current) + }, []) + + const handleDocumentMouseDown = (e) => { + latestDocumentMouseDownEvent.current = e } - handleDocumentClick = (e) => { - const { closeOnDocumentClick } = this.props - const currentMouseDownEvent = this.latestDocumentMouseDownEvent - this.latestDocumentMouseDownEvent = null + const handleDocumentClick = (e) => { + const currentMouseDownEvent = latestDocumentMouseDownEvent.current + latestDocumentMouseDownEvent.current = null + + // event happened in trigger (delegate to trigger handlers) + const isInsideTrigger = doesNodeContainClick(triggerRef.current, e) + // event originated in the portal but was ended outside + const isOriginatedFromPortal = + currentMouseDownEvent && doesNodeContainClick(contentRef.current, currentMouseDownEvent) + // event happened in the portal + const isInsidePortal = doesNodeContainClick(contentRef.current, e) if ( - !this.contentRef.current || // no portal - doesNodeContainClick(this.triggerRef.current, e) || // event happened in trigger (delegate to trigger handlers) - (currentMouseDownEvent && - doesNodeContainClick(this.contentRef.current, currentMouseDownEvent)) || // event originated in the portal but was ended outside - doesNodeContainClick(this.contentRef.current, e) // event happened in the portal + !contentRef.current?.contains || // no portal + isInsideTrigger || + isOriginatedFromPortal || + isInsidePortal ) { return } // ignore the click if (closeOnDocumentClick) { debug('handleDocumentClick()') - this.close(e) + closePortal(e) } } - handleEscape = (e) => { - if (!this.props.closeOnEscape) return - if (keyboardKey.getCode(e) !== keyboardKey.Escape) return + const handleEscape = (e) => { + if (!closeOnEscape) { + return + } + if (keyboardKey.getCode(e) !== keyboardKey.Escape) { + return + } debug('handleEscape()') - this.close(e) + closePortal(e) } // ---------------------------------------- // Component Event Handlers // ---------------------------------------- - handlePortalMouseLeave = (e) => { - const { closeOnPortalMouseLeave, mouseLeaveDelay } = this.props - - if (!closeOnPortalMouseLeave) return + const handlePortalMouseLeave = (e) => { + if (!closeOnPortalMouseLeave) { + return + } // Do not close the portal when 'mouseleave' is triggered by children - if (e.target !== this.contentRef.current) return + if (e.target !== contentRef.current) { + return + } debug('handlePortalMouseLeave()') - this.mouseLeaveTimer = this.closeWithTimeout(e, mouseLeaveDelay) + mouseLeaveTimer.current = closePortalWithTimeout(e, mouseLeaveDelay) } - handlePortalMouseEnter = () => { + const handlePortalMouseEnter = () => { // In order to enable mousing from the trigger to the portal, we need to // clear the mouseleave timer that was set when leaving the trigger. - const { closeOnPortalMouseLeave } = this.props - - if (!closeOnPortalMouseLeave) return + if (!closeOnPortalMouseLeave) { + return + } debug('handlePortalMouseEnter()') - clearTimeout(this.mouseLeaveTimer) + clearTimeout(mouseLeaveTimer.current) } - handleTriggerBlur = (e, ...rest) => { - const { trigger, closeOnTriggerBlur } = this.props - + const handleTriggerBlur = (e, ...rest) => { // Call original event handler _.invoke(trigger, 'props.onBlur', e, ...rest) // IE 11 doesn't work with relatedTarget in blur events const target = e.relatedTarget || document.activeElement // do not close if focus is given to the portal - const didFocusPortal = _.invoke(this.contentRef.current, 'contains', target) + const didFocusPortal = _.invoke(contentRef.current, 'contains', target) - if (!closeOnTriggerBlur || didFocusPortal) return + if (!closeOnTriggerBlur || didFocusPortal) { + return + } debug('handleTriggerBlur()') - this.close(e) + closePortal(e) } - handleTriggerClick = (e, ...rest) => { - const { trigger, closeOnTriggerClick, openOnTriggerClick } = this.props - const { open } = this.state - + const handleTriggerClick = (e, ...rest) => { // Call original event handler _.invoke(trigger, 'props.onClick', e, ...rest) if (open && closeOnTriggerClick) { debug('handleTriggerClick() - close') - this.close(e) + closePortal(e) } else if (!open && openOnTriggerClick) { debug('handleTriggerClick() - open') - - this.open(e) + openPortal(e) } } - handleTriggerFocus = (e, ...rest) => { - const { trigger, openOnTriggerFocus } = this.props - + const handleTriggerFocus = (e, ...rest) => { // Call original event handler _.invoke(trigger, 'props.onFocus', e, ...rest) - if (!openOnTriggerFocus) return + if (!openOnTriggerFocus) { + return + } debug('handleTriggerFocus()') - this.open(e) + openPortal(e) } - handleTriggerMouseLeave = (e, ...rest) => { - clearTimeout(this.mouseEnterTimer) - - const { trigger, closeOnTriggerMouseLeave, mouseLeaveDelay } = this.props + const handleTriggerMouseLeave = (e, ...rest) => { + clearTimeout(mouseEnterTimer) // Call original event handler _.invoke(trigger, 'props.onMouseLeave', e, ...rest) - if (!closeOnTriggerMouseLeave) return + if (!closeOnTriggerMouseLeave) { + return + } debug('handleTriggerMouseLeave()') - this.mouseLeaveTimer = this.closeWithTimeout(e, mouseLeaveDelay) + mouseLeaveTimer.current = closePortalWithTimeout(e, mouseLeaveDelay) } - handleTriggerMouseEnter = (e, ...rest) => { - clearTimeout(this.mouseLeaveTimer) - - const { trigger, mouseEnterDelay, openOnTriggerMouseEnter } = this.props + const handleTriggerMouseEnter = (e, ...rest) => { + clearTimeout(mouseLeaveTimer) // Call original event handler _.invoke(trigger, 'props.onMouseEnter', e, ...rest) - if (!openOnTriggerMouseEnter) return + if (!openOnTriggerMouseEnter) { + return + } debug('handleTriggerMouseEnter()') - this.mouseEnterTimer = this.openWithTimeout(e, mouseEnterDelay) - } - - // ---------------------------------------- - // Behavior - // ---------------------------------------- - - open = (e) => { - debug('open()') - - _.invoke(this.props, 'onOpen', e, { ...this.props, open: true }) - this.setState({ open: true }) - } - - openWithTimeout = (e, delay) => { - debug('openWithTimeout()', delay) - // React wipes the entire event object and suggests using e.persist() if - // you need the event for async access. However, even with e.persist - // certain required props (e.g. currentTarget) are null so we're forced to clone. - const eventClone = { ...e } - return setTimeout(() => this.open(eventClone), delay || 0) + mouseEnterTimer.current = openPortalWithTimeout(e, mouseEnterDelay) } - close = (e) => { - debug('close()') - - this.setState({ open: false }) - _.invoke(this.props, 'onClose', e, { ...this.props, open: false }) - } - - closeWithTimeout = (e, delay) => { - debug('closeWithTimeout()', delay) - // React wipes the entire event object and suggests using e.persist() if - // you need the event for async access. However, even with e.persist - // certain required props (e.g. currentTarget) are null so we're forced to clone. - const eventClone = { ...e } - return setTimeout(() => this.close(eventClone), delay || 0) - } - - handleMount = () => { - debug('handleMount()') - _.invoke(this.props, 'onMount', null, this.props) - } - - handleUnmount = () => { - debug('handleUnmount()') - _.invoke(this.props, 'onUnmount', null, this.props) - } - - handleTriggerRef = (c) => { - debug('handleTriggerRef()') - this.triggerRef.current = c - handleRef(this.props.triggerRef, c) - } - - render() { - const { children, eventPool, mountNode, trigger } = this.props - const { open } = this.state - - /* istanbul ignore else */ - if (process.env.NODE_ENV !== 'production') { - validateTrigger(trigger) - } - - return ( - <> - {open && ( - <> - - {children} - - - - - - - - - )} - {trigger && ( - - {React.cloneElement(trigger, { - onBlur: this.handleTriggerBlur, - onClick: this.handleTriggerClick, - onFocus: this.handleTriggerFocus, - onMouseLeave: this.handleTriggerMouseLeave, - onMouseEnter: this.handleTriggerMouseEnter, - })} - - )} - - ) - } + return ( + <> + {open && ( + <> + _.invoke(props, 'onMount', null, props)} + onUnmount={() => _.invoke(props, 'onUnmount', null, props)} + ref={contentRef} + > + {children} + + + + + + + + + )} + {trigger && + React.cloneElement(trigger, { + onBlur: handleTriggerBlur, + onClick: handleTriggerClick, + onFocus: handleTriggerFocus, + onMouseLeave: handleTriggerMouseLeave, + onMouseEnter: handleTriggerMouseEnter, + ref: triggerRef, + })} + + ) } +Portal.displayName = 'Portal' Portal.propTypes = { /** Primary content. */ children: PropTypes.node.isRequired, @@ -379,8 +385,6 @@ Portal.defaultProps = { openOnTriggerClick: true, } -Portal.autoControlledProps = ['open'] - Portal.Inner = PortalInner export default Portal diff --git a/src/addons/Portal/PortalInner.d.ts b/src/addons/Portal/PortalInner.d.ts index 9975bec5d5..6ccdf0a45e 100644 --- a/src/addons/Portal/PortalInner.d.ts +++ b/src/addons/Portal/PortalInner.d.ts @@ -8,9 +8,6 @@ export interface StrictPortalInnerProps { /** Primary content. */ children: React.ReactNode - /** Called with a ref to the inner node. */ - innerRef?: React.Ref - /** The node where the portal should mount. */ mountNode?: any diff --git a/src/addons/Portal/PortalInner.js b/src/addons/Portal/PortalInner.js index 163ac35983..2c8c5bb929 100644 --- a/src/addons/Portal/PortalInner.js +++ b/src/addons/Portal/PortalInner.js @@ -1,47 +1,44 @@ -import { handleRef, Ref } from '@fluentui/react-component-ref' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { createPortal } from 'react-dom' -import { customPropTypes, isBrowser, makeDebugger } from '../../lib' +import { isBrowser, makeDebugger, useEventCallback } from '../../lib' +import usePortalElement from './usePortalElement' -const debug = makeDebugger('portalInner') +const debug = makeDebugger('PortalInner') /** * An inner component that allows you to render children outside their parent. */ -class PortalInner extends Component { - componentDidMount() { - debug('componentDidMount()') - _.invoke(this.props, 'onMount', null, this.props) - } +const PortalInner = React.forwardRef(function (props, ref) { + const handleMount = useEventCallback(() => _.invoke(props, 'onMount', null, props)) + const handleUnmount = useEventCallback(() => _.invoke(props, 'onUnmount', null, props)) - componentWillUnmount() { - debug('componentWillUnmount()') - _.invoke(this.props, 'onUnmount', null, this.props) - } + const element = usePortalElement(props.children, ref) - handleRef = (c) => { - debug('handleRef', c) - handleRef(this.props.innerRef, c) - } + React.useEffect(() => { + debug('componentDidMount()') + handleMount() - render() { - if (!isBrowser()) return null - const { children, mountNode = document.body } = this.props + return () => { + debug('componentWillUnmount()') + handleUnmount() + } + }, []) - return createPortal({children}, mountNode) + if (!isBrowser()) { + return null } -} + return createPortal(element, props.mountNode || document.body) +}) + +PortalInner.displayName = 'PortalInner' PortalInner.propTypes = { /** Primary content. */ children: PropTypes.node.isRequired, - /** Called with a ref to the inner node. */ - innerRef: customPropTypes.ref, - /** The node where the portal should mount. */ mountNode: PropTypes.any, diff --git a/src/addons/Portal/usePortalElement.js b/src/addons/Portal/usePortalElement.js new file mode 100644 index 0000000000..7c5b8fd491 --- /dev/null +++ b/src/addons/Portal/usePortalElement.js @@ -0,0 +1,30 @@ +import React from 'react' +import ReactIs from 'react-is' + +import { useMergedRefs } from '../../lib' + +/** + * Assigns merged ref to an existing element is possible or wraps it with an additional "div". + * + * @param {React.ReactNode} node + * @param {React.Ref} userRef + */ +export default function usePortalElement(node, userRef) { + const ref = useMergedRefs(node.ref, userRef) + + if (React.isValidElement(node)) { + if (ReactIs.isForwardRef(node)) { + return React.cloneElement(node, { ref }) + } + + if (typeof node.type === 'string') { + return React.cloneElement(node, { ref }) + } + } + + return ( +
+ {node} +
+ ) +} diff --git a/src/addons/Portal/utils/useTrigger.js b/src/addons/Portal/utils/useTrigger.js new file mode 100644 index 0000000000..503e231e33 --- /dev/null +++ b/src/addons/Portal/utils/useTrigger.js @@ -0,0 +1,25 @@ +import React from 'react' + +import { useMergedRefs } from '../../../lib' +import validateTrigger from './validateTrigger' + +/** + * @param {React.ReactNode} trigger + * @param {React.Ref} triggerRef + */ +function useTrigger(trigger, triggerRef) { + const ref = useMergedRefs(trigger?.ref, triggerRef) + + if (trigger) { + /* istanbul ignore else */ + if (process.env.NODE_ENV !== 'production') { + validateTrigger(trigger) + } + + return [ref, React.cloneElement(trigger, { ref })] + } + + return [ref, null] +} + +export default useTrigger diff --git a/src/addons/Portal/utils/validateTrigger.js b/src/addons/Portal/utils/validateTrigger.js index 52ed7ab5c5..5dcd4282c1 100644 --- a/src/addons/Portal/utils/validateTrigger.js +++ b/src/addons/Portal/utils/validateTrigger.js @@ -5,11 +5,9 @@ import * as ReactIs from 'react-is' * Asserts that a passed element can be used cloned a props will be applied properly. */ export default function validateTrigger(element) { - if (element) { - React.Children.only(element) + React.Children.only(element) - if (ReactIs.isFragment(element)) { - throw new Error('An "React.Fragment" cannot be used as a `trigger`.') - } + if (ReactIs.isFragment(element)) { + throw new Error('An "React.Fragment" cannot be used as a `trigger`.') } } diff --git a/src/addons/Radio/Radio.js b/src/addons/Radio/Radio.js index 4edc9add52..0159880db2 100644 --- a/src/addons/Radio/Radio.js +++ b/src/addons/Radio/Radio.js @@ -9,17 +9,19 @@ import Checkbox from '../../modules/Checkbox' * @see Checkbox * @see Form */ -function Radio(props) { +const Radio = React.forwardRef(function (props, ref) { const { slider, toggle, type } = props + const rest = getUnhandledProps(Radio, props) // const ElementType = getElementType(Radio, props) // radio, slider, toggle are exclusive // use an undefined radio if slider or toggle are present const radio = !(slider || toggle) || undefined - return -} + return +}) +Radio.displayName = 'Radio' Radio.propTypes = { /** Format to emphasize the current selection state. */ slider: Checkbox.propTypes.slider, diff --git a/src/addons/Select/Select.js b/src/addons/Select/Select.js index f6051dc2ca..184993b72f 100644 --- a/src/addons/Select/Select.js +++ b/src/addons/Select/Select.js @@ -8,10 +8,11 @@ import Dropdown from '../../modules/Dropdown' * @see Dropdown * @see Form */ -function Select(props) { - return -} +const Select = React.forwardRef(function (props, ref) { + return +}) +Select.displayName = 'Select' Select.propTypes = { /** Array of Dropdown.Item props e.g. `{ text: '', value: '' }` */ options: PropTypes.arrayOf(PropTypes.shape(Dropdown.Item.propTypes)).isRequired, diff --git a/src/addons/TextArea/TextArea.js b/src/addons/TextArea/TextArea.js index 91e4bdbb88..d6b0537f02 100644 --- a/src/addons/TextArea/TextArea.js +++ b/src/addons/TextArea/TextArea.js @@ -1,50 +1,45 @@ -import { Ref } from '@fluentui/react-component-ref' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component, createRef } from 'react' +import React from 'react' -import { getElementType, getUnhandledProps } from '../../lib' +import { getElementType, getUnhandledProps, useMergedRefs } from '../../lib' /** * A TextArea can be used to allow for extended user input. * @see Form */ -class TextArea extends Component { - ref = createRef() +const TextArea = React.forwardRef(function (props, ref) { + const { rows, value } = props + const elementRef = useMergedRefs(ref, React.useRef()) - focus = () => this.ref.current.focus() + const handleChange = (e) => { + const newValue = _.get(e, 'target.value') - handleChange = (e) => { - const value = _.get(e, 'target.value') - - _.invoke(this.props, 'onChange', e, { ...this.props, value }) + _.invoke(props, 'onChange', e, { ...props, value: newValue }) } - handleInput = (e) => { - const value = _.get(e, 'target.value') + const handleInput = (e) => { + const newValue = _.get(e, 'target.value') - _.invoke(this.props, 'onInput', e, { ...this.props, value }) + _.invoke(props, 'onInput', e, { ...props, value: newValue }) } - render() { - const { rows, value } = this.props - const rest = getUnhandledProps(TextArea, this.props) - const ElementType = getElementType(TextArea, this.props) - - return ( - - - - ) - } -} - + const rest = getUnhandledProps(TextArea, props) + const ElementType = getElementType(TextArea, props) + + return ( + + ) +}) + +TextArea.displayName = 'TextArea' TextArea.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/addons/TransitionablePortal/TransitionablePortal.js b/src/addons/TransitionablePortal/TransitionablePortal.js index 9ab8d8b60d..37bce0ee52 100644 --- a/src/addons/TransitionablePortal/TransitionablePortal.js +++ b/src/addons/TransitionablePortal/TransitionablePortal.js @@ -1,113 +1,127 @@ import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import Portal from '../Portal' import Transition from '../../modules/Transition' import { TRANSITION_STATUS_ENTERING } from '../../modules/Transition/utils/computeStatuses' -import { getUnhandledProps, makeDebugger } from '../../lib' +import { getUnhandledProps, makeDebugger, useForceUpdate } from '../../lib' const debug = makeDebugger('transitionable_portal') -/** - * A sugar for `Portal` and `Transition`. - * @see Portal - * @see Transition - */ -export default class TransitionablePortal extends Component { - state = {} +function usePortalState(props) { + const portalOpen = React.useRef(false) + const forceUpdate = useForceUpdate() - // ---------------------------------------- - // Lifecycle - // ---------------------------------------- + const setPortalOpen = React.useCallback((value) => { + portalOpen.current = value + forceUpdate() + }, []) - static getDerivedStateFromProps(props, state) { + React.useEffect(() => { + if (!_.isUndefined(props.open)) { + portalOpen.current = props.open + } + }, [props.open]) + + if (_.isUndefined(props.open)) { // This is definitely a hack :( // // It's coupled with handlePortalClose() for force set the state of `portalOpen` omitting // props.open. It's related to implementation of the component itself as `onClose()` will be // called after a transition will end. // https://github.com/Semantic-Org/Semantic-UI-React/issues/2382 - if (state.portalOpen === -1) { - return { portalOpen: false } - } - - if (_.isUndefined(props.open)) { - return null + if (portalOpen.current === -1) { + return [false, setPortalOpen] } - return { portalOpen: props.open } + return [portalOpen.current, setPortalOpen] } + return [props.open, setPortalOpen] +} + +/** + * A sugar for `Portal` and `Transition`. + * @see Portal + * @see Transition + */ +function TransitionablePortal(props) { + const { children, transition } = props + + const [portalOpen, setPortalOpen] = usePortalState(props) + const [transitionVisible, setTransitionVisible] = React.useState(false) + + const open = portalOpen || transitionVisible + // ---------------------------------------- // Callback handling // ---------------------------------------- - handlePortalClose = () => { + const handlePortalClose = () => { debug('handlePortalClose()') - - this.setState({ portalOpen: -1 }) + setPortalOpen(-1) } - handlePortalOpen = () => { + const handlePortalOpen = () => { debug('handlePortalOpen()') - - this.setState({ portalOpen: true }) + setPortalOpen(true) } - handleTransitionHide = (nothing, data) => { + const handleTransitionHide = (nothing, data) => { debug('handleTransitionHide()') - const { portalOpen } = this.state - this.setState({ transitionVisible: false }) - _.invoke(this.props, 'onClose', null, { ...data, portalOpen: false, transitionVisible: false }) - _.invoke(this.props, 'onHide', null, { ...data, portalOpen, transitionVisible: false }) + setTransitionVisible(false) + _.invoke(props, 'onClose', null, { ...data, portalOpen: false, transitionVisible: false }) + _.invoke(props, 'onHide', null, { ...data, portalOpen, transitionVisible: false }) } - handleTransitionStart = (nothing, data) => { + const handleTransitionStart = (nothing, data) => { debug('handleTransitionStart()') - const { portalOpen } = this.state const { status } = data - const transitionVisible = status === TRANSITION_STATUS_ENTERING + const nextTransitionVisible = status === TRANSITION_STATUS_ENTERING - _.invoke(this.props, 'onStart', null, { ...data, portalOpen, transitionVisible }) + _.invoke(props, 'onStart', null, { + ...data, + portalOpen, + transitionVisible: nextTransitionVisible, + }) // Heads up! TransitionablePortal fires onOpen callback on the start of transition animation - if (!transitionVisible) return + if (!nextTransitionVisible) { + return + } - this.setState({ transitionVisible }) - _.invoke(this.props, 'onOpen', null, { ...data, transitionVisible, portalOpen: true }) + setTransitionVisible(nextTransitionVisible) + _.invoke(props, 'onOpen', null, { + ...data, + transitionVisible: nextTransitionVisible, + portalOpen: true, + }) } // ---------------------------------------- // Render // ---------------------------------------- - render() { - debug('render()', this.state) - - const { children, transition } = this.props - const { portalOpen, transitionVisible } = this.state - - const open = portalOpen || transitionVisible - const rest = getUnhandledProps(TransitionablePortal, this.props) - - return ( - - - {children} - - - ) - } + const rest = getUnhandledProps(TransitionablePortal, props) + + return ( + + + {children} + + + ) } +TransitionablePortal.displayName = 'TransitionablePortal' TransitionablePortal.propTypes = { /** Primary content. */ children: PropTypes.node.isRequired, @@ -157,3 +171,5 @@ TransitionablePortal.defaultProps = { duration: 400, }, } + +export default TransitionablePortal diff --git a/src/behaviors/Visibility/Visibility.d.ts b/src/behaviors/Visibility/Visibility.d.ts deleted file mode 100644 index f9f168e62a..0000000000 --- a/src/behaviors/Visibility/Visibility.d.ts +++ /dev/null @@ -1,176 +0,0 @@ -import * as React from 'react' - -export interface VisibilityProps extends StrictVisibilityProps { - [key: string]: any -} - -export interface StrictVisibilityProps { - /** An element type to render as (string or function). */ - as?: any - - /** Primary content. */ - children?: React.ReactNode - - /** Context which sticky element should stick to. */ - context?: Document | Window | HTMLElement - - /** - * When set to true a callback will occur anytime an element passes a condition not just immediately after the - * threshold is met. - */ - continuous?: boolean - - /** Fires callbacks immediately after mount. */ - fireOnMount?: boolean - - /** - * Element's bottom edge has passed top of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onBottomPassed?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element's bottom edge has not passed top of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onBottomPassedReverse?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element's bottom edge has passed bottom of screen - * - * @param {null} - * @param {object} data - All props. - */ - onBottomVisible?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element's bottom edge has not passed bottom of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onBottomVisibleReverse?: (nothing: null, data: VisibilityEventData) => void - - /** - * Value that context should be adjusted in pixels. Useful for making content appear below content fixed to the - * page. - */ - offset?: number | string | (number | string)[] - - /** When set to false a callback will occur each time an element passes the threshold for a condition. */ - once?: boolean - - /** Element is not visible on the screen. */ - onPassed?: VisibilityOnPassed - - /** - * Any part of an element is visible on screen. - * - * @param {null} - * @param {object} data - All props. - */ - onPassing?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element's top has not passed top of screen but bottom has. - * - * @param {null} - * @param {object} data - All props. - */ - onPassingReverse?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element is not visible on the screen. - * - * @param {null} - * @param {object} data - All props. - */ - onOffScreen?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element is visible on the screen. - * - * @param {null} - * @param {object} data - All props. - */ - onOnScreen?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element's top edge has passed top of the screen. - * - * @param {null} - * @param {object} data - All props. - */ - onTopPassed?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element's top edge has not passed top of the screen. - * - * @param {null} - * @param {object} data - All props. - */ - onTopPassedReverse?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element's top edge has passed bottom of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onTopVisible?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element's top edge has not passed bottom of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onTopVisibleReverse?: (nothing: null, data: VisibilityEventData) => void - - /** - * Element's top edge has passed bottom of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onUpdate?: (nothing: null, data: VisibilityEventData) => void - - /** - * Allows to choose the mode of the position calculations: - * - `events` - (default) update and fire callbacks only on scroll/resize events - * - `repaint` - update and fire callbacks on browser repaint (animation frames) - */ - updateOn?: 'events' | 'repaint' -} - -export interface VisibilityCalculations { - bottomPassed: boolean - bottomVisible: boolean - direction: 'down' | 'up' - fits: boolean - height: number - passing: boolean - percentagePassed: number - pixelsPassed: number - offScreen: boolean - onScreen: boolean - topPassed: boolean - topVisible: boolean - width: number -} - -export interface VisibilityEventData extends VisibilityProps { - calculations: VisibilityCalculations -} - -export interface VisibilityOnPassed { - [key: string]: (nothing: null, data: VisibilityEventData) => void -} - -declare const Visibility: React.ComponentClass - -export default Visibility diff --git a/src/behaviors/Visibility/Visibility.js b/src/behaviors/Visibility/Visibility.js deleted file mode 100644 index e0c93b141c..0000000000 --- a/src/behaviors/Visibility/Visibility.js +++ /dev/null @@ -1,428 +0,0 @@ -import { Ref } from '@fluentui/react-component-ref' -import _ from 'lodash' -import PropTypes from 'prop-types' -import React, { Component, createRef } from 'react' - -import { - eventStack, - getElementType, - getUnhandledProps, - normalizeOffset, - isBrowser, -} from '../../lib' - -/** - * Visibility provides a set of callbacks for when a content appears in the viewport. - * - * @deprecated This component is deprecated and will be removed in next major release. - */ -export default class Visibility extends Component { - calculations = { - bottomPassed: false, - bottomVisible: false, - fits: false, - passing: false, - offScreen: false, - onScreen: false, - topPassed: false, - topVisible: false, - } - firedCallbacks = [] - ref = createRef() - - // ---------------------------------------- - // Lifecycle - // ---------------------------------------- - - componentDidMount() { - this.mounted = true - - if (!isBrowser()) return - const { context, fireOnMount, updateOn } = this.props - - this.pageYOffset = this.getPageYOffset() - this.attachHandlers(context, updateOn) - - if (fireOnMount) this.update() - } - - componentDidUpdate(prevProps) { - const cleanHappened = - prevProps.continuous !== this.props.continuous || - prevProps.once !== this.props.once || - prevProps.updateOn !== this.props.updateOn - - // Heads up! We should clean up array of happened callbacks, if values of these props are changed - if (cleanHappened) this.firedCallbacks = [] - - if (prevProps.context !== this.props.context || prevProps.updateOn !== this.props.updateOn) { - this.unattachHandlers(prevProps.context) - this.attachHandlers(this.props.context, this.props.updateOn) - } - } - - componentWillUnmount() { - const { context } = this.props - - this.unattachHandlers(context) - this.mounted = false - } - - attachHandlers(context, updateOn) { - if (updateOn === 'events') { - if (context) { - eventStack.sub('resize', this.handleUpdate, { target: context }) - eventStack.sub('scroll', this.handleUpdate, { target: context }) - } - - return - } - - // Heads up! - // We will deal with `repaint` there - this.handleUpdate() - } - - unattachHandlers(context) { - if (context) { - eventStack.unsub('resize', this.handleUpdate, { target: context }) - eventStack.unsub('scroll', this.handleUpdate, { target: context }) - } - - if (this.frameId) cancelAnimationFrame(this.frameId) - } - - // ---------------------------------------- - // Callback handling - // ---------------------------------------- - - execute(callback, name) { - const { continuous } = this.props - if (!callback) return - - // Heads up! When `continuous` is true, callback will be fired always - if (!continuous && _.includes(this.firedCallbacks, name)) return - - callback(null, { ...this.props, calculations: this.calculations }) - this.firedCallbacks.push(name) - } - - fire = ({ callback, name }, value, reverse = false) => { - const { continuous, once } = this.props - - // Heads up! For the execution is required: - // - current value correspond to the fired direction - // - `continuous` is true or calculation values are different - const matchesDirection = this.calculations[value] !== reverse - const executionPossible = continuous || this.calculations[value] !== this.oldCalculations[value] - - if (matchesDirection && executionPossible) this.execute(callback, name) - - // Heads up! We should remove callback from the happened when it's not `once` - if (!once) this.firedCallbacks = _.without(this.firedCallbacks, name) - } - - fireOnPassed() { - const { percentagePassed, pixelsPassed } = this.calculations - const { onPassed } = this.props - - _.forEach(onPassed, (callback, passed) => { - const pixelsValue = Number(passed) - - if (pixelsValue && pixelsPassed >= pixelsValue) { - this.execute(callback, passed) - return - } - - const matchPercentage = `${passed}`.match(/^(\d+)%$/) - if (!matchPercentage) return - - const percentageValue = Number(matchPercentage[1]) / 100 - if (percentagePassed >= percentageValue) this.execute(callback, passed) - }) - } - - handleUpdate = () => { - if (this.ticking) return - - this.ticking = true - this.frameId = requestAnimationFrame(this.update) - } - - update = () => { - if (!this.mounted) return - - this.ticking = false - - this.oldCalculations = this.calculations - this.calculations = this.computeCalculations() - this.pageYOffset = this.getPageYOffset() - - const { - onBottomPassed, - onBottomPassedReverse, - onBottomVisible, - onBottomVisibleReverse, - onPassing, - onPassingReverse, - onTopPassed, - onTopPassedReverse, - onTopVisible, - onTopVisibleReverse, - onOffScreen, - onOnScreen, - updateOn, - } = this.props - const forward = { - bottomPassed: { callback: onBottomPassed, name: 'onBottomPassed' }, - bottomVisible: { callback: onBottomVisible, name: 'onBottomVisible' }, - passing: { callback: onPassing, name: 'onPassing' }, - offScreen: { callback: onOffScreen, name: 'onOffScreen' }, - onScreen: { callback: onOnScreen, name: 'onOnScreen' }, - topPassed: { callback: onTopPassed, name: 'onTopPassed' }, - topVisible: { callback: onTopVisible, name: 'onTopVisible' }, - } - - const reverse = { - bottomPassed: { callback: onBottomPassedReverse, name: 'onBottomPassedReverse' }, - bottomVisible: { callback: onBottomVisibleReverse, name: 'onBottomVisibleReverse' }, - passing: { callback: onPassingReverse, name: 'onPassingReverse' }, - topPassed: { callback: onTopPassedReverse, name: 'onTopPassedReverse' }, - topVisible: { callback: onTopVisibleReverse, name: 'onTopVisibleReverse' }, - } - - _.invoke(this.props, 'onUpdate', null, { ...this.props, calculations: this.calculations }) - this.fireOnPassed() - - // Heads up! Reverse callbacks should be fired first - _.forEach(reverse, (data, value) => this.fire(data, value, true)) - _.forEach(forward, (data, value) => this.fire(data, value)) - - if (updateOn === 'repaint') this.handleUpdate() - } - - // ---------------------------------------- - // Helpers - // ---------------------------------------- - - computeCalculations() { - const { offset } = this.props - const { bottom, height, top, width } = this.ref.current.getBoundingClientRect() - const [topOffset, bottomOffset] = normalizeOffset(offset) - - const newOffset = this.getPageYOffset() - const direction = newOffset > this.pageYOffset ? 'down' : 'up' - const topPassed = top < topOffset - const bottomPassed = bottom < bottomOffset - - const pixelsPassed = bottomPassed ? 0 : Math.max(top * -1, 0) - const percentagePassed = pixelsPassed / height - - const bottomVisible = bottom >= bottomOffset && bottom <= window.innerHeight - const topVisible = top >= topOffset && top <= window.innerHeight - - const fits = topVisible && bottomVisible - const passing = topPassed && !bottomPassed - - const onScreen = (topVisible || topPassed) && !bottomPassed - const offScreen = !onScreen - - return { - bottomPassed, - bottomVisible, - direction, - fits, - height, - passing, - percentagePassed, - pixelsPassed, - offScreen, - onScreen, - topPassed, - topVisible, - width, - } - } - - getPageYOffset() { - const { context } = this.props - - if (context) { - // Heads up! `window` doesn't have `pageYOffset` property - return context === window ? window.pageYOffset : context.scrollTop - } - - return 0 - } - - // ---------------------------------------- - // Render - // ---------------------------------------- - - render() { - const { children } = this.props - const ElementType = getElementType(Visibility, this.props) - const rest = getUnhandledProps(Visibility, this.props) - - return ( - - {children} - - ) - } -} - -Visibility.propTypes = { - /** An element type to render as (string or function). */ - as: PropTypes.elementType, - - /** Primary content. */ - children: PropTypes.node, - - /** Context which visibility should attach onscroll events. */ - context: PropTypes.object, - - /** - * When set to true a callback will occur anytime an element passes a condition not just immediately after the - * threshold is met. - */ - continuous: PropTypes.bool, - - /** Fires callbacks immediately after mount. */ - fireOnMount: PropTypes.bool, - - /** - * Element's bottom edge has passed top of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onBottomPassed: PropTypes.func, - - /** - * Element's bottom edge has not passed top of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onBottomPassedReverse: PropTypes.func, - - /** - * Element's bottom edge has passed bottom of screen - * - * @param {null} - * @param {object} data - All props. - */ - onBottomVisible: PropTypes.func, - - /** - * Element's bottom edge has not passed bottom of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onBottomVisibleReverse: PropTypes.func, - - /** - * Value that context should be adjusted in pixels. Useful for making content appear below content fixed to the - * page. - */ - offset: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.string, - PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])), - ]), - - /** When set to false a callback will occur each time an element passes the threshold for a condition. */ - once: PropTypes.bool, - - /** Element is not visible on the screen. */ - onPassed: PropTypes.object, - - /** - * Any part of an element is visible on screen. - * - * @param {null} - * @param {object} data - All props. - */ - onPassing: PropTypes.func, - - /** - * Element's top has not passed top of screen but bottom has. - * - * @param {null} - * @param {object} data - All props. - */ - onPassingReverse: PropTypes.func, - - /** - * Element is not visible on the screen. - * - * @param {null} - * @param {object} data - All props. - */ - onOffScreen: PropTypes.func, - - /** - * Element is visible on the screen. - * - * @param {null} - * @param {object} data - All props. - */ - onOnScreen: PropTypes.func, - - /** - * Element's top edge has passed top of the screen. - * - * @param {null} - * @param {object} data - All props. - */ - onTopPassed: PropTypes.func, - - /** - * Element's top edge has not passed top of the screen. - * - * @param {null} - * @param {object} data - All props. - */ - onTopPassedReverse: PropTypes.func, - - /** - * Element's top edge has passed bottom of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onTopVisible: PropTypes.func, - - /** - * Element's top edge has not passed bottom of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onTopVisibleReverse: PropTypes.func, - - /** - * Element's top edge has passed bottom of screen. - * - * @param {null} - * @param {object} data - All props. - */ - onUpdate: PropTypes.func, - - /** - * Allows to choose the mode of the position calculations: - * - `events` - (default) update and fire callbacks only on scroll/resize events - * - `repaint` - update and fire callbacks on browser repaint (animation frames) - */ - updateOn: PropTypes.oneOf(['events', 'repaint']), -} - -Visibility.defaultProps = { - context: isBrowser() ? window : null, - continuous: false, - offset: [0, 0], - once: true, - updateOn: 'events', -} diff --git a/src/behaviors/Visibility/index.d.ts b/src/behaviors/Visibility/index.d.ts deleted file mode 100644 index 1026545769..0000000000 --- a/src/behaviors/Visibility/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export { - default, - VisibilityCalculations, - VisibilityEventData, - VisibilityOnPassed, - VisibilityProps, - StrictVisibilityProps, -} from './Visibility' diff --git a/src/behaviors/Visibility/index.js b/src/behaviors/Visibility/index.js deleted file mode 100644 index 0893be889f..0000000000 --- a/src/behaviors/Visibility/index.js +++ /dev/null @@ -1 +0,0 @@ -export default from './Visibility' diff --git a/src/collections/Breadcrumb/Breadcrumb.js b/src/collections/Breadcrumb/Breadcrumb.js index ec00735556..e638b16101 100644 --- a/src/collections/Breadcrumb/Breadcrumb.js +++ b/src/collections/Breadcrumb/Breadcrumb.js @@ -10,7 +10,7 @@ import BreadcrumbSection from './BreadcrumbSection' /** * A breadcrumb is used to show hierarchy between content. */ -function Breadcrumb(props) { +const Breadcrumb = React.forwardRef(function (props, ref) { const { children, className, divider, icon, sections, size } = props const classes = cx('ui', size, 'breadcrumb', className) @@ -19,7 +19,7 @@ function Breadcrumb(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) @@ -40,12 +40,13 @@ function Breadcrumb(props) { }) return ( - + {childElements} ) -} +}) +Breadcrumb.displayName = 'Breadcrumb' Breadcrumb.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Breadcrumb/BreadcrumbDivider.js b/src/collections/Breadcrumb/BreadcrumbDivider.js index e6fbac1d8b..e91b5c0f81 100644 --- a/src/collections/Breadcrumb/BreadcrumbDivider.js +++ b/src/collections/Breadcrumb/BreadcrumbDivider.js @@ -15,7 +15,7 @@ import Icon from '../../elements/Icon' /** * A divider sub-component for Breadcrumb component. */ -function BreadcrumbDivider(props) { +const BreadcrumbDivider = React.forwardRef(function (props, ref) { const { children, className, content, icon } = props const classes = cx('divider', className) @@ -26,24 +26,26 @@ function BreadcrumbDivider(props) { return Icon.create(icon, { defaultProps: { ...rest, className: classes }, autoGenerateKey: false, + ref, }) } if (!_.isNil(content)) { return ( - + {content} ) } return ( - + {childrenUtils.isNil(children) ? '/' : children} ) -} +}) +BreadcrumbDivider.displayName = 'BreadcrumbDivider' BreadcrumbDivider.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Breadcrumb/BreadcrumbSection.js b/src/collections/Breadcrumb/BreadcrumbSection.js index 5d82510976..d8349a2ac8 100644 --- a/src/collections/Breadcrumb/BreadcrumbSection.js +++ b/src/collections/Breadcrumb/BreadcrumbSection.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { childrenUtils, @@ -10,35 +10,31 @@ import { getUnhandledProps, getElementType, useKeyOnly, + useEventCallback, } from '../../lib' /** * A section sub-component for Breadcrumb component. */ -export default class BreadcrumbSection extends Component { - computeElementType = () => { - const { link, onClick } = this.props +const BreadcrumbSection = React.forwardRef(function (props, ref) { + const { active, children, className, content, href, link, onClick } = props + const classes = cx(useKeyOnly(active, 'active'), 'section', className) + const rest = getUnhandledProps(BreadcrumbSection, props) + const ElementType = getElementType(BreadcrumbSection, props, () => { if (link || onClick) return 'a' - } + }) - handleClick = (e) => _.invoke(this.props, 'onClick', e, this.props) + const handleClick = useEventCallback((e) => _.invoke(props, 'onClick', e, props)) - render() { - const { active, children, className, content, href } = this.props - - const classes = cx(useKeyOnly(active, 'active'), 'section', className) - const rest = getUnhandledProps(BreadcrumbSection, this.props) - const ElementType = getElementType(BreadcrumbSection, this.props, this.computeElementType) - - return ( - - {childrenUtils.isNil(children) ? content : children} - - ) - } -} + return ( + + {childrenUtils.isNil(children) ? content : children} + + ) +}) +BreadcrumbSection.displayName = 'BreadcrumbSection' BreadcrumbSection.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -75,3 +71,5 @@ BreadcrumbSection.create = createShorthandFactory(BreadcrumbSection, (content) = content, link: true, })) + +export default BreadcrumbSection diff --git a/src/collections/Form/Form.js b/src/collections/Form/Form.js index ef3c85718a..6c1facc274 100644 --- a/src/collections/Form/Form.js +++ b/src/collections/Form/Form.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { getElementType, getUnhandledProps, SUI, useKeyOnly, useWidthProp } from '../../lib' import FormButton from './FormButton' @@ -23,58 +23,55 @@ import FormTextArea from './FormTextArea' * @see Message * @see Radio * @see Select - * @see Visibility */ -class Form extends Component { - handleSubmit = (e, ...args) => { - const { action } = this.props - +const Form = React.forwardRef(function (props, ref) { + const { + action, + children, + className, + error, + inverted, + loading, + reply, + size, + success, + unstackable, + warning, + widths, + } = props + + const handleSubmit = (e, ...args) => { // Heads up! Third party libs can pass own data as first argument, we need to check that it has preventDefault() // method. if (typeof action !== 'string') _.invoke(e, 'preventDefault') - _.invoke(this.props, 'onSubmit', e, this.props, ...args) + _.invoke(props, 'onSubmit', e, props, ...args) } - render() { - const { - action, - children, - className, - error, - inverted, - loading, - reply, - size, - success, - unstackable, - warning, - widths, - } = this.props - - const classes = cx( - 'ui', - size, - useKeyOnly(error, 'error'), - useKeyOnly(inverted, 'inverted'), - useKeyOnly(loading, 'loading'), - useKeyOnly(reply, 'reply'), - useKeyOnly(success, 'success'), - useKeyOnly(unstackable, 'unstackable'), - useKeyOnly(warning, 'warning'), - useWidthProp(widths, null, true), - 'form', - className, - ) - const rest = getUnhandledProps(Form, this.props) - const ElementType = getElementType(Form, this.props) - - return ( - - {children} - - ) - } -} + const classes = cx( + 'ui', + size, + useKeyOnly(error, 'error'), + useKeyOnly(inverted, 'inverted'), + useKeyOnly(loading, 'loading'), + useKeyOnly(reply, 'reply'), + useKeyOnly(success, 'success'), + useKeyOnly(unstackable, 'unstackable'), + useKeyOnly(warning, 'warning'), + useWidthProp(widths, null, true), + 'form', + className, + ) + const rest = getUnhandledProps(Form, props) + const ElementType = getElementType(Form, props) + + return ( + + {children} + + ) +}) + +Form.displayName = 'Form' Form.propTypes = { /** An element type to render as (string or function). */ diff --git a/src/collections/Form/FormButton.js b/src/collections/Form/FormButton.js index 2ae1de7cf5..cf4a5f816f 100644 --- a/src/collections/Form/FormButton.js +++ b/src/collections/Form/FormButton.js @@ -10,13 +10,15 @@ import FormField from './FormField' * @see Button * @see Form */ -function FormButton(props) { +const FormButton = React.forwardRef((props, ref) => { const { control } = props const rest = getUnhandledProps(FormButton, props) const ElementType = getElementType(FormButton, props) - return -} + return +}) + +FormButton.displayName = 'FormButton' FormButton.propTypes = { /** An element type to render as (string or function). */ diff --git a/src/collections/Form/FormCheckbox.js b/src/collections/Form/FormCheckbox.js index 4f734c7aa9..f98dad56cc 100644 --- a/src/collections/Form/FormCheckbox.js +++ b/src/collections/Form/FormCheckbox.js @@ -10,13 +10,15 @@ import FormField from './FormField' * @see Checkbox * @see Form */ -function FormCheckbox(props) { +const FormCheckbox = React.forwardRef((props, ref) => { const { control } = props const rest = getUnhandledProps(FormCheckbox, props) const ElementType = getElementType(FormCheckbox, props) - return -} + return +}) + +FormCheckbox.displayName = 'FormCheckbox' FormCheckbox.propTypes = { /** An element type to render as (string or function). */ diff --git a/src/collections/Form/FormDropdown.js b/src/collections/Form/FormDropdown.js index 52e9648f31..aeeb745314 100644 --- a/src/collections/Form/FormDropdown.js +++ b/src/collections/Form/FormDropdown.js @@ -10,14 +10,15 @@ import FormField from './FormField' * @see Dropdown * @see Form */ -function FormDropdown(props) { +const FormDropdown = React.forwardRef(function (props, ref) { const { control } = props const rest = getUnhandledProps(FormDropdown, props) const ElementType = getElementType(FormDropdown, props) - return -} + return +}) +FormDropdown.displayName = 'FormDropdown' FormDropdown.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Form/FormField.js b/src/collections/Form/FormField.js index 9180b2d153..29d0448df2 100644 --- a/src/collections/Form/FormField.js +++ b/src/collections/Form/FormField.js @@ -26,9 +26,8 @@ import Radio from '../../addons/Radio' * @see Input * @see Radio * @see Select - * @see Visibility */ -function FormField(props) { +const FormField = React.forwardRef(function (props, ref) { const { children, className, @@ -78,14 +77,14 @@ function FormField(props) { if (_.isNil(control)) { if (_.isNil(label)) { return ( - + {childrenUtils.isNil(children) ? content : children} ) } return ( - + {errorLabelBefore} {createHTMLLabel(label, { autoGenerateKey: false })} {errorLabelAfter} @@ -102,7 +101,7 @@ function FormField(props) { 'aria-describedby': ariaDescribedBy, 'aria-invalid': error ? true : undefined, } - const controlProps = { ...rest, content, children, disabled, required, type, id } + const controlProps = { ...rest, content, children, disabled, required, type, id, ref } // wrap HTML checkboxes/radios in the label if (control === 'input' && (type === 'checkbox' || type === 'radio')) { @@ -143,7 +142,9 @@ function FormField(props) { {errorLabelAfter} ) -} +}) + +FormField.displayName = 'FormField' FormField.propTypes = { /** An element type to render as (string or function). */ diff --git a/src/collections/Form/FormGroup.js b/src/collections/Form/FormGroup.js index 335c1c2a4b..cf2e16df18 100644 --- a/src/collections/Form/FormGroup.js +++ b/src/collections/Form/FormGroup.js @@ -15,7 +15,7 @@ import { * A set of fields can appear grouped together. * @see Form */ -function FormGroup(props) { +const FormGroup = React.forwardRef((props, ref) => { const { children, className, grouped, inline, unstackable, widths } = props const classes = cx( @@ -30,11 +30,13 @@ function FormGroup(props) { const ElementType = getElementType(FormGroup, props) return ( - + {children} ) -} +}) + +FormGroup.displayName = 'FormGroup' FormGroup.propTypes = { /** An element type to render as (string or function). */ diff --git a/src/collections/Form/FormInput.js b/src/collections/Form/FormInput.js index 472c02ce93..bd5468a81e 100644 --- a/src/collections/Form/FormInput.js +++ b/src/collections/Form/FormInput.js @@ -10,14 +10,15 @@ import FormField from './FormField' * @see Form * @see Input */ -function FormInput(props) { +const FormInput = React.forwardRef(function (props, ref) { const { control } = props const rest = getUnhandledProps(FormInput, props) const ElementType = getElementType(FormInput, props) - return -} + return +}) +FormInput.displayName = 'FormInput' FormInput.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Form/FormRadio.js b/src/collections/Form/FormRadio.js index 5b77ecb404..82dd3bfc64 100644 --- a/src/collections/Form/FormRadio.js +++ b/src/collections/Form/FormRadio.js @@ -10,14 +10,15 @@ import FormField from './FormField' * @see Form * @see Radio */ -function FormRadio(props) { +const FormRadio = React.forwardRef(function (props, ref) { const { control } = props const rest = getUnhandledProps(FormRadio, props) const ElementType = getElementType(FormRadio, props) - return -} + return +}) +FormRadio.displayName = 'FormRadio' FormRadio.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Form/FormSelect.js b/src/collections/Form/FormSelect.js index d867140945..30c6d3f185 100644 --- a/src/collections/Form/FormSelect.js +++ b/src/collections/Form/FormSelect.js @@ -11,14 +11,15 @@ import FormField from './FormField' * @see Form * @see Select */ -function FormSelect(props) { +const FormSelect = React.forwardRef(function (props, ref) { const { control, options } = props const rest = getUnhandledProps(FormSelect, props) const ElementType = getElementType(FormSelect, props) - return -} + return +}) +FormSelect.displayName = 'FormSelect' FormSelect.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Form/FormTextArea.js b/src/collections/Form/FormTextArea.js index 6660b3344e..2395749970 100644 --- a/src/collections/Form/FormTextArea.js +++ b/src/collections/Form/FormTextArea.js @@ -10,14 +10,15 @@ import FormField from './FormField' * @see Form * @see TextArea */ -function FormTextArea(props) { +const FormTextArea = React.forwardRef(function (props, ref) { const { control } = props const rest = getUnhandledProps(FormTextArea, props) const ElementType = getElementType(FormTextArea, props) - return -} + return +}) +FormTextArea.displayName = 'FormTextArea' FormTextArea.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Grid/Grid.js b/src/collections/Grid/Grid.js index 6104c69811..7f856c5bdf 100644 --- a/src/collections/Grid/Grid.js +++ b/src/collections/Grid/Grid.js @@ -20,7 +20,7 @@ import GridRow from './GridRow' /** * A grid is used to harmonize negative space in a layout. */ -function Grid(props) { +const Grid = React.forwardRef(function (props, ref) { const { celled, centered, @@ -63,15 +63,16 @@ function Grid(props) { const ElementType = getElementType(Grid, props) return ( - + {children} ) -} +}) Grid.Column = GridColumn Grid.Row = GridRow +Grid.displayName = 'Grid' Grid.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Grid/GridColumn.js b/src/collections/Grid/GridColumn.js index b9b134bdc0..44d2e9be8a 100644 --- a/src/collections/Grid/GridColumn.js +++ b/src/collections/Grid/GridColumn.js @@ -19,7 +19,7 @@ import { /** * A column sub-component for Grid. */ -function GridColumn(props) { +const GridColumn = React.forwardRef(function (props, ref) { const { children, className, @@ -57,12 +57,13 @@ function GridColumn(props) { const ElementType = getElementType(GridColumn, props) return ( - + {children} ) -} +}) +GridColumn.displayName = 'GridColumn' GridColumn.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Grid/GridRow.js b/src/collections/Grid/GridRow.js index bd81472bdf..b84de480bc 100644 --- a/src/collections/Grid/GridRow.js +++ b/src/collections/Grid/GridRow.js @@ -17,7 +17,7 @@ import { /** * A row sub-component for Grid. */ -function GridRow(props) { +const GridRow = React.forwardRef(function (props, ref) { const { centered, children, @@ -49,12 +49,13 @@ function GridRow(props) { const ElementType = getElementType(GridRow, props) return ( - + {children} ) -} +}) +GridRow.displayName = 'GridRow' GridRow.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Menu/Menu.js b/src/collections/Menu/Menu.js index d6662fa92d..5e2db94868 100644 --- a/src/collections/Menu/Menu.js +++ b/src/collections/Menu/Menu.js @@ -4,7 +4,6 @@ import PropTypes from 'prop-types' import React from 'react' import { - ModernAutoControlledComponent as Component, childrenUtils, customPropTypes, createShorthandFactory, @@ -15,6 +14,7 @@ import { useKeyOrValueAndKey, useValueAndKey, useWidthProp, + useAutoControlledValue, } from '../../lib' import MenuHeader from './MenuHeader' import MenuItem from './MenuItem' @@ -24,90 +24,95 @@ import MenuMenu from './MenuMenu' * A menu displays grouped navigation actions. * @see Dropdown */ -class Menu extends Component { - handleItemOverrides = (predefinedProps) => ({ - onClick: (e, itemProps) => { - const { index } = itemProps - - this.setState({ activeIndex: index }) - - _.invoke(predefinedProps, 'onClick', e, itemProps) - _.invoke(this.props, 'onItemClick', e, itemProps) - }, +const Menu = React.forwardRef(function (props, ref) { + const { + attached, + borderless, + children, + className, + color, + compact, + fixed, + floated, + fluid, + icon, + inverted, + items, + pagination, + pointing, + secondary, + size, + stackable, + tabular, + text, + vertical, + widths, + } = props + const [activeIndex, setActiveIndex] = useAutoControlledValue({ + state: props.activeIndex, + defaultState: props.defaultActiveIndex, + initialState: -1, }) - renderItems() { - const { items } = this.props - const { activeIndex } = this.state - - return _.map(items, (item, index) => - MenuItem.create(item, { - defaultProps: { - active: parseInt(activeIndex, 10) === index, - index, - }, - overrideProps: this.handleItemOverrides, - }), - ) - } - - render() { - const { - attached, - borderless, - children, - className, - color, - compact, - fixed, - floated, - fluid, - icon, - inverted, - pagination, - pointing, - secondary, - size, - stackable, - tabular, - text, - vertical, - widths, - } = this.props - const classes = cx( - 'ui', - color, - size, - useKeyOnly(borderless, 'borderless'), - useKeyOnly(compact, 'compact'), - useKeyOnly(fluid, 'fluid'), - useKeyOnly(inverted, 'inverted'), - useKeyOnly(pagination, 'pagination'), - useKeyOnly(pointing, 'pointing'), - useKeyOnly(secondary, 'secondary'), - useKeyOnly(stackable, 'stackable'), - useKeyOnly(text, 'text'), - useKeyOnly(vertical, 'vertical'), - useKeyOrValueAndKey(attached, 'attached'), - useKeyOrValueAndKey(floated, 'floated'), - useKeyOrValueAndKey(icon, 'icon'), - useKeyOrValueAndKey(tabular, 'tabular'), - useValueAndKey(fixed, 'fixed'), - useWidthProp(widths, 'item'), - className, - 'menu', - ) - const rest = getUnhandledProps(Menu, this.props) - const ElementType = getElementType(Menu, this.props) - + const classes = cx( + 'ui', + color, + size, + useKeyOnly(borderless, 'borderless'), + useKeyOnly(compact, 'compact'), + useKeyOnly(fluid, 'fluid'), + useKeyOnly(inverted, 'inverted'), + useKeyOnly(pagination, 'pagination'), + useKeyOnly(pointing, 'pointing'), + useKeyOnly(secondary, 'secondary'), + useKeyOnly(stackable, 'stackable'), + useKeyOnly(text, 'text'), + useKeyOnly(vertical, 'vertical'), + useKeyOrValueAndKey(attached, 'attached'), + useKeyOrValueAndKey(floated, 'floated'), + useKeyOrValueAndKey(icon, 'icon'), + useKeyOrValueAndKey(tabular, 'tabular'), + useValueAndKey(fixed, 'fixed'), + useWidthProp(widths, 'item'), + className, + 'menu', + ) + const rest = getUnhandledProps(Menu, props) + const ElementType = getElementType(Menu, props) + + if (!childrenUtils.isNil(children)) { return ( - - {childrenUtils.isNil(children) ? this.renderItems() : children} + + {children} ) } -} + return ( + + {_.map(items, (item, index) => + MenuItem.create(item, { + defaultProps: { + active: parseInt(activeIndex, 10) === index, + index, + }, + overrideProps: (predefinedProps) => ({ + onClick: (e, itemProps) => { + const itemIndex = itemProps.index + + setActiveIndex(itemIndex) + + _.invoke(predefinedProps, 'onClick', e, itemProps) + _.invoke(props, 'onItemClick', e, itemProps) + }, + }), + }), + )} + + ) +}) + +Menu.displayName = 'Menu' Menu.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -190,8 +195,6 @@ Menu.propTypes = { widths: PropTypes.oneOf(SUI.WIDTHS), } -Menu.autoControlledProps = ['activeIndex'] - Menu.Header = MenuHeader Menu.Item = MenuItem Menu.Menu = MenuMenu diff --git a/src/collections/Menu/MenuHeader.js b/src/collections/Menu/MenuHeader.js index 136ffddbf1..9c0652d1dc 100644 --- a/src/collections/Menu/MenuHeader.js +++ b/src/collections/Menu/MenuHeader.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A menu item may include a header or may itself be a header. */ -function MenuHeader(props) { +const MenuHeader = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('header', className) const rest = getUnhandledProps(MenuHeader, props) const ElementType = getElementType(MenuHeader, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +MenuHeader.displayName = 'MenuHeader' MenuHeader.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Menu/MenuItem.js b/src/collections/Menu/MenuItem.js index 6026edd2fe..728a8ec13f 100644 --- a/src/collections/Menu/MenuItem.js +++ b/src/collections/Menu/MenuItem.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { childrenUtils, @@ -12,70 +12,70 @@ import { SUI, useKeyOnly, useKeyOrValueAndKey, + useEventCallback, } from '../../lib' import Icon from '../../elements/Icon' /** * A menu can contain an item. */ -export default class MenuItem extends Component { - handleClick = (e) => { - const { disabled } = this.props - - if (!disabled) _.invoke(this.props, 'onClick', e, this.props) - } - - render() { - const { - active, - children, - className, - color, - content, - disabled, - fitted, - header, - icon, - link, - name, - onClick, - position, - } = this.props - - const classes = cx( - color, - position, - useKeyOnly(active, 'active'), - useKeyOnly(disabled, 'disabled'), - useKeyOnly(icon === true || (icon && !(name || content)), 'icon'), - useKeyOnly(header, 'header'), - useKeyOnly(link, 'link'), - useKeyOrValueAndKey(fitted, 'fitted'), - 'item', - className, - ) - const ElementType = getElementType(MenuItem, this.props, () => { - if (onClick) return 'a' - }) - const rest = getUnhandledProps(MenuItem, this.props) - - if (!childrenUtils.isNil(children)) { - return ( - - {children} - - ) +const MenuItem = React.forwardRef(function (props, ref) { + const { + active, + children, + className, + color, + content, + disabled, + fitted, + header, + icon, + link, + name, + onClick, + position, + } = props + + const classes = cx( + color, + position, + useKeyOnly(active, 'active'), + useKeyOnly(disabled, 'disabled'), + useKeyOnly(icon === true || (icon && !(name || content)), 'icon'), + useKeyOnly(header, 'header'), + useKeyOnly(link, 'link'), + useKeyOrValueAndKey(fitted, 'fitted'), + 'item', + className, + ) + const ElementType = getElementType(MenuItem, props, () => { + if (onClick) return 'a' + }) + const rest = getUnhandledProps(MenuItem, props) + + const handleClick = useEventCallback((e) => { + if (!disabled) { + _.invoke(props, 'onClick', e, props) } + }) + if (!childrenUtils.isNil(children)) { return ( - - {Icon.create(icon, { autoGenerateKey: false })} - {childrenUtils.isNil(content) ? _.startCase(name) : content} + + {children} ) } -} + return ( + + {Icon.create(icon, { autoGenerateKey: false })} + {childrenUtils.isNil(content) ? _.startCase(name) : content} + + ) +}) + +MenuItem.displayName = 'MenuItem' MenuItem.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -130,3 +130,5 @@ MenuItem.propTypes = { } MenuItem.create = createShorthandFactory(MenuItem, (val) => ({ content: val, name: val })) + +export default MenuItem diff --git a/src/collections/Menu/MenuMenu.js b/src/collections/Menu/MenuMenu.js index 2a35683a6a..f87a8619cc 100644 --- a/src/collections/Menu/MenuMenu.js +++ b/src/collections/Menu/MenuMenu.js @@ -7,7 +7,7 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A menu can contain a sub menu. */ -function MenuMenu(props) { +const MenuMenu = React.forwardRef(function (props, ref) { const { children, className, content, position } = props const classes = cx(position, 'menu', className) @@ -15,12 +15,13 @@ function MenuMenu(props) { const ElementType = getElementType(MenuMenu, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +MenuMenu.displayName = 'MenuMenu' MenuMenu.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Message/Message.js b/src/collections/Message/Message.js index 5b060cd0e1..68cfe3e3aa 100644 --- a/src/collections/Message/Message.js +++ b/src/collections/Message/Message.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { childrenUtils, @@ -12,6 +12,7 @@ import { SUI, useKeyOnly, useKeyOrValueAndKey, + useEventCallback, } from '../../lib' import Icon from '../../elements/Icon' import MessageContent from './MessageContent' @@ -23,86 +24,82 @@ import MessageItem from './MessageItem' * A message displays information that explains nearby content. * @see Form */ -export default class Message extends Component { - handleDismiss = (e) => { - const { onDismiss } = this.props - - if (onDismiss) onDismiss(e, this.props) - } - - render() { - const { - attached, - children, - className, - color, - compact, - content, - error, - floating, - header, - hidden, - icon, - info, - list, - negative, - onDismiss, - positive, - size, - success, - visible, - warning, - } = this.props - - const classes = cx( - 'ui', - color, - size, - useKeyOnly(compact, 'compact'), - useKeyOnly(error, 'error'), - useKeyOnly(floating, 'floating'), - useKeyOnly(hidden, 'hidden'), - useKeyOnly(icon, 'icon'), - useKeyOnly(info, 'info'), - useKeyOnly(negative, 'negative'), - useKeyOnly(positive, 'positive'), - useKeyOnly(success, 'success'), - useKeyOnly(visible, 'visible'), - useKeyOnly(warning, 'warning'), - useKeyOrValueAndKey(attached, 'attached'), - 'message', - className, - ) - - const dismissIcon = onDismiss && - const rest = getUnhandledProps(Message, this.props) - const ElementType = getElementType(Message, this.props) - - if (!childrenUtils.isNil(children)) { - return ( - - {dismissIcon} - {children} - - ) - } - +const Message = React.forwardRef(function (props, ref) { + const { + attached, + children, + className, + color, + compact, + content, + error, + floating, + header, + hidden, + icon, + info, + list, + negative, + onDismiss, + positive, + size, + success, + visible, + warning, + } = props + + const classes = cx( + 'ui', + color, + size, + useKeyOnly(compact, 'compact'), + useKeyOnly(error, 'error'), + useKeyOnly(floating, 'floating'), + useKeyOnly(hidden, 'hidden'), + useKeyOnly(icon, 'icon'), + useKeyOnly(info, 'info'), + useKeyOnly(negative, 'negative'), + useKeyOnly(positive, 'positive'), + useKeyOnly(success, 'success'), + useKeyOnly(visible, 'visible'), + useKeyOnly(warning, 'warning'), + useKeyOrValueAndKey(attached, 'attached'), + 'message', + className, + ) + const rest = getUnhandledProps(Message, props) + const ElementType = getElementType(Message, props) + + const handleDismiss = useEventCallback((e) => { + _.invoke(props, 'onDismiss', e, props) + }) + const dismissIcon = onDismiss && + + if (!childrenUtils.isNil(children)) { return ( - + {dismissIcon} - {Icon.create(icon, { autoGenerateKey: false })} - {(!_.isNil(header) || !_.isNil(content) || !_.isNil(list)) && ( - - {MessageHeader.create(header, { autoGenerateKey: false })} - {MessageList.create(list, { autoGenerateKey: false })} - {createHTMLParagraph(content, { autoGenerateKey: false })} - - )} + {children} ) } -} + return ( + + {dismissIcon} + {Icon.create(icon, { autoGenerateKey: false })} + {(!_.isNil(header) || !_.isNil(content) || !_.isNil(list)) && ( + + {MessageHeader.create(header, { autoGenerateKey: false })} + {MessageList.create(list, { autoGenerateKey: false })} + {createHTMLParagraph(content, { autoGenerateKey: false })} + + )} + + ) +}) + +Message.displayName = 'Message' Message.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -178,3 +175,5 @@ Message.Content = MessageContent Message.Header = MessageHeader Message.List = MessageList Message.Item = MessageItem + +export default Message diff --git a/src/collections/Message/MessageContent.js b/src/collections/Message/MessageContent.js index a60c076fcc..b6412b3d8b 100644 --- a/src/collections/Message/MessageContent.js +++ b/src/collections/Message/MessageContent.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A message can contain a content. */ -function MessageContent(props) { +const MessageContent = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('content', className) const rest = getUnhandledProps(MessageContent, props) const ElementType = getElementType(MessageContent, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +MessageContent.displayName = 'MessageContent' MessageContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Message/MessageHeader.js b/src/collections/Message/MessageHeader.js index 41c37e013e..88536f4846 100644 --- a/src/collections/Message/MessageHeader.js +++ b/src/collections/Message/MessageHeader.js @@ -13,19 +13,21 @@ import { /** * A message can contain a header. */ -function MessageHeader(props) { +const MessageHeader = React.forwardRef(function (props, ref) { const { children, className, content } = props + const classes = cx('header', className) const rest = getUnhandledProps(MessageHeader, props) const ElementType = getElementType(MessageHeader, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +MessageHeader.displayName = 'MessageHeader' MessageHeader.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Message/MessageItem.js b/src/collections/Message/MessageItem.js index 7ace0df3ec..73cfe5af42 100644 --- a/src/collections/Message/MessageItem.js +++ b/src/collections/Message/MessageItem.js @@ -13,19 +13,21 @@ import { /** * A message list can contain an item. */ -function MessageItem(props) { +const MessageItem = React.forwardRef(function (props, ref) { const { children, className, content } = props + const classes = cx('content', className) const rest = getUnhandledProps(MessageItem, props) const ElementType = getElementType(MessageItem, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +MessageItem.displayName = 'MessageItem' MessageItem.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Message/MessageList.js b/src/collections/Message/MessageList.js index 923bda8785..7262f0ad58 100644 --- a/src/collections/Message/MessageList.js +++ b/src/collections/Message/MessageList.js @@ -15,19 +15,21 @@ import MessageItem from './MessageItem' /** * A message can contain a list of items. */ -function MessageList(props) { +const MessageList = React.forwardRef(function (props, ref) { const { children, className, items } = props + const classes = cx('list', className) const rest = getUnhandledProps(MessageList, props) const ElementType = getElementType(MessageList, props) return ( - + {childrenUtils.isNil(children) ? _.map(items, MessageItem.create) : children} ) -} +}) +MessageList.displayName = 'MessageList' MessageList.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Table/Table.js b/src/collections/Table/Table.js index 3809dc48c5..d9bf410c1a 100644 --- a/src/collections/Table/Table.js +++ b/src/collections/Table/Table.js @@ -25,7 +25,7 @@ import TableRow from './TableRow' /** * A table displays a collections of data grouped into rows. */ -function Table(props) { +const Table = React.forwardRef(function (props, ref) { const { attached, basic, @@ -88,7 +88,7 @@ function Table(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) @@ -104,7 +104,7 @@ function Table(props) { ) return ( - + {headerElement} {renderBodyRow && @@ -113,8 +113,9 @@ function Table(props) { {footerRow && {TableRow.create(footerRow)}} ) -} +}) +Table.displayName = 'Table' Table.defaultProps = { as: 'table', } diff --git a/src/collections/Table/TableBody.js b/src/collections/Table/TableBody.js index 258bd512e4..605512e7d4 100644 --- a/src/collections/Table/TableBody.js +++ b/src/collections/Table/TableBody.js @@ -4,19 +4,20 @@ import React from 'react' import { getElementType, getUnhandledProps } from '../../lib' -function TableBody(props) { +const TableBody = React.forwardRef(function (props, ref) { const { children, className } = props const classes = cx(className) const rest = getUnhandledProps(TableBody, props) const ElementType = getElementType(TableBody, props) return ( - + {children} ) -} +}) +TableBody.displayName = 'TableBody' TableBody.defaultProps = { as: 'tbody', } diff --git a/src/collections/Table/TableCell.js b/src/collections/Table/TableCell.js index 848f36a4eb..dcb008c3d8 100644 --- a/src/collections/Table/TableCell.js +++ b/src/collections/Table/TableCell.js @@ -20,7 +20,7 @@ import Icon from '../../elements/Icon' /** * A table row can have cells. */ -function TableCell(props) { +const TableCell = React.forwardRef(function (props, ref) { const { active, children, @@ -60,24 +60,25 @@ function TableCell(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {Icon.create(icon)} {content} ) -} +}) TableCell.defaultProps = { as: 'td', } +TableCell.displayName = 'TableCell' TableCell.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Table/TableFooter.js b/src/collections/Table/TableFooter.js index 0f6d7e0989..c5ff0b8e6b 100644 --- a/src/collections/Table/TableFooter.js +++ b/src/collections/Table/TableFooter.js @@ -7,13 +7,14 @@ import TableHeader from './TableHeader' /** * A table can have a footer. */ -function TableFooter(props) { +const TableFooter = React.forwardRef(function (props, ref) { const { as } = props const rest = getUnhandledProps(TableFooter, props) - return -} + return +}) +TableFooter.displayName = 'TableFooter' TableFooter.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Table/TableHeader.js b/src/collections/Table/TableHeader.js index 7994531b6e..4c7f9fe284 100644 --- a/src/collections/Table/TableHeader.js +++ b/src/collections/Table/TableHeader.js @@ -13,23 +13,24 @@ import { /** * A table can have a header. */ -function TableHeader(props) { +const TableHeader = React.forwardRef(function (props, ref) { const { children, className, content, fullWidth } = props const classes = cx(useKeyOnly(fullWidth, 'full-width'), className) const rest = getUnhandledProps(TableHeader, props) const ElementType = getElementType(TableHeader, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) TableHeader.defaultProps = { as: 'thead', } +TableHeader.displayName = 'TableHeader' TableHeader.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Table/TableHeaderCell.js b/src/collections/Table/TableHeaderCell.js index 7a2a1d2cb3..a4a23b2488 100644 --- a/src/collections/Table/TableHeaderCell.js +++ b/src/collections/Table/TableHeaderCell.js @@ -8,14 +8,15 @@ import TableCell from './TableCell' /** * A table can have a header cell. */ -function TableHeaderCell(props) { +const TableHeaderCell = React.forwardRef(function (props, ref) { const { as, className, sorted } = props const classes = cx(useValueAndKey(sorted, 'sorted'), className) const rest = getUnhandledProps(TableHeaderCell, props) - return -} + return +}) +TableHeaderCell.displayName = 'TableHeaderCell' TableHeaderCell.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/collections/Table/TableRow.js b/src/collections/Table/TableRow.js index 9c9bb019d5..5e7e83d1d5 100644 --- a/src/collections/Table/TableRow.js +++ b/src/collections/Table/TableRow.js @@ -19,7 +19,7 @@ import TableCell from './TableCell' /** * A table can have rows. */ -function TableRow(props) { +const TableRow = React.forwardRef(function (props, ref) { const { active, cellAs, @@ -51,24 +51,25 @@ function TableRow(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {_.map(cells, (cell) => TableCell.create(cell, { defaultProps: { as: cellAs } }))} ) -} +}) TableRow.defaultProps = { as: 'tr', cellAs: 'td', } +TableRow.displayName = 'TableRow' TableRow.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Button/Button.js b/src/elements/Button/Button.js index 7518f559f0..f2fd188de6 100644 --- a/src/elements/Button/Button.js +++ b/src/elements/Button/Button.js @@ -1,8 +1,7 @@ -import { Ref } from '@fluentui/react-component-ref' import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component, createRef } from 'react' +import React from 'react' import { childrenUtils, @@ -14,6 +13,7 @@ import { useKeyOnly, useKeyOrValueAndKey, useValueAndKey, + useMergedRefs, } from '../../lib' import Icon from '../Icon/Icon' import Label from '../Label/Label' @@ -22,165 +22,176 @@ import ButtonGroup from './ButtonGroup' import ButtonOr from './ButtonOr' /** - * A Button indicates a possible user action. - * @see Form - * @see Icon - * @see Label + * @param {React.ElementType} ElementType + * @param {String} role */ -class Button extends Component { - ref = createRef() - - computeButtonAriaRole(ElementType) { - const { role } = this.props - - if (!_.isNil(role)) return role - if (ElementType !== 'button') return 'button' +function computeButtonAriaRole(ElementType, role) { + if (!_.isNil(role)) { + return role } - computeElementType = () => { - const { attached, label } = this.props + if (ElementType !== 'button') { + return 'button' + } +} - if (!_.isNil(attached) || !_.isNil(label)) return 'div' +/** + * @param {React.ElementType} ElementType + * @param {Boolean} disabled + * @param {Number} tabIndex + */ +function computeTabIndex(ElementType, disabled, tabIndex) { + if (!_.isNil(tabIndex)) { + return tabIndex + } + if (disabled) { + return -1 + } + if (ElementType === 'div') { + return 0 } +} - computeTabIndex = (ElementType) => { - const { disabled, tabIndex } = this.props +function hasIconClass(props) { + const { children, content, icon, labelPosition } = props - if (!_.isNil(tabIndex)) return tabIndex - if (disabled) return -1 - if (ElementType === 'div') return 0 + if (icon === true) { + return true } - focus = (options) => _.invoke(this.ref.current, 'focus', options) + if (icon) { + return labelPosition || (childrenUtils.isNil(children) && _.isNil(content)) + } +} - handleClick = (e) => { - const { disabled } = this.props +/** + * A Button indicates a possible user action. + * @see Form + * @see Icon + * @see Label + */ +const Button = React.forwardRef(function (props, ref) { + const { + active, + animated, + attached, + basic, + children, + circular, + className, + color, + compact, + content, + disabled, + floated, + fluid, + icon, + inverted, + label, + labelPosition, + loading, + negative, + positive, + primary, + secondary, + size, + toggle, + type + } = props + const elementRef = useMergedRefs(ref, React.useRef()) + + const baseClasses = cx( + color, + size, + useKeyOnly(active, 'active'), + useKeyOnly(basic, 'basic'), + useKeyOnly(circular, 'circular'), + useKeyOnly(compact, 'compact'), + useKeyOnly(fluid, 'fluid'), + useKeyOnly(hasIconClass(props), 'icon'), + useKeyOnly(inverted, 'inverted'), + useKeyOnly(loading, 'loading'), + useKeyOnly(negative, 'negative'), + useKeyOnly(positive, 'positive'), + useKeyOnly(primary, 'primary'), + useKeyOnly(secondary, 'secondary'), + useKeyOnly(toggle, 'toggle'), + useKeyOrValueAndKey(animated, 'animated'), + useKeyOrValueAndKey(attached, 'attached'), + ) + const labeledClasses = cx(useKeyOrValueAndKey(labelPosition || !!label, 'labeled')) + const wrapperClasses = cx(useKeyOnly(disabled, 'disabled'), useValueAndKey(floated, 'floated')) + + const rest = getUnhandledProps(Button, props) + const ElementType = getElementType(Button, props, () => { + if (!_.isNil(attached) || !_.isNil(label)) { + return 'div' + } + }) + const tabIndex = computeTabIndex(ElementType, disabled, props.tabIndex) + const handleClick = (e) => { if (disabled) { e.preventDefault() return } - _.invoke(this.props, 'onClick', e, this.props) - } - - hasIconClass = () => { - const { labelPosition, children, content, icon } = this.props - - if (icon === true) return true - return icon && (labelPosition || (childrenUtils.isNil(children) && _.isNil(content))) + _.invoke(props, 'onClick', e, props) } - render() { - const { - active, - animated, - attached, - basic, - children, - circular, - className, - color, - compact, - content, - disabled, - floated, - fluid, - icon, - inverted, - label, - labelPosition, - loading, - negative, - positive, - primary, - secondary, - size, - toggle, - type, - } = this.props - - const baseClasses = cx( - color, - size, - useKeyOnly(active, 'active'), - useKeyOnly(basic, 'basic'), - useKeyOnly(circular, 'circular'), - useKeyOnly(compact, 'compact'), - useKeyOnly(fluid, 'fluid'), - useKeyOnly(this.hasIconClass(), 'icon'), - useKeyOnly(inverted, 'inverted'), - useKeyOnly(loading, 'loading'), - useKeyOnly(negative, 'negative'), - useKeyOnly(positive, 'positive'), - useKeyOnly(primary, 'primary'), - useKeyOnly(secondary, 'secondary'), - useKeyOnly(toggle, 'toggle'), - useKeyOrValueAndKey(animated, 'animated'), - useKeyOrValueAndKey(attached, 'attached'), - ) - const labeledClasses = cx(useKeyOrValueAndKey(labelPosition || !!label, 'labeled')) - const wrapperClasses = cx(useKeyOnly(disabled, 'disabled'), useValueAndKey(floated, 'floated')) - - const rest = getUnhandledProps(Button, this.props) - const ElementType = getElementType(Button, this.props, this.computeElementType) - const tabIndex = this.computeTabIndex(ElementType) - - if (!_.isNil(label)) { - const buttonClasses = cx('ui', baseClasses, 'button', className) - const containerClasses = cx('ui', labeledClasses, 'button', className, wrapperClasses) - const labelElement = Label.create(label, { - defaultProps: { - basic: true, - pointing: labelPosition === 'left' ? 'right' : 'left', - }, - autoGenerateKey: false, - }) - - return ( - - {labelPosition === 'left' && labelElement} - - - - {(labelPosition === 'right' || !labelPosition) && labelElement} - - ) - } - - const classes = cx('ui', baseClasses, wrapperClasses, labeledClasses, 'button', className) - const hasChildren = !childrenUtils.isNil(children) - const role = this.computeButtonAriaRole(ElementType) + if (!_.isNil(label)) { + const buttonClasses = cx('ui', baseClasses, 'button', className) + const containerClasses = cx('ui', labeledClasses, 'button', className, wrapperClasses) + const labelElement = Label.create(label, { + defaultProps: { + basic: true, + pointing: labelPosition === 'left' ? 'right' : 'left', + }, + autoGenerateKey: false, + }) return ( - - + {labelPosition === 'left' && labelElement} + + {(labelPosition === 'right' || !labelPosition) && labelElement} + ) } -} + const classes = cx('ui', baseClasses, wrapperClasses, labeledClasses, 'button', className) + const hasChildren = !childrenUtils.isNil(children) + const role = computeButtonAriaRole(ElementType, props.role) + + return ( + + {hasChildren && children} + {!hasChildren && Icon.create(icon, { autoGenerateKey: false })} + {!hasChildren && content} + + ) +}) + +Button.displayName = 'Button' Button.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Button/ButtonContent.js b/src/elements/Button/ButtonContent.js index 7622007fbe..af248b1022 100644 --- a/src/elements/Button/ButtonContent.js +++ b/src/elements/Button/ButtonContent.js @@ -13,8 +13,9 @@ import { /** * Used in some Button types, such as `animated`. */ -function ButtonContent(props) { +const ButtonContent = React.forwardRef(function (props, ref) { const { children, className, content, hidden, visible } = props + const classes = cx( useKeyOnly(visible, 'visible'), useKeyOnly(hidden, 'hidden'), @@ -25,12 +26,13 @@ function ButtonContent(props) { const ElementType = getElementType(ButtonContent, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +ButtonContent.displayName = 'ButtonContent' ButtonContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Button/ButtonGroup.js b/src/elements/Button/ButtonGroup.js index 06dfc61de9..79a1db17c5 100644 --- a/src/elements/Button/ButtonGroup.js +++ b/src/elements/Button/ButtonGroup.js @@ -19,7 +19,7 @@ import Button from './Button' /** * Buttons can be grouped. */ -function ButtonGroup(props) { +const ButtonGroup = React.forwardRef(function (props, ref) { const { attached, basic, @@ -71,19 +71,20 @@ function ButtonGroup(props) { if (_.isNil(buttons)) { return ( - + {childrenUtils.isNil(children) ? content : children} ) } return ( - + {_.map(buttons, (button) => Button.create(button))} ) -} +}) +ButtonGroup.displayName = 'ButtonGroup' ButtonGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Button/ButtonOr.js b/src/elements/Button/ButtonOr.js index 834d088549..89b05a80fa 100644 --- a/src/elements/Button/ButtonOr.js +++ b/src/elements/Button/ButtonOr.js @@ -7,15 +7,16 @@ import { getElementType, getUnhandledProps } from '../../lib' /** * Button groups can contain conditionals. */ -function ButtonOr(props) { +const ButtonOr = React.forwardRef(function (props, ref) { const { className, text } = props const classes = cx('or', className) const rest = getUnhandledProps(ButtonOr, props) const ElementType = getElementType(ButtonOr, props) - return -} + return +}) +ButtonOr.displayName = 'ButtonOr' ButtonOr.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Container/Container.js b/src/elements/Container/Container.js index 29cc74c778..ea9cafe64d 100644 --- a/src/elements/Container/Container.js +++ b/src/elements/Container/Container.js @@ -15,7 +15,7 @@ import { /** * A container limits content to a maximum width. */ -function Container(props) { +const Container = React.forwardRef(function (props, ref) { const { children, className, content, fluid, text, textAlign } = props const classes = cx( 'ui', @@ -29,12 +29,13 @@ function Container(props) { const ElementType = getElementType(Container, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +Container.displayName = 'Container' Container.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Divider/Divider.js b/src/elements/Divider/Divider.js index b36c5325fc..2f2147c188 100644 --- a/src/elements/Divider/Divider.js +++ b/src/elements/Divider/Divider.js @@ -13,7 +13,7 @@ import { /** * A divider visually segments content into groups. */ -function Divider(props) { +const Divider = React.forwardRef(function (props, ref) { const { children, className, @@ -43,12 +43,13 @@ function Divider(props) { const ElementType = getElementType(Divider, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +Divider.displayName = 'Divider' Divider.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Flag/Flag.js b/src/elements/Flag/Flag.js index cae20263c9..1ad15a8aaa 100644 --- a/src/elements/Flag/Flag.js +++ b/src/elements/Flag/Flag.js @@ -1,6 +1,6 @@ import cx from 'clsx' import PropTypes from 'prop-types' -import React, { PureComponent } from 'react' +import React from 'react' import { createShorthandFactory, @@ -509,17 +509,16 @@ export const names = [ /** * A flag is is used to represent a political state. */ -class Flag extends PureComponent { - render() { - const { className, name } = this.props - const classes = cx(name, 'flag', className) - const rest = getUnhandledProps(Flag, this.props) - const ElementType = getElementType(Flag, this.props) +const Flag = React.forwardRef(function (props, ref) { + const { className, name } = props + const classes = cx(name, 'flag', className) + const rest = getUnhandledProps(Flag, props) + const ElementType = getElementType(Flag, props) - return - } -} + return +}) +Flag.displayName = 'Flag' Flag.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -531,10 +530,13 @@ Flag.propTypes = { name: customPropTypes.suggest(names), } -Flag.defaultProps = { +// Heads up! +// .create() factories should be defined on exported component to be visible as static properties +const MemoFlag = React.memo(Flag) + +MemoFlag.create = createShorthandFactory(MemoFlag, (value) => ({ name: value })) +MemoFlag.defaultProps = { as: 'i', } -Flag.create = createShorthandFactory(Flag, (value) => ({ name: value })) - -export default Flag +export default MemoFlag diff --git a/src/elements/Header/Header.js b/src/elements/Header/Header.js index fb5b69fbee..b25a7421df 100644 --- a/src/elements/Header/Header.js +++ b/src/elements/Header/Header.js @@ -23,7 +23,7 @@ import HeaderContent from './HeaderContent' /** * A header provides a short summary of content */ -function Header(props) { +const Header = React.forwardRef(function (props, ref) { const { attached, block, @@ -65,7 +65,7 @@ function Header(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) @@ -77,7 +77,7 @@ function Header(props) { if (iconElement || imageElement) { return ( - + {iconElement || imageElement} {(content || subheaderElement) && ( @@ -90,13 +90,14 @@ function Header(props) { } return ( - + {content} {subheaderElement} ) -} +}) +Header.displayName = 'Header' Header.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Header/HeaderContent.js b/src/elements/Header/HeaderContent.js index 8ddd16edb4..b6dc8a1bf4 100644 --- a/src/elements/Header/HeaderContent.js +++ b/src/elements/Header/HeaderContent.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * Header content wraps the main content when there is an adjacent Icon or Image. */ -function HeaderContent(props) { +const HeaderContent = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('content', className) const rest = getUnhandledProps(HeaderContent, props) const ElementType = getElementType(HeaderContent, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +HeaderContent.displayName = 'HeaderContent' HeaderContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Header/HeaderSubheader.js b/src/elements/Header/HeaderSubheader.js index 2ed4bbc6bd..3925146440 100644 --- a/src/elements/Header/HeaderSubheader.js +++ b/src/elements/Header/HeaderSubheader.js @@ -13,19 +13,20 @@ import { /** * Headers may contain subheaders. */ -function HeaderSubheader(props) { +const HeaderSubheader = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('sub header', className) const rest = getUnhandledProps(HeaderSubheader, props) const ElementType = getElementType(HeaderSubheader, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +HeaderSubheader.displayName = 'HeaderSubheader' HeaderSubheader.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Icon/Icon.js b/src/elements/Icon/Icon.js index 71c2651ab1..1e180fcecd 100644 --- a/src/elements/Icon/Icon.js +++ b/src/elements/Icon/Icon.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { PureComponent } from 'react' +import React from 'react' import { createShorthandFactory, @@ -9,88 +9,89 @@ import { getElementType, getUnhandledProps, SUI, + useEventCallback, useKeyOnly, useKeyOrValueAndKey, useValueAndKey, } from '../../lib' import IconGroup from './IconGroup' -/** - * An icon is a glyph used to represent something else. - * @see Image - */ -class Icon extends PureComponent { - getIconAriaOptions() { - const ariaOptions = {} - const { 'aria-label': ariaLabel, 'aria-hidden': ariaHidden } = this.props - - if (_.isNil(ariaLabel)) { - ariaOptions['aria-hidden'] = 'true' - } else { - ariaOptions['aria-label'] = ariaLabel - } +function getAriaProps(props) { + const ariaOptions = {} + const { 'aria-label': ariaLabel, 'aria-hidden': ariaHidden } = props - if (!_.isNil(ariaHidden)) { - ariaOptions['aria-hidden'] = ariaHidden - } + if (_.isNil(ariaLabel)) { + ariaOptions['aria-hidden'] = 'true' + } else { + ariaOptions['aria-label'] = ariaLabel + } - return ariaOptions + if (!_.isNil(ariaHidden)) { + ariaOptions['aria-hidden'] = ariaHidden } - handleClick = (e) => { - const { disabled } = this.props + return ariaOptions +} +/** + * An icon is a glyph used to represent something else. + * @see Image + */ +const Icon = React.forwardRef(function (props, ref) { + const { + bordered, + circular, + className, + color, + corner, + disabled, + fitted, + flipped, + inverted, + link, + loading, + name, + rotated, + size, + } = props + + const classes = cx( + color, + name, + size, + useKeyOnly(bordered, 'bordered'), + useKeyOnly(circular, 'circular'), + useKeyOnly(disabled, 'disabled'), + useKeyOnly(fitted, 'fitted'), + useKeyOnly(inverted, 'inverted'), + useKeyOnly(link, 'link'), + useKeyOnly(loading, 'loading'), + useKeyOrValueAndKey(corner, 'corner'), + useValueAndKey(flipped, 'flipped'), + useValueAndKey(rotated, 'rotated'), + 'icon', + className, + ) + + const rest = getUnhandledProps(Icon, props) + const ElementType = getElementType(Icon, props) + const ariaProps = getAriaProps(props) + + const handleClick = useEventCallback((e) => { if (disabled) { e.preventDefault() return } - _.invoke(this.props, 'onClick', e, this.props) - } + _.invoke(props, 'onClick', e, props) + }) - render() { - const { - bordered, - circular, - className, - color, - corner, - disabled, - fitted, - flipped, - inverted, - link, - loading, - name, - rotated, - size, - } = this.props - - const classes = cx( - color, - name, - size, - useKeyOnly(bordered, 'bordered'), - useKeyOnly(circular, 'circular'), - useKeyOnly(disabled, 'disabled'), - useKeyOnly(fitted, 'fitted'), - useKeyOnly(inverted, 'inverted'), - useKeyOnly(link, 'link'), - useKeyOnly(loading, 'loading'), - useKeyOrValueAndKey(corner, 'corner'), - useValueAndKey(flipped, 'flipped'), - useValueAndKey(rotated, 'rotated'), - 'icon', - className, - ) - const rest = getUnhandledProps(Icon, this.props) - const ElementType = getElementType(Icon, this.props) - const ariaOptions = this.getIconAriaOptions() - - return - } -} + return ( + + ) +}) +Icon.displayName = 'Icon' Icon.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -147,12 +148,15 @@ Icon.propTypes = { 'aria-label': PropTypes.string, } -Icon.defaultProps = { - as: 'i', -} +// Heads up! +// .create() factories should be defined on exported component to be visible as static properties +const MemoIcon = React.memo(Icon) -Icon.Group = IconGroup +MemoIcon.Group = IconGroup +MemoIcon.create = createShorthandFactory(MemoIcon, (value) => ({ name: value })) -Icon.create = createShorthandFactory(Icon, (value) => ({ name: value })) +MemoIcon.defaultProps = { + as: 'i', +} -export default Icon +export default MemoIcon diff --git a/src/elements/Icon/IconGroup.js b/src/elements/Icon/IconGroup.js index 934381c432..2c17cfbf36 100644 --- a/src/elements/Icon/IconGroup.js +++ b/src/elements/Icon/IconGroup.js @@ -8,19 +8,21 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI /** * Several icons can be used together as a group. */ -function IconGroup(props) { +const IconGroup = React.forwardRef(function (props, ref) { const { children, className, content, size } = props + const classes = cx(size, 'icons', className) const rest = getUnhandledProps(IconGroup, props) const ElementType = getElementType(IconGroup, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +IconGroup.displayName = 'IconGroup' IconGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Image/Image.js b/src/elements/Image/Image.js index 45d7b17410..c72c22ff79 100644 --- a/src/elements/Image/Image.js +++ b/src/elements/Image/Image.js @@ -25,7 +25,7 @@ import ImageGroup from './ImageGroup' * An image is a graphic representation of something. * @see Icon */ -function Image(props) { +const Image = React.forwardRef(function (props, ref) { const { avatar, bordered, @@ -68,8 +68,10 @@ function Image(props) { 'image', className, ) + const rest = getUnhandledProps(Image, props) const [imgTagProps, rootProps] = partitionHTMLProps(rest, { htmlProps: htmlImageProps }) + const ElementType = getElementType(Image, props, () => { if ( !_.isNil(dimmer) || @@ -83,33 +85,36 @@ function Image(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } if (!childrenUtils.isNil(content)) { return ( - + {content} ) } if (ElementType === 'img') { - return + return } + return ( {Dimmer.create(dimmer, { autoGenerateKey: false })} {Label.create(label, { autoGenerateKey: false })} - + + ) -} +}) Image.Group = ImageGroup +Image.displayName = 'Image' Image.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Image/ImageGroup.js b/src/elements/Image/ImageGroup.js index 8f81a54c2c..8ac80b9221 100644 --- a/src/elements/Image/ImageGroup.js +++ b/src/elements/Image/ImageGroup.js @@ -7,19 +7,21 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps, SUI /** * A group of images. */ -function ImageGroup(props) { +const ImageGroup = React.forwardRef(function (props, ref) { const { children, className, content, size } = props + const classes = cx('ui', size, className, 'images') const rest = getUnhandledProps(ImageGroup, props) const ElementType = getElementType(ImageGroup, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +ImageGroup.displayName = 'ImageGroup' ImageGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Input/Input.js b/src/elements/Input/Input.js index 6892f09140..7f830a4a65 100644 --- a/src/elements/Input/Input.js +++ b/src/elements/Input/Input.js @@ -1,8 +1,7 @@ -import { handleRef } from '@fluentui/react-component-ref' import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Children, cloneElement, Component, createRef } from 'react' +import React from 'react' import { childrenUtils, @@ -14,6 +13,7 @@ import { partitionHTMLProps, useKeyOnly, useValueAndKey, + setRef, } from '../../lib' import Button from '../Button' import Icon from '../Icon' @@ -26,146 +26,144 @@ import Label from '../Label' * @see Icon * @see Label */ -class Input extends Component { - inputRef = createRef() - - computeIcon = () => { - const { loading, icon } = this.props +const Input = React.forwardRef(function (props, ref) { + const { + action, + actionPosition, + children, + className, + disabled, + error, + fluid, + focus, + icon, + iconPosition, + input, + inverted, + label, + labelPosition, + loading, + size, + tabIndex, + transparent, + type, + } = props + + const computeIcon = () => { + if (!_.isNil(icon)) { + return icon + } - if (!_.isNil(icon)) return icon - if (loading) return 'spinner' + if (loading) { + return 'spinner' + } } - computeTabIndex = () => { - const { disabled, tabIndex } = this.props + const computeTabIndex = () => { + if (!_.isNil(tabIndex)) { + return tabIndex + } - if (!_.isNil(tabIndex)) return tabIndex - if (disabled) return -1 + if (disabled) { + return -1 + } } - focus = (options) => this.inputRef.current.focus(options) + const handleChange = (e) => { + const newValue = _.get(e, 'target.value') - select = () => this.inputRef.current.select() - - handleChange = (e) => { - const value = _.get(e, 'target.value') - - _.invoke(this.props, 'onChange', e, { ...this.props, value }) + _.invoke(props, 'onChange', e, { ...props, value: newValue }) } - handleChildOverrides = (child, defaultProps) => ({ - ...defaultProps, - ...child.props, - ref: (c) => { - handleRef(child.ref, c) - this.inputRef.current = c - }, - }) - - partitionProps = () => { - const { disabled, type } = this.props - - const tabIndex = this.computeTabIndex() - const unhandled = getUnhandledProps(Input, this.props) - const [htmlInputProps, rest] = partitionHTMLProps(unhandled) + const partitionProps = () => { + const unhandledProps = getUnhandledProps(Input, props) + const [htmlInputProps, rest] = partitionHTMLProps(unhandledProps) return [ { ...htmlInputProps, disabled, type, - tabIndex, - onChange: this.handleChange, - ref: this.inputRef, + tabIndex: computeTabIndex(), + onChange: handleChange, + ref, }, rest, ] } - render() { - const { - action, - actionPosition, - children, - className, - disabled, - error, - fluid, - focus, - icon, - iconPosition, - input, - inverted, - label, - labelPosition, - loading, - size, - transparent, - type, - } = this.props - - const classes = cx( - 'ui', - size, - useKeyOnly(disabled, 'disabled'), - useKeyOnly(error, 'error'), - useKeyOnly(fluid, 'fluid'), - useKeyOnly(focus, 'focus'), - useKeyOnly(inverted, 'inverted'), - useKeyOnly(loading, 'loading'), - useKeyOnly(transparent, 'transparent'), - useValueAndKey(actionPosition, 'action') || useKeyOnly(action, 'action'), - useValueAndKey(iconPosition, 'icon') || useKeyOnly(icon || loading, 'icon'), - useValueAndKey(labelPosition, 'labeled') || useKeyOnly(label, 'labeled'), - 'input', - className, - ) - const ElementType = getElementType(Input, this.props) - const [htmlInputProps, rest] = this.partitionProps() - - // Render with children - // ---------------------------------------- - if (!childrenUtils.isNil(children)) { - // add htmlInputProps to the `` child - const childElements = _.map(Children.toArray(children), (child) => { - if (child.type !== 'input') return child - return cloneElement(child, this.handleChildOverrides(child, htmlInputProps)) - }) - - return ( - - {childElements} - - ) - } - - // Render Shorthand - // ---------------------------------------- - const actionElement = Button.create(action, { autoGenerateKey: false }) - const labelElement = Label.create(label, { - defaultProps: { - className: cx( - 'label', - // add 'left|right corner' - _.includes(labelPosition, 'corner') && labelPosition, - ), - }, - autoGenerateKey: false, + const classes = cx( + 'ui', + size, + useKeyOnly(disabled, 'disabled'), + useKeyOnly(error, 'error'), + useKeyOnly(fluid, 'fluid'), + useKeyOnly(focus, 'focus'), + useKeyOnly(inverted, 'inverted'), + useKeyOnly(loading, 'loading'), + useKeyOnly(transparent, 'transparent'), + useValueAndKey(actionPosition, 'action') || useKeyOnly(action, 'action'), + useValueAndKey(iconPosition, 'icon') || useKeyOnly(icon || loading, 'icon'), + useValueAndKey(labelPosition, 'labeled') || useKeyOnly(label, 'labeled'), + 'input', + className, + ) + const ElementType = getElementType(Input, props) + const [htmlInputProps, rest] = partitionProps() + + // Render with children + // ---------------------------------------- + if (!childrenUtils.isNil(children)) { + // add htmlInputProps to the `` child + const childElements = _.map(React.Children.toArray(children), (child) => { + if (child.type === 'input') { + return React.cloneElement(child, { + ...htmlInputProps, + ...child.props, + ref: (c) => { + setRef(child.ref, c) + setRef(ref, c) + }, + }) + } + + return child }) return ( - {actionPosition === 'left' && actionElement} - {labelPosition !== 'right' && labelElement} - {createHTMLInput(input || type, { defaultProps: htmlInputProps, autoGenerateKey: false })} - {Icon.create(this.computeIcon(), { autoGenerateKey: false })} - {actionPosition !== 'left' && actionElement} - {labelPosition === 'right' && labelElement} + {childElements} ) } -} + // Render Shorthand + // ---------------------------------------- + const actionElement = Button.create(action, { autoGenerateKey: false }) + const labelElement = Label.create(label, { + defaultProps: { + className: cx( + 'label', + // add 'left|right corner' + _.includes(labelPosition, 'corner') && labelPosition, + ), + }, + autoGenerateKey: false, + }) + + return ( + + {actionPosition === 'left' && actionElement} + {labelPosition !== 'right' && labelElement} + {createHTMLInput(input || type, { defaultProps: htmlInputProps, autoGenerateKey: false })} + {Icon.create(computeIcon(), { autoGenerateKey: false })} + {actionPosition !== 'left' && actionElement} + {labelPosition === 'right' && labelElement} + + ) +}) + +Input.displayName = 'Input' Input.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Label/Label.js b/src/elements/Label/Label.js index 1dedfffa50..30abb13cde 100644 --- a/src/elements/Label/Label.js +++ b/src/elements/Label/Label.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { childrenUtils, @@ -13,6 +13,7 @@ import { useKeyOnly, useKeyOrValueAndKey, useValueAndKey, + useEventCallback, } from '../../lib' import Icon from '../Icon/Icon' import Image from '../Image/Image' @@ -22,100 +23,95 @@ import LabelGroup from './LabelGroup' /** * A label displays content classification. */ -export default class Label extends Component { - handleClick = (e) => { - const { onClick } = this.props - - if (onClick) onClick(e, this.props) - } - - handleIconOverrides = (predefinedProps) => ({ - onClick: (e) => { - _.invoke(predefinedProps, 'onClick', e) - _.invoke(this.props, 'onRemove', e, this.props) - }, +const Label = React.forwardRef(function (props, ref) { + const { + active, + attached, + basic, + children, + circular, + className, + color, + content, + corner, + detail, + empty, + floating, + horizontal, + icon, + image, + onRemove, + pointing, + prompt, + removeIcon, + ribbon, + size, + tag, + } = props + + const pointingClass = + (pointing === true && 'pointing') || + ((pointing === 'left' || pointing === 'right') && `${pointing} pointing`) || + ((pointing === 'above' || pointing === 'below') && `pointing ${pointing}`) + + const classes = cx( + 'ui', + color, + pointingClass, + size, + useKeyOnly(active, 'active'), + useKeyOnly(basic, 'basic'), + useKeyOnly(circular, 'circular'), + useKeyOnly(empty, 'empty'), + useKeyOnly(floating, 'floating'), + useKeyOnly(horizontal, 'horizontal'), + useKeyOnly(image === true, 'image'), + useKeyOnly(prompt, 'prompt'), + useKeyOnly(tag, 'tag'), + useKeyOrValueAndKey(corner, 'corner'), + useKeyOrValueAndKey(ribbon, 'ribbon'), + useValueAndKey(attached, 'attached'), + 'label', + className, + ) + const rest = getUnhandledProps(Label, props) + const ElementType = getElementType(Label, props) + + const handleClick = useEventCallback((e) => { + _.invoke(props, 'onClick', e, props) }) - render() { - const { - active, - attached, - basic, - children, - circular, - className, - color, - content, - corner, - detail, - empty, - floating, - horizontal, - icon, - image, - onRemove, - pointing, - prompt, - removeIcon, - ribbon, - size, - tag, - } = this.props - - const pointingClass = - (pointing === true && 'pointing') || - ((pointing === 'left' || pointing === 'right') && `${pointing} pointing`) || - ((pointing === 'above' || pointing === 'below') && `pointing ${pointing}`) - - const classes = cx( - 'ui', - color, - pointingClass, - size, - useKeyOnly(active, 'active'), - useKeyOnly(basic, 'basic'), - useKeyOnly(circular, 'circular'), - useKeyOnly(empty, 'empty'), - useKeyOnly(floating, 'floating'), - useKeyOnly(horizontal, 'horizontal'), - useKeyOnly(image === true, 'image'), - useKeyOnly(prompt, 'prompt'), - useKeyOnly(tag, 'tag'), - useKeyOrValueAndKey(corner, 'corner'), - useKeyOrValueAndKey(ribbon, 'ribbon'), - useValueAndKey(attached, 'attached'), - 'label', - className, - ) - const rest = getUnhandledProps(Label, this.props) - const ElementType = getElementType(Label, this.props) - - if (!childrenUtils.isNil(children)) { - return ( - - {children} - - ) - } - - const removeIconShorthand = _.isUndefined(removeIcon) ? 'delete' : removeIcon - + if (!childrenUtils.isNil(children)) { return ( - - {Icon.create(icon, { autoGenerateKey: false })} - {typeof image !== 'boolean' && Image.create(image, { autoGenerateKey: false })} - {content} - {LabelDetail.create(detail, { autoGenerateKey: false })} - {onRemove && - Icon.create(removeIconShorthand, { - autoGenerateKey: false, - overrideProps: this.handleIconOverrides, - })} + + {children} ) } -} + const removeIconShorthand = _.isUndefined(removeIcon) ? 'delete' : removeIcon + + return ( + + {Icon.create(icon, { autoGenerateKey: false })} + {typeof image !== 'boolean' && Image.create(image, { autoGenerateKey: false })} + {content} + {LabelDetail.create(detail, { autoGenerateKey: false })} + {onRemove && + Icon.create(removeIconShorthand, { + autoGenerateKey: false, + overrideProps: (predefinedProps) => ({ + onClick: (e) => { + _.invoke(predefinedProps, 'onClick', e) + _.invoke(props, 'onRemove', e, props) + }, + }), + })} + + ) +}) + +Label.displayName = 'Label' Label.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -214,3 +210,5 @@ Label.Detail = LabelDetail Label.Group = LabelGroup Label.create = createShorthandFactory(Label, (value) => ({ content: value })) + +export default Label diff --git a/src/elements/Label/LabelDetail.js b/src/elements/Label/LabelDetail.js index 67c10fb714..6da4de001a 100644 --- a/src/elements/Label/LabelDetail.js +++ b/src/elements/Label/LabelDetail.js @@ -10,19 +10,21 @@ import { getUnhandledProps, } from '../../lib' -function LabelDetail(props) { +const LabelDetail = React.forwardRef(function (props, ref) { const { children, className, content } = props + const classes = cx('detail', className) const rest = getUnhandledProps(LabelDetail, props) const ElementType = getElementType(LabelDetail, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +LabelDetail.displayName = 'LabelDetail' LabelDetail.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Label/LabelGroup.js b/src/elements/Label/LabelGroup.js index 795707aee0..01cf51dc5d 100644 --- a/src/elements/Label/LabelGroup.js +++ b/src/elements/Label/LabelGroup.js @@ -14,7 +14,7 @@ import { /** * A label can be grouped. */ -function LabelGroup(props) { +const LabelGroup = React.forwardRef(function (props, ref) { const { children, circular, className, color, content, size, tag } = props const classes = cx( @@ -30,12 +30,13 @@ function LabelGroup(props) { const ElementType = getElementType(LabelGroup, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +LabelGroup.displayName = 'LabelGroup' LabelGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/List/List.js b/src/elements/List/List.js index 19fec4094d..f805838b3c 100644 --- a/src/elements/List/List.js +++ b/src/elements/List/List.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { childrenUtils, @@ -24,80 +24,81 @@ import ListList from './ListList' /** * A list groups related content. */ -class List extends Component { - handleItemOverrides = (predefinedProps) => ({ - onClick: (e, itemProps) => { - _.invoke(predefinedProps, 'onClick', e, itemProps) - _.invoke(this.props, 'onItemClick', e, itemProps) - }, - }) - - render() { - const { - animated, - bulleted, - celled, - children, - className, - content, - divided, - floated, - horizontal, - inverted, - items, - link, - ordered, - relaxed, - selection, - size, - verticalAlign, - } = this.props - - const classes = cx( - 'ui', - size, - useKeyOnly(animated, 'animated'), - useKeyOnly(bulleted, 'bulleted'), - useKeyOnly(celled, 'celled'), - useKeyOnly(divided, 'divided'), - useKeyOnly(horizontal, 'horizontal'), - useKeyOnly(inverted, 'inverted'), - useKeyOnly(link, 'link'), - useKeyOnly(ordered, 'ordered'), - useKeyOnly(selection, 'selection'), - useKeyOrValueAndKey(relaxed, 'relaxed'), - useValueAndKey(floated, 'floated'), - useVerticalAlignProp(verticalAlign), - 'list', - className, +const List = React.forwardRef(function (props, ref) { + const { + animated, + bulleted, + celled, + children, + className, + content, + divided, + floated, + horizontal, + inverted, + items, + link, + ordered, + relaxed, + selection, + size, + verticalAlign, + } = props + + const classes = cx( + 'ui', + size, + useKeyOnly(animated, 'animated'), + useKeyOnly(bulleted, 'bulleted'), + useKeyOnly(celled, 'celled'), + useKeyOnly(divided, 'divided'), + useKeyOnly(horizontal, 'horizontal'), + useKeyOnly(inverted, 'inverted'), + useKeyOnly(link, 'link'), + useKeyOnly(ordered, 'ordered'), + useKeyOnly(selection, 'selection'), + useKeyOrValueAndKey(relaxed, 'relaxed'), + useValueAndKey(floated, 'floated'), + useVerticalAlignProp(verticalAlign), + 'list', + className, + ) + const rest = getUnhandledProps(List, props) + const ElementType = getElementType(List, props) + + if (!childrenUtils.isNil(children)) { + return ( + + {children} + ) - const rest = getUnhandledProps(List, this.props) - const ElementType = getElementType(List, this.props) - - if (!childrenUtils.isNil(children)) { - return ( - - {children} - - ) - } - - if (!childrenUtils.isNil(content)) { - return ( - - {content} - - ) - } + } + if (!childrenUtils.isNil(content)) { return ( - - {_.map(items, (item) => ListItem.create(item, { overrideProps: this.handleItemOverrides }))} + + {content} ) } -} + return ( + + {_.map(items, (item) => + ListItem.create(item, { + overrideProps: (predefinedProps) => ({ + onClick: (e, itemProps) => { + _.invoke(predefinedProps, 'onClick', e, itemProps) + _.invoke(props, 'onItemClick', e, itemProps) + }, + }), + }), + )} + + ) +}) + +List.displayName = 'List' List.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/List/ListContent.js b/src/elements/List/ListContent.js index 467da05b57..667e6bf0f6 100644 --- a/src/elements/List/ListContent.js +++ b/src/elements/List/ListContent.js @@ -18,7 +18,7 @@ import ListHeader from './ListHeader' /** * A list item can contain a content. */ -function ListContent(props) { +const ListContent = React.forwardRef(function (props, ref) { const { children, className, content, description, floated, header, verticalAlign } = props const classes = cx( @@ -32,21 +32,22 @@ function ListContent(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {ListHeader.create(header)} {ListDescription.create(description)} {content} ) -} +}) +ListContent.displayName = 'ListContent' ListContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/List/ListDescription.js b/src/elements/List/ListDescription.js index 95b143af61..b2672442e3 100644 --- a/src/elements/List/ListDescription.js +++ b/src/elements/List/ListDescription.js @@ -13,19 +13,20 @@ import { /** * A list item can contain a description. */ -function ListDescription(props) { +const ListDescription = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx(className, 'description') const rest = getUnhandledProps(ListDescription, props) const ElementType = getElementType(ListDescription, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +ListDescription.displayName = 'ListDescription' ListDescription.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/List/ListHeader.js b/src/elements/List/ListHeader.js index e4f7af0248..c26850c199 100644 --- a/src/elements/List/ListHeader.js +++ b/src/elements/List/ListHeader.js @@ -13,19 +13,21 @@ import { /** * A list item can contain a header. */ -function ListHeader(props) { +const ListHeader = React.forwardRef(function (props, ref) { const { children, className, content } = props + const classes = cx('header', className) const rest = getUnhandledProps(ListHeader, props) const ElementType = getElementType(ListHeader, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +ListHeader.displayName = 'ListHeader' ListHeader.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/List/ListIcon.js b/src/elements/List/ListIcon.js index 0cb223af06..64d91edaac 100644 --- a/src/elements/List/ListIcon.js +++ b/src/elements/List/ListIcon.js @@ -8,14 +8,15 @@ import Icon from '../Icon/Icon' /** * A list item can contain an icon. */ -function ListIcon(props) { +const ListIcon = React.forwardRef(function (props, ref) { const { className, verticalAlign } = props const classes = cx(useVerticalAlignProp(verticalAlign), className) const rest = getUnhandledProps(ListIcon, props) - return -} + return +}) +ListIcon.displayName = 'ListIcon' ListIcon.propTypes = { /** Additional classes. */ className: PropTypes.string, diff --git a/src/elements/List/ListItem.js b/src/elements/List/ListItem.js index c5dc711489..c0fba5fb72 100644 --- a/src/elements/List/ListItem.js +++ b/src/elements/List/ListItem.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component, isValidElement } from 'react' +import React, { isValidElement } from 'react' import { childrenUtils, @@ -10,6 +10,7 @@ import { getElementType, getUnhandledProps, useKeyOnly, + useEventCallback, } from '../../lib' import Image from '../Image' import ListContent from './ListContent' @@ -20,112 +21,116 @@ import ListIcon from './ListIcon' /** * A list item can contain a set of items. */ -class ListItem extends Component { - handleClick = (e) => { - const { disabled } = this.props +const ListItem = React.forwardRef(function (props, ref) { + const { + active, + children, + className, + content, + description, + disabled, + header, + icon, + image, + value, + } = props + + const ElementType = getElementType(ListItem, props) + const classes = cx( + useKeyOnly(active, 'active'), + useKeyOnly(disabled, 'disabled'), + useKeyOnly(ElementType !== 'li', 'item'), + className, + ) + const rest = getUnhandledProps(ListItem, props) + + const handleClick = useEventCallback((e) => { + if (!disabled) { + _.invoke(props, 'onClick', e, props) + } + }) + const valueProp = ElementType === 'li' ? { value } : { 'data-value': value } - if (!disabled) _.invoke(this.props, 'onClick', e, this.props) + if (!childrenUtils.isNil(children)) { + return ( + + {children} + + ) } - render() { - const { - active, - children, - className, - content, - description, - disabled, - header, - icon, - image, - value, - } = this.props - - const ElementType = getElementType(ListItem, this.props) - const classes = cx( - useKeyOnly(active, 'active'), - useKeyOnly(disabled, 'disabled'), - useKeyOnly(ElementType !== 'li', 'item'), - className, - ) - const rest = getUnhandledProps(ListItem, this.props) - const valueProp = ElementType === 'li' ? { value } : { 'data-value': value } - - if (!childrenUtils.isNil(children)) { - return ( - - {children} - - ) - } + const iconElement = ListIcon.create(icon, { autoGenerateKey: false }) + const imageElement = Image.create(image, { autoGenerateKey: false }) - const iconElement = ListIcon.create(icon, { autoGenerateKey: false }) - const imageElement = Image.create(image, { autoGenerateKey: false }) - - // See description of `content` prop for explanation about why this is necessary. - if (!isValidElement(content) && _.isPlainObject(content)) { - return ( - - {iconElement || imageElement} - {ListContent.create(content, { - autoGenerateKey: false, - defaultProps: { header, description }, - })} - - ) - } + // See description of `content` prop for explanation about why this is necessary. + if (!isValidElement(content) && _.isPlainObject(content)) { + return ( + + {iconElement || imageElement} + {ListContent.create(content, { + autoGenerateKey: false, + defaultProps: { header, description }, + })} + + ) + } - const headerElement = ListHeader.create(header, { autoGenerateKey: false }) - const descriptionElement = ListDescription.create(description, { autoGenerateKey: false }) - if (iconElement || imageElement) { - return ( - - {iconElement || imageElement} - {(content || headerElement || descriptionElement) && ( - - {headerElement} - {descriptionElement} - {content} - - )} - - ) - } + const headerElement = ListHeader.create(header, { autoGenerateKey: false }) + const descriptionElement = ListDescription.create(description, { autoGenerateKey: false }) + if (iconElement || imageElement) { return ( - {headerElement} - {descriptionElement} - {content} + {iconElement || imageElement} + {(content || headerElement || descriptionElement) && ( + + {headerElement} + {descriptionElement} + {content} + + )} ) } -} + return ( + + {headerElement} + {descriptionElement} + {content} + + ) +}) + +ListItem.displayName = 'ListItem' ListItem.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/List/ListList.js b/src/elements/List/ListList.js index fac22a8491..403d243b79 100644 --- a/src/elements/List/ListList.js +++ b/src/elements/List/ListList.js @@ -13,7 +13,7 @@ import { /** * A list can contain a sub list. */ -function ListList(props) { +const ListList = React.forwardRef(function (props, ref) { const { children, className, content } = props const rest = getUnhandledProps(ListList, props) @@ -21,12 +21,13 @@ function ListList(props) { const classes = cx(useKeyOnly(ElementType !== 'ul' && ElementType !== 'ol', 'list'), className) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +ListList.displayName = 'ListList' ListList.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Loader/Loader.js b/src/elements/Loader/Loader.js index 1f1d5dd5cb..ed270fa6cd 100644 --- a/src/elements/Loader/Loader.js +++ b/src/elements/Loader/Loader.js @@ -16,7 +16,7 @@ import { * A loader alerts a user to wait for an activity to complete. * @see Dimmer */ -function Loader(props) { +const Loader = React.forwardRef(function (props, ref) { const { active, children, @@ -45,12 +45,13 @@ function Loader(props) { const ElementType = getElementType(Loader, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +Loader.displayName = 'Loader' Loader.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Placeholder/Placeholder.js b/src/elements/Placeholder/Placeholder.js index 23f77ac969..d7bd272da5 100644 --- a/src/elements/Placeholder/Placeholder.js +++ b/src/elements/Placeholder/Placeholder.js @@ -17,7 +17,7 @@ import PlaceholderParagraph from './PlaceholderParagraph' /** * A placeholder is used to reserve space for content that soon will appear in a layout. */ -function Placeholder(props) { +const Placeholder = React.forwardRef(function (props, ref) { const { children, className, content, fluid, inverted } = props const classes = cx( 'ui', @@ -30,12 +30,13 @@ function Placeholder(props) { const ElementType = getElementType(Placeholder, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +Placeholder.displayName = 'Placeholder' Placeholder.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Placeholder/PlaceholderHeader.js b/src/elements/Placeholder/PlaceholderHeader.js index cfc33ea20f..6f8293b3ad 100644 --- a/src/elements/Placeholder/PlaceholderHeader.js +++ b/src/elements/Placeholder/PlaceholderHeader.js @@ -13,19 +13,20 @@ import { /** * A placeholder can contain a header. */ -function PlaceholderHeader(props) { +const PlaceholderHeader = React.forwardRef(function (props, ref) { const { children, className, content, image } = props const classes = cx(useKeyOnly(image, 'image'), 'header', className) const rest = getUnhandledProps(PlaceholderHeader, props) const ElementType = getElementType(PlaceholderHeader, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +PlaceholderHeader.displayName = 'PlaceholderHeader' PlaceholderHeader.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Placeholder/PlaceholderImage.js b/src/elements/Placeholder/PlaceholderImage.js index 84e9348094..86f3a6e824 100644 --- a/src/elements/Placeholder/PlaceholderImage.js +++ b/src/elements/Placeholder/PlaceholderImage.js @@ -7,7 +7,7 @@ import { customPropTypes, getElementType, getUnhandledProps, useKeyOnly } from ' /** * A placeholder can contain an image. */ -function PlaceholderImage(props) { +const PlaceholderImage = React.forwardRef(function (props, ref) { const { className, square, rectangular } = props const classes = cx( useKeyOnly(square, 'square'), @@ -18,9 +18,10 @@ function PlaceholderImage(props) { const rest = getUnhandledProps(PlaceholderImage, props) const ElementType = getElementType(PlaceholderImage, props) - return -} + return +}) +PlaceholderImage.displayName = 'PlaceholderImage' PlaceholderImage.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Placeholder/PlaceholderLine.js b/src/elements/Placeholder/PlaceholderLine.js index 0682daff9d..7ff192252e 100644 --- a/src/elements/Placeholder/PlaceholderLine.js +++ b/src/elements/Placeholder/PlaceholderLine.js @@ -7,15 +7,16 @@ import { getElementType, getUnhandledProps } from '../../lib' /** * A placeholder can contain have lines of text. */ -function PlaceholderLine(props) { +const PlaceholderLine = React.forwardRef(function (props, ref) { const { className, length } = props const classes = cx('line', length, className) const rest = getUnhandledProps(PlaceholderLine, props) const ElementType = getElementType(PlaceholderLine, props) - return -} + return +}) +PlaceholderLine.displayName = 'PlaceholderLine' PlaceholderLine.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Placeholder/PlaceholderParagraph.js b/src/elements/Placeholder/PlaceholderParagraph.js index 535a87c26e..91a949d7a5 100644 --- a/src/elements/Placeholder/PlaceholderParagraph.js +++ b/src/elements/Placeholder/PlaceholderParagraph.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A placeholder can contain a paragraph. */ -function PlaceholderParagraph(props) { +const PlaceholderParagraph = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('paragraph', className) const rest = getUnhandledProps(PlaceholderParagraph, props) const ElementType = getElementType(PlaceholderParagraph, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +PlaceholderParagraph.displayName = 'PlaceholderParagraph' PlaceholderParagraph.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Rail/Rail.js b/src/elements/Rail/Rail.js index 90a69445fc..74ffc79607 100644 --- a/src/elements/Rail/Rail.js +++ b/src/elements/Rail/Rail.js @@ -16,7 +16,7 @@ import { /** * A rail is used to show accompanying content outside the boundaries of the main view of a site. */ -function Rail(props) { +const Rail = React.forwardRef(function (props, ref) { const { attached, children, @@ -44,12 +44,13 @@ function Rail(props) { const ElementType = getElementType(Rail, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +Rail.displayName = 'Rail' Rail.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Reveal/Reveal.js b/src/elements/Reveal/Reveal.js index 971608cb8c..f18fcf120f 100644 --- a/src/elements/Reveal/Reveal.js +++ b/src/elements/Reveal/Reveal.js @@ -14,7 +14,7 @@ import RevealContent from './RevealContent' /** * A reveal displays additional content in place of previous content when activated. */ -function Reveal(props) { +const Reveal = React.forwardRef(function (props, ref) { const { active, animated, children, className, content, disabled, instant } = props const classes = cx( @@ -30,12 +30,13 @@ function Reveal(props) { const ElementType = getElementType(Reveal, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +Reveal.displayName = 'Reveal' Reveal.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Reveal/RevealContent.js b/src/elements/Reveal/RevealContent.js index 1e25912df8..1a2fb4cf30 100644 --- a/src/elements/Reveal/RevealContent.js +++ b/src/elements/Reveal/RevealContent.js @@ -13,7 +13,7 @@ import { /** * A content sub-component for the Reveal. */ -function RevealContent(props) { +const RevealContent = React.forwardRef(function (props, ref) { const { children, className, content, hidden, visible } = props const classes = cx( @@ -27,12 +27,13 @@ function RevealContent(props) { const ElementType = getElementType(RevealContent, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +RevealContent.displayName = 'RevealContent' RevealContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Segment/Segment.js b/src/elements/Segment/Segment.js index 015c21bf85..cb73a0e7d6 100644 --- a/src/elements/Segment/Segment.js +++ b/src/elements/Segment/Segment.js @@ -20,7 +20,7 @@ import SegmentInline from './SegmentInline' /** * A segment is used to create a grouping of related content. */ -function Segment(props) { +const Segment = React.forwardRef(function (props, ref) { const { attached, basic, @@ -76,15 +76,16 @@ function Segment(props) { const ElementType = getElementType(Segment, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) Segment.Group = SegmentGroup Segment.Inline = SegmentInline +Segment.displayName = 'Segment' Segment.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Segment/SegmentGroup.js b/src/elements/Segment/SegmentGroup.js index 64b938eb80..a5b00d6c30 100644 --- a/src/elements/Segment/SegmentGroup.js +++ b/src/elements/Segment/SegmentGroup.js @@ -15,7 +15,7 @@ import { /** * A group of segments can be formatted to appear together. */ -function SegmentGroup(props) { +const SegmentGroup = React.forwardRef(function (props, ref) { const { children, className, compact, content, horizontal, piled, raised, size, stacked } = props const classes = cx( @@ -33,12 +33,13 @@ function SegmentGroup(props) { const ElementType = getElementType(SegmentGroup, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +SegmentGroup.displayName = 'SegmentGroup' SegmentGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Segment/SegmentInline.js b/src/elements/Segment/SegmentInline.js index 70b1d8db95..2ce0aeb0e9 100644 --- a/src/elements/Segment/SegmentInline.js +++ b/src/elements/Segment/SegmentInline.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A placeholder segment can be inline. */ -function SegmentInline(props) { +const SegmentInline = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('inline', className) const rest = getUnhandledProps(SegmentInline, props) const ElementType = getElementType(SegmentInline, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +SegmentInline.displayName = 'SegmentInline' SegmentInline.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Step/Step.js b/src/elements/Step/Step.js index 55866f09a3..bebf135191 100644 --- a/src/elements/Step/Step.js +++ b/src/elements/Step/Step.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { childrenUtils, @@ -10,6 +10,7 @@ import { getElementType, getUnhandledProps, useKeyOnly, + useEventCallback, } from '../../lib' import Icon from '../Icon' import StepContent from './StepContent' @@ -20,70 +21,69 @@ import StepTitle from './StepTitle' /** * A step shows the completion status of an activity in a series of activities. */ -class Step extends Component { - computeElementType = () => { - const { onClick } = this.props - - if (onClick) return 'a' - } - - handleClick = (e) => { - const { disabled } = this.props - - if (!disabled) _.invoke(this.props, 'onClick', e, this.props) - } - - render() { - const { - active, - children, - className, - completed, - content, - description, - disabled, - href, - icon, - link, - title, - } = this.props - - const classes = cx( - useKeyOnly(active, 'active'), - useKeyOnly(completed, 'completed'), - useKeyOnly(disabled, 'disabled'), - useKeyOnly(link, 'link'), - 'step', - className, - ) - const rest = getUnhandledProps(Step, this.props) - const ElementType = getElementType(Step, this.props, this.computeElementType) - - if (!childrenUtils.isNil(children)) { - return ( - - {children} - - ) +const Step = React.forwardRef(function (props, ref) { + const { + active, + children, + className, + completed, + content, + description, + disabled, + href, + onClick, + icon, + link, + title, + } = props + + const handleClick = useEventCallback((e) => { + if (!disabled) { + _.invoke(props, 'onClick', e, props) } - - if (!childrenUtils.isNil(content)) { - return ( - - {content} - - ) + }) + + const classes = cx( + useKeyOnly(active, 'active'), + useKeyOnly(completed, 'completed'), + useKeyOnly(disabled, 'disabled'), + useKeyOnly(link, 'link'), + 'step', + className, + ) + + const rest = getUnhandledProps(Step, props) + const ElementType = getElementType(Step, props, () => { + if (onClick) { + return 'a' } + }) + if (!childrenUtils.isNil(children)) { return ( - - {Icon.create(icon, { autoGenerateKey: false })} - {StepContent.create({ description, title }, { autoGenerateKey: false })} + + {children} ) } -} + if (!childrenUtils.isNil(content)) { + return ( + + {content} + + ) + } + + return ( + + {Icon.create(icon, { autoGenerateKey: false })} + {StepContent.create({ description, title }, { autoGenerateKey: false })} + + ) +}) + +Step.displayName = 'Step' Step.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Step/StepContent.js b/src/elements/Step/StepContent.js index 2285ff2e08..d71a931e21 100644 --- a/src/elements/Step/StepContent.js +++ b/src/elements/Step/StepContent.js @@ -15,7 +15,7 @@ import StepTitle from './StepTitle' /** * A step can contain a content. */ -function StepContent(props) { +const StepContent = React.forwardRef(function (props, ref) { const { children, className, content, description, title } = props const classes = cx('content', className) const rest = getUnhandledProps(StepContent, props) @@ -23,27 +23,29 @@ function StepContent(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } + if (!childrenUtils.isNil(content)) { return ( - + {content} ) } return ( - + {StepTitle.create(title, { autoGenerateKey: false })} {StepDescription.create(description, { autoGenerateKey: false })} ) -} +}) +StepContent.displayName = 'StepContent' StepContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Step/StepDescription.js b/src/elements/Step/StepDescription.js index ad4b511209..6bde53b17e 100644 --- a/src/elements/Step/StepDescription.js +++ b/src/elements/Step/StepDescription.js @@ -10,19 +10,20 @@ import { getUnhandledProps, } from '../../lib' -function StepDescription(props) { +const StepDescription = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('description', className) const rest = getUnhandledProps(StepDescription, props) const ElementType = getElementType(StepDescription, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +StepDescription.displayName = 'StepDescription' StepDescription.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Step/StepGroup.js b/src/elements/Step/StepGroup.js index c85e5bfeec..1b7967809f 100644 --- a/src/elements/Step/StepGroup.js +++ b/src/elements/Step/StepGroup.js @@ -22,7 +22,7 @@ const numberMap = _.pickBy(numberToWordMap, (val, key) => key <= 8) /** * A set of steps. */ -function StepGroup(props) { +const StepGroup = React.forwardRef(function (props, ref) { const { attached, children, @@ -55,26 +55,27 @@ function StepGroup(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } if (!childrenUtils.isNil(content)) { return ( - + {content} ) } return ( - + {_.map(items, (item) => Step.create(item))} ) -} +}) +StepGroup.displayName = 'StepGroup' StepGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/elements/Step/StepTitle.js b/src/elements/Step/StepTitle.js index ebad010c93..ad03ec96df 100644 --- a/src/elements/Step/StepTitle.js +++ b/src/elements/Step/StepTitle.js @@ -13,19 +13,20 @@ import { /** * A step can contain a title. */ -function StepTitle(props) { +const StepTitle = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('title', className) const rest = getUnhandledProps(StepTitle, props) const ElementType = getElementType(StepTitle, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +StepTitle.displayName = 'StepTitle' StepTitle.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/index.js b/src/index.js index e4f85c45cb..7bbbba2c6b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,3 @@ -// Third party -export { Ref } from '@fluentui/react-component-ref' - // Addons export Confirm from './addons/Confirm' export Pagination from './addons/Pagination' @@ -12,9 +9,6 @@ export Select from './addons/Select' export TextArea from './addons/TextArea' export TransitionablePortal from './addons/TransitionablePortal' -// Behaviors -export Visibility from './behaviors/Visibility' - // Collections export Breadcrumb from './collections/Breadcrumb' export BreadcrumbDivider from './collections/Breadcrumb/BreadcrumbDivider' @@ -154,6 +148,7 @@ export RatingIcon from './modules/Rating/RatingIcon' export Search from './modules/Search' export SearchCategory from './modules/Search/SearchCategory' +export SearchCategoryLayout from './modules/Search/SearchCategoryLayout' export SearchResult from './modules/Search/SearchResult' export SearchResults from './modules/Search/SearchResults' diff --git a/src/lib/doesNodeContainClick.js b/src/lib/doesNodeContainClick.js index d1ae271216..d400098eeb 100644 --- a/src/lib/doesNodeContainClick.js +++ b/src/lib/doesNodeContainClick.js @@ -10,7 +10,9 @@ import _ from 'lodash' * @returns {boolean} */ const doesNodeContainClick = (node, e) => { - if (_.some([e, node], _.isNil)) return false + if (_.some([e, node], _.isNil)) { + return false + } // if there is an e.target and it is in the document, use a simple node.contains() check if (e.target) { @@ -18,7 +20,10 @@ const doesNodeContainClick = (node, e) => { if (document.querySelector('[data-suir-click-target=true]')) { _.invoke(e.target, 'removeAttribute', 'data-suir-click-target') - return node.contains(e.target) + + if (typeof node.contains === 'function') { + return node.contains(e.target) + } } } @@ -29,18 +34,31 @@ const doesNodeContainClick = (node, e) => { // return early if the event properties aren't available // prevent measuring the node and repainting if we don't need to const { clientX, clientY } = e - if (_.some([clientX, clientY], _.isNil)) return false + + if (_.some([clientX, clientY], _.isNil)) { + return false + } + + if (typeof node.getClientRects !== 'function') { + return false + } // false if the node is not visible const clientRects = node.getClientRects() + // Heads Up! // getClientRects returns a DOMRectList, not an array nor a plain object // We explicitly avoid _.isEmpty and check .length to cover all possible shapes - if (!node.offsetWidth || !node.offsetHeight || !clientRects || !clientRects.length) return false + if (!node.offsetWidth || !node.offsetHeight || !clientRects || !clientRects.length) { + return false + } // false if the node doesn't have a valid bounding rect const { top, bottom, left, right } = _.first(clientRects) - if (_.some([top, bottom, left, right], _.isNil)) return false + + if (_.some([top, bottom, left, right], _.isNil)) { + return false + } // we add a small decimal to the upper bound just to make it inclusive // don't add an whole pixel (1) as the event/node values may be decimal sensitive diff --git a/src/lib/factories.js b/src/lib/factories.js index 7e703ed8b9..4cc1c62a06 100644 --- a/src/lib/factories.js +++ b/src/lib/factories.js @@ -1,6 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import * as React from 'react' +import * as ReactIs from 'react-is' const DEPRECATED_CALLS = {} @@ -21,8 +22,8 @@ const DEPRECATED_CALLS = {} * @returns {object|null} */ export function createShorthand(Component, mapValueToProps, val, options = {}) { - if (typeof Component !== 'function' && typeof Component !== 'string') { - throw new Error('createShorthand() Component must be a string or function.') + if (!ReactIs.isValidElementType(Component)) { + throw new Error('createShorthand(): Component should be a valid element type.') } // short circuit noop values @@ -157,8 +158,8 @@ export function createShorthand(Component, mapValueToProps, val, options = {}) { * @returns {function} A shorthand factory function waiting for `val` and `defaultProps`. */ export function createShorthandFactory(Component, mapValueToProps) { - if (typeof Component !== 'function' && typeof Component !== 'string') { - throw new Error('createShorthandFactory() Component must be a string or function.') + if (!ReactIs.isValidElementType(Component)) { + throw new Error('createShorthandFactory(): Component should be a valid element type.') } return (val, options) => createShorthand(Component, mapValueToProps, val, options) diff --git a/src/lib/getUnhandledProps.js b/src/lib/getUnhandledProps.js index 1a4d199541..344d7b337a 100644 --- a/src/lib/getUnhandledProps.js +++ b/src/lib/getUnhandledProps.js @@ -10,7 +10,9 @@ const getUnhandledProps = (Component, props) => { const { handledProps = [] } = Component return Object.keys(props).reduce((acc, prop) => { - if (prop === 'childKey') return acc + // "childKey" and "innerRef" are internal props of Semantic UI React + // "innerRef" can be removed when "Search" & "Dropdown components will be removed to be functional + if (prop === 'childKey' || prop === 'innerRef') return acc if (handledProps.indexOf(prop) === -1) acc[prop] = props[prop] return acc }, {}) diff --git a/src/lib/hooks/useAutoControlledValue.js b/src/lib/hooks/useAutoControlledValue.js new file mode 100644 index 0000000000..756ed79fb7 --- /dev/null +++ b/src/lib/hooks/useAutoControlledValue.js @@ -0,0 +1,45 @@ +import * as React from 'react' + +/** + * A hook that allows optional user control, implements an interface similar to `React.useState()`. + * Useful for components which allow uncontrolled and controlled behaviours for users. + * + * - defaultState - default state or factory initializer + * - state - controllable state, undefined state means internal state will be used + * - initialState - Used to initialize state if all user provided states are undefined + * + * @param {{ defaultState?: any, state: any, initialState: any }} options + * + * @see https://reactjs.org/docs/uncontrolled-components.html + * @see https://reactjs.org/docs/hooks-state.html + */ +function useAutoControlledValue(options) { + const initialState = + typeof options.defaultState === 'undefined' ? options.initialState : options.defaultState + const [internalState, setInternalState] = React.useState(initialState) + + const state = typeof options.state === 'undefined' ? internalState : options.state + const stateRef = React.useRef(state) + + React.useEffect(() => { + stateRef.current = state + }, [state]) + + // To match the behavior of the setter returned by React.useState, this callback's identity + // should never change. This means it MUST NOT directly reference variables that can change. + const setState = React.useCallback((newState) => { + // React dispatch can use a factory + // https://reactjs.org/docs/hooks-reference.html#functional-updates + if (typeof newState === 'function') { + stateRef.current = newState(stateRef.current) + } else { + stateRef.current = newState + } + + setInternalState(stateRef.current) + }, []) + + return [state, setState] +} + +export default useAutoControlledValue diff --git a/src/lib/hooks/useClassNamesOnNode.js b/src/lib/hooks/useClassNamesOnNode.js index b1571f5842..479142ee91 100644 --- a/src/lib/hooks/useClassNamesOnNode.js +++ b/src/lib/hooks/useClassNamesOnNode.js @@ -1,6 +1,6 @@ -import { isRefObject } from '@fluentui/react-component-ref' import React from 'react' +import isRefObject from '../isRefObject' import useIsomorphicLayoutEffect from './useIsomorphicLayoutEffect' const CLASS_NAME_DELITIMITER = /\s+/ diff --git a/src/lib/hooks/useEventCallback.js b/src/lib/hooks/useEventCallback.js new file mode 100644 index 0000000000..f83a07cc66 --- /dev/null +++ b/src/lib/hooks/useEventCallback.js @@ -0,0 +1,35 @@ +import * as React from 'react' +import useIsomorphicLayoutEffect from './useIsomorphicLayoutEffect' + +/** + * https://reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback + * + * Modified `useCallback` that can be used when dependencies change too frequently. Can occur when: + * e.g. user props are depedencies which could change on every render + * e.g. volatile values (i.e. useState/useDispatch) are dependencies which could change frequently + * + * This should not be used often, but can be a useful re-render optimization since the callback is + * a ref and will not be invalidated between rerenders. + * + * @param {Function} fn The callback function that will be used + */ +export default function useEventCallback(fn) { + const callbackRef = React.useRef(() => { + if (process.env.NODE_ENV !== 'production') { + throw new Error('Cannot call an event handler while rendering...') + } + }) + + useIsomorphicLayoutEffect(() => { + callbackRef.current = fn + }, [fn]) + + return React.useCallback( + (...args) => { + const callback = callbackRef.current + + return callback(...args) + }, + [callbackRef], + ) +} diff --git a/src/lib/hooks/useForceUpdate.js b/src/lib/hooks/useForceUpdate.js new file mode 100644 index 0000000000..9f5deaee85 --- /dev/null +++ b/src/lib/hooks/useForceUpdate.js @@ -0,0 +1,8 @@ +import * as React from 'react' + +/** + * Returns a callback that causes force render of a component. + */ +export default function useForceUpdate() { + return React.useReducer((x) => x + 1, 0)[1] +} diff --git a/src/lib/hooks/useMergedRefs.js b/src/lib/hooks/useMergedRefs.js new file mode 100644 index 0000000000..17b569cd77 --- /dev/null +++ b/src/lib/hooks/useMergedRefs.js @@ -0,0 +1,40 @@ +import * as React from 'react' + +/** + * Assigns a value to a React ref. + * + * @param {React.Ref} ref + * @param {HTMLElement} value + */ +export function setRef(ref, value) { + if (typeof ref === 'function') { + ref(value) + } else if (ref) { + // eslint-disable-next-line no-param-reassign + ref.current = value + } +} + +/** + * React hook to merge multiple React refs (either MutableRefObjects or ref callbacks) into a single ref callback that + * updates all provided refs. + * + * @param {React.Ref} refA + * @param {React.Ref} refB + * + * @return {React.Ref} A function with an attached "current" prop, so that it can be treated like a React.RefObject. + */ +export default function useMergedRefs(refA, refB) { + const mergedCallback = React.useCallback( + (value) => { + // Update the "current" prop hanging on the function. + mergedCallback.current = value + + setRef(refA, value) + setRef(refB, value) + }, + [refA, refB], + ) + + return mergedCallback +} diff --git a/src/lib/hooks/usePrevious.js b/src/lib/hooks/usePrevious.js new file mode 100644 index 0000000000..0178735c75 --- /dev/null +++ b/src/lib/hooks/usePrevious.js @@ -0,0 +1,18 @@ +import * as React from 'react' + +/** + * Hook keeping track of a given value from a previous execution of the component the Hook is used in. + * + * @see https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state + */ +function usePrevious(value) { + const ref = React.useRef() + + React.useEffect(() => { + ref.current = value + }) + + return ref.current +} + +export default usePrevious diff --git a/src/lib/index.js b/src/lib/index.js index 808896b7e9..9325384369 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -35,9 +35,9 @@ export createPaginationItems from './createPaginationItems' export * as SUI from './SUI' export { numberToWordMap, numberToWord } from './numberToWord' -export normalizeOffset from './normalizeOffset' export normalizeTransitionDuration from './normalizeTransitionDuration' export objectDiff from './objectDiff' +export isRefObject from './isRefObject' // Heads up! We import/export for this module to safely remove it with "babel-plugin-filter-imports" export { makeDebugger } @@ -46,4 +46,10 @@ export { makeDebugger } // Hooks // +export useAutoControlledValue from './hooks/useAutoControlledValue' export useClassNamesOnNode from './hooks/useClassNamesOnNode' +export useEventCallback from './hooks/useEventCallback' +export useForceUpdate from './hooks/useForceUpdate' +export useIsomorphicLayoutEffect from './hooks/useIsomorphicLayoutEffect' +export useMergedRefs, { setRef } from './hooks/useMergedRefs' +export usePrevious from './hooks/usePrevious' diff --git a/src/lib/isRefObject.js b/src/lib/isRefObject.js new file mode 100644 index 0000000000..c026162eff --- /dev/null +++ b/src/lib/isRefObject.js @@ -0,0 +1,6 @@ +/** Checks that the passed object is a valid React ref object. */ +export default function isRefObject(ref) { + // https://github.com/facebook/react/blob/v16.8.2/packages/react-reconciler/src/ReactFiberCommitWork.js#L665 + // eslint-disable-next-line no-prototype-builtins + return ref !== null && typeof ref === 'object' && ref.hasOwnProperty('current') +} diff --git a/src/lib/normalizeOffset.js b/src/lib/normalizeOffset.js deleted file mode 100644 index 97be40480f..0000000000 --- a/src/lib/normalizeOffset.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Normalizes the offset value. - * @param {number|array} value The value to normalize. - * @returns {number} - */ -export default (value) => - typeof value === 'number' || typeof value === 'string' ? [value, value] : value diff --git a/src/modules/Accordion/Accordion.js b/src/modules/Accordion/Accordion.js index 33058ab169..4d76ecc440 100644 --- a/src/modules/Accordion/Accordion.js +++ b/src/modules/Accordion/Accordion.js @@ -11,7 +11,7 @@ import AccordionTitle from './AccordionTitle' /** * An accordion allows users to toggle the display of sections of content. */ -function Accordion(props) { +const Accordion = React.forwardRef(function (props, ref) { const { className, fluid, inverted, styled } = props const classes = cx( @@ -23,9 +23,11 @@ function Accordion(props) { ) const rest = getUnhandledProps(Accordion, props) - return -} + // TODO: extract behavior into useAccordion() hook instead of "AccordionAccordion" component + return +}) +Accordion.displayName = 'Accordion' Accordion.propTypes = { /** Additional classes. */ className: PropTypes.string, diff --git a/src/modules/Accordion/AccordionAccordion.js b/src/modules/Accordion/AccordionAccordion.js index ca2dbfbb6e..8b6227d7f5 100644 --- a/src/modules/Accordion/AccordionAccordion.js +++ b/src/modules/Accordion/AccordionAccordion.js @@ -4,97 +4,99 @@ import PropTypes from 'prop-types' import React from 'react' import { - ModernAutoControlledComponent as Component, childrenUtils, createShorthandFactory, customPropTypes, getElementType, getUnhandledProps, + useAutoControlledValue, + useEventCallback, } from '../../lib' import AccordionPanel from './AccordionPanel' -const warnIfPropsAreInvalid = (props, state) => { - const { exclusive } = props - const { activeIndex } = state - - /* eslint-disable no-console */ - if (exclusive && typeof activeIndex !== 'number') { - console.error('`activeIndex` must be a number if `exclusive` is true') - } else if (!exclusive && !_.isArray(activeIndex)) { - console.error('`activeIndex` must be an array if `exclusive` is false') - } - /* eslint-enable no-console */ +/** + * @param {Boolean} exclusive + * @param {Number} activeIndex + * @param {Number} itemIndex + */ +function isIndexActive(exclusive, activeIndex, itemIndex) { + return exclusive ? activeIndex === itemIndex : _.includes(activeIndex, itemIndex) } /** - * An Accordion can contain sub-accordions. + * @param {Boolean} exclusive + * @param {Number} activeIndex + * @param {Number} itemIndex */ -export default class AccordionAccordion extends Component { - getInitialAutoControlledState({ exclusive }) { - return { activeIndex: exclusive ? -1 : [] } - } - - componentDidMount() { - if (process.env.NODE_ENV !== 'production') { - warnIfPropsAreInvalid(this.props, this.state) - } +function computeNewIndex(exclusive, activeIndex, itemIndex) { + if (exclusive) { + return itemIndex === activeIndex ? -1 : itemIndex } - componentDidUpdate() { - if (process.env.NODE_ENV !== 'production') { - warnIfPropsAreInvalid(this.props, this.state) - } + // check to see if index is in array, and remove it, if not then add it + if (_.includes(activeIndex, itemIndex)) { + return _.without(activeIndex, itemIndex) } - computeNewIndex = (index) => { - const { exclusive } = this.props - const { activeIndex } = this.state - - if (exclusive) return index === activeIndex ? -1 : index - - // check to see if index is in array, and remove it, if not then add it - return _.includes(activeIndex, index) ? _.without(activeIndex, index) : [...activeIndex, index] - } + return [...activeIndex, itemIndex] +} - handleTitleClick = (e, titleProps) => { +/** + * An Accordion can contain sub-accordions. + */ +const AccordionAccordion = React.forwardRef(function (props, ref) { + const { className, children, exclusive, panels } = props + const [activeIndex, setActiveIndex] = useAutoControlledValue({ + state: props.activeIndex, + defaultState: props.defaultActiveIndex, + initialState: () => (exclusive ? -1 : []), + }) + + const classes = cx('accordion', className) + const rest = getUnhandledProps(AccordionAccordion, props) + const ElementType = getElementType(AccordionAccordion, props) + + const handleTitleClick = useEventCallback((e, titleProps) => { const { index } = titleProps - this.setState({ activeIndex: this.computeNewIndex(index) }) - _.invoke(this.props, 'onTitleClick', e, titleProps) + setActiveIndex(computeNewIndex(exclusive, activeIndex, index)) + _.invoke(props, 'onTitleClick', e, titleProps) + }) + + if (process.env.NODE_ENV !== 'production') { + React.useEffect(() => { + /* eslint-disable no-console */ + if (exclusive && typeof activeIndex !== 'number') { + console.error('`activeIndex` must be a number if `exclusive` is true') + } else if (!exclusive && !_.isArray(activeIndex)) { + console.error('`activeIndex` must be an array if `exclusive` is false') + } + /* eslint-enable no-console */ + }, [exclusive, activeIndex]) } - isIndexActive = (index) => { - const { exclusive } = this.props - const { activeIndex } = this.state - - return exclusive ? activeIndex === index : _.includes(activeIndex, index) - } + return ( + + {childrenUtils.isNil(children) + ? _.map(panels, (panel, index) => + AccordionPanel.create(panel, { + defaultProps: { + active: isIndexActive(exclusive, activeIndex, index), + index, + onTitleClick: handleTitleClick, + }, + }), + ) + : children} + + ) +}) - render() { - const { className, children, panels } = this.props - - const classes = cx('accordion', className) - const rest = getUnhandledProps(AccordionAccordion, this.props) - const ElementType = getElementType(AccordionAccordion, this.props) - - return ( - - {childrenUtils.isNil(children) - ? _.map(panels, (panel, index) => - AccordionPanel.create(panel, { - defaultProps: { - active: this.isIndexActive(index), - index, - onTitleClick: this.handleTitleClick, - }, - }), - ) - : children} - - ) - } +AccordionAccordion.defaultProps = { + exclusive: true, } +AccordionAccordion.displayName = 'AccordionAccordion' AccordionAccordion.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -140,10 +142,6 @@ AccordionAccordion.propTypes = { ]), } -AccordionAccordion.defaultProps = { - exclusive: true, -} - -AccordionAccordion.autoControlledProps = ['activeIndex'] - AccordionAccordion.create = createShorthandFactory(AccordionAccordion, (content) => ({ content })) + +export default AccordionAccordion diff --git a/src/modules/Accordion/AccordionContent.js b/src/modules/Accordion/AccordionContent.js index eb9af2d63e..9fae433ee0 100644 --- a/src/modules/Accordion/AccordionContent.js +++ b/src/modules/Accordion/AccordionContent.js @@ -14,19 +14,21 @@ import { /** * A content sub-component for Accordion component. */ -function AccordionContent(props) { +const AccordionContent = React.forwardRef(function (props, ref) { const { active, children, className, content } = props + const classes = cx('content', useKeyOnly(active, 'active'), className) const rest = getUnhandledProps(AccordionContent, props) const ElementType = getElementType(AccordionContent, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +AccordionContent.displayName = 'AccordionContent' AccordionContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/modules/Accordion/AccordionTitle.js b/src/modules/Accordion/AccordionTitle.js index 5372df666d..f9c7ef7fde 100644 --- a/src/modules/Accordion/AccordionTitle.js +++ b/src/modules/Accordion/AccordionTitle.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { childrenUtils, @@ -10,40 +10,42 @@ import { getElementType, getUnhandledProps, useKeyOnly, + useEventCallback, } from '../../lib' import Icon from '../../elements/Icon' /** * A title sub-component for Accordion component. */ -export default class AccordionTitle extends Component { - handleClick = (e) => _.invoke(this.props, 'onClick', e, this.props) +const AccordionTitle = React.forwardRef(function (props, ref) { + const { active, children, className, content, icon } = props - render() { - const { active, children, className, content, icon } = this.props + const classes = cx(useKeyOnly(active, 'active'), 'title', className) + const rest = getUnhandledProps(AccordionTitle, props) + const ElementType = getElementType(AccordionTitle, props) + const iconValue = _.isNil(icon) ? 'dropdown' : icon - const classes = cx(useKeyOnly(active, 'active'), 'title', className) - const rest = getUnhandledProps(AccordionTitle, this.props) - const ElementType = getElementType(AccordionTitle, this.props) - const iconValue = _.isNil(icon) ? 'dropdown' : icon - - if (!childrenUtils.isNil(children)) { - return ( - - {children} - - ) - } + const handleClick = useEventCallback((e) => { + _.invoke(props, 'onClick', e, props) + }) + if (!childrenUtils.isNil(children)) { return ( - - {Icon.create(iconValue, { autoGenerateKey: false })} - {content} + + {children} ) } -} + return ( + + {Icon.create(iconValue, { autoGenerateKey: false })} + {content} + + ) +}) + +AccordionTitle.displayName = 'AccordionTitle' AccordionTitle.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -75,3 +77,5 @@ AccordionTitle.propTypes = { onClick: PropTypes.func, } AccordionTitle.create = createShorthandFactory(AccordionTitle, (content) => ({ content })) + +export default AccordionTitle diff --git a/src/modules/Checkbox/Checkbox.js b/src/modules/Checkbox/Checkbox.js index bd4e02f10f..00eeeb80a6 100644 --- a/src/modules/Checkbox/Checkbox.js +++ b/src/modules/Checkbox/Checkbox.js @@ -1,11 +1,9 @@ -import { Ref } from '@fluentui/react-component-ref' import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { createRef } from 'react' +import React from 'react' import { - ModernAutoControlledComponent as Component, createHTMLLabel, customPropTypes, getElementType, @@ -14,6 +12,9 @@ import { makeDebugger, partitionHTMLProps, useKeyOnly, + useAutoControlledValue, + useMergedRefs, + useIsomorphicLayoutEffect, } from '../../lib' const debug = makeDebugger('checkbox') @@ -23,39 +24,92 @@ const debug = makeDebugger('checkbox') * @see Form * @see Radio */ -export default class Checkbox extends Component { - inputRef = createRef() - labelRef = createRef() +const Checkbox = React.forwardRef(function (props, ref) { + const { + className, + disabled, + label, + id, + name, + radio, + readOnly, + slider, + tabIndex, + toggle, + type, + value, + } = props + + const [checked, setChecked] = useAutoControlledValue({ + state: props.checked, + defaultState: props.defaultChecked, + initialState: false, + }) + const [indeterminate, setIndeterminate] = useAutoControlledValue({ + state: props.indeterminate, + defaultState: props.defaultIndeterminate, + initialState: false, + }) + + const inputRef = useMergedRefs(React.useRef(), ref) + const labelRef = React.useRef() + + const isClickFromMouse = React.useRef() + + // ---------------------------------------- + // Effects + // ---------------------------------------- + + useIsomorphicLayoutEffect(() => { + // Note: You can't directly set the indeterminate prop on the input, so we + // need to maintain a ref to the input and set it manually whenever the + // component updates. + if (inputRef.current) { + inputRef.current.indeterminate = !!indeterminate + } + }) - componentDidMount() { - this.setIndeterminate() - } + // ---------------------------------------- + // Helpers + // ---------------------------------------- - componentDidUpdate() { - this.setIndeterminate() + const canToggle = () => { + return !disabled && !readOnly && !(radio && checked) } - canToggle = () => { - const { disabled, radio, readOnly } = this.props - const { checked } = this.state + const computeTabIndex = () => { + if (!_.isNil(tabIndex)) { + return tabIndex + } - return !disabled && !readOnly && !(radio && checked) + return disabled ? -1 : 0 } - computeTabIndex = () => { - const { disabled, tabIndex } = this.props + // ---------------------------------------- + // Handlers + // ---------------------------------------- - if (!_.isNil(tabIndex)) return tabIndex - return disabled ? -1 : 0 + const handleChange = (e) => { + if (!canToggle()) { + return + } + + debug('handleChange()', _.get(e, 'target.tagName')) + + _.invoke(props, 'onChange', e, { + ...props, + checked: !checked, + indeterminate: false, + }) + setChecked(!checked) + setIndeterminate(false) } - handleClick = (e) => { + const handleClick = (e) => { debug('handleClick()', _.get(e, 'target.tagName')) - const { id } = this.props - const { checked, indeterminate } = this.state - const isInputClick = _.invoke(this.inputRef.current, 'contains', e.target) - const isLabelClick = _.invoke(this.labelRef.current, 'contains', e.target) + const isInputClick = _.invoke(inputRef.current, 'contains', e.target) + const isLabelClick = _.invoke(labelRef.current, 'contains', e.target) const isRootClick = !isLabelClick && !isInputClick const hasId = !_.isNil(id) @@ -63,23 +117,23 @@ export default class Checkbox extends Component { // https://github.com/Semantic-Org/Semantic-UI-React/pull/3351 if (!isLabelClickAndForwardedToInput) { - _.invoke(this.props, 'onClick', e, { - ...this.props, + _.invoke(props, 'onClick', e, { + ...props, checked: !checked, indeterminate: !!indeterminate, }) } - if (this.isClickFromMouse) { - this.isClickFromMouse = false + if (isClickFromMouse.current) { + isClickFromMouse.current = false if (isLabelClick && !hasId) { - this.handleChange(e) + handleChange(e) } // Changes should be triggered for the slider variation if (isRootClick) { - this.handleChange(e) + handleChange(e) } if (isLabelClick && hasId) { @@ -90,32 +144,17 @@ export default class Checkbox extends Component { } } - handleChange = (e) => { - const { checked } = this.state - - if (!this.canToggle()) return - debug('handleChange()', _.get(e, 'target.tagName')) - - _.invoke(this.props, 'onChange', e, { - ...this.props, - checked: !checked, - indeterminate: false, - }) - this.setState({ checked: !checked, indeterminate: false }) - } - - handleMouseDown = (e) => { + const handleMouseDown = (e) => { debug('handleMouseDown()') - const { checked, indeterminate } = this.state - _.invoke(this.props, 'onMouseDown', e, { - ...this.props, + _.invoke(props, 'onMouseDown', e, { + ...props, checked: !!checked, indeterminate: !!indeterminate, }) if (!e.defaultPrevented) { - _.invoke(this.inputRef.current, 'focus') + _.invoke(inputRef.current, 'focus') } // Heads up! @@ -123,98 +162,75 @@ export default class Checkbox extends Component { e.preventDefault() } - handleMouseUp = (e) => { + const handleMouseUp = (e) => { debug('handleMouseUp()') - const { checked, indeterminate } = this.state - this.isClickFromMouse = true - _.invoke(this.props, 'onMouseUp', e, { - ...this.props, + isClickFromMouse.current = true + _.invoke(props, 'onMouseUp', e, { + ...props, checked: !!checked, indeterminate: !!indeterminate, }) } - // Note: You can't directly set the indeterminate prop on the input, so we - // need to maintain a ref to the input and set it manually whenever the - // component updates. - setIndeterminate = () => { - const { indeterminate } = this.state - - _.set(this.inputRef, 'current.indeterminate', !!indeterminate) - } - - render() { - const { - className, - disabled, - label, - id, - name, - radio, - readOnly, - slider, - toggle, - type, - value, - } = this.props - const { checked, indeterminate } = this.state - - const classes = cx( - 'ui', - useKeyOnly(checked, 'checked'), - useKeyOnly(disabled, 'disabled'), - useKeyOnly(indeterminate, 'indeterminate'), - // auto apply fitted class to compact white space when there is no label - // https://semantic-ui.com/modules/checkbox.html#fitted - useKeyOnly(_.isNil(label), 'fitted'), - useKeyOnly(radio, 'radio'), - useKeyOnly(readOnly, 'read-only'), - useKeyOnly(slider, 'slider'), - useKeyOnly(toggle, 'toggle'), - 'checkbox', - className, - ) - const unhandled = getUnhandledProps(Checkbox, this.props) - const ElementType = getElementType(Checkbox, this.props) - const [htmlInputProps, rest] = partitionHTMLProps(unhandled, { htmlProps: htmlInputAttrs }) - - // Heads Up! - // Do not remove empty labels, they are required by SUI CSS - const labelElement = createHTMLLabel(label, { - defaultProps: { htmlFor: id }, - autoGenerateKey: false, - }) ||
, ] -export default class SearchResult extends Component { - handleClick = (e) => { - const { onClick } = this.props +const SearchResult = React.forwardRef(function (props, ref) { + const { active, className, renderer } = props - if (onClick) onClick(e, this.props) + const handleClick = (e) => { + _.invoke(props, 'onClick', e, props) } - render() { - const { active, className, renderer } = this.props - - const classes = cx(useKeyOnly(active, 'active'), 'result', className) - const rest = getUnhandledProps(SearchResult, this.props) - const ElementType = getElementType(SearchResult, this.props) - - // Note: You technically only need the 'content' wrapper when there's an - // image. However, optionally wrapping it makes this function a lot more - // complicated and harder to read. Since always wrapping it doesn't affect - // the style in any way let's just do that. - return ( - - {renderer(this.props)} - - ) - } -} - + const classes = cx(useKeyOnly(active, 'active'), 'result', className) + const rest = getUnhandledProps(SearchResult, props) + const ElementType = getElementType(SearchResult, props) + + // Note: You technically only need the 'content' wrapper when there's an + // image. However, optionally wrapping it makes this function a lot more + // complicated and harder to read. Since always wrapping it doesn't affect + // the style in any way let's just do that. + return ( + + {renderer(props)} + + ) +}) + +SearchResult.displayName = 'SearchResult' SearchResult.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -104,3 +102,5 @@ SearchResult.propTypes = { SearchResult.defaultProps = { renderer: defaultRenderer, } + +export default SearchResult diff --git a/src/modules/Search/SearchResults.js b/src/modules/Search/SearchResults.js index 1d277d4f2b..dc39226950 100644 --- a/src/modules/Search/SearchResults.js +++ b/src/modules/Search/SearchResults.js @@ -4,19 +4,20 @@ import React from 'react' import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } from '../../lib' -function SearchResults(props) { +const SearchResults = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('results transition', className) const rest = getUnhandledProps(SearchResults, props) const ElementType = getElementType(SearchResults, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +SearchResults.displayName = 'SearchResults' SearchResults.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/modules/Sidebar/Sidebar.js b/src/modules/Sidebar/Sidebar.js index fbe5c0a1e3..764c16178e 100644 --- a/src/modules/Sidebar/Sidebar.js +++ b/src/modules/Sidebar/Sidebar.js @@ -1,9 +1,8 @@ import { EventListener, documentRef } from '@fluentui/react-component-event-listener' -import { Ref, isRefObject } from '@fluentui/react-component-ref' import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component, createRef } from 'react' +import React from 'react' import { childrenUtils, @@ -11,118 +10,118 @@ import { doesNodeContainClick, getUnhandledProps, getElementType, + isRefObject, useKeyOnly, + useIsomorphicLayoutEffect, + useEventCallback, + useForceUpdate, + useMergedRefs, + usePrevious, } from '../../lib' import SidebarPushable from './SidebarPushable' import SidebarPusher from './SidebarPusher' /** - * A sidebar hides additional content beside a page. + * We use `animationTick` to understand when an animation should be scheduled. + * + * @param {Boolean} visible */ -class Sidebar extends Component { - ref = createRef() +function useAnimationTick(visible) { + const previousVisible = usePrevious(visible) + const tickIncrement = !!visible === !!previousVisible ? 0 : 1 - constructor(props) { - super(props) + const animationTick = React.useRef(0) + const forceUpdate = useForceUpdate() - this.state = { - animationTick: 0, - visible: props.visible, - } - } + const currentTick = animationTick.current + tickIncrement + const resetAnimationTick = React.useCallback(() => { + animationTick.current = 0 + forceUpdate() + }, []) - static getDerivedStateFromProps(props, state) { - // We use `animationTick` to understand when an animation should be scheduled - const tickIncrement = !!props.visible === !!state.visible ? 0 : 1 + React.useEffect(() => { + animationTick.current = currentTick + }) - return { - animationTick: state.animationTick + tickIncrement, - visible: props.visible, - } - } + return [currentTick, resetAnimationTick] +} - componentDidUpdate(prevProps, prevState) { - if (this.state.animationTick > prevState.animationTick) { - this.handleAnimationStart() - } - } +/** + * A sidebar hides additional content beside a page. + */ +const Sidebar = React.forwardRef((props, ref) => { + const { animation, className, children, content, direction, target, visible, width } = props - componentWillUnmount() { - clearTimeout(this.animationTimer) - } + const [animationTick, resetAnimationTick] = useAnimationTick(visible) + const elementRef = useMergedRefs(ref, React.useRef()) - handleAnimationStart = () => { - const { visible } = this.props + const animationTimer = React.useRef() + const skipNextCallback = React.useRef() + + const handleAnimationEnd = useEventCallback(() => { + const callback = visible ? 'onShow' : 'onHidden' + + resetAnimationTick() + _.invoke(props, callback, null, props) + }) + + const handleAnimationStart = useEventCallback(() => { const callback = visible ? 'onVisible' : 'onHide' - clearTimeout(this.animationTimer) - this.animationTimer = setTimeout(this.handleAnimationEnd, Sidebar.animationDuration) + clearTimeout(animationTimer.current) + animationTimer.current = setTimeout(handleAnimationEnd, Sidebar.animationDuration) - if (this.skipNextCallback) { - this.skipNextCallback = false + if (skipNextCallback.current) { + skipNextCallback.current = false return } - _.invoke(this.props, callback, null, this.props) - } - - handleAnimationEnd = () => { - const { visible } = this.props - const callback = visible ? 'onShow' : 'onHidden' - - this.setState({ animationTick: 0 }) - _.invoke(this.props, callback, null, this.props) - } + _.invoke(props, callback, null, props) + }) - handleDocumentClick = (e) => { - if (!doesNodeContainClick(this.ref.current, e)) { - this.skipNextCallback = true - _.invoke(this.props, 'onHide', e, { ...this.props, visible: false }) + const handleDocumentClick = (e) => { + if (!doesNodeContainClick(elementRef.current, e)) { + skipNextCallback.current = true + _.invoke(props, 'onHide', e, { ...props, visible: false }) } } - render() { - const { - animation, - className, - children, - content, - direction, - target, - visible, - width, - } = this.props - const { animationTick } = this.state - - const classes = cx( - 'ui', - animation, - direction, - width, - useKeyOnly(animationTick > 0, 'animating'), - useKeyOnly(visible, 'visible'), - 'sidebar', - className, - ) - const rest = getUnhandledProps(Sidebar, this.props) - const ElementType = getElementType(Sidebar, this.props) - const targetProp = isRefObject(target) ? { targetRef: target } : { target } - - return ( - <> - - - {childrenUtils.isNil(children) ? content : children} - - - {visible && ( - - )} - - ) - } -} + useIsomorphicLayoutEffect(() => { + handleAnimationStart() + }, [animationTick]) + React.useEffect(() => { + return () => { + clearTimeout(animationTimer.current) + } + }, []) + + const classes = cx( + 'ui', + animation, + direction, + width, + useKeyOnly(animationTick > 0, 'animating'), + useKeyOnly(visible, 'visible'), + 'sidebar', + className, + ) + const rest = getUnhandledProps(Sidebar, props) + const ElementType = getElementType(Sidebar, props) + const targetProp = isRefObject(target) ? { targetRef: target } : { target } + + return ( + <> + + {childrenUtils.isNil(children) ? content : children} + + + {visible && } + + ) +}) + +Sidebar.displayName = 'Sidebar' Sidebar.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -198,7 +197,6 @@ Sidebar.defaultProps = { } Sidebar.animationDuration = 500 -Sidebar.autoControlledProps = ['visible'] Sidebar.Pushable = SidebarPushable Sidebar.Pusher = SidebarPusher diff --git a/src/modules/Sidebar/SidebarPushable.js b/src/modules/Sidebar/SidebarPushable.js index 437b74943f..ab7ce6b604 100644 --- a/src/modules/Sidebar/SidebarPushable.js +++ b/src/modules/Sidebar/SidebarPushable.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A pushable sub-component for Sidebar. */ -function SidebarPushable(props) { +const SidebarPushable = React.forwardRef(function (props, ref) { const { className, children, content } = props const classes = cx('pushable', className) const rest = getUnhandledProps(SidebarPushable, props) const ElementType = getElementType(SidebarPushable, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +SidebarPushable.displayName = 'SidebarPushable' SidebarPushable.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/modules/Sidebar/SidebarPusher.js b/src/modules/Sidebar/SidebarPusher.js index 10ef660378..670e92eb92 100644 --- a/src/modules/Sidebar/SidebarPusher.js +++ b/src/modules/Sidebar/SidebarPusher.js @@ -13,7 +13,7 @@ import { /** * A pushable sub-component for Sidebar. */ -function SidebarPusher(props) { +const SidebarPusher = React.forwardRef(function (props, ref) { const { className, dimmed, children, content } = props const classes = cx('pusher', useKeyOnly(dimmed, 'dimmed'), className) @@ -21,12 +21,13 @@ function SidebarPusher(props) { const ElementType = getElementType(SidebarPusher, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +SidebarPusher.displayName = 'SidebarPusher' SidebarPusher.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/modules/Sticky/Sticky.js b/src/modules/Sticky/Sticky.js index d8b46c0bc5..ab8c821c9a 100644 --- a/src/modules/Sticky/Sticky.js +++ b/src/modules/Sticky/Sticky.js @@ -1,267 +1,274 @@ -import { isRefObject } from '@fluentui/react-component-ref' import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component, createRef } from 'react' +import React from 'react' import { customPropTypes, - eventStack, getElementType, getUnhandledProps, + isRefObject, isBrowser, + useEventCallback, + useIsomorphicLayoutEffect, } from '../../lib' /** * Sticky content stays fixed to the browser viewport while another column of content is visible on the page. */ -export default class Sticky extends Component { - state = { - active: true, - sticky: false, - } +const Sticky = React.forwardRef(function (props, ref) { + const { + active, + bottomOffset, + children, + className, + context, + offset, + scrollContext, + styleElement, + } = props + + const [sticky, setSticky] = React.useState(false) + const [bound, setBound] = React.useState() + const [bottom, setBottom] = React.useState() + const [pushing, setPushing] = React.useState() + const [top, setTop] = React.useState() + + const stickyRef = React.useRef() + const triggerRef = React.useRef() + + const triggerRect = React.useRef() + const contextRect = React.useRef() + const stickyRect = React.useRef() + + const frameId = React.useRef() + const ticking = React.useRef() - stickyRef = createRef() - triggerRef = createRef() + // ---------------------------------------- + // Helpers + // ---------------------------------------- - componentDidMount() { - if (!isBrowser()) return - const { active } = this.state + const assignRects = () => { + const contextNode = isRefObject(context) ? context.current : context || document.body - if (active) { - this.handleUpdate() - this.addListeners(this.props.scrollContext) - } + triggerRect.current = triggerRef.current.getBoundingClientRect() + contextRect.current = contextNode.getBoundingClientRect() + stickyRect.current = stickyRef.current.getBoundingClientRect() } - static getDerivedStateFromProps(props, state) { - if (state.active !== props.active && !props.active) { - return { active: props.active, sticky: false } + const computeStyle = () => { + if (!sticky) { + return styleElement } - return { active: props.active } + return { + bottom: bound ? 0 : bottom, + top: bound ? undefined : top, + width: triggerRect.current.width, + ...styleElement, + } } - componentDidUpdate(prevProps, prevState) { - if (prevState.active === this.state.active) { - if (prevProps.scrollContext !== this.props.scrollContext) { - this.removeListeners(prevProps.scrollContext) - this.addListeners(this.props.scrollContext) - } - - return - } + // Return true when the component reached the bottom of the context + const didReachContextBottom = () => + stickyRect.current.height + offset >= contextRect.current.bottom - if (this.state.active) { - this.handleUpdate() - this.addListeners(this.props.scrollContext) - return - } + // Return true when the component reached the starting point + const didReachStartingPoint = () => stickyRect.current.top <= triggerRect.current.top - this.removeListeners(prevProps.scrollContext) - } + // Return true when the top of the screen overpasses the Sticky component + const didTouchScreenTop = () => triggerRect.current.top < offset - componentWillUnmount() { - if (!isBrowser()) return - const { active } = this.state + // Return true when the bottom of the screen overpasses the Sticky component + const didTouchScreenBottom = () => contextRect.current.bottom + bottomOffset > window.innerHeight - if (active) { - this.removeListeners(this.props.scrollContext) - cancelAnimationFrame(this.frameId) - } - } + // Return true if the height of the component is higher than the window + const isOversized = () => stickyRect.current.height > window.innerHeight // ---------------------------------------- - // Events + // Stick helpers // ---------------------------------------- - addListeners = (scrollContext) => { - const scrollContextNode = isRefObject(scrollContext) ? scrollContext.current : scrollContext - - if (scrollContextNode) { - eventStack.sub('resize', this.handleUpdate, { target: scrollContextNode }) - eventStack.sub('scroll', this.handleUpdate, { target: scrollContextNode }) + // If true, the component will stick to the bottom of the screen instead of the top + const togglePushing = (value) => { + if (props.pushing) { + setPushing(value) } } - removeListeners = (scrollContext) => { - const scrollContextNode = isRefObject(scrollContext) ? scrollContext.current : scrollContext + const setSticked = (e, newBound) => { + setBound(newBound) + setSticky(true) - if (scrollContextNode) { - eventStack.unsub('resize', this.handleUpdate, { target: scrollContextNode }) - eventStack.unsub('scroll', this.handleUpdate, { target: scrollContextNode }) - } + _.invoke(props, 'onStick', e, props) } - // ---------------------------------------- - // Handlers - // ---------------------------------------- + const setUnsticked = (e, newBound) => { + setBound(newBound) + setSticky(false) - update = (e) => { - const { pushing } = this.state + _.invoke(props, 'onUnstick', e, props) + } - this.ticking = false - this.assignRects() + const stickToContextBottom = (e) => { + setSticked(e, true) + togglePushing(true) - if (pushing) { - if (this.didReachStartingPoint()) return this.stickToContextTop(e) - if (this.didTouchScreenBottom()) return this.stickToScreenBottom(e) - return this.stickToContextBottom(e) - } + _.invoke(props, 'onBottom', e, props) + } - if (this.isOversized()) { - if (this.contextRect.top > 0) return this.stickToContextTop(e) - if (this.contextRect.bottom < window.innerHeight) return this.stickToContextBottom(e) - } + const stickToContextTop = (e) => { + setUnsticked(e, false) + togglePushing(false) - if (this.didTouchScreenTop()) { - if (this.didReachContextBottom()) return this.stickToContextBottom(e) - return this.stickToScreenTop(e) - } + _.invoke(props, 'onTop', e, props) + } + + const stickToScreenBottom = (e) => { + setSticked(e, false) - return this.stickToContextTop(e) + setBottom(bottomOffset) + setTop(null) } - handleUpdate = (e) => { - if (!this.ticking) { - this.ticking = true - this.frameId = requestAnimationFrame(() => this.update(e)) - } + const stickToScreenTop = (e) => { + setSticked(e, false) + + setBottom(null) + setTop(offset) } // ---------------------------------------- - // Helpers + // Handlers // ---------------------------------------- - assignRects = () => { - const { context } = this.props - const contextNode = isRefObject(context) ? context.current : context || document.body + const update = (e) => { + ticking.current = false + assignRects() - this.triggerRect = this.triggerRef.current.getBoundingClientRect() - this.contextRect = contextNode.getBoundingClientRect() - this.stickyRect = this.stickyRef.current.getBoundingClientRect() - } + if (pushing) { + if (didReachStartingPoint()) { + stickToContextTop(e) + return + } - computeStyle() { - const { styleElement } = this.props - const { bottom, bound, sticky, top } = this.state + if (didTouchScreenBottom()) { + stickToScreenBottom(e) + return + } - if (!sticky) return styleElement - return { - bottom: bound ? 0 : bottom, - top: bound ? undefined : top, - width: this.triggerRect.width, - ...styleElement, + stickToContextBottom(e) + return } - } - - // Return true when the component reached the bottom of the context - didReachContextBottom = () => { - const { offset } = this.props - return this.stickyRect.height + offset >= this.contextRect.bottom - } + if (isOversized()) { + if (contextRect.current.top > 0) { + stickToContextTop(e) + return + } - // Return true when the component reached the starting point - didReachStartingPoint = () => this.stickyRect.top <= this.triggerRect.top + if (contextRect.current.bottom < window.innerHeight) { + stickToContextBottom(e) + return + } + } - // Return true when the top of the screen overpasses the Sticky component - didTouchScreenTop = () => this.triggerRect.top < this.props.offset + if (didTouchScreenTop()) { + if (didReachContextBottom()) { + stickToContextBottom(e) + return + } - // Return true when the bottom of the screen overpasses the Sticky component - didTouchScreenBottom = () => { - const { bottomOffset } = this.props + stickToScreenTop(e) + return + } - return this.contextRect.bottom + bottomOffset > window.innerHeight + stickToContextTop(e) } - // Return true if the height of the component is higher than the window - isOversized = () => this.stickyRect.height > window.innerHeight + const handleUpdate = useEventCallback((e) => { + if (!ticking.current) { + ticking.current = true + frameId.current = requestAnimationFrame(() => update(e)) + } + }) // ---------------------------------------- - // Stick helpers + // State control // ---------------------------------------- - // If true, the component will stick to the bottom of the screen instead of the top - pushing = (pushing) => { - const { pushing: possible } = this.props - - if (possible) this.setState({ pushing }) - } - - stick = (e, bound) => { - this.setState({ bound, sticky: true }) - _.invoke(this.props, 'onStick', e, this.props) - } - - unstick = (e, bound) => { - this.setState({ bound, sticky: false }) - _.invoke(this.props, 'onUnstick', e, this.props) - } - - stickToContextBottom = (e) => { - _.invoke(this.props, 'onBottom', e, this.props) + useIsomorphicLayoutEffect(() => { + if (!active) { + setSticky(false) + } + }, [active]) - this.stick(e, true) - this.pushing(true) - } + // ---------------------------------------- + // Effects + // ---------------------------------------- - stickToContextTop = (e) => { - _.invoke(this.props, 'onTop', e, this.props) + useIsomorphicLayoutEffect(() => { + if (active) { + handleUpdate() + } + }, [active]) - this.unstick(e, false) - this.pushing(false) - } + React.useEffect(() => { + return () => { + cancelAnimationFrame(frameId.current) + } + }, []) - stickToScreenBottom = (e) => { - const { bottomOffset: bottom } = this.props + // ---------------------------------------- + // Document events + // ---------------------------------------- - this.stick(e, false) - this.setState({ bottom, top: null }) - } + React.useEffect(() => { + const scrollContextNode = isRefObject(scrollContext) ? scrollContext.current : scrollContext - stickToScreenTop = (e) => { - const { offset: top } = this.props + if (active && scrollContextNode) { + scrollContextNode?.addEventListener('resize', handleUpdate) + scrollContextNode?.addEventListener('scroll', handleUpdate) + } - this.stick(e, false) - this.setState({ top, bottom: null }) - } + return () => { + scrollContextNode?.removeEventListener('resize', handleUpdate) + scrollContextNode?.removeEventListener('scroll', handleUpdate) + } + }, [active, scrollContext]) // ---------------------------------------- // Render // ---------------------------------------- - render() { - const { children, className } = this.props - const { bottom, bound, sticky } = this.state - const rest = getUnhandledProps(Sticky, this.props) - const ElementType = getElementType(Sticky, this.props) - - const containerClasses = cx( - sticky && 'ui', - sticky && 'stuck-container', - sticky && (bound ? 'bound-container' : 'fixed-container'), - className, - ) - const elementClasses = cx( - 'ui', - sticky && (bound ? 'bound bottom' : 'fixed'), - sticky && !bound && (bottom === null ? 'top' : 'bottom'), - 'sticky', - ) - const triggerStyles = sticky && this.stickyRect ? { height: this.stickyRect.height } : {} - - return ( - -
-
- {children} -
- - ) - } -} - + const rest = getUnhandledProps(Sticky, props) + const ElementType = getElementType(Sticky, props) + + const containerClasses = cx( + sticky && 'ui', + sticky && 'stuck-container', + sticky && (bound ? 'bound-container' : 'fixed-container'), + className, + ) + const elementClasses = cx( + 'ui', + sticky && (bound ? 'bound bottom' : 'fixed'), + sticky && !bound && (bottom === null ? 'top' : 'bottom'), + 'sticky', + ) + const triggerStyles = sticky ? { height: stickyRect.current?.height } : {} + + return ( + +
+
+ {children} +
+ + ) +}) + +Sticky.displayName = 'Sticky' Sticky.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -332,3 +339,5 @@ Sticky.defaultProps = { offset: 0, scrollContext: isBrowser() ? window : null, } + +export default Sticky diff --git a/src/modules/Tab/Tab.js b/src/modules/Tab/Tab.js index 9e2a57973f..3004f4ceda 100644 --- a/src/modules/Tab/Tab.js +++ b/src/modules/Tab/Tab.js @@ -3,10 +3,10 @@ import PropTypes from 'prop-types' import React from 'react' import { - ModernAutoControlledComponent as Component, customPropTypes, getElementType, getUnhandledProps, + useAutoControlledValue, } from '../../lib' import Grid from '../../collections/Grid/Grid' import GridColumn from '../../collections/Grid/GridColumn' @@ -18,21 +18,25 @@ import TabPane from './TabPane' * @see Menu * @see Segment */ -class Tab extends Component { - getInitialAutoControlledState() { - return { activeIndex: 0 } +const Tab = React.forwardRef(function (props, ref) { + const { grid, menu, panes, menuPosition, renderActiveOnly } = props + + const [activeIndex, setActiveIndex] = useAutoControlledValue({ + state: props.activeIndex, + defaultState: props.defaultActiveIndex, + initialState: 0, + }) + + const handleItemClick = (e, { index }) => { + _.invoke(props, 'onTabChange', e, { ...props, activeIndex: index }) + setActiveIndex(index) } - handleItemClick = (e, { index }) => { - _.invoke(this.props, 'onTabChange', e, { ...this.props, activeIndex: index }) - this.setState({ activeIndex: index }) - } - - renderItems() { - const { panes, renderActiveOnly } = this.props - const { activeIndex } = this.state + const renderItems = () => { + if (renderActiveOnly) { + return _.invoke(_.get(panes, `[${activeIndex}]`), 'render', props) + } - if (renderActiveOnly) return _.invoke(_.get(panes, `[${activeIndex}]`), 'render', this.props) return _.map(panes, ({ pane }, index) => TabPane.create(pane, { overrideProps: { @@ -42,10 +46,7 @@ class Tab extends Component { ) } - renderMenu() { - const { menu, panes, menuPosition } = this.props - const { activeIndex } = this.state - + const renderMenu = () => { if (menu.tabular === true && menuPosition === 'right') { menu.tabular = 'right' } @@ -54,55 +55,57 @@ class Tab extends Component { autoGenerateKey: false, overrideProps: { items: _.map(panes, 'menuItem'), - onItemClick: this.handleItemClick, + onItemClick: handleItemClick, activeIndex, }, }) } - renderVertical(menu) { - const { grid, menuPosition } = this.props + const renderVertical = (menuElement) => { const { paneWidth, tabWidth, ...gridProps } = grid - const position = menuPosition || (menu.props.tabular === 'right' && 'right') || 'left' + const position = menuPosition || (menuElement.props.tabular === 'right' && 'right') || 'left' return ( {position === 'left' && - GridColumn.create({ width: tabWidth, children: menu }, { autoGenerateKey: false })} + GridColumn.create({ width: tabWidth, children: menuElement }, { autoGenerateKey: false })} {GridColumn.create( { width: paneWidth, - children: this.renderItems(), + children: renderItems(), stretched: true, }, { autoGenerateKey: false }, )} {position === 'right' && - GridColumn.create({ width: tabWidth, children: menu }, { autoGenerateKey: false })} + GridColumn.create({ width: tabWidth, children: menuElement }, { autoGenerateKey: false })} ) } - render() { - const menu = this.renderMenu() - const rest = getUnhandledProps(Tab, this.props) - const ElementType = getElementType(Tab, this.props) - - if (menu.props.vertical) { - return {this.renderVertical(menu)} - } + const menuElement = renderMenu() + const rest = getUnhandledProps(Tab, props) + const ElementType = getElementType(Tab, props) + if (menuElement.props.vertical) { return ( - - {menu.props.attached !== 'bottom' && menu} - {this.renderItems()} - {menu.props.attached === 'bottom' && menu} + + {renderVertical(menuElement)} ) } -} + return ( + + {menuElement.props.attached !== 'bottom' && menuElement} + {renderItems()} + {menuElement.props.attached === 'bottom' && menuElement} + + ) +}) + +Tab.displayName = 'Tab' Tab.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/modules/Tab/TabPane.js b/src/modules/Tab/TabPane.js index 0ecd3d2e73..4551dfb497 100644 --- a/src/modules/Tab/TabPane.js +++ b/src/modules/Tab/TabPane.js @@ -15,7 +15,7 @@ import Segment from '../../elements/Segment/Segment' /** * A tab pane holds the content of a tab. */ -function TabPane(props) { +const TabPane = React.forwardRef(function (props, ref) { const { active, children, className, content, loading } = props const classes = cx(useKeyOnly(active, 'active'), useKeyOnly(loading, 'loading'), 'tab', className) @@ -23,22 +23,24 @@ function TabPane(props) { const ElementType = getElementType(TabPane, props) const calculatedDefaultProps = {} + if (ElementType === Segment) { calculatedDefaultProps.attached = 'bottom' } return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) TabPane.defaultProps = { as: Segment, active: true, } +TabPane.displayName = 'TabPane' TabPane.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/modules/Transition/Transition.js b/src/modules/Transition/Transition.js index 0cd0fb8e09..3ad3c88018 100644 --- a/src/modules/Transition/Transition.js +++ b/src/modules/Transition/Transition.js @@ -1,7 +1,7 @@ import cx from 'clsx' import _ from 'lodash' import PropTypes from 'prop-types' -import { cloneElement, Component } from 'react' +import * as React from 'react' import { makeDebugger, normalizeTransitionDuration, SUI, useKeyOnly } from '../../lib' import TransitionGroup from './TransitionGroup' @@ -29,15 +29,7 @@ const TRANSITION_STYLE_TYPE = { /** * A transition is an animation usually used to move content in or out of view. */ -export default class Transition extends Component { - /** @deprecated Static properties will be removed in v2. */ - static INITIAL = TRANSITION_STATUS_INITIAL - static ENTERED = TRANSITION_STATUS_ENTERED - static ENTERING = TRANSITION_STATUS_ENTERING - static EXITED = TRANSITION_STATUS_EXITED - static EXITING = TRANSITION_STATUS_EXITING - static UNMOUNTED = TRANSITION_STATUS_UNMOUNTED - +export default class Transition extends React.Component { static Group = TransitionGroup state = { @@ -87,7 +79,11 @@ export default class Transition extends Component { const durationType = TRANSITION_CALLBACK_TYPE[nextStatus] const durationValue = normalizeTransitionDuration(duration, durationType) - this.timeoutId = setTimeout(() => this.setState({ status: nextStatus }), durationValue) + if (durationValue === 0) { + this.setState({ status: nextStatus }) + } else { + this.timeoutId = setTimeout(() => this.setState({ status: nextStatus }), durationValue) + } } updateStatus = (prevState) => { @@ -161,15 +157,19 @@ export default class Transition extends Component { debug('render(): state', this.state) const { children } = this.props - const { status } = this.state + const { nextStatus, status } = this.state if (status === TRANSITION_STATUS_UNMOUNTED) { return null } - return cloneElement(children, { + return React.cloneElement(children, { className: this.computeClasses(), style: this.computeStyle(), + ...(process.env.NODE_ENV !== 'production' && { + 'data-test-status': status, + 'data-test-next-status': nextStatus, + }), }) } } diff --git a/src/modules/Transition/TransitionGroup.js b/src/modules/Transition/TransitionGroup.js index 4716c903ce..0a8142939e 100644 --- a/src/modules/Transition/TransitionGroup.js +++ b/src/modules/Transition/TransitionGroup.js @@ -2,64 +2,72 @@ import _ from 'lodash' import PropTypes from 'prop-types' import React from 'react' -import { getElementType, getUnhandledProps, makeDebugger, SUI } from '../../lib' +import { + getElementType, + getUnhandledProps, + makeDebugger, + SUI, + useEventCallback, + useForceUpdate, +} from '../../lib' import { getChildMapping, mergeChildMappings } from './utils/childMapping' import wrapChild from './utils/wrapChild' const debug = makeDebugger('transition_group') /** - * A Transition.Group animates children as they mount and unmount. + * Wraps all children elements with proper callbacks and props. + * + * @param {React.ReactNode} children + * @param {Stream} animation + * @param {Number|String|Object} duration + * @param {Boolean} directional + * + * @return {Object} */ -export default class TransitionGroup extends React.Component { - state = { - // Keeping a callback under the state is a hack to make it accessible under getDerivedStateFromProps() - handleOnHide: (nothing, childProps) => { - debug('handleOnHide', childProps) - const { reactKey } = childProps - - this.setState((state) => { - const children = { ...state.children } - delete children[reactKey] - - return { children } - }) - }, - } +function useWrappedChildren(children, animation, duration, directional) { + debug('wrapChildren()') - static getDerivedStateFromProps(props, state) { - debug('getDerivedStateFromProps()') - - const { animation, duration, directional } = props - const { children: prevMapping } = state - - // A short circuit for an initial render as there will be no `prevMapping` - if (typeof prevMapping === 'undefined') { - return { - children: _.mapValues(getChildMapping(props.children), (child) => - wrapChild(child, state.handleOnHide, { - animation, - duration, - directional, - }), - ), - } - } + const forceUpdate = useForceUpdate() + const previousChildren = React.useRef() + + let wrappedChildren + React.useEffect(() => { + previousChildren.current = wrappedChildren + }) - const nextMapping = getChildMapping(props.children) - const children = mergeChildMappings(prevMapping, nextMapping) + const handleChildHide = useEventCallback((nothing, childProps) => { + debug('handleOnHide', childProps) + const { reactKey } = childProps + + delete previousChildren.current[reactKey] + forceUpdate() + }) + + // A short circuit for an initial render as there will be no `prevMapping` + if (typeof previousChildren.current === 'undefined') { + wrappedChildren = _.mapValues(getChildMapping(children), (child) => + wrapChild(child, handleChildHide, { + animation, + duration, + directional, + }), + ) + } else { + const nextMapping = getChildMapping(children) + wrappedChildren = mergeChildMappings(previousChildren.current, nextMapping) - _.forEach(children, (child, key) => { - const hasPrev = _.has(prevMapping, key) - const hasNext = _.has(nextMapping, key) + _.forEach(wrappedChildren, (child, key) => { + const hasPrev = previousChildren.current[key] + const hasNext = nextMapping[key] - const { [key]: prevChild } = prevMapping + const prevChild = previousChildren.current[key] const isLeaving = !_.get(prevChild, 'props.visible') // Heads up! // An item is new (entering), it will be picked from `nextChildren`, so it should be wrapped if (hasNext && (!hasPrev || isLeaving)) { - children[key] = wrapChild(child, state.handleOnHide, { + wrappedChildren[key] = wrapChild(child, handleChildHide, { animation, duration, directional, @@ -72,7 +80,7 @@ export default class TransitionGroup extends React.Component { // An item is old (exiting), it will be picked from `prevChildren`, so it has been already // wrapped, so should be only updated if (!hasNext && hasPrev && !isLeaving) { - children[key] = React.cloneElement(prevChild, { visible: false }) + wrappedChildren[key] = React.cloneElement(prevChild, { visible: false }) return } @@ -83,7 +91,7 @@ export default class TransitionGroup extends React.Component { props: { visible, transitionOnMount }, } = prevChild - children[key] = wrapChild(child, state.handleOnHide, { + wrappedChildren[key] = wrapChild(child, handleChildHide, { animation, duration, directional, @@ -91,23 +99,36 @@ export default class TransitionGroup extends React.Component { visible, }) }) - - return { children } } - render() { - debug('render') - debug('props', this.props) - debug('state', this.state) - - const { children } = this.state - const ElementType = getElementType(TransitionGroup, this.props) - const rest = getUnhandledProps(TransitionGroup, this.props) - - return {_.values(children)} - } + return wrappedChildren } +/** + * A Transition.Group animates children as they mount and unmount. + */ +const TransitionGroup = React.forwardRef(function (props, ref) { + debug('render') + debug('props', props) + + const children = useWrappedChildren( + props.children, + props.animation, + props.duration, + props.directional, + ) + + const ElementType = getElementType(TransitionGroup, props) + const rest = getUnhandledProps(TransitionGroup, props) + + return ( + + {_.values(children)} + + ) +}) + +TransitionGroup.displayName = 'TransitionGroup' TransitionGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -137,3 +158,5 @@ TransitionGroup.defaultProps = { animation: 'fade', duration: 500, } + +export default TransitionGroup diff --git a/src/views/Advertisement/Advertisement.js b/src/views/Advertisement/Advertisement.js index 756f1a4fa9..733e20c3b2 100644 --- a/src/views/Advertisement/Advertisement.js +++ b/src/views/Advertisement/Advertisement.js @@ -13,7 +13,7 @@ import { /** * An ad displays third-party promotional content. */ -function Advertisement(props) { +const Advertisement = React.forwardRef(function (props, ref) { const { centered, children, className, content, test, unit } = props const classes = cx( @@ -28,12 +28,13 @@ function Advertisement(props) { const ElementType = getElementType(Advertisement, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +Advertisement.displayName = 'Advertisement' Advertisement.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Card/Card.js b/src/views/Card/Card.js index a414d633d3..13cefed144 100644 --- a/src/views/Card/Card.js +++ b/src/views/Card/Card.js @@ -1,6 +1,7 @@ import cx from 'clsx' +import _ from 'lodash' import PropTypes from 'prop-types' -import React, { Component } from 'react' +import React from 'react' import { childrenUtils, @@ -9,6 +10,7 @@ import { getUnhandledProps, SUI, useKeyOnly, + useEventCallback, } from '../../lib' import Image from '../../elements/Image' import CardContent from './CardContent' @@ -20,80 +22,79 @@ import CardMeta from './CardMeta' /** * A card displays site content in a manner similar to a playing card. */ -export default class Card extends Component { - handleClick = (e) => { - const { onClick } = this.props +const Card = React.forwardRef(function (props, ref) { + const { + centered, + children, + className, + color, + content, + description, + extra, + fluid, + header, + href, + image, + link, + meta, + onClick, + raised, + } = props + + const classes = cx( + 'ui', + color, + useKeyOnly(centered, 'centered'), + useKeyOnly(fluid, 'fluid'), + useKeyOnly(link, 'link'), + useKeyOnly(raised, 'raised'), + 'card', + className, + ) + const rest = getUnhandledProps(Card, props) + const ElementType = getElementType(Card, props, () => { + if (onClick) { + return 'a' + } + }) - if (onClick) onClick(e, this.props) - } + const handleClick = useEventCallback((e) => { + _.invoke(props, 'onClick', e, props) + }) - render() { - const { - centered, - children, - className, - color, - content, - description, - extra, - fluid, - header, - href, - image, - link, - meta, - onClick, - raised, - } = this.props - - const classes = cx( - 'ui', - color, - useKeyOnly(centered, 'centered'), - useKeyOnly(fluid, 'fluid'), - useKeyOnly(link, 'link'), - useKeyOnly(raised, 'raised'), - 'card', - className, + if (!childrenUtils.isNil(children)) { + return ( + + {children} + ) - const rest = getUnhandledProps(Card, this.props) - const ElementType = getElementType(Card, this.props, () => { - if (onClick) return 'a' - }) - - if (!childrenUtils.isNil(children)) { - return ( - - {children} - - ) - } - if (!childrenUtils.isNil(content)) { - return ( - - {content} - - ) - } - + } + if (!childrenUtils.isNil(content)) { return ( - - {Image.create(image, { - autoGenerateKey: false, - defaultProps: { - ui: false, - wrapped: true, - }, - })} - {(description || header || meta) && ( - - )} - {extra && {extra}} + + {content} ) } -} + return ( + + {Image.create(image, { + autoGenerateKey: false, + defaultProps: { + ui: false, + wrapped: true, + }, + })} + {(description || header || meta) && ( + + )} + {extra && {extra}} + + ) +}) + +Card.displayName = 'Card' Card.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, @@ -155,3 +156,5 @@ Card.Description = CardDescription Card.Group = CardGroup Card.Header = CardHeader Card.Meta = CardMeta + +export default Card diff --git a/src/views/Card/CardContent.js b/src/views/Card/CardContent.js index d293948293..475ca2e719 100644 --- a/src/views/Card/CardContent.js +++ b/src/views/Card/CardContent.js @@ -20,7 +20,7 @@ import CardMeta from './CardMeta' /** * A card can contain blocks of content or extra content meant to be formatted separately from the main content. */ -function CardContent(props) { +const CardContent = React.forwardRef(function (props, ref) { const { children, className, content, description, extra, header, meta, textAlign } = props const classes = cx(useKeyOnly(extra, 'extra'), useTextAlignProp(textAlign), 'content', className) @@ -29,21 +29,21 @@ function CardContent(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } if (!childrenUtils.isNil(content)) { return ( - + {content} ) } return ( - + {createShorthand(CardHeader, (val) => ({ content: val }), header, { autoGenerateKey: false })} {createShorthand(CardMeta, (val) => ({ content: val }), meta, { autoGenerateKey: false })} {createShorthand(CardDescription, (val) => ({ content: val }), description, { @@ -51,8 +51,9 @@ function CardContent(props) { })} ) -} +}) +CardContent.displayName = 'CardContent' CardContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Card/CardDescription.js b/src/views/Card/CardDescription.js index 1edc971632..49352e62f7 100644 --- a/src/views/Card/CardDescription.js +++ b/src/views/Card/CardDescription.js @@ -15,19 +15,20 @@ import { /** * A card can contain a description with one or more paragraphs. */ -function CardDescription(props) { +const CardDescription = React.forwardRef(function (props, ref) { const { children, className, content, textAlign } = props const classes = cx(useTextAlignProp(textAlign), 'description', className) const rest = getUnhandledProps(CardDescription, props) const ElementType = getElementType(CardDescription, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +CardDescription.displayName = 'CardDescription' CardDescription.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Card/CardGroup.js b/src/views/Card/CardGroup.js index 9402b13da0..276aa27056 100644 --- a/src/views/Card/CardGroup.js +++ b/src/views/Card/CardGroup.js @@ -18,7 +18,7 @@ import Card from './Card' /** * A group of cards. */ -function CardGroup(props) { +const CardGroup = React.forwardRef(function (props, ref) { const { centered, children, @@ -46,14 +46,14 @@ function CardGroup(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } if (!childrenUtils.isNil(content)) { return ( - + {content} ) @@ -65,12 +65,13 @@ function CardGroup(props) { }) return ( - + {itemsJSX} ) -} +}) +CardGroup.displayName = 'CardGroup' CardGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Card/CardHeader.js b/src/views/Card/CardHeader.js index abf740da70..9dd0e16d31 100644 --- a/src/views/Card/CardHeader.js +++ b/src/views/Card/CardHeader.js @@ -15,19 +15,20 @@ import { /** * A card can contain a header. */ -function CardHeader(props) { +const CardHeader = React.forwardRef(function (props, ref) { const { children, className, content, textAlign } = props const classes = cx(useTextAlignProp(textAlign), 'header', className) const rest = getUnhandledProps(CardHeader, props) const ElementType = getElementType(CardHeader, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +CardHeader.displayName = 'CardHeader' CardHeader.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Card/CardMeta.js b/src/views/Card/CardMeta.js index 20b0ebd9bd..ac1377d220 100644 --- a/src/views/Card/CardMeta.js +++ b/src/views/Card/CardMeta.js @@ -15,19 +15,20 @@ import { /** * A card can contain content metadata. */ -function CardMeta(props) { +const CardMeta = React.forwardRef(function (props, ref) { const { children, className, content, textAlign } = props const classes = cx(useTextAlignProp(textAlign), 'meta', className) const rest = getUnhandledProps(CardMeta, props) const ElementType = getElementType(CardMeta, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +CardMeta.displayName = 'CardMeta' CardMeta.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Comment/Comment.js b/src/views/Comment/Comment.js index d981accf5a..bf136fbed0 100644 --- a/src/views/Comment/Comment.js +++ b/src/views/Comment/Comment.js @@ -21,7 +21,7 @@ import CommentText from './CommentText' /** * A comment displays user feedback to site content. */ -function Comment(props) { +const Comment = React.forwardRef(function (props, ref) { const { className, children, collapsed, content } = props const classes = cx(useKeyOnly(collapsed, 'collapsed'), 'comment', className) @@ -29,12 +29,13 @@ function Comment(props) { const ElementType = getElementType(Comment, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +Comment.displayName = 'Comment' Comment.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Comment/CommentAction.js b/src/views/Comment/CommentAction.js index bb447a4e87..3dde605c83 100644 --- a/src/views/Comment/CommentAction.js +++ b/src/views/Comment/CommentAction.js @@ -13,7 +13,7 @@ import { /** * A comment can contain an action. */ -function CommentAction(props) { +const CommentAction = React.forwardRef(function (props, ref) { const { active, className, children, content } = props const classes = cx(useKeyOnly(active, 'active'), className) @@ -21,16 +21,17 @@ function CommentAction(props) { const ElementType = getElementType(CommentAction, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) CommentAction.defaultProps = { as: 'a', } +CommentAction.displayName = 'CommentAction' CommentAction.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Comment/CommentActions.js b/src/views/Comment/CommentActions.js index 7f8651fa23..8286ae7005 100644 --- a/src/views/Comment/CommentActions.js +++ b/src/views/Comment/CommentActions.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A comment can contain an list of actions a user may perform related to this comment. */ -function CommentActions(props) { +const CommentActions = React.forwardRef(function (props, ref) { const { className, children, content } = props const classes = cx('actions', className) const rest = getUnhandledProps(CommentActions, props) const ElementType = getElementType(CommentActions, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +CommentActions.displayName = 'CommentActions' CommentActions.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Comment/CommentAuthor.js b/src/views/Comment/CommentAuthor.js index b5285101a7..be3e412ac7 100644 --- a/src/views/Comment/CommentAuthor.js +++ b/src/views/Comment/CommentAuthor.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A comment can contain an author. */ -function CommentAuthor(props) { +const CommentAuthor = React.forwardRef(function (props, ref) { const { className, children, content } = props const classes = cx('author', className) const rest = getUnhandledProps(CommentAuthor, props) const ElementType = getElementType(CommentAuthor, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +CommentAuthor.displayName = 'CommentAuthor' CommentAuthor.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Comment/CommentAvatar.js b/src/views/Comment/CommentAvatar.js index ba14086893..c709321080 100644 --- a/src/views/Comment/CommentAvatar.js +++ b/src/views/Comment/CommentAvatar.js @@ -13,7 +13,7 @@ import { /** * A comment can contain an image or avatar. */ -function CommentAvatar(props) { +const CommentAvatar = React.forwardRef(function (props, ref) { const { className, src } = props const classes = cx('avatar', className) @@ -22,12 +22,13 @@ function CommentAvatar(props) { const ElementType = getElementType(CommentAvatar, props) return ( - + {createHTMLImage(src, { autoGenerateKey: false, defaultProps: imageProps })} ) -} +}) +CommentAvatar.displayName = 'CommentAvatar' CommentAvatar.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Comment/CommentContent.js b/src/views/Comment/CommentContent.js index b1e79ac813..9badf0c8ec 100644 --- a/src/views/Comment/CommentContent.js +++ b/src/views/Comment/CommentContent.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A comment can contain content. */ -function CommentContent(props) { +const CommentContent = React.forwardRef(function (props, ref) { const { className, children, content } = props const classes = cx(className, 'content') const rest = getUnhandledProps(CommentContent, props) const ElementType = getElementType(CommentContent, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +CommentContent.displayName = 'CommentContent' CommentContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Comment/CommentGroup.js b/src/views/Comment/CommentGroup.js index 9539b8ebd9..5b18238dea 100644 --- a/src/views/Comment/CommentGroup.js +++ b/src/views/Comment/CommentGroup.js @@ -15,7 +15,7 @@ import { /** * Comments can be grouped. */ -function CommentGroup(props) { +const CommentGroup = React.forwardRef(function (props, ref) { const { className, children, collapsed, content, minimal, size, threaded } = props const classes = cx( @@ -31,12 +31,13 @@ function CommentGroup(props) { const ElementType = getElementType(CommentGroup, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +CommentGroup.displayName = 'CommentGroup' CommentGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Comment/CommentMetadata.js b/src/views/Comment/CommentMetadata.js index feabb8b2ef..f06970322e 100644 --- a/src/views/Comment/CommentMetadata.js +++ b/src/views/Comment/CommentMetadata.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A comment can contain metadata about the comment, an arbitrary amount of metadata may be defined. */ -function CommentMetadata(props) { +const CommentMetadata = React.forwardRef(function (props, ref) { const { className, children, content } = props const classes = cx('metadata', className) const rest = getUnhandledProps(CommentMetadata, props) const ElementType = getElementType(CommentMetadata, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +CommentMetadata.displayName = 'CommentMetadata' CommentMetadata.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Comment/CommentText.js b/src/views/Comment/CommentText.js index 9b1e8b5f4c..45392353bf 100644 --- a/src/views/Comment/CommentText.js +++ b/src/views/Comment/CommentText.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A comment can contain text. */ -function CommentText(props) { +const CommentText = React.forwardRef(function (props, ref) { const { className, children, content } = props const classes = cx(className, 'text') const rest = getUnhandledProps(CommentText, props) const ElementType = getElementType(CommentText, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +CommentText.displayName = 'CommentText' CommentText.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/Feed.js b/src/views/Feed/Feed.js index f14990f08e..725db44d14 100644 --- a/src/views/Feed/Feed.js +++ b/src/views/Feed/Feed.js @@ -17,7 +17,7 @@ import FeedUser from './FeedUser' /** * A feed presents user activity chronologically. */ -function Feed(props) { +const Feed = React.forwardRef(function (props, ref) { const { children, className, events, size } = props const classes = cx('ui', size, 'feed', className) @@ -26,7 +26,7 @@ function Feed(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) @@ -36,16 +36,18 @@ function Feed(props) { const { childKey, date, meta, summary, ...eventData } = eventProps const finalKey = childKey ?? [date, meta, summary].join('-') + // TODO: use .create() factory return }) return ( - + {eventElements} ) -} +}) +Feed.displayName = 'Feed' Feed.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/FeedContent.js b/src/views/Feed/FeedContent.js index 7f0c574f78..1ee33e2eb8 100644 --- a/src/views/Feed/FeedContent.js +++ b/src/views/Feed/FeedContent.js @@ -14,7 +14,7 @@ import FeedExtra from './FeedExtra' import FeedMeta from './FeedMeta' import FeedSummary from './FeedSummary' -function FeedContent(props) { +const FeedContent = React.forwardRef(function (props, ref) { const { children, className, content, extraImages, extraText, date, meta, summary } = props const classes = cx('content', className) @@ -23,14 +23,14 @@ function FeedContent(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {createShorthand(FeedDate, (val) => ({ content: val }), date, { autoGenerateKey: false })} {createShorthand(FeedSummary, (val) => ({ content: val }), summary, { autoGenerateKey: false, @@ -45,8 +45,9 @@ function FeedContent(props) { {createShorthand(FeedMeta, (val) => ({ content: val }), meta, { autoGenerateKey: false })} ) -} +}) +FeedContent.displayName = 'FeedContent' FeedContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/FeedDate.js b/src/views/Feed/FeedDate.js index 48c3e781a1..628f73aabb 100644 --- a/src/views/Feed/FeedDate.js +++ b/src/views/Feed/FeedDate.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * An event or an event summary can contain a date. */ -function FeedDate(props) { +const FeedDate = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('date', className) const rest = getUnhandledProps(FeedDate, props) const ElementType = getElementType(FeedDate, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +FeedDate.displayName = 'FeedDate' FeedDate.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/FeedEvent.js b/src/views/Feed/FeedEvent.js index 64a326b51c..31867b3b73 100644 --- a/src/views/Feed/FeedEvent.js +++ b/src/views/Feed/FeedEvent.js @@ -9,7 +9,7 @@ import FeedLabel from './FeedLabel' /** * A feed contains an event. */ -function FeedEvent(props) { +const FeedEvent = React.forwardRef(function (props, ref) { const { content, children, @@ -31,15 +31,16 @@ function FeedEvent(props) { const contentProps = { content, date, extraImages, extraText, meta, summary } return ( - + {createShorthand(FeedLabel, (val) => ({ icon: val }), icon, { autoGenerateKey: false })} {createShorthand(FeedLabel, (val) => ({ image: val }), image, { autoGenerateKey: false })} {hasContentProp && } {children} ) -} +}) +FeedEvent.displayName = 'FeedEvent' FeedEvent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/FeedExtra.js b/src/views/Feed/FeedExtra.js index 4592fc1661..cb5d446fe6 100644 --- a/src/views/Feed/FeedExtra.js +++ b/src/views/Feed/FeedExtra.js @@ -15,7 +15,7 @@ import { /** * A feed can contain an extra content. */ -function FeedExtra(props) { +const FeedExtra = React.forwardRef(function (props, ref) { const { children, className, content, images, text } = props const classes = cx( @@ -29,7 +29,7 @@ function FeedExtra(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) @@ -42,13 +42,14 @@ function FeedExtra(props) { }) return ( - + {content} {imageElements} ) -} +}) +FeedExtra.displayName = 'FeedExtra' FeedExtra.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/FeedLabel.js b/src/views/Feed/FeedLabel.js index 650f2bb6de..93f28bd6cd 100644 --- a/src/views/Feed/FeedLabel.js +++ b/src/views/Feed/FeedLabel.js @@ -14,7 +14,7 @@ import Icon from '../../elements/Icon' /** * An event can contain an image or icon label. */ -function FeedLabel(props) { +const FeedLabel = React.forwardRef(function (props, ref) { const { children, className, content, icon, image } = props const classes = cx('label', className) @@ -23,21 +23,22 @@ function FeedLabel(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {content} {Icon.create(icon, { autoGenerateKey: false })} {createHTMLImage(image)} ) -} +}) +FeedLabel.displayName = 'FeedLabel' FeedLabel.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/FeedLike.js b/src/views/Feed/FeedLike.js index 95dd164b61..70eca84786 100644 --- a/src/views/Feed/FeedLike.js +++ b/src/views/Feed/FeedLike.js @@ -8,7 +8,7 @@ import Icon from '../../elements/Icon' /** * A feed can contain a like element. */ -function FeedLike(props) { +const FeedLike = React.forwardRef(function (props, ref) { const { children, className, content, icon } = props const classes = cx('like', className) @@ -17,24 +17,25 @@ function FeedLike(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {Icon.create(icon, { autoGenerateKey: false })} {content} ) -} +}) FeedLike.defaultProps = { as: 'a', } +FeedLike.displayName = 'FeedLike' FeedLike.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/FeedMeta.js b/src/views/Feed/FeedMeta.js index 8282a787cb..816dbc9dba 100644 --- a/src/views/Feed/FeedMeta.js +++ b/src/views/Feed/FeedMeta.js @@ -14,7 +14,7 @@ import FeedLike from './FeedLike' /** * A feed can contain a meta. */ -function FeedMeta(props) { +const FeedMeta = React.forwardRef(function (props, ref) { const { children, className, content, like } = props const classes = cx('meta', className) @@ -23,20 +23,21 @@ function FeedMeta(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {createShorthand(FeedLike, (val) => ({ content: val }), like, { autoGenerateKey: false })} {content} ) -} +}) +FeedMeta.displayName = 'FeedMeta' FeedMeta.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/FeedSummary.js b/src/views/Feed/FeedSummary.js index d79e891a04..2e2055c7f8 100644 --- a/src/views/Feed/FeedSummary.js +++ b/src/views/Feed/FeedSummary.js @@ -15,7 +15,7 @@ import FeedUser from './FeedUser' /** * A feed can contain a summary. */ -function FeedSummary(props) { +const FeedSummary = React.forwardRef(function (props, ref) { const { children, className, content, date, user } = props const classes = cx('summary', className) @@ -24,14 +24,14 @@ function FeedSummary(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {createShorthand(FeedUser, (val) => ({ content: val }), user, { autoGenerateKey: false })} {/* Content styles require wrapping whitespace @@ -43,8 +43,9 @@ function FeedSummary(props) { {createShorthand(FeedDate, (val) => ({ content: val }), date, { autoGenerateKey: false })} ) -} +}) +FeedSummary.displayName = 'FeedSummary' FeedSummary.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Feed/FeedUser.js b/src/views/Feed/FeedUser.js index a4d90e7a74..9b7d44e55c 100644 --- a/src/views/Feed/FeedUser.js +++ b/src/views/Feed/FeedUser.js @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro /** * A feed can contain a user element. */ -function FeedUser(props) { +const FeedUser = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('user', className) const rest = getUnhandledProps(FeedUser, props) const ElementType = getElementType(FeedUser, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +FeedUser.displayName = 'FeedUser' FeedUser.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Item/Item.js b/src/views/Item/Item.js index a66d7ce841..e76e5e4862 100644 --- a/src/views/Item/Item.js +++ b/src/views/Item/Item.js @@ -14,7 +14,7 @@ import ItemMeta from './ItemMeta' /** * An item view presents large collections of site content for display. */ -function Item(props) { +const Item = React.forwardRef(function (props, ref) { const { children, className, content, description, extra, header, image, meta } = props const classes = cx('item', className) @@ -23,14 +23,14 @@ function Item(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {ItemImage.create(image, { autoGenerateKey: false })} ) -} +}) Item.Content = ItemContent Item.Description = ItemDescription @@ -52,6 +52,7 @@ Item.Header = ItemHeader Item.Image = ItemImage Item.Meta = ItemMeta +Item.displayName = 'Item' Item.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Item/ItemContent.js b/src/views/Item/ItemContent.js index ab3df2ec32..6699a1cbc1 100644 --- a/src/views/Item/ItemContent.js +++ b/src/views/Item/ItemContent.js @@ -18,7 +18,7 @@ import ItemMeta from './ItemMeta' /** * An item can contain content. */ -function ItemContent(props) { +const ItemContent = React.forwardRef(function (props, ref) { const { children, className, content, description, extra, header, meta, verticalAlign } = props const classes = cx(useVerticalAlignProp(verticalAlign), 'content', className) @@ -27,14 +27,14 @@ function ItemContent(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } return ( - + {ItemHeader.create(header, { autoGenerateKey: false })} {ItemMeta.create(meta, { autoGenerateKey: false })} {ItemDescription.create(description, { autoGenerateKey: false })} @@ -42,8 +42,9 @@ function ItemContent(props) { {content} ) -} +}) +ItemContent.displayName = 'ItemContent' ItemContent.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Item/ItemDescription.js b/src/views/Item/ItemDescription.js index 1dc86c537f..be5440a41d 100644 --- a/src/views/Item/ItemDescription.js +++ b/src/views/Item/ItemDescription.js @@ -13,19 +13,20 @@ import { /** * An item can contain a description with a single or multiple paragraphs. */ -function ItemDescription(props) { +const ItemDescription = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('description', className) const rest = getUnhandledProps(ItemDescription, props) const ElementType = getElementType(ItemDescription, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +ItemDescription.displayName = 'ItemDescription' ItemDescription.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Item/ItemExtra.js b/src/views/Item/ItemExtra.js index 5cab3b3642..ed9a2a0add 100644 --- a/src/views/Item/ItemExtra.js +++ b/src/views/Item/ItemExtra.js @@ -13,19 +13,20 @@ import { /** * An item can contain extra content meant to be formatted separately from the main content. */ -function ItemExtra(props) { +const ItemExtra = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('extra', className) const rest = getUnhandledProps(ItemExtra, props) const ElementType = getElementType(ItemExtra, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +ItemExtra.displayName = 'ItemExtra' ItemExtra.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Item/ItemGroup.js b/src/views/Item/ItemGroup.js index e41e5ea96c..7ceca3b9ea 100644 --- a/src/views/Item/ItemGroup.js +++ b/src/views/Item/ItemGroup.js @@ -16,7 +16,7 @@ import Item from './Item' /** * A group of items. */ -function ItemGroup(props) { +const ItemGroup = React.forwardRef(function (props, ref) { const { children, className, content, divided, items, link, relaxed, unstackable } = props const classes = cx( @@ -33,14 +33,14 @@ function ItemGroup(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } if (!childrenUtils.isNil(content)) { return ( - + {content} ) @@ -56,12 +56,13 @@ function ItemGroup(props) { }) return ( - + {itemsJSX} ) -} +}) +ItemGroup.displayName = 'ItemGroup' ItemGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Item/ItemHeader.js b/src/views/Item/ItemHeader.js index e01f59cbf3..610e6d649a 100644 --- a/src/views/Item/ItemHeader.js +++ b/src/views/Item/ItemHeader.js @@ -13,19 +13,20 @@ import { /** * An item can contain a header. */ -function ItemHeader(props) { +const ItemHeader = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('header', className) const rest = getUnhandledProps(ItemHeader, props) const ElementType = getElementType(ItemHeader, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +ItemHeader.displayName = 'ItemHeader' ItemHeader.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Item/ItemImage.d.ts b/src/views/Item/ItemImage.d.ts index 3a94165d47..d19c8009d5 100644 --- a/src/views/Item/ItemImage.d.ts +++ b/src/views/Item/ItemImage.d.ts @@ -1,9 +1,19 @@ import * as React from 'react' + import { ImageProps, StrictImageProps } from '../../elements/Image' +import { SemanticSIZES } from '../../generic' + +export interface ItemImageProps extends ImageProps { + [key: string]: any -export interface ItemImageProps extends ImageProps {} + /** An image may appear at different sizes. */ + size?: SemanticSIZES +} -export interface StrictItemImageProps extends StrictImageProps {} +export interface StrictItemImageProps extends StrictImageProps { + /** An image may appear at different sizes. */ + size?: SemanticSIZES +} declare const ItemImage: React.FC diff --git a/src/views/Item/ItemImage.js b/src/views/Item/ItemImage.js index 5e06be9a18..55854ec66e 100644 --- a/src/views/Item/ItemImage.js +++ b/src/views/Item/ItemImage.js @@ -6,13 +6,14 @@ import Image from '../../elements/Image' /** * An item can contain an image. */ -function ItemImage(props) { +const ItemImage = React.forwardRef(function (props, ref) { const { size } = props const rest = getUnhandledProps(ItemImage, props) - return -} + return +}) +ItemImage.displayName = 'ItemImage' ItemImage.propTypes = { /** An image may appear at different sizes. */ size: Image.propTypes.size, diff --git a/src/views/Item/ItemMeta.js b/src/views/Item/ItemMeta.js index 1bacc4b2b8..307bf59a72 100644 --- a/src/views/Item/ItemMeta.js +++ b/src/views/Item/ItemMeta.js @@ -13,19 +13,20 @@ import { /** * An item can contain content metadata. */ -function ItemMeta(props) { +const ItemMeta = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('meta', className) const rest = getUnhandledProps(ItemMeta, props) const ElementType = getElementType(ItemMeta, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +ItemMeta.displayName = 'ItemMeta' ItemMeta.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Statistic/Statistic.js b/src/views/Statistic/Statistic.js index 4fcfeedf7f..e11df59393 100644 --- a/src/views/Statistic/Statistic.js +++ b/src/views/Statistic/Statistic.js @@ -20,7 +20,7 @@ import StatisticValue from './StatisticValue' /** * A statistic emphasizes the current value of an attribute. */ -function Statistic(props) { +const Statistic = React.forwardRef(function (props, ref) { const { children, className, @@ -50,21 +50,21 @@ function Statistic(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } if (!childrenUtils.isNil(content)) { return ( - + {content} ) } return ( - + {StatisticValue.create(value, { defaultProps: { text }, autoGenerateKey: false, @@ -72,8 +72,9 @@ function Statistic(props) { {StatisticLabel.create(label, { autoGenerateKey: false })} ) -} +}) +Statistic.displayName = 'Statistic' Statistic.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Statistic/StatisticGroup.js b/src/views/Statistic/StatisticGroup.js index d6106d4d9b..eac360d23b 100644 --- a/src/views/Statistic/StatisticGroup.js +++ b/src/views/Statistic/StatisticGroup.js @@ -17,7 +17,7 @@ import Statistic from './Statistic' /** * A group of statistics. */ -function StatisticGroup(props) { +const StatisticGroup = React.forwardRef(function (props, ref) { const { children, className, color, content, horizontal, inverted, items, size, widths } = props const classes = cx( @@ -35,26 +35,27 @@ function StatisticGroup(props) { if (!childrenUtils.isNil(children)) { return ( - + {children} ) } if (!childrenUtils.isNil(content)) { return ( - + {content} ) } return ( - + {_.map(items, (item) => Statistic.create(item))} ) -} +}) +StatisticGroup.displayName = 'StatisticGroup' StatisticGroup.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Statistic/StatisticLabel.js b/src/views/Statistic/StatisticLabel.js index 19f116812c..efc01ab9bc 100644 --- a/src/views/Statistic/StatisticLabel.js +++ b/src/views/Statistic/StatisticLabel.js @@ -13,19 +13,20 @@ import { /** * A statistic can contain a label to help provide context for the presented value. */ -function StatisticLabel(props) { +const StatisticLabel = React.forwardRef(function (props, ref) { const { children, className, content } = props const classes = cx('label', className) const rest = getUnhandledProps(StatisticLabel, props) const ElementType = getElementType(StatisticLabel, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +StatisticLabel.displayName = 'StatisticLabel' StatisticLabel.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/src/views/Statistic/StatisticValue.js b/src/views/Statistic/StatisticValue.js index 0e84115220..78ac615220 100644 --- a/src/views/Statistic/StatisticValue.js +++ b/src/views/Statistic/StatisticValue.js @@ -14,7 +14,7 @@ import { /** * A statistic can contain a numeric, icon, image, or text value. */ -function StatisticValue(props) { +const StatisticValue = React.forwardRef(function (props, ref) { const { children, className, content, text } = props const classes = cx(useKeyOnly(text, 'text'), 'value', className) @@ -22,12 +22,13 @@ function StatisticValue(props) { const ElementType = getElementType(StatisticValue, props) return ( - + {childrenUtils.isNil(children) ? content : children} ) -} +}) +StatisticValue.displayName = 'StatisticValue' StatisticValue.propTypes = { /** An element type to render as (string or function). */ as: PropTypes.elementType, diff --git a/static.routes.js b/static.routes.js index ed64b1fe16..5093932991 100644 --- a/static.routes.js +++ b/static.routes.js @@ -36,82 +36,27 @@ export default async () => { })), // Routes for components, i.e. /element/button - ..._.map( - _.filter(getComponentMenu(), (baseInfo) => !baseInfo.external), - (baseInfo) => ({ - path: getComponentPathname(baseInfo), - component: 'docs/src/components/ComponentDoc', - priority: 0.8, - getData: async () => { - const componentsInfo = getComponentGroupInfo(baseInfo.displayName) - const sidebarSections = getSidebarSections(baseInfo.displayName) - - return { - componentsInfo, - exampleSources, - sidebarSections, - displayName: baseInfo.displayName, - deprecated: !!_.find( - _.get(componentsInfo[baseInfo.displayName], 'docblock.tags'), - (tag) => tag.title === 'deprecated', - ), - seeTags: getInfoForSeeTags(componentsInfo[baseInfo.displayName]), - } - }, - }), - ), - - { - path: `/addons/ref/`, + ..._.map(getComponentMenu(), (baseInfo) => ({ + path: getComponentPathname(baseInfo), component: 'docs/src/components/ComponentDoc', priority: 0.8, getData: async () => { - const componentsInfo = { - Ref: { - displayName: 'Ref', - props: [ - { - description: ['Called when a child component will be mounted or updated.'], - name: 'innerRef', - type: 'func', - required: true, - tags: [ - { - title: 'param', - description: 'Referred node.', - type: { - type: 'NameExpression', - name: 'HTMLElement', - }, - name: 'node', - }, - ], - }, - ], - type: 'addon', - isParent: true, - subcomponents: [], - docblock: { - tags: [], - description: [ - 'This component exposes the `innerRef` prop that supports functional and React.createRef()/React.useRef() API and returns the DOM node of both functional and class component children.', - ], - }, - examplesExist: true, - }, - } - const sidebarSections = getSidebarSections('Ref') + const componentsInfo = getComponentGroupInfo(baseInfo.displayName) + const sidebarSections = getSidebarSections(baseInfo.displayName) return { componentsInfo, exampleSources, sidebarSections, - displayName: 'Ref', - deprecated: true, - seeTags: [], + displayName: baseInfo.displayName, + deprecated: !!_.find( + _.get(componentsInfo[baseInfo.displayName], 'docblock.tags'), + (tag) => tag.title === 'deprecated', + ), + seeTags: getInfoForSeeTags(componentsInfo[baseInfo.displayName]), } }, - }, + })), // Routes for layouts, i.e. /layouts/theming ..._.map(await getLayoutPaths(), ({ routeName, componentFilename }) => ({ diff --git a/test/specs/addons/Confirm/Confirm-test.js b/test/specs/addons/Confirm/Confirm-test.js index d59a48c8ec..46a96b471e 100644 --- a/test/specs/addons/Confirm/Confirm-test.js +++ b/test/specs/addons/Confirm/Confirm-test.js @@ -26,19 +26,23 @@ describe('Confirm', () => { if (wrapper && wrapper.unmount) wrapper.unmount() }) - common.isConformant(Confirm) + common.isConformant(Confirm, { rendersPortal: true }) common.implementsShorthandProp(Confirm, { autoGenerateKey: false, propKey: 'header', ShorthandComponent: Modal.Header, + rendersPortal: true, mapValueToProps: (content) => ({ content }), + requiredProps: { open: true }, }) common.implementsShorthandProp(Confirm, { autoGenerateKey: false, propKey: 'content', ShorthandComponent: Modal.Content, + rendersPortal: true, mapValueToProps: (content) => ({ content }), + requiredProps: { open: true }, }) describe('children', () => { diff --git a/test/specs/addons/Pagination/Pagination-test.js b/test/specs/addons/Pagination/Pagination-test.js index 97cc1d19ff..0b50014282 100644 --- a/test/specs/addons/Pagination/Pagination-test.js +++ b/test/specs/addons/Pagination/Pagination-test.js @@ -5,12 +5,13 @@ import PaginationItem from 'src/addons/Pagination/PaginationItem' import * as common from 'test/specs/commonTests' import { sandbox } from 'test/utils' +const requiredProps = { + totalPages: 0, +} + describe('Pagination', () => { - common.isConformant(Pagination, { - requiredProps: { - totalPages: 0, - }, - }) + common.isConformant(Pagination, { requiredProps }) + common.forwardsRef(Pagination, { requiredProps, tagName: 'div' }) common.hasSubcomponents(Pagination, [PaginationItem]) describe('disabled', () => { @@ -24,11 +25,10 @@ describe('Pagination', () => { describe('onPageChange', () => { it('is called with (e, data) when clicked on a pagination item', () => { - const event = { target: null } const onPageChange = sandbox.spy() const onPageItemClick = sandbox.spy() - mount( + const wrapper = mount( { totalPages={3} />, ) - .find('PaginationItem') - .at(4) - .simulate('click', event) + + wrapper.find('PaginationItem').at(4).simulate('click') onPageChange.should.have.been.calledOnce() - onPageChange.should.have.been.calledWithMatch(event, { activePage: 3 }) + onPageChange.should.have.been.calledWithMatch({ type: 'click' }, { activePage: 3 }) onPageItemClick.should.have.been.calledOnce() - onPageItemClick.should.have.been.calledWithMatch(event, { value: 3 }) + onPageItemClick.should.have.been.calledWithMatch({ type: 'click' }, { value: 3 }) }) it('will be omitted if occurred for the same pagination item as the current', () => { diff --git a/test/specs/addons/Pagination/PaginationItem-test.js b/test/specs/addons/Pagination/PaginationItem-test.js index cdf9f0a342..33bb84b3b0 100644 --- a/test/specs/addons/Pagination/PaginationItem-test.js +++ b/test/specs/addons/Pagination/PaginationItem-test.js @@ -6,6 +6,7 @@ import { sandbox } from 'test/utils' describe('PaginationItem', () => { common.isConformant(PaginationItem) + common.forwardsRef(PaginationItem, { tagName: 'a' }) common.implementsCreateMethod(PaginationItem) describe('active', () => { diff --git a/test/specs/addons/Portal/Portal-test.js b/test/specs/addons/Portal/Portal-test.js index 383e8bbcfc..05cf68a1ae 100644 --- a/test/specs/addons/Portal/Portal-test.js +++ b/test/specs/addons/Portal/Portal-test.js @@ -1,6 +1,7 @@ import _ from 'lodash' import PropTypes from 'prop-types' import React from 'react' +import { act } from 'react-dom/test-utils' import * as common from 'test/specs/commonTests' import { domEvent, sandbox } from 'test/utils' @@ -147,7 +148,9 @@ describe('Portal', () => { ) wrapper.setProps({ open: false, children:

}) - wrapper.unmount() + act(() => { + wrapper.unmount() + }) onUnmount.should.have.been.calledOnce() }) @@ -159,33 +162,13 @@ describe('Portal', () => { , ) - wrapper.unmount() + act(() => { + wrapper.unmount() + }) onUnmount.should.have.been.calledOnce() }) }) - describe('portalNode', () => { - it('maintains ref to DOM node with host element', () => { - wrapperMount( - -

- , - ) - wrapper.instance().contentRef.current.tagName.should.equal('P') - }) - - it('maintains ref to DOM node with React component', () => { - const EmptyComponent = () =>

- - wrapperMount( - - - , - ) - wrapper.instance().contentRef.current.tagName.should.equal('P') - }) - }) - describe('onOpen', () => { it('is called on trigger click', () => { const onOpen = sandbox.spy() @@ -263,6 +246,25 @@ describe('Portal', () => { }) }) + describe('triggerRef', () => { + it('calls itself and an original ref', () => { + const elementRef = React.createRef() + const triggerRef = React.createRef() + + wrapperMount( + } triggerRef={triggerRef}> +

+ , + ) + const element = wrapper.getDOMNode() + + expect(element.tagName).to.equal('DIV') + + expect(elementRef.current).to.equal(element) + expect(triggerRef.current).to.equal(element) + }) + }) + describe('mountNode', () => { it('passed to PortalInner', () => { const mountNode = document.createElement('div') @@ -712,26 +714,4 @@ describe('Portal', () => { }, 0) }) }) - - describe('triggerRef', () => { - it('maintains ref on the trigger', () => { - const triggerRef = sandbox.spy() - const mountNode = document.createElement('div') - document.body.appendChild(mountNode) - - wrapperMount( - } triggerRef={triggerRef}> -

- , - { attachTo: mountNode }, - ) - const trigger = document.querySelector('#trigger') - - triggerRef.should.have.been.calledOnce() - triggerRef.should.have.been.calledWithMatch(trigger) - - wrapper.detach() - document.body.removeChild(mountNode) - }) - }) }) diff --git a/test/specs/addons/Portal/PortalInner-test.js b/test/specs/addons/Portal/PortalInner-test.js index e53c2724be..47af45d2e4 100644 --- a/test/specs/addons/Portal/PortalInner-test.js +++ b/test/specs/addons/Portal/PortalInner-test.js @@ -1,4 +1,5 @@ -import React, { createRef } from 'react' +import React from 'react' +import { act } from 'react-dom/test-utils' import PortalInner from 'src/addons/Portal/PortalInner' import { isBrowser } from 'src/lib' @@ -20,7 +21,7 @@ describe('PortalInner', () => { isBrowser.override = null }) - it('renders `null` when is SSR', () => { + it('renders `null` when during Server-Side Rendering', () => { mount(

@@ -29,16 +30,59 @@ describe('PortalInner', () => { }) }) - describe('innerRef', () => { - it('returns ref', () => { - const innerRef = createRef() + describe('ref', () => { + it('returns ref a DOM element', () => { + const portalRef = React.createRef() + const elementRef = React.createRef() + const wrapper = mount( - -

+ +

+ , + ) + const domNode = wrapper.getDOMNode() + + expect(elementRef.current).to.equal(domNode) + expect(portalRef.current).to.equal(domNode) + expect(domNode.tagName).to.equal('P') + }) + + it('returns ref a elements that uses ref forwarding', () => { + const CustomComponent = React.forwardRef((props, ref) => { + return

+ }) + + const portalRef = React.createRef() + const elementRef = React.createRef() + + const wrapper = mount( + + + , + ) + const domNode = wrapper.getDOMNode() + + expect(elementRef.current).to.equal(domNode) + expect(portalRef.current).to.equal(domNode) + expect(domNode.tagName).to.equal('P') + }) + + it('returns ref to a create element in other cases', () => { + function CustomComponent(props) { + return

+ } + + const portalRef = React.createRef() + const wrapper = mount( + + , ) + const domNode = wrapper.getDOMNode() - expect(wrapper.getDOMNode()).to.equal(innerRef.current) + expect(portalRef.current).to.equal(domNode) + expect(domNode.tagName).to.equal('DIV') + expect(domNode.dataset.suirPortal).to.equal('true') }) }) @@ -64,7 +108,9 @@ describe('PortalInner', () => { , ) - wrapper.unmount() + act(() => { + wrapper.unmount() + }) onUnmount.should.have.been.calledOnce() }) }) diff --git a/test/specs/addons/Radio/Radio-test.js b/test/specs/addons/Radio/Radio-test.js index aaf4ad215a..96826928df 100644 --- a/test/specs/addons/Radio/Radio-test.js +++ b/test/specs/addons/Radio/Radio-test.js @@ -6,6 +6,7 @@ import * as common from 'test/specs/commonTests' describe('Radio', () => { common.isConformant(Radio) + common.forwardsRef(Radio, { tagName: 'input' }) it('renders a radio Checkbox', () => { const wrapper = shallow() diff --git a/test/specs/addons/Select/Select-test.js b/test/specs/addons/Select/Select-test.js index a0c59db4e6..de0a909bf9 100644 --- a/test/specs/addons/Select/Select-test.js +++ b/test/specs/addons/Select/Select-test.js @@ -11,6 +11,7 @@ const requiredProps = { describe('Select', () => { common.isConformant(Select, { requiredProps }) common.hasSubcomponents(Select, [Dropdown.Divider, Dropdown.Header, Dropdown.Item, Dropdown.Menu]) + common.forwardsRef(Select, { requiredProps }) it('renders a selection Dropdown', () => { shallow(