Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/allow-style-prop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@unpic/core": patch
"@unpic/react": patch
---

Fix type definition to allow `style` prop on Image component. This is a TypeScript-only change that corrects an incorrect type definition - the `style` prop was always supported at runtime but was incorrectly omitted from the type. No runtime behavior has changed.
4 changes: 2 additions & 2 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ type FullWidthLayout = {
export type UnpicImageProps<
TImageAttributes extends CoreImageAttributes<TStyle>,
TStyle = TImageAttributes["style"],
> = Omit<TImageAttributes, "srcset" | "style"> &
> = Omit<TImageAttributes, "srcset"> &
BaseOptions &
(FixedLayout | ConstrainedLayout | FullWidthLayout);

Expand All @@ -155,7 +155,7 @@ export type UnpicBaseImageProps<
TOptions,
TImageAttributes extends CoreImageAttributes<TStyle>,
TStyle = TImageAttributes["style"],
> = Omit<TImageAttributes, "srcset" | "style"> &
> = Omit<TImageAttributes, "srcset"> &
BaseTransformerOptions<TOperations, TOptions> &
(FixedLayout | ConstrainedLayout | FullWidthLayout);

Expand Down
38 changes: 38 additions & 0 deletions packages/core/test/core.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,42 @@ describe("Core", () => {
expect(props.width).toEqual(100);
expect(props.height).toEqual(200);
});

test("merges user styles with generated styles", () => {
const props = transformBaseImageProps({
src: "images/my-image",
width: 800,
height: 600,
layout: "constrained",
objectFit: "cover",
style: { border: "1px solid red", opacity: "0.5" },
transformer: (tUrl) => tUrl,
});
expect(props.style).toBeDefined();
// Generated styles should be present
expect(props.style?.["object-fit"]).toEqual("cover");
expect(props.style?.["max-width"]).toEqual("800px");
expect(props.style?.["width"]).toEqual("100%");
// User styles should be present and override if needed
expect(props.style?.["border"]).toEqual("1px solid red");
expect(props.style?.["opacity"]).toEqual("0.5");
});

test("user styles override generated styles", () => {
const props = transformBaseImageProps({
src: "images/my-image",
width: 800,
height: 600,
layout: "constrained",
objectFit: "contain",
style: { "object-fit": "fill", border: "2px solid blue" },
transformer: (tUrl) => tUrl,
});
expect(props.style).toBeDefined();
// User's object-fit should override generated one
expect(props.style?.["object-fit"]).toEqual("fill");
expect(props.style?.["border"]).toEqual("2px solid blue");
// Other generated styles should still be present
expect(props.style?.["max-width"]).toEqual("800px");
});
});
13 changes: 13 additions & 0 deletions packages/react/test/react.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,17 @@ describe("the React component", () => {
expect(img.getAttribute("aria-label")).toBe("A cool image");
expectImagePropsToMatchTransformed(img, props);
});

test(`renders an image with style prop`, () => {
const props = {
style: { border: "1px solid red", opacity: "0.5" },
...imgTestCases[0],
};

render(<Image {...props} />);
const img = screen.getByAltText<HTMLImageElement>(props.alt);
expect(img).toBeTruthy();
expect(img.style.border).toBe("1px solid red");
expect(img.style.opacity).toBe("0.5");
});
});