Files
Oleg Isonen db3b11970f fix: Optimize images in Markdown Embed (#6089)
## Summary

Markdown Embed now renders image tags with the same optimized attributes
and canvas behavior as the SDK Image component.

The implementation shares the complete attribute-resolution path without
rendering React inside the Markdown pipeline:

- `@webstudio-is/image` exposes one framework-independent
`getImageAttributes` function for optimization, placeholder fallback,
loading, decoding, dimensions, alternative text, and responsive sources.
- React-only element props such as `className`, `style`, handlers,
context, and refs stay in React callers.
- The SDK Image component and Markdown renderer both use
`getSdkImageProps` for canvas-specific loading, decoding, asset
identity, and incomplete-upload handling.
- Markdown retains only the necessary HTML attribute-name conversion,
sanitization, and Safari-safe `sizes` / `srcset` / `src` ordering.
- The redundant low-level React Image primitive was removed. Its callers
now render native `img` elements, and the image package no longer has
React runtime or peer dependencies.

## Compatibility and tradeoffs

- The SDK Image component remains the public React component because it
owns React context and ref forwarding.
- The removed low-level `@webstudio-is/image` Image export is replaced
by the pure attribute function for internal callers.
- No data migration or schema change is required.
- Loader output is sanitized after transformation, while unsafe input
URLs are sanitized before reaching the loader.

## Todo

- [x] Share image attribute resolution between native, SDK, and Markdown
images.
- [x] Preserve SDK canvas behavior for Markdown images.
- [x] Preserve safe URL sanitization and Safari-safe responsive
attribute ordering.
- [x] Remove the redundant low-level React image primitive and migrate
its callers.
- [x] Remove the overlapping `getImageProps` abstraction.
- [x] Add regression coverage comparing Markdown, SDK Image, and native
attribute output.
- [x] Review documentation impact and update the Markdown Embed
documentation.
- [x] Run targeted tests, typechecks, builds, lint, formatting,
package-boundary checks, and fixture generation.

## Verification

- `pnpm --filter @webstudio-is/image test`
- `pnpm --filter @webstudio-is/image typecheck`
- `pnpm --filter @webstudio-is/image build`
- `pnpm --filter @webstudio-is/image dts`
- `pnpm --filter @webstudio-is/sdk-components-react test`
- `pnpm --filter @webstudio-is/sdk-components-react typecheck`
- `pnpm --filter @webstudio-is/sdk-components-react build`
- `pnpm --filter @webstudio-is/sdk-components-react dts`
- `pnpm --filter @webstudio-is/builder typecheck`
- `pnpm --filter @webstudio-is/design-system typecheck`
- Targeted Oxlint and Oxfmt checks
- `pnpm check:package-boundaries`
- `pnpm fixtures` (no fixture diff)

Ref #6014
2026-08-10 18:21:45 +02:00

40 lines
1.1 KiB
JSON

{
"name": "@webstudio-is/image",
"version": "0.0.0-webstudio-version",
"description": "Image optimization",
"author": "Webstudio <github@webstudio.is>",
"homepage": "https://webstudio.is",
"type": "module",
"scripts": {
"typecheck": "tsc --noEmit",
"test": "vitest run",
"build": "rm -rf lib && esbuild src/index.ts --outdir=lib --bundle --format=esm --packages=external",
"dts": "tsc --project tsconfig.dts.json"
},
"dependencies": {
"@webstudio-is/sdk": "workspace:*",
"warn-once": "^0.1.1"
},
"devDependencies": {
"@types/react": "^18.2.70",
"@types/react-dom": "^18.2.25",
"@webstudio-is/design-system": "workspace:*",
"@webstudio-is/tsconfig": "workspace:*",
"react": "18.3.0-canary-14898b6a9-20240318",
"react-dom": "18.3.0-canary-14898b6a9-20240318",
"vitest": "^3.1.2"
},
"exports": {
"webstudio": "./src/index.ts",
"types": "./lib/types/index.d.ts",
"import": "./lib/index.js"
},
"files": [
"lib/*",
"!*.{test,stories}.*"
],
"license": "AGPL-3.0-or-later",
"private": false,
"sideEffects": false
}