Skip to content

feat(ver): add support for react 19 #95

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/jsx-runtime",
"prettier"
],
"overrides": [
Expand Down
24,993 changes: 0 additions & 24,993 deletions package-lock.json

This file was deleted.

4 changes: 2 additions & 2 deletions packages/module/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
"@patternfly/react-icons": "^6.0.0"
},
"peerDependencies": {
"react": "^17 || ^18",
"react-dom": "^17 || ^18"
"react": "^17 || ^18 || ^19",
"react-dom": "^17 || ^18 || ^19"
},
"devDependencies": {
"copyfiles": "2.4.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/module/patternfly-docs/content/examples/Advanced.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-disable no-console */
import React from 'react';
import { FunctionComponent, useState } from 'react';
import { FeedbackModal} from '@patternfly/react-user-feedback';
import { Button } from '@patternfly/react-core';
import feedbackImage from '@patternfly/react-user-feedback/dist/esm/images/rh_feedback.svg';

export const AdvancedExample: React.FunctionComponent = () => {
const [isOpen, setIsOpen] = React.useState<boolean>(false);
export const AdvancedExample: FunctionComponent = () => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const handleButtonClicked = () => {setIsOpen(true)};
return <>
<Button onClick={handleButtonClicked}>Show Modal</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-disable no-console */
import React from 'react';
import { FunctionComponent, useState } from 'react';
import { FeedbackModal} from '@patternfly/react-user-feedback';
import { Button } from '@patternfly/react-core';
import feedbackImage from '@patternfly/react-user-feedback/dist/esm/images/rh_feedback.svg';

export const AdvancedStaticEmailExample: React.FunctionComponent = () => {
const [isOpen, setIsOpen] = React.useState<boolean>(false);
export const AdvancedStaticEmailExample: FunctionComponent = () => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const handleButtonClicked = () => {setIsOpen(true)};
return <>
<Button onClick={handleButtonClicked}>Show Modal</Button>
Expand Down
6 changes: 3 additions & 3 deletions packages/module/patternfly-docs/content/examples/Async.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* eslint-disable no-console */
import React from 'react';
import { FunctionComponent, useState } from 'react';
import { FeedbackModal} from '@patternfly/react-user-feedback';
import { Button } from '@patternfly/react-core';

export const AsyncExample: React.FunctionComponent = () => {
const [isOpen, setIsOpen] = React.useState<boolean>(false);
export const AsyncExample: FunctionComponent = () => {
const [isOpen, setIsOpen] = useState<boolean>(false);

const fakeNetworkCall = (email:string, feedback:string, bug:string) => new Promise<boolean>(resolve => {
setTimeout(() => {
Expand Down
17 changes: 13 additions & 4 deletions packages/module/patternfly-docs/content/examples/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,26 @@ propComponents: ['FeedbackModalProps']
sourceLink: https://github.com/patternfly/react-user-feedback/blob/c0c51c751abf0b798f511806409f25d2a2e87a60/packages/module/patternfly-docs/content/examples/basic.md
---

import { FunctionComponent, useState } from 'react';
import { FeedbackModal } from "@patternfly/react-user-feedback";
import feedbackImage from '@patternfly/react-user-feedback/dist/esm/images/rh_feedback.svg';

## About

The user feedback extension is a PatternFly React based component used to collect user feedback. Examples of how to use this extension are documented below. This extensions allows users to submit feedback, report a bug, request support, as well as join a mailing list to stay updated on the latest news and research opportunities.

## Examples

### Basic modal

To collect data, you can link modal items to external sources instead of a built in form. For example, you can link to a custom form, which will be opened in a new tab.

```js file="./URL.tsx"

```

### Advanced modal

User feedback offers additional modal items that support different types of feedback. To allow users to report a bug, use the `onReportABug` property. To allow users to join a mailing list, such as one dedicated to future research participation, use the `onJoinMailingList` property. To allow users to open a support case, use the `onOpenSupportCase` property and link users to your support team.

The following example demonstrates each of these modal items. The "Share feedback", "Report a bug", and "Inform the direction of products" items all point to built-in forms.
Expand All @@ -40,20 +43,26 @@ The following example demonstrates each of these modal items. The "Share feedbac
```

### Advanced that autofills an email address

To automatically pass a user's email address into a feedback modal, use the email property. This allows you to pre-populate the modal's email field.

```js file="./AdvancedWithEmail.tsx"

```

### Modal with asynchronous call support
User feedback supports the ability to make asynchronous calls to send data collected from the modal to a backend service.

User feedback supports the ability to make asynchronous calls to send data collected from the modal to a backend service.
The following example demonstrates how to use the `async` function to send data to a backend service.

```js file="./Async.tsx"

```

### Modal with internationalization support

To customize the content displayed in the feedback modal, pass in a custom `i18n` object with values for each property of `<FeedbackModal>`. This allows you to prepare a modal for different languages and requirements.

```js file="./i18n.tsx"

```
```
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { AutoLinkHeader, Example, Link as PatternflyThemeLink } from '@patternfly/documentation-framework/components';
import { FunctionComponent, useState } from 'react';
import { FeedbackModal } from "@patternfly/react-user-feedback";
import feedbackImage from '@patternfly/react-user-feedback/dist/esm/images/rh_feedback.svg';
const pageData = {
Expand All @@ -14,7 +15,7 @@ const pageData = {
"source": "react",
"tabName": null,
"slug": "/extensions/user-feedback/react",
"sourceLink": "https://github.com/patternfly/patternfly-react/blob/main/packages/module/patternfly-docs/content/examples/basic.md",
"sourceLink": "https://github.com/patternfly/react-user-feedback/blob/c0c51c751abf0b798f511806409f25d2a2e87a60/packages/module/patternfly-docs/content/examples/basic.md",
"relPath": "packages/module/patternfly-docs/content/examples/basic.md",
"propComponents": [
{
Expand Down Expand Up @@ -51,7 +52,7 @@ const pageData = {
{
"name": "onJoinMailingList",
"type": "string | ((email: string) => boolean | Promise<boolean>)",
"description": "If a URL is given the join mailing list link will redirect to another site to join the mailing list. \nIf a function is provided we will display a join mailing list screen with a submit button. The callback function should return a boolean or a Promise if the callback is successful or unsuccessful.\nIf it's undefined then report a bug will be removed from share feedback modal"
"description": "If a URL is given the join mailing list link will redirect to another site to join the mailing list.\nIf a function is provided we will display a join mailing list screen with a submit button. The callback function should return a boolean or a Promise if the callback is successful or unsuccessful.\nIf it's undefined then report a bug will be removed from share feedback modal"
},
{
"name": "onOpenSupportCase",
Expand All @@ -61,12 +62,12 @@ const pageData = {
{
"name": "onReportABug",
"type": "string | ((email: string, bug: string) => boolean | Promise<boolean>)",
"description": "If a URL is given the report a bug link will redirect to another site to report the bug. \nIf a function is provided we will display a feedback screen with a submit button. The callback function should return a boolean or a Promise \nif the callback is successful or unsuccessful.\nIf it's undefined then join mailing list will be removed from the share feedback modal"
"description": "If a URL is given the report a bug link will redirect to another site to report the bug.\nIf a function is provided we will display a feedback screen with a submit button. The callback function should return a boolean or a Promise\nif the callback is successful or unsuccessful.\nIf it's undefined then join mailing list will be removed from the share feedback modal"
},
{
"name": "onShareFeedback",
"type": "string | ((email: string, feedback: string) => boolean | Promise<boolean>)",
"description": "If a URL is given the share feedback link will redirect to another site share feedback. \nIf a function is provided we will display a share feedback screen with a submit button. The callback function should return a boolean or a Promise if the callback is successful or unsuccessful.",
"description": "If a URL is given the share feedback link will redirect to another site share feedback.\nIf a function is provided we will display a share feedback screen with a submit button. The callback function should return a boolean or a Promise if the callback is successful or unsuccessful.",
"required": true
}
]
Expand All @@ -81,6 +82,8 @@ const pageData = {
]
};
pageData.liveContext = {
FunctionComponent,
useState,
FeedbackModal,
feedbackImage
};
Expand All @@ -93,7 +96,7 @@ pageData.examples = {
</p>
</Example>,
'Advanced modal': props =>
<Example {...pageData} {...props} {...{"code":"/* eslint-disable no-console */\nimport React from 'react';\nimport { FeedbackModal} from '@patternfly/react-user-feedback';\nimport { Button } from '@patternfly/react-core';\nimport feedbackImage from '@patternfly/react-user-feedback/dist/esm/images/rh_feedback.svg';\n\nexport const AdvancedExample: React.FunctionComponent = () => {\n const [isOpen, setIsOpen] = React.useState<boolean>(false);\n const handleButtonClicked = () => {setIsOpen(true)}; \n return <>\n <Button onClick={handleButtonClicked}>Show Modal</Button>\n <FeedbackModal \n onShareFeedback={(email:string, feedback:string)=>{\n // Example of a successful callback\n console.log (`Email Address: ${email} Feedback: ${feedback}`);\n return true\n }}\n onJoinMailingList={(email:string)=>{\n // Example of am unsuccessful callback\n console.log (`Email Address: ${email}`);\n return false;\n }}\n onOpenSupportCase='https://pf-user-feedback-extension-form-demos.surge.sh/requestSupport.html'\n onReportABug={(email:string, bug:string)=>{\n console.log (`Email Address: ${email} Bug: ${bug}`)\n return true;}}\n feedbackImg={feedbackImage}\n isOpen={isOpen}\n onClose={()=>setIsOpen(false)}/>\n </>\n}","title":"Advanced modal","lang":"js","className":""}}>
<Example {...pageData} {...props} {...{"code":"/* eslint-disable no-console */\nimport { FunctionComponent, useState } from 'react';\nimport { FeedbackModal} from '@patternfly/react-user-feedback';\nimport { Button } from '@patternfly/react-core';\nimport feedbackImage from '@patternfly/react-user-feedback/dist/esm/images/rh_feedback.svg';\n\nexport const AdvancedExample: FunctionComponent = () => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const handleButtonClicked = () => {setIsOpen(true)}; \n return <>\n <Button onClick={handleButtonClicked}>Show Modal</Button>\n <FeedbackModal \n onShareFeedback={(email:string, feedback:string)=>{\n // Example of a successful callback\n console.log (`Email Address: ${email} Feedback: ${feedback}`);\n return true\n }}\n onJoinMailingList={(email:string)=>{\n // Example of am unsuccessful callback\n console.log (`Email Address: ${email}`);\n return false;\n }}\n onOpenSupportCase='https://pf-user-feedback-extension-form-demos.surge.sh/requestSupport.html'\n onReportABug={(email:string, bug:string)=>{\n console.log (`Email Address: ${email} Bug: ${bug}`)\n return true;}}\n feedbackImg={feedbackImage}\n isOpen={isOpen}\n onClose={()=>setIsOpen(false)}/>\n </>\n}","title":"Advanced modal","lang":"js","className":""}}>

<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
{`User feedback offers additional modal items that support different types of feedback. To allow users to report a bug, use the `}
Expand All @@ -119,21 +122,18 @@ pageData.examples = {
</p>
</Example>,
'Advanced that autofills an email address': props =>
<Example {...pageData} {...props} {...{"code":"/* eslint-disable no-console */\nimport React from 'react';\nimport { FeedbackModal} from '@patternfly/react-user-feedback';\nimport { Button } from '@patternfly/react-core';\nimport feedbackImage from '@patternfly/react-user-feedback/dist/esm/images/rh_feedback.svg';\n\nexport const AdvancedStaticEmailExample: React.FunctionComponent = () => {\n const [isOpen, setIsOpen] = React.useState<boolean>(false);\n const handleButtonClicked = () => {setIsOpen(true)}; \n return <>\n <Button onClick={handleButtonClicked}>Show Modal</Button>\n <FeedbackModal \n email='test.user@patternfly.org'\n onShareFeedback={(email:string, feedback:string)=>{\n // Example of a successful callback\n console.log (`Email Address: ${email} Feedback: ${feedback}`);\n return true\n }}\n onJoinMailingList={(email:string)=>{\n // Example of am unsuccessful callback\n console.log (`Email Address: ${email}`);\n return false;\n }}\n onOpenSupportCase='https://pf-user-feedback-extension-form-demos.surge.sh/requestSupport.html'\n onReportABug={(email:string, bug:string)=>{\n console.log (`Email Address: ${email} Bug: ${bug}`)\n return true;}}\n feedbackImg={feedbackImage}\n isOpen={isOpen}\n onClose={()=>setIsOpen(false)}/>\n </>\n}","title":"Advanced that autofills an email address","lang":"js","className":""}}>
<Example {...pageData} {...props} {...{"code":"/* eslint-disable no-console */\nimport { FunctionComponent, useState } from 'react';\nimport { FeedbackModal} from '@patternfly/react-user-feedback';\nimport { Button } from '@patternfly/react-core';\nimport feedbackImage from '@patternfly/react-user-feedback/dist/esm/images/rh_feedback.svg';\n\nexport const AdvancedStaticEmailExample: FunctionComponent = () => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const handleButtonClicked = () => {setIsOpen(true)}; \n return <>\n <Button onClick={handleButtonClicked}>Show Modal</Button>\n <FeedbackModal \n email='test.user@patternfly.org'\n onShareFeedback={(email:string, feedback:string)=>{\n // Example of a successful callback\n console.log (`Email Address: ${email} Feedback: ${feedback}`);\n return true\n }}\n onJoinMailingList={(email:string)=>{\n // Example of am unsuccessful callback\n console.log (`Email Address: ${email}`);\n return false;\n }}\n onOpenSupportCase='https://pf-user-feedback-extension-form-demos.surge.sh/requestSupport.html'\n onReportABug={(email:string, bug:string)=>{\n console.log (`Email Address: ${email} Bug: ${bug}`)\n return true;}}\n feedbackImg={feedbackImage}\n isOpen={isOpen}\n onClose={()=>setIsOpen(false)}/>\n </>\n}","title":"Advanced that autofills an email address","lang":"js","className":""}}>

<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
{`To automatically pass a user's email address into a feedback modal, use the email property. This allows you to pre-populate the modal's email field.`}
</p>
</Example>,
'Modal with asynchronous call support': props =>
<Example {...pageData} {...props} {...{"code":"/* eslint-disable no-console */\nimport React from 'react';\nimport { FeedbackModal} from '@patternfly/react-user-feedback';\nimport { Button } from '@patternfly/react-core';\n\nexport const AsyncExample: React.FunctionComponent = () => {\n const [isOpen, setIsOpen] = React.useState<boolean>(false);\n\n const fakeNetworkCall = (email:string, feedback:string, bug:string) => new Promise<boolean>(resolve => {\n setTimeout(() => {\n console.log(`Email Address: ${email} Feedback: ${feedback} Bug: ${bug}`);\n console.log('Network call complete successfully so return true');\n resolve(true);\n }, 2000);\n })\n \n const simulatedAsyncCall = async (email='', feedback='', bug='') => {\n console.log('simulatedAsyncCall');\n const result = await fakeNetworkCall(email, feedback, bug);\n return result;\n }\n \n\n const handleButtonClicked = () => {setIsOpen(true)}; \n return <>\n <Button onClick={handleButtonClicked}>Show Modal</Button>\n <FeedbackModal \n onShareFeedback={(email:string, feedback:string)=>simulatedAsyncCall(email, feedback)}\n onJoinMailingList={(email:string)=>simulatedAsyncCall(email)}\n onOpenSupportCase='https://pf-user-feedback-extension-form-demos.surge.sh/requestSupport.html'\n onReportABug={(email:string, bug:string)=>simulatedAsyncCall(email, '', bug)}\n isOpen={isOpen}\n onClose={()=>setIsOpen(false)}/>\n </>\n}","title":"Modal with asynchronous call support","lang":"js","className":""}}>
<Example {...pageData} {...props} {...{"code":"/* eslint-disable no-console */\nimport { FunctionComponent, useState } from 'react';\nimport { FeedbackModal} from '@patternfly/react-user-feedback';\nimport { Button } from '@patternfly/react-core';\n\nexport const AsyncExample: FunctionComponent = () => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const fakeNetworkCall = (email:string, feedback:string, bug:string) => new Promise<boolean>(resolve => {\n setTimeout(() => {\n console.log(`Email Address: ${email} Feedback: ${feedback} Bug: ${bug}`);\n console.log('Network call complete successfully so return true');\n resolve(true);\n }, 2000);\n })\n \n const simulatedAsyncCall = async (email='', feedback='', bug='') => {\n console.log('simulatedAsyncCall');\n const result = await fakeNetworkCall(email, feedback, bug);\n return result;\n }\n \n\n const handleButtonClicked = () => {setIsOpen(true)}; \n return <>\n <Button onClick={handleButtonClicked}>Show Modal</Button>\n <FeedbackModal \n onShareFeedback={(email:string, feedback:string)=>simulatedAsyncCall(email, feedback)}\n onJoinMailingList={(email:string)=>simulatedAsyncCall(email)}\n onOpenSupportCase='https://pf-user-feedback-extension-form-demos.surge.sh/requestSupport.html'\n onReportABug={(email:string, bug:string)=>simulatedAsyncCall(email, '', bug)}\n isOpen={isOpen}\n onClose={()=>setIsOpen(false)}/>\n </>\n}","title":"Modal with asynchronous call support","lang":"js","className":""}}>

<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
{`User feedback supports the ability to make asynchronous calls to send data collected from the modal to a backend service.`}
</p>

<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
{`The following example demonstrates how to use the `}
{`User feedback supports the ability to make asynchronous calls to send data collected from the modal to a backend service.
The following example demonstrates how to use the `}

<code {...{"className":"ws-code "}}>
{`async`}
Expand All @@ -150,7 +150,7 @@ pageData.examples = {
<code {...{"className":"ws-code "}}>
{`i18n`}
</code>
{` object with values for each property of`}
{` object with values for each property of `}

<code {...{"className":"ws-code "}}>
{`<FeedbackModal>`}
Expand Down
Loading