diff --git a/package.json b/package.json index 3cf0ffb6ff5..3ceeb2b60ac 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "react-dom": "18.2.0", "react-dropzone": "14.2.3", "react-ga4": "2.1.0", - "react-portal": "4.2.2", "react-redux": "8.0.5", "react-router-dom": "6.22.3", "react-storage-hooks": "4.0.1", @@ -110,7 +109,6 @@ "@types/pluralize": "0.0.33", "@types/react": "18.2.73", "@types/react-dom": "18.2.23", - "@types/react-portal": "4.0.7", "@types/react-redux": "7.1.33", "@types/react-router": "5.1.20", "@types/react-router-dom": "5.3.3", diff --git a/src/app/base/components/NodeConfigurationFields/NodeConfigurationFields.tsx b/src/app/base/components/NodeConfigurationFields/NodeConfigurationFields.tsx index 819d4f9206d..1bffc46ed29 100644 --- a/src/app/base/components/NodeConfigurationFields/NodeConfigurationFields.tsx +++ b/src/app/base/components/NodeConfigurationFields/NodeConfigurationFields.tsx @@ -2,8 +2,8 @@ import { useState } from "react"; import { Col, Modal, Row, Textarea } from "@canonical/react-components"; import { useFormikContext } from "formik"; -import { Portal } from "react-portal"; import { useSelector } from "react-redux"; +import usePortal from "react-useportal"; import * as Yup from "yup"; import type { SchemaOf } from "yup"; @@ -31,11 +31,11 @@ export const NodeConfigurationSchema: SchemaOf = .defined(); const NodeConfigurationFields = (): JSX.Element => { + const { openPortal, closePortal, isOpen, Portal } = usePortal(); const { setFieldValue, values } = useFormikContext(); const selectedTags = useSelector((state: RootState) => tagSelectors.getByIDs(state, values.tags) ); - const [isOpen, setIsOpen] = useState(false); const [newTagName, setNewTagName] = useState(null); const manualTags = useSelector(tagSelectors.getManual); @@ -55,9 +55,9 @@ const NodeConfigurationFields = (): JSX.Element => { )} externalSelectedTags={selectedTags} name="tags" - onAddNewTag={(name) => { + onAddNewTag={(name) => (event) => { setNewTagName(name); - setIsOpen(true); + openPortal(event); }} placeholder="Create or remove tags" tagList={manualTags} @@ -68,7 +68,7 @@ const NodeConfigurationFields = (): JSX.Element => { setIsOpen(false)} + close={() => closePortal()} title={Label.AddTag} > { onTagCreated={(tag) => { setFieldValue("tags", values.tags.concat([tag.id])); setNewTagName(null); - setIsOpen(false); + closePortal(); }} /> diff --git a/src/app/base/components/TagSelector/TagSelector.tsx b/src/app/base/components/TagSelector/TagSelector.tsx index 0d7cffac7af..f4f5c08ee38 100644 --- a/src/app/base/components/TagSelector/TagSelector.tsx +++ b/src/app/base/components/TagSelector/TagSelector.tsx @@ -20,7 +20,7 @@ export type Props = { help?: string; initialSelected?: Tag[]; label?: string | null; - onAddNewTag?: (name: string) => void; + onAddNewTag?: (name: string) => (event?: React.SyntheticEvent) => void; onTagsUpdate?: (tags: Tag[]) => void; placeholder?: string; required?: boolean; @@ -91,10 +91,10 @@ const generateDropdownItems = ({ appearance="base" className="tag-selector__dropdown-button u-break-word" data-testid="new-tag" - onClick={() => { + onClick={(e) => { const cleanedFilter = sanitiseFilter(filter); if (onAddNewTag) { - onAddNewTag(cleanedFilter.name); + onAddNewTag(cleanedFilter.name)(e); setFilter(""); } else { updateTags([...selectedTags, cleanedFilter]); @@ -272,7 +272,7 @@ export const TagSelector = ({ if (allowNewTags) { const cleanedFilter = sanitiseFilter(filter); if (onAddNewTag) { - onAddNewTag(cleanedFilter.name); + onAddNewTag(cleanedFilter.name)(e); setFilter(""); } else { updateTags([...selectedTags, cleanedFilter]); diff --git a/src/app/machines/components/MachineForms/MachineActionFormWrapper/TagForm/TagFormFields/TagFormFields.tsx b/src/app/machines/components/MachineForms/MachineActionFormWrapper/TagForm/TagFormFields/TagFormFields.tsx index 16ae56a1a3a..01d21d9252f 100644 --- a/src/app/machines/components/MachineForms/MachineActionFormWrapper/TagForm/TagFormFields/TagFormFields.tsx +++ b/src/app/machines/components/MachineForms/MachineActionFormWrapper/TagForm/TagFormFields/TagFormFields.tsx @@ -117,7 +117,7 @@ export const TagFormFields = ({ } label={Label.TagInput} name="added" - onAddNewTag={(name) => { + onAddNewTag={(name) => (_) => { setNewTagName(name); setSecondaryContent("addTag"); }} diff --git a/yarn.lock b/yarn.lock index 62b91a7db10..77dc94303e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4801,13 +4801,6 @@ dependencies: "@types/react" "*" -"@types/react-portal@4.0.7": - version "4.0.7" - resolved "https://registry.yarnpkg.com/@types/react-portal/-/react-portal-4.0.7.tgz#c7436c5039e74ec80d488fbe5c98dbcc6469bf44" - integrity sha512-3zQJL6Pqcq7d73+cakVkZDqAYGFBo37XXPfahjhdScr9EdYPlf9evYilL38Fpzs1YGWz7F2SkPtN6+ygTO7ymg== - dependencies: - "@types/react" "*" - "@types/react-redux@7.1.33": version "7.1.33" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.33.tgz#53c5564f03f1ded90904e3c90f77e4bd4dc20b15" @@ -11209,7 +11202,7 @@ prompts@^2.4.0: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@15.8.1, prop-types@^15.5.8, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@15.8.1, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -11471,13 +11464,6 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -react-portal@4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/react-portal/-/react-portal-4.2.2.tgz#bff1e024147d6041ba8c530ffc99d4c8248f49fa" - integrity sha512-vS18idTmevQxyQpnde0Td6ZcUlv+pD8GTyR42n3CHUQq9OHi1C4jDE4ZWEbEsrbrLRhSECYiao58cvocwMtP7Q== - dependencies: - prop-types "^15.5.8" - react-redux@8.0.5: version "8.0.5" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.5.tgz#e5fb8331993a019b8aaf2e167a93d10af469c7bd" @@ -12461,6 +12447,7 @@ string-natural-compare@^3.0.1: integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.2.3: + name string-width-cjs version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12544,6 +12531,7 @@ string_decoder@~1.1.1: safe-buffer "~5.1.0" "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.1: + name strip-ansi-cjs version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -13735,6 +13723,7 @@ wordwrap@^1.0.0: integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + name wrap-ansi-cjs version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==