From 022988a54e44ba9fdedc1fd0bc31c8be6af8a40f Mon Sep 17 00:00:00 2001 From: Erik Hanchett Date: Wed, 11 Dec 2024 15:09:02 -0800 Subject: [PATCH] Added new badge and message for AI kit (#8110) Co-authored-by: dindjarinjs <187552781+dindjarinjs@users.noreply.github.com> --- mdx-components.tsx | 2 + src/components/AIBanner/AIBanner.tsx | 43 +++++++++++++++++++ .../AIBanner/__tests__/AIBanner.test.tsx | 13 ++++++ src/components/AIBanner/index.tsx | 1 + src/components/Layout/Layout.tsx | 3 ++ src/components/Menu/MenuItem.tsx | 3 +- src/directory/directory.d.ts | 5 +++ src/pages/[platform]/ai/index.mdx | 1 + src/styles/banner.scss | 22 ++++++++++ src/styles/styles.scss | 1 + 10 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/components/AIBanner/AIBanner.tsx create mode 100644 src/components/AIBanner/__tests__/AIBanner.test.tsx create mode 100644 src/components/AIBanner/index.tsx create mode 100644 src/styles/banner.scss diff --git a/mdx-components.tsx b/mdx-components.tsx index a587becd6b3..7ce3e403259 100644 --- a/mdx-components.tsx +++ b/mdx-components.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import type { MDXComponents } from 'mdx/types'; import ExportedImage from 'next-image-export-optimizer'; +import { AIBanner } from './src/components/AIBanner'; import InlineFilter from './src/components/InlineFilter'; import { YoutubeEmbed } from './src/components/YoutubeEmbed'; import { Accordion } from './src/components/Accordion'; @@ -64,6 +65,7 @@ export function useMDXComponents(components: MDXComponents): MDXComponents { InlineFilter, MigrationAlert, YoutubeEmbed, + AIBanner, Overview, ExternalLink, ExternalLinkButton, diff --git a/src/components/AIBanner/AIBanner.tsx b/src/components/AIBanner/AIBanner.tsx new file mode 100644 index 00000000000..fd4db18e93a --- /dev/null +++ b/src/components/AIBanner/AIBanner.tsx @@ -0,0 +1,43 @@ +import { Flex, Message, IconsProvider, Text } from '@aws-amplify/ui-react'; +import { IconStar, IconChevron } from '../Icons'; +import { Button } from '@aws-amplify/ui-react'; + +export const AIBanner: React.FC = () => { + const URL = '/react/ai/set-up-ai/'; + return ( + + } + }} + > + + + + + Amplify AI kit is now generally available + + + Create fullstack AI-powered apps with TypeScript, no prior + experience in cloud architecture or AI needed. + + + + + + + + ); +}; diff --git a/src/components/AIBanner/__tests__/AIBanner.test.tsx b/src/components/AIBanner/__tests__/AIBanner.test.tsx new file mode 100644 index 00000000000..60110d8ed8d --- /dev/null +++ b/src/components/AIBanner/__tests__/AIBanner.test.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { AIBanner } from '../index'; + +describe('AIBanner', () => { + it('should render the AIBanner component', async () => { + const bannerText = 'Amplify AI kit is now generally available'; + render(); + + const component = await screen.findByText(bannerText); + expect(component).toBeInTheDocument(); + }); +}); diff --git a/src/components/AIBanner/index.tsx b/src/components/AIBanner/index.tsx new file mode 100644 index 00000000000..8cf7601c7bb --- /dev/null +++ b/src/components/AIBanner/index.tsx @@ -0,0 +1 @@ +export { AIBanner } from './AIBanner'; diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 4638d637994..b3419509203 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -29,6 +29,7 @@ import type { HeadingInterface } from '@/components/TableOfContents/TableOfConte import { Breadcrumbs } from '@/components/Breadcrumbs'; import { debounce } from '@/utils/debounce'; import '@docsearch/css'; +import { AIBanner } from '@/components/AIBanner'; import { usePathWithoutHash } from '@/utils/usePathWithoutHash'; import { NextPrevious, @@ -71,6 +72,7 @@ export const Layout = ({ const basePath = 'docs.amplify.aws'; const metaUrl = url ? url : basePath + asPathWithNoHash; const pathname = router.pathname; + const shouldShowAIBanner = asPathWithNoHash === '/'; const isGen1 = asPathWithNoHash.split('/')[1] === 'gen1'; const isContributor = asPathWithNoHash.split('/')[1] === 'contribute'; const currentGlobalNavMenuItem = isContributor ? 'Contribute' : 'Docs'; @@ -272,6 +274,7 @@ export const Layout = ({ platform={currentPlatform} /> ) : null} + {shouldShowAIBanner ? : null} {useCustomTitle ? null : ( {pageTitle} )} diff --git a/src/components/Menu/MenuItem.tsx b/src/components/Menu/MenuItem.tsx index e49cbe2510f..6478c5de608 100644 --- a/src/components/Menu/MenuItem.tsx +++ b/src/components/Menu/MenuItem.tsx @@ -1,6 +1,6 @@ import { usePathWithoutHash } from '@/utils/usePathWithoutHash'; import { ReactElement, useContext, useEffect, useState, useMemo } from 'react'; -import { Link as AmplifyUILink, Flex } from '@aws-amplify/ui-react'; +import { Link as AmplifyUILink, Flex, Badge } from '@aws-amplify/ui-react'; import { IconExternalLink, IconChevron } from '@/components/Icons'; import Link from 'next/link'; import { JS_PLATFORMS, Platform, JSPlatform } from '@/data/platforms'; @@ -200,6 +200,7 @@ export function MenuItem({ className={`menu__list-item__link__inner ${listItemLinkInnerStyle}`} > {pageNode.title} + {pageNode.isNew && New} {children && hasVisibleChildren && level !== Levels.Category && ( )} diff --git a/src/directory/directory.d.ts b/src/directory/directory.d.ts index 5d1433a162b..ad0fd85e291 100644 --- a/src/directory/directory.d.ts +++ b/src/directory/directory.d.ts @@ -57,4 +57,9 @@ export type PageNode = { * This is being used for categories like Cli - Legacy and SDK */ hideChildrenOnBase?: boolean; + + /** + * This flag indicates that the item is new and will display a "new" badge + */ + isNew?: boolean; }; diff --git a/src/pages/[platform]/ai/index.mdx b/src/pages/[platform]/ai/index.mdx index edee3b692a2..efc70d6d257 100644 --- a/src/pages/[platform]/ai/index.mdx +++ b/src/pages/[platform]/ai/index.mdx @@ -4,6 +4,7 @@ import { getCustomStaticPath } from '@/utils/getCustomStaticPath'; export const meta = { title: 'AI kit', description: 'The quickest way for fullstack developers to build web apps with AI capabilities such as chat, conversational search, and summarization', + isNew: true, route: '/[platform]/ai', platforms: [ 'angular', diff --git a/src/styles/banner.scss b/src/styles/banner.scss new file mode 100644 index 00000000000..ab0330430b9 --- /dev/null +++ b/src/styles/banner.scss @@ -0,0 +1,22 @@ +.message-banner { + align-items: start; + /* Specificity to override Amplify UI color theme */ + &.amplify-message--info { + border: 1px solid var(--amplify-colors-purple-20); + background-color: var(--amplify-colors-purple-10); + @include darkMode { + background-color: var(--amplify-colors-purple-20); + } + } + .amplify-message__icon { + color: var(--amplify-colors-purple-80); + } + &__inner { + display: flex; + flex-direction: column; + align-items: flex-start; + } + &__heading { + font-weight: 700; + } +} diff --git a/src/styles/styles.scss b/src/styles/styles.scss index fa59b64e62c..c6958471e7b 100644 --- a/src/styles/styles.scss +++ b/src/styles/styles.scss @@ -9,6 +9,7 @@ @import './accordion.scss'; @import './block-switcher.scss'; @import './breadcrumbs.scss'; +@import './banner.scss'; @import './callout.scss'; @import './code.scss'; @import './color-switcher.scss';