diff --git a/apps/website/pages/components/image/usage.tsx b/apps/website/pages/components/image/usage.tsx new file mode 100644 index 000000000..622c520f7 --- /dev/null +++ b/apps/website/pages/components/image/usage.tsx @@ -0,0 +1,21 @@ +import Head from "next/head"; +import type { ReactElement } from "react"; +import ImagePageLayout from "../../../screens/components/image/ImagePageLayout"; +import ImageUsagePage from "../../../screens/components/image/usage/ImageUsagePage"; + +const Usage = () => { + return ( + <> + + Image Usage — Halstack Design System + + + + ); +}; + +Usage.getLayout = function getLayout(page: ReactElement) { + return {page}; +}; + +export default Usage; diff --git a/apps/website/screens/common/MainContent.tsx b/apps/website/screens/common/MainContent.tsx index 05ea75e0b..0eb6b6eb4 100644 --- a/apps/website/screens/common/MainContent.tsx +++ b/apps/website/screens/common/MainContent.tsx @@ -1,29 +1,26 @@ import { useToast } from "@dxc-technology/halstack-react"; -import { ReactNode, useMemo, useState, useEffect } from "react"; +import { ReactNode, useState, useEffect } from "react"; import styled from "styled-components"; import { responsiveSizes } from "./variables"; const MainContainer = styled.div` - margin: 80px 0; + margin: 80px auto; max-width: 1124px; - margin-inline: max(5%, 50% - 1124px/2); + padding: 0 5%; @media (max-width: ${responsiveSizes.laptop}px) { margin: 80px 32px; } `; +const pathVersion = + process.env.NEXT_PUBLIC_SITE_VERSION === "next" || process.env.NODE_ENV === "development" + ? 0 + : parseInt(process.env.NEXT_PUBLIC_SITE_VERSION?.split(".")[0], 10); + const MainContent = ({ children }: { children: ReactNode }) => { const toast = useToast(); - const pathVersion = useMemo( - () => - process.env.NEXT_PUBLIC_SITE_VERSION === "next" || process.env.NODE_ENV === "development" - ? 0 - : parseInt(process.env.NEXT_PUBLIC_SITE_VERSION?.split(".")[0], 10), - - [] - ); - const [latestRelease, setLatestRelease] = useState(null); + const [latestRelease, setLatestRelease] = useState(null); useEffect(() => { (async () => { @@ -39,7 +36,7 @@ const MainContent = ({ children }: { children: ReactNode }) => { }, []); useEffect(() => { - if (latestRelease > pathVersion) { + if (pathVersion && latestRelease && latestRelease > pathVersion) { toast.info({ message: `Halstack ${latestRelease} is now available!`, action: { @@ -54,7 +51,7 @@ const MainContent = ({ children }: { children: ReactNode }) => { }, }); } - }, [latestRelease, pathVersion, toast]); + }, [latestRelease, toast]); return {children}; }; diff --git a/apps/website/screens/common/componentsList.json b/apps/website/screens/common/componentsList.json index 36e361338..aea357ea2 100644 --- a/apps/website/screens/common/componentsList.json +++ b/apps/website/screens/common/componentsList.json @@ -29,7 +29,7 @@ { "label": "Container", "path": "/components/container", - "status": "new" + "status": "stable" }, { "label": "Contextual Menu", @@ -63,7 +63,7 @@ { "label": "Grid", "path": "/components/grid", "status": "stable" }, { "label": "Header", "path": "/components/header", "status": "stable" }, { "label": "Heading", "path": "/components/heading", "status": "stable" }, - { "label": "Image", "path": "/components/image", "status": "experimental" }, + { "label": "Image", "path": "/components/image", "status": "stable" }, { "label": "Inset", "path": "/components/inset", "status": "stable" }, { "label": "Link", "path": "/components/link", "status": "stable" }, { "label": "Nav Tabs", "path": "/components/nav-tabs", "status": "stable" }, diff --git a/apps/website/screens/components/flex/usage/FlexUsagePage.tsx b/apps/website/screens/components/flex/usage/FlexUsagePage.tsx index 17a25d71a..7fbcd8da6 100644 --- a/apps/website/screens/components/flex/usage/FlexUsagePage.tsx +++ b/apps/website/screens/components/flex/usage/FlexUsagePage.tsx @@ -5,6 +5,27 @@ import QuickNavContainer from "@/common/QuickNavContainer"; import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; const sections = [ + { + title: "Overview", + content: ( + <> + + The Flex component is designed to provide a more efficient way to organize, align, and distribute space among + items within a container, even when their size is unknown or dynamic (hence the term 'flex'). + + + By leveraging the capabilities of the Flex component, developers can create more flexible and responsive + layouts that adapt to different screen sizes and device types. This powerful tool enables the creation of + complex structures that can be easily adjusted to accommodate various content types and user interactions. + + + In the sections that follow, we'll explore the core concepts and best practices for using the Flex component. + By understanding these principles, you can optimize the layout of your application, enhance the user experience, + and create more engaging and visually appealing interfaces. + + + ), + }, { title: "Axes", content: ( diff --git a/apps/website/screens/components/image/ImagePageLayout.tsx b/apps/website/screens/components/image/ImagePageLayout.tsx index 968e6ba23..5bbfd4322 100644 --- a/apps/website/screens/components/image/ImagePageLayout.tsx +++ b/apps/website/screens/components/image/ImagePageLayout.tsx @@ -4,7 +4,10 @@ import TabsPageHeading from "@/common/TabsPageLayout"; import ComponentHeading from "@/common/ComponentHeading"; const ImagePageHeading = ({ children }: { children: React.ReactNode }) => { - const tabs = [{ label: "Code", path: "/components/image" }]; + const tabs = [ + { label: "Code", path: "/components/image" }, + { label: "Usage", path: "/components/image/usage" }, + ]; return ( diff --git a/apps/website/screens/components/image/usage/ImageUsagePage.tsx b/apps/website/screens/components/image/usage/ImageUsagePage.tsx new file mode 100644 index 000000000..410789c41 --- /dev/null +++ b/apps/website/screens/components/image/usage/ImageUsagePage.tsx @@ -0,0 +1,156 @@ +import { DxcImage, DxcParagraph, DxcFlex, DxcBulletedList } from "@dxc-technology/halstack-react"; +import Code from "@/common/Code"; +import DocFooter from "@/common/DocFooter"; +import QuickNavContainer from "@/common/QuickNavContainer"; +import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; + +const sections = [ + { + title: "Overview", + content: ( + <> + + The Image component serves as a versatile tool for efficiently loading and displaying visual content across + diverse contexts within your application. This powerful component is designed to optimize performance while + enhancing the overall user experience. By leveraging its capabilities, developers can seamlessly integrate + images into their projects, ensuring smooth rendering and responsive behavior. + + + To maximize the potential of the Image component and create visually appealing, high-performing applications, + it's crucial to adhere to certain best practices and usage guidelines. These recommendations encompass various + aspects of image implementation, from technical considerations to user-centric design principles. By following + these guidelines, you can ensure that your images not only load quickly and efficiently but also contribute + positively to the user's interaction with your application. + + + In the sections that follow, we'll delve into a comprehensive set of best practices and usage guidelines. + These insights will help you optimize performance, enhance accessibility, and create a more engaging visual + experience for your users across different devices and contexts. + + + ), + }, + { + title: "Accessibility", + content: ( + <> + + The Image component should always include an alt property to describe the content of the image. + This is important for users who rely on screen readers to understand the content of the page. The alt text + should be a short description of the image content. + + + If an image is purely decorative, use an empty value (alt="") to indicate this to screen readers, + preventing unnecessary noise. Also, include captions when the image is an integral part of the content, + providing users with additional context. + + + ), + }, + { + title: "Aspect ratio and cropping", + content: ( + + + Preserve aspect ratio. The aspect ratio of an image should generally be preserved, unless + explicitly specified otherwise by the design. + + + Avoid distortion. When resizing images, avoid stretching or squashing them to prevent + distortion. Instead, use object-fit to set how the image is displayed or control the dimensions + through the container. + + + Thumbnails and zoom. When displaying thumbnails or zoomed images, ensure that the image is + cropped appropriately to focus on the most relevant content. + + + ), + }, + { + title: "Considerations for background images", + content: ( + + + Image as content vs. background. If the image is essential content, use the Image component. + For decorative backgrounds, consider using CSS background images to keep content and design separate. + + + Contrast and readability. Ensure sufficient contrast between background images and overlaid + text. This may require applying filters or overlays to the image. + + + ), + }, + { + title: "Responsiveness", + content: ( + + An image should always adapt fluidly to the size of its container, ensuring that it maintains its aspect ratio + unless otherwise specified. To achieve this, it's important to define the width and height properties to ensure + images are loaded with known dimensions, which helps maintain layout stability and reduces cumulative layout + shifts. When designing for multiple devices, leveraging responsive image techniques, such as the{" "} + srcset and + sizes props, ensures that the appropriate resolution is served based on the user's screen size and + the layout's space allocation. This not only improves performance but also optimizes the experience across + different viewports. + + ), + }, + { + title: "Best practices", + content: ( + + + Use high-quality images. Always use high-resolution images to deliver a crisp and clear + display, especially on high-density (retina) screens. This ensures a professional look and prevents + pixelation. + + + Optimize images. Compress and optimize images for the web to minimize file sizes. Reducing + load times and bandwidth consumption is crucial for performance, especially on mobile devices. + + + Leverage modern formats. Whenever possible, use newer image formats like WebP for improved + compression without sacrificing quality. Be sure to provide fallback formats for browsers that don't support + them. + + + Allow lazy loading. Implement lazy loading (loading="lazy") for images that + appear later on the page (below the fold). This helps speed up initial page loads and improve overall + performance. + + + Use responsive image techniques. Make use of srcset and sizes props + to serve images that adapt to different screen resolutions and sizes, ensuring the best display quality across + devices. + + + Avoid using images for text content. Text embedded within images reduces accessibility and + harms SEO. Always use HTML text to ensure readability by screen readers and search engines. + + + Limit decorative images. Avoid overloading pages with unnecessary decorative images. This not + only reduces performance but can also distract users from the main content. + + + Avoid images for icons. Use scalable vector graphics (SVGs) instead of images for icons. SVGs + offer better performance, scalability, and accessibility across various screen sizes. + + + ), + }, +]; + +const ImageUsagePage = () => { + return ( + + + + + + + ); +}; + +export default ImageUsagePage; diff --git a/apps/website/screens/components/tabs/usage/TabsUsagePage.tsx b/apps/website/screens/components/tabs/usage/TabsUsagePage.tsx index 6d019c0a2..7f73ab74b 100644 --- a/apps/website/screens/components/tabs/usage/TabsUsagePage.tsx +++ b/apps/website/screens/components/tabs/usage/TabsUsagePage.tsx @@ -4,7 +4,6 @@ import QuickNavContainer from "@/common/QuickNavContainer"; import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; import Figure from "@/common/Figure"; import DocFooter from "@/common/DocFooter"; -import tabsUsage from "./examples/usage"; import defaultUsage from "./examples/default"; import scrollableUsage from "./examples/scrollable"; import contentUsageTabImage from "./images/tabs_content.png"; @@ -27,7 +26,6 @@ const sections = [ Tabs organize and allow navigation between groups of content that are related and at the same level of hierarchy. - ), }, diff --git a/apps/website/screens/components/tabs/usage/examples/usage.ts b/apps/website/screens/components/tabs/usage/examples/usage.ts deleted file mode 100644 index 0ab590747..000000000 --- a/apps/website/screens/components/tabs/usage/examples/usage.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { DxcTabs, DxcInset } from "@dxc-technology/halstack-react"; - -const code = `() => { - return ( - - - - - - - - - - - - - )} active> - <> - - - - - - )}> - <> - - - - - - )}> - <> - - - - ); -}`; - -const scope = { - DxcTabs, - DxcInset, -}; - -export default { code, scope }; diff --git a/packages/lib/src/link/Link.tsx b/packages/lib/src/link/Link.tsx index 396a1b0e9..44e1e05fe 100644 --- a/packages/lib/src/link/Link.tsx +++ b/packages/lib/src/link/Link.tsx @@ -7,7 +7,7 @@ import { LinkProps } from "./types"; const LinkContent = memo( ({ iconPosition, icon, inheritColor, children }: LinkProps): JSX.Element => ( - + {iconPosition === "after" && children} {icon && (