From 256c7dc0e1b6f73cd9a3448c9ea7c761ee60bd12 Mon Sep 17 00:00:00 2001 From: Cody Mitchell Date: Thu, 21 Mar 2024 10:14:44 -0400 Subject: [PATCH 1/5] Add loading message component --- .../VirtualAssistant/LoadingMessageEntry.tsx | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 packages/module/src/VirtualAssistant/LoadingMessageEntry.tsx diff --git a/packages/module/src/VirtualAssistant/LoadingMessageEntry.tsx b/packages/module/src/VirtualAssistant/LoadingMessageEntry.tsx new file mode 100644 index 00000000..10a6d958 --- /dev/null +++ b/packages/module/src/VirtualAssistant/LoadingMessageEntry.tsx @@ -0,0 +1,80 @@ +import React from 'react'; +import { Icon, Split, SplitItem } from '@patternfly/react-core'; +import { createUseStyles } from 'react-jss'; +import classnames from "clsx"; + +import RobotIcon from '@patternfly/react-icons/dist/js/icons/robot-icon'; + +const useStyles = createUseStyles({ + chatbot: { + marginBottom: "var(--pf-v5-global--spacer--md)", + marginRight: "40px", + }, + bubble: { + border: "1px solid var(--pf-v5-global--BackgroundColor--dark-400)", + borderRadius: "14px", + padding: "var(--pf-v5-global--spacer--sm) var(--pf-v5-global--spacer--md) var(--pf-v5-global--spacer--sm) var(--pf-v5-global--spacer--md)", + maxWidth: "100%", + wordWrap: "break-word", + }, + "@keyframes mercuryTypingAnimation": { + "0%": { + transform: "translateY(0px)", + backgroundColor: "var(--pf-v5-global--palette--black-600)", + }, + "28%": { + transform: "translateY(-7px)", + backgroundColor: "var(--pf-v5-global--palette--black-400)", + }, + "44%": { + transform: "translateY(0px)", + backgroundColor: "var(--pf-v5-global--palette--black-200)", + } + }, + dot: {}, + typing: { + height: "17px", + "& $dot": { + animation: "$mercuryTypingAnimation 1.8s infinite ease-in-out", + borderRadius: "50%", + display: "inline-block", + height: "7px", + marginRight: "4px", + marginTop: "6px", + verticalAlign: "middle", + width: "7px", + "&:nth-child(1)": { + animationDelay: "200ms", + }, + "&:nth-child(2)": { + animationDelay: "300ms", + }, + "&:nth-child(3)": { + animationDelay: "400ms", + }, + "&:last-child": { + marginRight: "0", + }, + } + } +}) + +export const LoadingMessageEntry = () => { + const classes = useStyles(); + return ( + + + + + + + +
+
+
+
+
+
+
+ ); +}; From 980a2d122f73e79c45b02a1988b3d55588542416 Mon Sep 17 00:00:00 2001 From: Cody Mitchell Date: Fri, 22 Mar 2024 10:07:35 -0400 Subject: [PATCH 2/5] rename loading message component --- .../{LoadingMessageEntry.tsx => LoadingMessage.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/module/src/VirtualAssistant/{LoadingMessageEntry.tsx => LoadingMessage.tsx} (100%) diff --git a/packages/module/src/VirtualAssistant/LoadingMessageEntry.tsx b/packages/module/src/VirtualAssistant/LoadingMessage.tsx similarity index 100% rename from packages/module/src/VirtualAssistant/LoadingMessageEntry.tsx rename to packages/module/src/VirtualAssistant/LoadingMessage.tsx From 258be2706996688c0fed0159248f4b832ca95a96 Mon Sep 17 00:00:00 2001 From: Cody Mitchell Date: Tue, 26 Mar 2024 20:49:52 -0400 Subject: [PATCH 3/5] Add LoadingMessage component to docs --- .../examples/VirtualAssistant/VirtualAssistant.md | 9 +++++++++ .../VirtualAssistant/VirtualAssistantLoadingMessage.tsx | 9 +++++++++ .../LoadingMessage.tsx | 4 +++- packages/module/src/LoadingMessage/index.ts | 3 +++ packages/module/src/index.ts | 3 +++ 5 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistantLoadingMessage.tsx rename packages/module/src/{VirtualAssistant => LoadingMessage}/LoadingMessage.tsx (97%) create mode 100644 packages/module/src/LoadingMessage/index.ts diff --git a/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistant.md b/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistant.md index 0b7ad3a9..8c73798c 100644 --- a/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistant.md +++ b/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistant.md @@ -16,6 +16,7 @@ sourceLink: https://github.com/patternfly/virtual-assistant/blob/main/packages/m import VirtualAssistant from '@patternfly/virtual-assistant/dist/dynamic/VirtualAssistant'; import VirtualAssistantAction from '@patternfly/virtual-assistant/dist/dynamic/VirtualAssistantAction'; +import LoadingMessage from '@patternfly/virtual-assistant/dist/dynamic/LoadingMessage'; import { AngleDownIcon } from '@patternfly/react-icons'; The **virtual assistant** component renders body of the virtual assistant window. @@ -61,3 +62,11 @@ Custom actions can be added to the assistant body using the `actions` property. ```js file="./VirtualAssistantWithActions.tsx" ``` + +### Loading Messages + +The LoadingMessage component displays a typing indicator for messages that are still processing, adding an artificial delay to create a more natural conversation flow. + +```js file="./VirtualAssistantLoadingMessage.tsx" + +``` diff --git a/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistantLoadingMessage.tsx b/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistantLoadingMessage.tsx new file mode 100644 index 00000000..f8204121 --- /dev/null +++ b/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistantLoadingMessage.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import VirtualAssistant from '@patternfly/virtual-assistant/dist/dynamic/VirtualAssistant'; +import LoadingMessage from '@patternfly/virtual-assistant/dist/esm/LoadingMessage' + +export const BasicExample: React.FunctionComponent = () => ( + + + +); diff --git a/packages/module/src/VirtualAssistant/LoadingMessage.tsx b/packages/module/src/LoadingMessage/LoadingMessage.tsx similarity index 97% rename from packages/module/src/VirtualAssistant/LoadingMessage.tsx rename to packages/module/src/LoadingMessage/LoadingMessage.tsx index 10a6d958..fe7a0f9e 100644 --- a/packages/module/src/VirtualAssistant/LoadingMessage.tsx +++ b/packages/module/src/LoadingMessage/LoadingMessage.tsx @@ -59,7 +59,7 @@ const useStyles = createUseStyles({ } }) -export const LoadingMessageEntry = () => { +export const LoadingMessage = () => { const classes = useStyles(); return ( @@ -78,3 +78,5 @@ export const LoadingMessageEntry = () => { ); }; + +export default LoadingMessage; diff --git a/packages/module/src/LoadingMessage/index.ts b/packages/module/src/LoadingMessage/index.ts new file mode 100644 index 00000000..8386e1b3 --- /dev/null +++ b/packages/module/src/LoadingMessage/index.ts @@ -0,0 +1,3 @@ +export { default } from './LoadingMessage'; + +export * from './LoadingMessage'; \ No newline at end of file diff --git a/packages/module/src/index.ts b/packages/module/src/index.ts index 477c6c40..40c2a25c 100644 --- a/packages/module/src/index.ts +++ b/packages/module/src/index.ts @@ -1,5 +1,8 @@ // this file is autogenerated by generate-index.js, modifying it manually will have no effect +export { default as LoadingMessage } from './LoadingMessage'; +export * from './LoadingMessage'; + export { default as VirtualAssistant } from './VirtualAssistant'; export * from './VirtualAssistant'; From 645840338da1b4a3fb4267554d763600ef9df474 Mon Sep 17 00:00:00 2001 From: Cody Mitchell Date: Fri, 29 Mar 2024 10:06:24 -0400 Subject: [PATCH 4/5] Allow user to pass custom icon to loadingMessage --- .../examples/VirtualAssistant/VirtualAssistant.md | 4 +++- .../VirtualAssistant/VirtualAssistantLoadingMessage.tsx | 2 ++ packages/module/src/LoadingMessage/LoadingMessage.tsx | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistant.md b/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistant.md index 8c73798c..a2efaf16 100644 --- a/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistant.md +++ b/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistant.md @@ -17,6 +17,7 @@ sourceLink: https://github.com/patternfly/virtual-assistant/blob/main/packages/m import VirtualAssistant from '@patternfly/virtual-assistant/dist/dynamic/VirtualAssistant'; import VirtualAssistantAction from '@patternfly/virtual-assistant/dist/dynamic/VirtualAssistantAction'; import LoadingMessage from '@patternfly/virtual-assistant/dist/dynamic/LoadingMessage'; +import { GrinIcon } from '@patternfly/react-icons'; import { AngleDownIcon } from '@patternfly/react-icons'; The **virtual assistant** component renders body of the virtual assistant window. @@ -65,7 +66,8 @@ Custom actions can be added to the assistant body using the `actions` property. ### Loading Messages -The LoadingMessage component displays a typing indicator for messages that are still processing, adding an artificial delay to create a more natural conversation flow. +The `LoadingMessage` component shows a typing indicator for messages still being processed, introducing an intentional delay to simulate a smoother flow of conversation. Additionally, it allows for the use of a custom icon through the `icon` property. + ```js file="./VirtualAssistantLoadingMessage.tsx" diff --git a/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistantLoadingMessage.tsx b/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistantLoadingMessage.tsx index f8204121..c032b755 100644 --- a/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistantLoadingMessage.tsx +++ b/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/VirtualAssistant/VirtualAssistantLoadingMessage.tsx @@ -1,9 +1,11 @@ import React from 'react'; import VirtualAssistant from '@patternfly/virtual-assistant/dist/dynamic/VirtualAssistant'; import LoadingMessage from '@patternfly/virtual-assistant/dist/esm/LoadingMessage' +import GrinIcon from '@patternfly/react-icons/dist/js/icons/bacon-icon'; export const BasicExample: React.FunctionComponent = () => ( + ); diff --git a/packages/module/src/LoadingMessage/LoadingMessage.tsx b/packages/module/src/LoadingMessage/LoadingMessage.tsx index fe7a0f9e..dfede7ea 100644 --- a/packages/module/src/LoadingMessage/LoadingMessage.tsx +++ b/packages/module/src/LoadingMessage/LoadingMessage.tsx @@ -59,13 +59,17 @@ const useStyles = createUseStyles({ } }) -export const LoadingMessage = () => { +export interface LoadingMessageProps { + icon?: React.ComponentClass; +} + +export const LoadingMessage: React.FunctionComponent = ({ icon: IconComponent = RobotIcon }) => { const classes = useStyles(); return ( - + From ab583e2691501b6705341e7c2ecf5b713508383f Mon Sep 17 00:00:00 2001 From: Filip Hlavac <50696716+fhlavac@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:31:45 +0200 Subject: [PATCH 5/5] Add initial contribution guide to README.md --- README.md | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7cf031e5..e4fba9d4 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,133 @@ # PatternFly Virtual Assistant -This repo contains react virtual assistant implementation. +This repo contains React Virtual assistant implementation. --- +## Contribution guide -## Building for production +### To add a new assistant sub-component: +1. create a folder in `src/` matching its name (for example `src/MyComponent`) +2. to the new folder add a new `.tsx` file named after the component (for example `src/MyComponent/MyComponent.tsx`) +3. to the same folder include an `index.ts` which will export the component as a default and then all necessary interfaces +4. if this file structure is not met, your component won't be exposed correctly + +#### Example component: +``` +import * as React from 'react'; +import { Text } from '@patternfly/react-core'; +import { createUseStyles } from 'react-jss'; + +// do not forget to export your component's interface +// always place the component's interface above the component itself in the code +export interface MyComponentProps { + text: String; +} + +const useStyles = createUseStyles({ + myText: { + fontFamily: 'monospace', + fontSize: 'var(--pf-v5-global--icon--FontSize--md)', + }, +}) + +// do not use the named export of your component, just a default one +const MyComponent: React.FunctionComponent = () => { + const classes = useStyles(); + + return ( + + This is my new component + + ); +}; + +export default MyComponent; +``` + +#### Index file example: +``` +export { default } from './MyComponent'; +export * from './MyComponent'; +``` + +#### Component directory structure example: +``` +src +|- MyComponent + |- index.ts + |- MyComponent.tsx +``` + +### Component's API rules: +- prop names comply with PatternFly components naming standards (`variant`, `onClick`, `position`, etc.) +- the API is maximally simplified and all props are provided with a description +- it is built on top of existing PatternFly types without prop omitting +- it is well documented using the PatternFly documentation (`/packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/MyComponent/MyComponent.md`) with examples of all possible use cases (`packages/module/patternfly-docs/content/extensions/virtual-assistant/examples/MyComponent/MyComponent[...]Example.tsx`) + +#### Component API definition example: +``` +// when possible, extend available PatternFly types +export interface MyComponentProps extends ButtonProps { + customLabel: Boolean +}; + +export const MyComponent: React.FunctionComponent = ({ customLabel, ...props }) => ( ... ); +``` + +#### Markdown file example: +``` +--- +section: extensions +subsection: Virtual assistant +id: MyComponent +propComponents: ['MyComponent'] +--- + +import MyComponent from "@patternfly/virtual-assistant/dist/dynamic/MyComponent"; +## Component usage + +MyComponent has been created to demo contributing to this repository. + +### MyComponent component example label + +```js file="./MyComponentExample.tsx"``` + +``` + +#### Component usage file example: (`MyComponentExample.tsx`) +``` +import React from 'react'; + +const MyComponentExample: React.FunctionComponent = () => ( + +); + +export default BatteryLowExample; +``` + +### Sub-components: +When adding a component for which it is advantageous to divide it into several sub-components make sure: +- component and all its sub-components are located in separate files and directories straight under the `src/` folder +- sub-components are exported and documented separately from their parent +- parent component should provide a way to pass props to all its sub-components + +The aim is to enable the user of our "complex" component to use either complete or take advantage of its sub-components and manage their composition independently. + +### Testing: +When adding/making changes to a component, always make sure your code is tested: +- use React Testing Library for testing +- add tests to a `[ComponentName].test.tsx` file to your component's directory +- make sure all the core logic is covered + +### Styling: +- for styling always use JSS +- new classNames should be named in camelCase starting with the name of a given component and following with more details clarifying its purpose/component's subsection to which the class is applied (`actionMenu`, `actionMenuDropdown`, `actionMenuDropdownToggle`, etc.) +- do not use `pf-v5-u-XXX` classes, use CSS variables in a custom class instead (styles for the utility classes are not bundled with the standard patternfly.css - it would require the consumer to import also addons.css) + +--- + +## Building for production - run npm install - run npm run build @@ -18,7 +140,6 @@ This repo contains react virtual assistant implementation. - run npm run lint to run the linter ## A11y testing - - run npm run build:docs followed by npm run serve:docs, then run npm run test:a11y in a new terminal window to run our accessibility tests. Once the accessibility tests have finished running you can run - npm run serve:a11y to locally view the generated report