From 688817674378bce35f86cdc0cad68e740acf6973 Mon Sep 17 00:00:00 2001 From: tex-murphy <140573651+tex-murphy@users.noreply.github.com> Date: Sun, 1 Sep 2024 16:19:49 -0400 Subject: [PATCH] fix: correct handling of custom `max-width` style (#13) - properly applies user-defined `max-width` - add storybook example for custom `max-width` - add unit tests for user-defined `aspect-ratio`, `max-width` - bump package version: `1.0.4` --- package-lock.json | 4 ++-- package.json | 2 +- src/components/Image/Image.tsx | 8 ++++++-- src/components/Image/ImageWrapper.tsx | 7 ++++++- src/components/Image/__test__/Image.test.tsx | 21 ++++++++++++++++++++ src/lib/test.ts | 1 + src/stories/Image.stories.ts | 15 ++++++++++++-- 7 files changed, 50 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6415dd3..281b010 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "visionary-image", - "version": "1.0.3", + "version": "1.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "visionary-image", - "version": "1.0.3", + "version": "1.0.4", "license": "ISC", "dependencies": { "classnames": "2.5.1", diff --git a/package.json b/package.json index ba40443..7fd8842 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "visionary-image", "description": "React image component with built-in Blurhash placeholders for better UX and Core Web Vitals.", - "version": "1.0.3", + "version": "1.0.4", "homepage": "https://visionary.cloud", "type": "module", "main": "./dist/visionary-image.umd.js", diff --git a/src/components/Image/Image.tsx b/src/components/Image/Image.tsx index c492b57..d6edd4f 100644 --- a/src/components/Image/Image.tsx +++ b/src/components/Image/Image.tsx @@ -148,13 +148,18 @@ export const Image = ({ position: "relative", width: "100%", }; - // User wants to hardcode height/width + // Apply user-specified container width if (userWidth) { containerStyles.width = userWidth; } + // Apply user-specified container height if (userHeight) { containerStyles.height = userHeight; } + // Allow user to override container's max-width + if (userStyles?.maxWidth) { + containerStyles.maxWidth = userStyles.maxWidth; + } const containerProps: DetailedHTMLProps, HTMLDivElement> = { onClick, }; @@ -164,7 +169,6 @@ export const Image = ({ className={containerClasses} ref={containerRef} style={containerStyles} - // style={{ aspectRatio }} {...getDebugIdProp(imageState.url, debug)} {...getTestIdProp(TEST_IDS.CONTAINER)} {...containerProps} diff --git a/src/components/Image/ImageWrapper.tsx b/src/components/Image/ImageWrapper.tsx index 203853a..3e65ec2 100644 --- a/src/components/Image/ImageWrapper.tsx +++ b/src/components/Image/ImageWrapper.tsx @@ -1,5 +1,8 @@ import type { CSSProperties, ReactNode } from "react"; +import { TEST_IDS } from "../../lib/test"; +import { getTestIdProp } from "../../lib/util"; + interface ImageWrapperProps { aspectRatio: CSSProperties["aspectRatio"]; children: ReactNode; @@ -16,5 +19,7 @@ const imageWrapperStyles: CSSProperties = { * - Storybook example: https://visionary-ux.github.io/visionary-image/?path=/story/visionary-image--custom-aspect-ratio */ export const ImageWrapper = ({ aspectRatio, children }: ImageWrapperProps) => ( -
{children}
+
+ {children} +
); diff --git a/src/components/Image/__test__/Image.test.tsx b/src/components/Image/__test__/Image.test.tsx index 6d3709d..d26ad1b 100644 --- a/src/components/Image/__test__/Image.test.tsx +++ b/src/components/Image/__test__/Image.test.tsx @@ -215,6 +215,27 @@ describe("Image component", () => { }); }); + describe("Style overrides", () => { + test("user can override max-width", () => { + render(); + + const containerElement = screen.getByTestId(TEST_IDS.CONTAINER); + const containerStyles = window.getComputedStyle(containerElement); + + expect(containerStyles.maxWidth).toBe("220px"); + }); + + test("user can specify custom aspect-ratio", () => { + const customAspectRatio = "3 / 1"; + render(); + + const containerElement = screen.getByTestId(TEST_IDS.ASPECT_RATIO_WRAPPER); + const containerStyles = window.getComputedStyle(containerElement); + + expect(containerStyles.getPropertyValue("aspect-ratio")).toBe(customAspectRatio); + }); + }); + describe("Using ordinary (non-visionary) URL ", () => { test("renders fallback element when src is not visionary", () => { const testClassname = "v7y_tester"; diff --git a/src/lib/test.ts b/src/lib/test.ts index 6f1f9f5..e8a477a 100644 --- a/src/lib/test.ts +++ b/src/lib/test.ts @@ -1,4 +1,5 @@ export const TEST_IDS = { + ASPECT_RATIO_WRAPPER: "aspect-ratio-wrapper", CANVAS: "canvas", CONTAINER: "container", IMAGE: "image", diff --git a/src/stories/Image.stories.ts b/src/stories/Image.stories.ts index 56b7076..41e5b04 100644 --- a/src/stories/Image.stories.ts +++ b/src/stories/Image.stories.ts @@ -66,6 +66,13 @@ export const PreventSelection: Story = { }, }; +export const CustomSizeToken: Story = { + args: { + ...sharedProps, + size: ImageSizeToken.xs, + }, +}; + export const CustomAspectRatio: Story = { args: { ...sharedProps, @@ -74,13 +81,17 @@ export const CustomAspectRatio: Story = { transform: "translateY(-30%)", }, }, + name: "Custom aspect-ratio style", }; -export const CustomSizeToken: Story = { +export const CustomMaxWidth: Story = { args: { ...sharedProps, - size: ImageSizeToken.xs, + style: { + maxWidth: 210, + }, }, + name: "Custom max-width style", }; export const ExternalImageUrl: Story = {