diff --git a/.storybook/routes.js b/.storybook/routes.js index f0dfd354fe..d0896bda64 100644 --- a/.storybook/routes.js +++ b/.storybook/routes.js @@ -3,10 +3,9 @@ // and will rewrite the URL to point to the correct URL for the story. The Storybook key will be // rewritten to something like `?path=/docs/${id}` const routes = { - '/assets/accent-icons/': 'tokens-icon--accent-icon', - '/assets/applet-icons/': 'tokens-icon--applet-icon', - '/assets/applet-icons/': 'tokens-icon--applet-icon', - '/assets/system-icons/': 'tokens-icon--system-icon', + '/assets/accent-icons/': 'assets-icons-list--accent-icon-list', + '/assets/applet-icons/': 'assets-icons-list--applet-icon-list', + '/assets/system-icons/': 'assets-icons-list--applet-icon-list', '/components/buttons/action-bar/': 'components-buttons-action-bar--basic', '/components/buttons/button/': 'components-buttons--primary', '/components/buttons/segmented-control/': 'preview-segmented-control--basic', diff --git a/modules/docs/mdx/11.0-UPGRADE-GUIDE.mdx b/modules/docs/mdx/11.0-UPGRADE-GUIDE.mdx index 19a4d17927..798a99a022 100644 --- a/modules/docs/mdx/11.0-UPGRADE-GUIDE.mdx +++ b/modules/docs/mdx/11.0-UPGRADE-GUIDE.mdx @@ -51,7 +51,9 @@ A note to the reader: - [Styling API and CSS Tokens](#styling-api-and-css-tokens) - [CountBadge](#count-badge) - [Form Field Preview](#form-field-preview) + - [Graphic](#graphic) - [Icons](#icons) + - [Image](#image) - [Status Indicator (Preview)](#status-indicator-preview) - [Table](#table) - [Text](#text) @@ -636,6 +638,12 @@ to check your logic to make sure it sets the appropaite value to the prop. > **Note:** If you use your own custom `input` you will need to handle the styling for error and > alert states. +### Graphic + +**PR:** [#3062](https://github.com/Workday/canvas-kit/pull/3062) + +We've updated `Graphic` and its `src` prop to accept a `string` value to support images loaded from a CDN or SAS. The previous API is still supported. + ### Icons
@@ -809,6 +817,13 @@ const MyComponent = StyledRadioButton('div')({ ; ``` +### Image + +**PR:** [#3062](https://github.com/Workday/canvas-kit/pull/3062) + +We've added a new `Image` component under the `@workday/canvas-kit-react/icon` package. This component renders an `img` element and is meant to be used when you need more control over the image attributes like aspect ratio or object fit. + + ### Status Indicator (Preview) diff --git a/modules/react/avatar/stories/stories.tsx b/modules/react/avatar/stories/stories.tsx index 9e3045a480..967a319f4e 100644 --- a/modules/react/avatar/stories/stories.tsx +++ b/modules/react/avatar/stories/stories.tsx @@ -61,13 +61,13 @@ storiesOf('Components/Indicators/Avatar', module) .add('Non-Square Image', () => (

Original Rectangle Image

- +

Using Object Fit on a Rectangle Image

- +

Original Square Image

- +

Using a Square Image

- +
)) .add('Lazy Loading', () => ( diff --git a/modules/react/icon/index.ts b/modules/react/icon/index.ts index af3173fe90..370e7c396c 100644 --- a/modules/react/icon/index.ts +++ b/modules/react/icon/index.ts @@ -3,4 +3,5 @@ export * from './lib/AppletIcon'; export * from './lib/SystemIcon'; export * from './lib/SystemIconCircle'; export * from './lib/Graphic'; +export * from './lib/Image'; export {Svg, SvgProps, svgStencil} from './lib/Svg'; diff --git a/modules/react/icon/lib/Graphic.tsx b/modules/react/icon/lib/Graphic.tsx index 6e9e4a73e5..5d4bd6733e 100644 --- a/modules/react/icon/lib/Graphic.tsx +++ b/modules/react/icon/lib/Graphic.tsx @@ -2,8 +2,9 @@ import * as React from 'react'; import {CanvasGraphic, CanvasIconTypes} from '@workday/design-assets-types'; import {CSSObject} from '@emotion/styled'; import {Svg, SvgProps, svgStencil} from './Svg'; -import {createComponent} from '@workday/canvas-kit-react/common'; +import {createComponent, ExtractProps} from '@workday/canvas-kit-react/common'; import {createStencil, handleCsProp, px2rem} from '@workday/canvas-kit-styling'; +import {Image} from './Image'; /** * @deprecated Interface `GraphicStyles` will be removed in a future version. `grow` prop will be moved inside `GraphicProps`. @@ -30,9 +31,13 @@ export interface GraphicProps extends GraphicStyles, Pick; + +export type GraphicsImageOrSvgProps = GraphicProps | GraphicsImageProps; + /** * @deprecated `graphicStyles` will be removed in in a future version as a part of implementation of stencils and new tokens. Consider to use `graphicStencil` instead. */ @@ -66,6 +71,18 @@ export const graphicStyles = ({width, height, grow}: GraphicStyles): CSSObject = return {}; }; +type GraphicImageProps = ExtractProps; + +/** + * Returns an overloaded functional component that uses Graphic props by default. + */ +type GraphicOverload = { + (props: {src: CanvasGraphic} & GraphicProps & {ref?: React.Ref}): React.ReactElement; + ( + props: {src: string} & GraphicImageProps & {ref?: React.Ref} + ): React.ReactElement; +}; + export const graphicStencil = createStencil({ extends: svgStencil, base: {}, @@ -79,23 +96,34 @@ export const graphicStencil = createStencil({ }, }); -export const Graphic = createComponent('span')({ +export const Graphic: GraphicOverload = createComponent('span')({ displayName: 'Graphic', - Component: ({grow, width, height, ...elemProps}: GraphicProps, ref, Element) => { + Component: ({src, ...elemProps}: GraphicProps, ref, Element) => { return ( - + {typeof src === 'string' && typeof src !== 'object' ? ( + + ) : ( + )} - /> + ); }, }); diff --git a/modules/react/icon/lib/Image.tsx b/modules/react/icon/lib/Image.tsx new file mode 100644 index 0000000000..885f091a87 --- /dev/null +++ b/modules/react/icon/lib/Image.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; + +import {createComponent} from '@workday/canvas-kit-react/common'; +import {CSProps, handleCsProp} from '@workday/canvas-kit-styling'; + +export interface ImageProps extends CSProps {} + +export const Image = createComponent('img')({ + displayName: 'Image', + Component: ({...elemProps}: ImageProps, ref, Element) => { + return ; + }, +}); diff --git a/modules/react/icon/stories/Assets.stories.mdx b/modules/react/icon/stories/Assets.stories.mdx deleted file mode 100644 index e17f19cb35..0000000000 --- a/modules/react/icon/stories/Assets.stories.mdx +++ /dev/null @@ -1,29 +0,0 @@ -import {SystemIconList} from './examples/IconList'; -import {AppletIconList} from './examples/AppletIconList'; -import{AccentIconList} from './examples/AccentIconList.tsx' -import {Overview} from './examples/Overview' - - - -# Assets -Assets are graphics which help communicate meaning or highlight areas of interaction to our users. These may be presented individually or as part of a group with related information in components and patterns. - - - -## Accent Icon List - -Accent Icons add clarity, and visual interest, they bring delight to the experience by communicating the overall tone and meaning of a page. - - - -## Applet Icon List - -Applet Icons convey entry points, categories of actions, or information sources on the Workday homepage. - - - -## System Icon List - -System Icons are symbols used to convey simple actions and functions, they are the most common icons encountered in products and help communicate metaphors at a glance. - - diff --git a/modules/react/icon/stories/IconsList.stories.mdx b/modules/react/icon/stories/IconsList.stories.mdx new file mode 100644 index 0000000000..127b17a32e --- /dev/null +++ b/modules/react/icon/stories/IconsList.stories.mdx @@ -0,0 +1,31 @@ +import {SystemIconList} from './examples/IconsList/IconList'; +import {AppletIconList} from './examples/IconsList/AppletIconList'; +import {AccentIconList} from './examples/IconsList/AccentIconList'; +import {Overview} from './examples/Overview' + + + +## Overview + + + +## Accent Icon List + +Accent Icons add clarity, and visual interest, they bring delight to the experience by communicating +the overall tone and meaning of a page. + + + +## Applet Icon List + +Applet Icons convey entry points, categories of actions, or information sources on the Workday +homepage. + + + +## System Icon List + +System Icons are symbols used to convey simple actions and functions, they are the most common icons +encountered in products and help communicate metaphors at a glance. + + diff --git a/modules/react/icon/stories/Image.stories.mdx b/modules/react/icon/stories/Image.stories.mdx new file mode 100644 index 0000000000..dc0feb4650 --- /dev/null +++ b/modules/react/icon/stories/Image.stories.mdx @@ -0,0 +1,52 @@ + +import {SymbolDoc} from '@workday/canvas-kit-docs'; +import {Basic} from './examples/Image/Basic'; +import {FromFileSystem} from './examples/Image/FromFileSystem'; + + + +# Canvas Kit Image + +Represents an `img` element. + +## Installation + +```sh +yarn add @workday/canvas-kit-react +``` + +## Usage + +## Basic + +The `Image` component is useful when trying to render raster files or images that need additional styling like aspect ratio or object fit. It renders an `img` element and therefore you have access to all [attributes and props](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) of a native `img` tag. + + + +## From File System + + + +## Accessibility + +### Alt Text (alt): +- Always provide descriptive alt text for images. This helps screen readers convey the purpose or content of the image to visually impaired users. +- Use meaningful descriptions that explain the image's context in the UI. +- If the image is decorative, use an empty alt attribute (alt=""), which signals assistive technologies to ignore the image. + +### Captioning (caption): + +- Include captions for images where additional explanatory text is required. +- Captions should be used for graphs, charts, or any image requiring a detailed explanation. + +### Role and ARIA Attributes: + +- Avoid adding ARIA roles such as role="img" unless the component uses non-standard HTML elements. +- Default `` elements are already recognized as images. +- Use ARIA attributes only when needed (e.g., aria-describedby for complex images with external descriptions). + +## API + + + + diff --git a/modules/react/icon/stories/examples/AccentIconList.tsx b/modules/react/icon/stories/examples/IconsList/AccentIconList.tsx similarity index 97% rename from modules/react/icon/stories/examples/AccentIconList.tsx rename to modules/react/icon/stories/examples/IconsList/AccentIconList.tsx index 06dfa1b238..7d728dadd7 100644 --- a/modules/react/icon/stories/examples/AccentIconList.tsx +++ b/modules/react/icon/stories/examples/IconsList/AccentIconList.tsx @@ -18,6 +18,8 @@ const styleOverrides = { }), iconGroupContainer: createStyles({ flexWrap: 'wrap', + maxHeight: 300, + overflowY: 'scroll', }), individualIconContainer: createStyles({ alignItems: 'center', diff --git a/modules/react/icon/stories/examples/AppletIconList.tsx b/modules/react/icon/stories/examples/IconsList/AppletIconList.tsx similarity index 97% rename from modules/react/icon/stories/examples/AppletIconList.tsx rename to modules/react/icon/stories/examples/IconsList/AppletIconList.tsx index 16b3f3624a..4d2c664b53 100644 --- a/modules/react/icon/stories/examples/AppletIconList.tsx +++ b/modules/react/icon/stories/examples/IconsList/AppletIconList.tsx @@ -18,6 +18,8 @@ const styleOverrides = { }), iconGroupContainer: createStyles({ flexWrap: 'wrap', + maxHeight: 300, + overflowY: 'scroll', }), individualIconContainer: createStyles({ alignItems: 'center', diff --git a/modules/react/icon/stories/examples/IconList.tsx b/modules/react/icon/stories/examples/IconsList/IconList.tsx similarity index 97% rename from modules/react/icon/stories/examples/IconList.tsx rename to modules/react/icon/stories/examples/IconsList/IconList.tsx index f7cc6265a2..d083ddece9 100644 --- a/modules/react/icon/stories/examples/IconList.tsx +++ b/modules/react/icon/stories/examples/IconsList/IconList.tsx @@ -18,6 +18,8 @@ const styleOverrides = { }), firstChildContainer: createStyles({ flexWrap: 'wrap', + maxHeight: 300, + overflowY: 'scroll', }), secondChildContainer: createStyles({ alignItems: 'center', diff --git a/modules/react/icon/stories/examples/Image/Basic.tsx b/modules/react/icon/stories/examples/Image/Basic.tsx new file mode 100644 index 0000000000..6b2d727e02 --- /dev/null +++ b/modules/react/icon/stories/examples/Image/Basic.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import {Flex} from '@workday/canvas-kit-react/layout'; +import {Image} from '@workday/canvas-kit-react/icon'; + +import {createStyles} from '@workday/canvas-kit-styling'; + +const styleOverrides = { + parentContainer: createStyles({ + maxHeight: 300, + }), +}; + +export const Basic = () => { + return ( + + Image of a cat pretending to be a scientist with beakers and a chalkboard behind it + + ); +}; diff --git a/modules/react/icon/stories/examples/Image/FromFileSystem.tsx b/modules/react/icon/stories/examples/Image/FromFileSystem.tsx new file mode 100644 index 0000000000..e6c294012c --- /dev/null +++ b/modules/react/icon/stories/examples/Image/FromFileSystem.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import {Flex} from '@workday/canvas-kit-react/layout'; +import {Image} from '@workday/canvas-kit-react/icon'; +import {createStyles} from '@workday/canvas-kit-styling'; + +// @ts-ignore: Cannot find module error +import catImage from '../images/cat.jpg'; + +const styleOverrides = { + parentContainer: createStyles({ + maxHeight: 300, + }), +}; + +export const FromFileSystem = () => { + return ( + + Image of a cat mid yawn + + ); +}; diff --git a/modules/react/icon/stories/examples/images/cat.jpg b/modules/react/icon/stories/examples/images/cat.jpg new file mode 100644 index 0000000000..b1b433e8ee Binary files /dev/null and b/modules/react/icon/stories/examples/images/cat.jpg differ diff --git a/modules/react/icon/stories/stories.tsx b/modules/react/icon/stories/stories.tsx index 59c3281f39..966d2239c3 100644 --- a/modules/react/icon/stories/stories.tsx +++ b/modules/react/icon/stories/stories.tsx @@ -19,7 +19,7 @@ const graphicExample: CanvasGraphic = { tags: [], }; -storiesOf('Tokens/Icon', module) +storiesOf('Images and Icons/Icon', module) .addParameters({component: AccentIcon}) .addParameters({ReadmePath: 'react/icon'}) .add('Accent Icon', () => ( @@ -41,7 +41,7 @@ storiesOf('Tokens/Icon', module)
)); -storiesOf('Tokens/Icon', module) +storiesOf('Images and Icons/Icon', module) .addParameters({component: AppletIcon}) .add('Applet Icon', () => (
@@ -53,7 +53,7 @@ storiesOf('Tokens/Icon', module)
)); -storiesOf('Tokens/Icon', module) +storiesOf('Images and Icons/Icon', module) .addParameters({component: SystemIcon}) .add('System Icon', () => (
@@ -103,7 +103,7 @@ storiesOf('Tokens/Icon', module)
)); -storiesOf('Tokens/Icon', module) +storiesOf('Images and Icons/Icon', module) .addParameters({component: Graphic}) .add('Graphic', () => (
@@ -116,5 +116,11 @@ storiesOf('Tokens/Icon', module)
+
+ +
));