diff --git a/.changeset/chatty-garlics-rest.md b/.changeset/chatty-garlics-rest.md new file mode 100644 index 0000000000..8ddd7ec8e6 --- /dev/null +++ b/.changeset/chatty-garlics-rest.md @@ -0,0 +1,6 @@ +--- +"@twilio-paste/chat-composer": patch +"@twilio-paste/core": patch +--- + +[Chat Composer] Increase max-height of ChatComposerContainer so that it's greater than the max-height of ChatComposer and doesn't create a vertical scrollbar when the default max-height is reached. diff --git a/cypress/integration/sitemap-vrt/constants.ts b/cypress/integration/sitemap-vrt/constants.ts index c7367f49f6..ec4ec6d669 100644 --- a/cypress/integration/sitemap-vrt/constants.ts +++ b/cypress/integration/sitemap-vrt/constants.ts @@ -279,6 +279,9 @@ export const SITEMAP = [ "/introduction/for-engineers/quickstart/", "/introduction/working-with-us/", "/new", + "/experiences", + "/experiences/artificial-intelligence/", + "/experiences/navigation/", "/page-templates/", "/page-templates/object-details/", "/page-templates/objects-list/", @@ -291,7 +294,6 @@ export const SITEMAP = [ "/patterns/", "/patterns/empty-state/", "/patterns/error-state/", - "/patterns/navigation/", "/patterns/notifications-and-feedback/", "/patterns/privacy/", "/patterns/status/", diff --git a/packages/paste-core/components/chat-composer/src/ChatComposerContainer.tsx b/packages/paste-core/components/chat-composer/src/ChatComposerContainer.tsx index 5c2952719e..7d17dfb950 100644 --- a/packages/paste-core/components/chat-composer/src/ChatComposerContainer.tsx +++ b/packages/paste-core/components/chat-composer/src/ChatComposerContainer.tsx @@ -42,7 +42,7 @@ export interface ChatComposerContainerProps { } export const ChatComposerContainer = React.forwardRef( - ({ variant = "default", element = "CHAT_COMPOSER_CONTAINER", maxHeight = "size30", children, ...props }, ref) => { + ({ variant = "default", element = "CHAT_COMPOSER_CONTAINER", maxHeight = "size40", children, ...props }, ref) => { const [isDisabled, setIsDisabled] = React.useState(false); return ( diff --git a/packages/paste-website/next.config.mjs b/packages/paste-website/next.config.mjs index fc0dbe5256..f9222bab6d 100644 --- a/packages/paste-website/next.config.mjs +++ b/packages/paste-website/next.config.mjs @@ -63,6 +63,7 @@ const nextConfig = { permanent: true, }, { source: "/articles", destination: "/blog", permanent: true }, + { source: "/patterns/navigation", destination: "/experiences/navigation", permanent: true }, ]; }, // https://nextjs.org/docs/pages/api-reference/next-config-js/headers diff --git a/packages/paste-website/scripts/fetch-data.mjs b/packages/paste-website/scripts/fetch-data.mjs index 17e60be814..15ec9435e9 100644 --- a/packages/paste-website/scripts/fetch-data.mjs +++ b/packages/paste-website/scripts/fetch-data.mjs @@ -29,7 +29,7 @@ const getCategory = (pkgPath) => { return ""; }; -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, consistent-return const getAllPatterns = async () => { try { const patterns = await systemTable @@ -47,7 +47,7 @@ const getAllPatterns = async () => { } }; -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, consistent-return const getAllPageTemplates = async () => { try { const patterns = await systemTable @@ -65,7 +65,24 @@ const getAllPageTemplates = async () => { } }; -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/explicit-function-return-type +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, consistent-return +const getAllExperiences = async () => { + try { + const experiences = await systemTable + .select({ + filterByFormula: 'AND({Component Category} = "experience", Documentation, status, status != "in development")', + sort: [{ field: "Feature" }], + fields: ["Feature", "status"], + }) + .all(); + return experiences.map(({ fields }) => fields); + } catch (error) { + // eslint-disable-next-line no-console + console.log("getAllExperiences fetch error:", error); + } +}; + +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type const getAllPackages = async () => { try { const root = path.resolve(process.cwd(), "../"); @@ -81,6 +98,7 @@ const getAllPackages = async () => { allPasteThemePackage: [], allPastePattern: [], allPastePageTemplate: [], + allPasteExperience: [], }; packages.forEach(async (packageJson) => { @@ -99,6 +117,9 @@ const getAllPackages = async () => { const pageTemplates = await getAllPageTemplates(); data.allPastePageTemplate = [...pageTemplates]; + const experiences = await getAllExperiences(); + data.allPasteExperience = [...experiences]; + await fs.mkdir(dataPath, { recursive: true }, (err) => { if (err) { // eslint-disable-next-line no-console diff --git a/packages/paste-website/src/assets/images/patterns/navigation-pattern.png b/packages/paste-website/src/assets/images/experiences/navigation-pattern.png similarity index 100% rename from packages/paste-website/src/assets/images/patterns/navigation-pattern.png rename to packages/paste-website/src/assets/images/experiences/navigation-pattern.png diff --git a/packages/paste-website/src/assets/images/patterns/navigation-sidebar.png b/packages/paste-website/src/assets/images/experiences/navigation-sidebar.png similarity index 100% rename from packages/paste-website/src/assets/images/patterns/navigation-sidebar.png rename to packages/paste-website/src/assets/images/experiences/navigation-sidebar.png diff --git a/packages/paste-website/src/assets/images/patterns/navigation-topbar.png b/packages/paste-website/src/assets/images/experiences/navigation-topbar.png similarity index 100% rename from packages/paste-website/src/assets/images/patterns/navigation-topbar.png rename to packages/paste-website/src/assets/images/experiences/navigation-topbar.png diff --git a/packages/paste-website/src/assets/images/patterns/navigation-wireframe.png b/packages/paste-website/src/assets/images/experiences/navigation-wireframe.png similarity index 100% rename from packages/paste-website/src/assets/images/patterns/navigation-wireframe.png rename to packages/paste-website/src/assets/images/experiences/navigation-wireframe.png diff --git a/packages/paste-website/src/assets/images/system.png b/packages/paste-website/src/assets/images/system.png index 4673c7f854..b577af2c46 100644 Binary files a/packages/paste-website/src/assets/images/system.png and b/packages/paste-website/src/assets/images/system.png differ diff --git a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx index 733db4d37a..17f2085deb 100644 --- a/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx +++ b/packages/paste-website/src/components/site-wrapper/sidebar/SidebarNavigation.tsx @@ -60,8 +60,14 @@ const SiteSidebarNavigation = (): JSX.Element => { const pathname = useLocationPathname(); // take airtable feature data and mutate it into navigation data - const { allPasteComponent, allPasteLayout, allPastePrimitive, allPastePattern, allPastePageTemplate } = - getNormalizedNavigationData(navigationData); + const { + allPasteComponent, + allPasteLayout, + allPastePrimitive, + allPastePattern, + allPastePageTemplate, + allPasteExperience, + } = getNormalizedNavigationData(navigationData); const allComponentSidebarItems = [...allPasteComponent, ...allPasteLayout]; const filteredComponentSidebarItems = allComponentSidebarItems.sort(alphabetizeComponents); @@ -201,6 +207,14 @@ const SiteSidebarNavigation = (): JSX.Element => { ))} + + Overview + {allPasteExperience.map(({ name, slug }: { [key: string]: string }) => ( + + {name} + + ))} + - [U]sers expect the same immediate results from a digital toggle as they do from their real-world counterparts (e.g., + Users expect the same immediate results from a digital toggle as they do from their real-world counterparts (e.g., light switches). Immediate results are a facet of toggle switches that grants users the freedom and control to update their preferences as needed. diff --git a/packages/paste-website/src/pages/experiences/artificial-intelligence/index.mdx b/packages/paste-website/src/pages/experiences/artificial-intelligence/index.mdx new file mode 100644 index 0000000000..c26301e192 --- /dev/null +++ b/packages/paste-website/src/pages/experiences/artificial-intelligence/index.mdx @@ -0,0 +1,352 @@ +export const meta = { + title: 'Artificial Intelligence', + description: + 'AI experiences help our customers meet their goals better and faster through predictions, recommendations, and insights.', + slug: '/experiences/artificial-intelligence/', +}; + +import { SidebarCategoryRoutes } from "../../../constants"; +import {ResponsiveImage} from '../../../components/ResponsiveImage'; +import {Blockquote} from '../../../components/Blockquote'; +import {Anchor} from '@twilio-paste/anchor'; +import {ArtificialIntelligenceIcon} from '@twilio-paste/icons/esm/ArtificialIntelligenceIcon'; +import {Button} from '@twilio-paste/button'; +import {ButtonGroup} from '@twilio-paste/button-group'; +import {Badge} from '@twilio-paste/badge'; +import {Box} from '@twilio-paste/box'; +import {ChatComposerContainer, ChatComposer, ChatComposerActionGroup} from '@twilio-paste/chat-composer'; +import {SendIcon} from '@twilio-paste/icons/esm/SendIcon'; +import {Label} from '@twilio-paste/label'; +import {TextArea} from '@twilio-paste/textarea'; +import {HelpText} from '@twilio-paste/help-text'; +import {Callout, CalloutHeading, CalloutText} from '@twilio-paste/callout'; +import {Heading} from '@twilio-paste/heading'; +import {Popover, PopoverContainer, PopoverButton} from '@twilio-paste/popover'; +import {NewIcon} from '@twilio-paste/icons/esm/NewIcon'; +import { ProductMessagingIcon } from "@twilio-paste/icons/esm/ProductMessagingIcon"; +import { ProductSendGridIcon } from "@twilio-paste/icons/esm/ProductSendGridIcon"; +import { ProductCLIIcon } from "@twilio-paste/icons/esm/ProductCLIIcon"; +import {Paragraph} from '@twilio-paste/paragraph'; +import DefaultLayout from '../../../layouts/DefaultLayout'; +import {getFeature, getNavigationData} from '../../../utils/api'; + +export default DefaultLayout; + +export const getStaticProps = async () => { + const navigationData = await getNavigationData(); + const feature = await getFeature('Artificial Intelligence'); + return { + props: { + data: { + ...feature, + }, + navigationData, + }, + }; +}; + + + + + + + + + + + + + {` + + +How can I help? + + + { + throw e; + }, + }} + /> + + + + + + + + + + + + + + +`} + + +## About + +These AI experience guidelines are a starting point for designing AI-powered experiences at Twilio and provide a list of components and layouts to use. + +These guidelines reference “Twilio Segment’s AI Handbook for Product Development”. The full handbook includes information that can’t be publicly shared yet, including: + +- Which user problems AI solutions are and aren’t good for. +- A breakdown of customer types, user journeys, and AI feature types. +- Research insights on what customers consider high-risk vs. low-risk features. +- A list of biases to prevent against. +- Methods of conducting research at different design phases, especially when the AI model isn’t developed enough for customer testing. + +You can find a link in #seg-ai-handbook-feedback on Slack, or reach out to your design partner. + +## Twilio policies + +When developing AI features, ensure you: +- **(Mandatory)** Partner with the Legal and Privacy teams to communicate Twilio’s terms and conditions, and include any opt-in requirements. Start by submitting a Privacy Impact Assessment (more details in Switchboard). +- Follow Twilio’s AI approach, including the trust principles: **Transparent, Responsible, Accountable**. Refer to the AI Handbook for practical guidelines on how to achieve these principles. +- Review these policies: “Generative AI policy”, “AI responsible use policy”, and “Global procurement policy.” Links to each are in the AI handbook. + + + + Standardized legal language and opt-in guidance for AI features is in development + If you’re working on a new feature and need legal text, reach out in #help-design-system to get connected with teams who are working to standardize our legal language for AI. While this is happening, continue partnering with Privacy and Legal for your feature. + + + +## Designing AI features + +Start with these base design principles: +1. Follow Twilio AI policies. +2. Inform users about data privacy. +3. Ensure customers can evaluate AI outcomes, fast, by allowing them to compare those outcomes to their current experience. +4. “[Anchor on familiarity.](https://pair.withgoogle.com/guidebook/patterns#anchor-on-familiarity)” Consider how you would design your AI feature if it were any other feature. +5. Assume errors, risks, biases, and slowness will happen. Plan for them. +6. Give customers control of the output, including ways to undo, stop generating, control data sources, and give feedback. +7. Build customers’ confidence in the output. + +Helpful resources on how to design human-centered AI experiences: +- [Twilio’s generative AI design framework cards](https://www.figma.com/community/file/1392507403743352508/generative-ai-design-framework) +- [Shape of AI](https://www.shapeof.ai/) +- [Google’s people + AI guidebook](https://pair.withgoogle.com/guidebook) +- [Microsoft HAX toolkit](https://www.microsoft.com/en-us/haxtoolkit/) +- [Microsoft HAX playbook](https://microsoft.github.io/HAXPlaybook/?state=xxxxxxxx) for simulating error scenarios + +### Building trust when introducing your feature + +When using Twilio AI features, customers care most about **data privacy** and the **outcomes** of a feature compared to the “old way” of doing things. When introducing your feature: + +- Include information about how customer data is handled, including how it’s used for training models, information on vendors the data is shared with, and how customers can minimize giving [Personally Identifiable Information (PII)](https://www.twilio.com/docs/glossary/what-is-personally-identifiable-information-pii) when it’s not needed. Taking these steps helps customers understand whether Twilio features meet their own AI policies. +- Give customers the ability to compare AI-generated outcomes to their current experience. + +Based on your use case, you might also include information about how the AI model works and when customers’ data quality can improve AI feature performance. + +Since AI can power a wide range of features, customers can be unsure where to start. Use [Twilio’s generative AI design framework cards](https://www.figma.com/community/file/1392507403743352508/generative-ai-design-framework) and the [Shape of AI wayfinders](https://www.shapeof.ai/pattern-types/wayfinders) to prompt customers to the feature and describe it in a simple way, so that they can evaluate AI outcomes faster. When introducing the feature, let customers know: +- How they can give feedback +- How they can ask questions +- What they should consider as they use the feature so they can ask the _right questions_, especially about their data and generated outcomes. + +### Naming your feature + +While AI features are still in rapid development, work with your Product Marketing team on a name. As a default, start with the name “[Product or Feature] assistant”. + +### Designing interactions and layouts + +Just because AI features are new, doesn’t mean we need to invent entirely new visual and interaction patterns for them. Start by asking yourself first: **“How would I design this feature if it did the same thing but didn’t use AI?”** Remember that customers have specific goals and tasks to achieve, and the task is rarely just “To use AI”. Avoid being too heavy-handed with communicating how a feature has been built or changed with AI since introducing new interaction patterns and unnecessary messaging can distract from the customer’s goals. + +
+With AI-driven products, there can be a temptation to communicate the “newness” or “magic” of the system’s predictions through its UI metaphors. +However, unfamiliar UI touchpoints can make it harder for users to learn to use your system, potentially leading to degraded understanding of, or trust in, your product…Instead, anchor new users with familiar UI patterns and features. +
+ +With AI features, there’s also a higher chance for things to go wrong. Be proactive about risks, error handling, and confidence: +- Give customers the ability to review, edit, undo, and give feedback on output. +- Design for poor data, common errors, biases, and customers being overly dependent on AI suggestions. Use the [error state pattern](/patterns/error-state) for ways to message errors. +- Show clear information that AI-generated output can be wrong or irrelevant. +- Give customers a manual option to solve their problem as an “escape hatch” when AI fails. +- Show data sources. Even better, let customers control data sources, or show our own level of confidence in the output. +- While the output is generating, give customers a way to control the flow of and anticipate the output. This includes a way to stop generating and adapting loading states based on the amount of time we expect it’ll take for output to generate. +- Use the [Microsoft HAX Playbook](https://microsoft.github.io/HAXPlaybook/?state=xxxxxxxx) for simulating error scenarios based on your AI scenario + +Remember that these methods are about building confidence, so not every one of them must be used. Use [Twilio’s generative AI design framework cards](https://www.figma.com/community/file/1392507403743352508/generative-ai-design-framework) for a list of output types, ways to give customers control, and ways to collect feedback. You can use the cards to generate different combinations of design options, and evaluate your design against other design alternatives. You can also use these cards in customer research to help customers better articulate and understand what they’d like to change about the feature. + +During your pilot or beta, collect customer feedback at least twice. Compared to older technologies, users’ perceptions and needs about AI will change over a shorter amount of time as they grow more familiar with the tool. Engage with your Research team so you can get more specific insights to your feature. + +### Content produced by AI + +In addition to AI features, content you produce with the help of AI should adhere to these basic guidelines: +- If a substantial amount of your work relied on AI, clearly state that. If possible, link to the model you used. +- Fact check the AI-produced content. LLMs produce hallucinations, resulting in content that is inconsistent with real-work facts or user inputs. +- Make sure the AI-produced content doesn’t violate Twilio policies, especially copyright and intellectual property. +- Verify that the model has a permissive license that allows output to be used for commercial purposes. + +Learn more on the [Twilio Style Guide](https://library.twilio.com/guidelines/guide/1b8c14a4-287d-47a4-8ac6-1621bfe97a6d/page/34720f98-b7f8-4436-8e66-4f814801eec1) and our “Generative AI policy”. + +--- + +## Ingredients + +The AI UI Kit includes these components: +- [ArtificialIntelligenceIcon](/components/icon) +- [Badge](/components/badge) +- [Button](/components/button) +- [Progress Bar](/components/progress-bar) +- [Skeleton Loader](/components/skeleton-loader) + +Components also used for AI chat experiences: +- [AI Chat Log](/components/ai-chat-log) +- [Avatar](/components/avatar) +- [Chat Composer](/components/chat-composer) +- [Side Panel](/components/side-panel) + +Related patterns: +- [Error state](/patterns/error-state) + + + + Need more AI components? + Our AI Kit was first designed primarily with chat and basic predictive and generative experiences in mind. If these components and patterns don’t meet your needs, please let us know in a Github Discussion. + + + +## Examples + +### Signposting + +When you need to indicate that a feature is using AI for transparency and/or marketing, use a `decorative20` Badge and the ArtificialIntelligenceIcon to help customers quickly identify these features, especially for: +- Recommendations +- Predictions and insights +- Automated tasks + +If you need to highlight the feature even more, use the marketing [Card](/components/card#marketing-card) guidelines, and partner with the Brand team. + +Keep in mind that over time, more and more of our features will use AI. Evaluate an experience holistically, and use AI badges and marketing when they matter most. Don’t blanket an experience in AI marketing at the expense of other business goals. + + + {` + Twilio AI +`} + + +### Generative feature + +Use [Twilio’s generative AI design framework cards](https://www.figma.com/community/file/1392507403743352508/generative-ai-design-framework) and the [Shape of AI wayfinders](https://www.shapeof.ai/pattern-types/wayfinders) to prompt customers to a generative AI feature. + + + {` + Help me build + + Help me buildBeta + Describe the audience you want to create and CustomerAI will help build it. Powered by OpenAI. Learn more + + +