diff --git a/.changeset/angry-terms-hammer.md b/.changeset/angry-terms-hammer.md new file mode 100644 index 0000000000..9aaf0d9c2e --- /dev/null +++ b/.changeset/angry-terms-hammer.md @@ -0,0 +1,5 @@ +--- +'@contentful/f36-core': minor +--- + +- add new `useImageLoaded` hook diff --git a/.changeset/config.json b/.changeset/config.json index 6e61746429..071bd9d402 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,6 +7,7 @@ } ], "ignore": [ + "@contentful/f36-image", "@contentful/f36-navlist", "@contentful/f36-website" ], diff --git a/package-lock.json b/package-lock.json index 7e2b3a7b34..cff478adf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "@storybook/theming": "^6.5.10", "@testing-library/jest-dom": "5.16.1", "@testing-library/react": "12.1.5", + "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "14.4.3", "@types/jest": "^29.2.2", "@types/jest-axe": "3.5.4", @@ -3453,6 +3454,10 @@ "resolved": "packages/components/icons", "link": true }, + "node_modules/@contentful/f36-image": { + "resolved": "packages/components/image", + "link": true + }, "node_modules/@contentful/f36-list": { "resolved": "packages/components/list", "link": true @@ -11343,6 +11348,36 @@ "react-dom": "<18.0.0" } }, + "node_modules/@testing-library/react-hooks": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz", + "integrity": "sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "react-error-boundary": "^3.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0", + "react": "^16.9.0 || ^17.0.0", + "react-dom": "^16.9.0 || ^17.0.0", + "react-test-renderer": "^16.9.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-test-renderer": { + "optional": true + } + } + }, "node_modules/@testing-library/react/node_modules/@types/react-dom": { "version": "16.9.14", "dev": true, @@ -31799,6 +31834,22 @@ "node": ">=0.10.0" } }, + "node_modules/react-error-boundary": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, "node_modules/react-fast-compare": { "version": "2.0.4", "dev": true, @@ -37717,14 +37768,14 @@ }, "packages/components/accordion": { "name": "@contentful/f36-accordion", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-collapse": "^4.41.1", - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-collapse": "^4.42.0", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" }, "peerDependencies": { @@ -37734,14 +37785,14 @@ }, "packages/components/asset": { "name": "@contentful/f36-asset", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" }, "peerDependencies": { @@ -37751,17 +37802,17 @@ }, "packages/components/autocomplete": { "name": "@contentful/f36-autocomplete", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-forms": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-forms": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-popover": "^4.41.1", - "@contentful/f36-skeleton": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-popover": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "@contentful/f36-utils": "^4.23.2", "downshift": "^6.1.12", "emotion": "^10.0.17" @@ -37773,16 +37824,16 @@ }, "packages/components/badge": { "name": "@contentful/f36-badge", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.25.0", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" }, "devDependencies": { - "@contentful/f36-typography": "^4.41.1" + "@contentful/f36-typography": "^4.42.0" }, "peerDependencies": { "react": ">=16.8", @@ -37791,17 +37842,17 @@ }, "packages/components/button": { "name": "@contentful/f36-button", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-spinner": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-spinner": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.24.1", "emotion": "^10.0.17" }, "devDependencies": { - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2" }, "peerDependencies": { @@ -37811,21 +37862,21 @@ }, "packages/components/card": { "name": "@contentful/f36-card", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-asset": "^4.41.1", - "@contentful/f36-badge": "^4.41.1", - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-drag-handle": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-asset": "^4.42.0", + "@contentful/f36-badge": "^4.42.0", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-drag-handle": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-menu": "^4.41.1", - "@contentful/f36-skeleton": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-tooltip": "^4.41.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-menu": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-tooltip": "^4.42.0", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17", "truncate": "^3.0.0" }, @@ -37836,11 +37887,11 @@ }, "packages/components/collapse": { "name": "@contentful/f36-collapse", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" }, "peerDependencies": { @@ -37850,14 +37901,14 @@ }, "packages/components/copybutton": { "name": "@contentful/f36-copybutton", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-tooltip": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-tooltip": "^4.42.0", "emotion": "^10.0.17" }, "peerDependencies": { @@ -37867,16 +37918,16 @@ }, "packages/components/datepicker": { "name": "@contentful/f36-datepicker", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-forms": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-forms": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-popover": "^4.41.1", - "@contentful/f36-tokens": "^4.0.0", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-popover": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "date-fns": "^2.28.0", "emotion": "^10.0.17", "react-day-picker": "^8.3.5", @@ -37901,11 +37952,11 @@ }, "packages/components/datetime": { "name": "@contentful/f36-datetime", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "dayjs": "^1.11.5", "emotion": "^10.0.17" }, @@ -37916,12 +37967,12 @@ }, "packages/components/drag-handle": { "name": "@contentful/f36-drag-handle", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.24.1", "emotion": "^10.0.17" }, @@ -37932,11 +37983,11 @@ }, "packages/components/empty-state": { "name": "@contentful/f36-empty-state", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" }, "peerDependencies": { @@ -37946,19 +37997,19 @@ }, "packages/components/entity-list": { "name": "@contentful/f36-entity-list", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-badge": "^4.41.1", - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-drag-handle": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-badge": "^4.42.0", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-drag-handle": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-menu": "^4.41.1", - "@contentful/f36-skeleton": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-menu": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" }, "peerDependencies": { @@ -37968,13 +38019,13 @@ }, "packages/components/forms": { "name": "@contentful/f36-forms", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" }, "devDependencies": { @@ -37988,11 +38039,11 @@ }, "packages/components/icon": { "name": "@contentful/f36-icon", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" }, "devDependencies": { @@ -38017,13 +38068,28 @@ "react-dom": ">=16.8" } }, + "packages/components/image": { + "name": "@contentful/f36-image", + "version": "4.0.0-alpha.0", + "license": "MIT", + "dependencies": { + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-tokens": "^4.0.0", + "emotion": "^10.0.17" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "packages/components/list": { "name": "@contentful/f36-list", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" }, "peerDependencies": { @@ -38032,14 +38098,14 @@ }, "packages/components/menu": { "name": "@contentful/f36-menu", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-popover": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-popover": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "@contentful/f36-utils": "^4.23.2", "emotion": "^10.0.17" }, @@ -38050,14 +38116,14 @@ }, "packages/components/modal": { "name": "@contentful/f36-modal", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "@types/react-modal": "^3.13.1", "emotion": "^10.0.17", "react-modal": "^3.16.1" @@ -38132,8 +38198,8 @@ "version": "4.1.0-alpha.1", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" }, "peerDependencies": { @@ -38143,15 +38209,15 @@ }, "packages/components/note": { "name": "@contentful/f36-note", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" }, "devDependencies": { @@ -38196,15 +38262,15 @@ }, "packages/components/notification": { "name": "@contentful/f36-notification", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-text-link": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-text-link": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "@swc/helpers": "^0.4.14", "emotion": "^10.0.17", "react-animate-height": "^3.0.4" @@ -38224,15 +38290,15 @@ }, "packages/components/pagination": { "name": "@contentful/f36-pagination", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-forms": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-forms": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.0", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" }, "peerDependencies": { @@ -38241,15 +38307,15 @@ }, "packages/components/pill": { "name": "@contentful/f36-pill", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-drag-handle": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-drag-handle": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-tooltip": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-tooltip": "^4.42.0", "emotion": "^10.0.17" }, "peerDependencies": { @@ -38259,11 +38325,11 @@ }, "packages/components/popover": { "name": "@contentful/f36-popover", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.23.2", "@popperjs/core": "^2.11.5", "emotion": "^10.0.17", @@ -38275,12 +38341,12 @@ }, "packages/components/skeleton": { "name": "@contentful/f36-skeleton", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-table": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-table": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" }, "peerDependencies": { @@ -38290,15 +38356,15 @@ }, "packages/components/spinner": { "name": "@contentful/f36-spinner", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" }, "devDependencies": { - "@contentful/f36-typography": "^4.41.1" + "@contentful/f36-typography": "^4.42.0" }, "peerDependencies": { "react": ">=16.8" @@ -38306,13 +38372,13 @@ }, "packages/components/table": { "name": "@contentful/f36-table", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.25.0", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" }, "peerDependencies": { @@ -38337,11 +38403,11 @@ }, "packages/components/tabs": { "name": "@contentful/f36-tabs", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "@radix-ui/react-tabs": "^1.0.1", "emotion": "^10.0.17" }, @@ -38488,11 +38554,11 @@ }, "packages/components/text-link": { "name": "@contentful/f36-text-link", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" }, "peerDependencies": { @@ -38501,11 +38567,11 @@ }, "packages/components/tooltip": { "name": "@contentful/f36-tooltip", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.23.2", "@popperjs/core": "^2.11.5", "csstype": "^3.1.1", @@ -38519,11 +38585,11 @@ }, "packages/components/typography": { "name": "@contentful/f36-typography", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" }, "peerDependencies": { @@ -38562,10 +38628,10 @@ }, "packages/core": { "name": "@contentful/f36-core", - "version": "4.41.1", + "version": "4.42.0", "license": "MIT", "dependencies": { - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-tokens": "^4.0.2", "@emotion/core": "^10.1.1", "@emotion/is-prop-valid": "^1.2.0", "csstype": "^3.1.1", @@ -38848,42 +38914,42 @@ }, "packages/forma-36-react-components": { "name": "@contentful/f36-components", - "version": "4.41.1", - "license": "MIT", - "dependencies": { - "@contentful/f36-accordion": "^4.41.1", - "@contentful/f36-asset": "^4.41.1", - "@contentful/f36-autocomplete": "^4.41.1", - "@contentful/f36-badge": "^4.41.1", - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-card": "^4.41.1", - "@contentful/f36-collapse": "^4.41.1", - "@contentful/f36-copybutton": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-datepicker": "^4.41.1", - "@contentful/f36-datetime": "^4.41.1", - "@contentful/f36-drag-handle": "^4.41.1", - "@contentful/f36-empty-state": "^4.41.1", - "@contentful/f36-entity-list": "^4.41.1", - "@contentful/f36-forms": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "version": "4.42.0", + "license": "MIT", + "dependencies": { + "@contentful/f36-accordion": "^4.42.0", + "@contentful/f36-asset": "^4.42.0", + "@contentful/f36-autocomplete": "^4.42.0", + "@contentful/f36-badge": "^4.42.0", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-card": "^4.42.0", + "@contentful/f36-collapse": "^4.42.0", + "@contentful/f36-copybutton": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-datepicker": "^4.42.0", + "@contentful/f36-datetime": "^4.42.0", + "@contentful/f36-drag-handle": "^4.42.0", + "@contentful/f36-empty-state": "^4.42.0", + "@contentful/f36-entity-list": "^4.42.0", + "@contentful/f36-forms": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-list": "^4.41.1", - "@contentful/f36-menu": "^4.41.1", - "@contentful/f36-modal": "^4.41.1", - "@contentful/f36-note": "^4.41.1", - "@contentful/f36-notification": "^4.41.1", - "@contentful/f36-pagination": "^4.41.1", - "@contentful/f36-pill": "^4.41.1", - "@contentful/f36-popover": "^4.41.1", - "@contentful/f36-skeleton": "^4.41.1", - "@contentful/f36-spinner": "^4.41.1", - "@contentful/f36-table": "^4.41.1", - "@contentful/f36-tabs": "^4.41.1", - "@contentful/f36-text-link": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-tooltip": "^4.41.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-list": "^4.42.0", + "@contentful/f36-menu": "^4.42.0", + "@contentful/f36-modal": "^4.42.0", + "@contentful/f36-note": "^4.42.0", + "@contentful/f36-notification": "^4.42.0", + "@contentful/f36-pagination": "^4.42.0", + "@contentful/f36-pill": "^4.42.0", + "@contentful/f36-popover": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-spinner": "^4.42.0", + "@contentful/f36-table": "^4.42.0", + "@contentful/f36-tabs": "^4.42.0", + "@contentful/f36-text-link": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-tooltip": "^4.42.0", + "@contentful/f36-typography": "^4.42.0", "@contentful/f36-utils": "^4.23.2", "@types/react": "16.14.22", "@types/react-dom": "16.9.14" @@ -42022,7 +42088,7 @@ }, "packages/forma-36-tokens": { "name": "@contentful/f36-tokens", - "version": "4.0.1", + "version": "4.0.2", "license": "MIT", "devDependencies": { "fs-extra": "^11.1.0", @@ -42073,14 +42139,15 @@ "version": "1.0.0", "dependencies": { "@codesandbox/sandpack-react": "^1.17.0", - "@contentful/f36-components": "^4.41.1", + "@contentful/f36-components": "^4.42.0", "@contentful/f36-docs-utils": "^4.0.2", - "@contentful/f36-empty-state": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-empty-state": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.25.0", + "@contentful/f36-image": "^4.0.0-alpha.0", "@contentful/f36-multiselect": "^4.20.11", "@contentful/f36-navlist": "4.1.0-alpha.1", - "@contentful/f36-tokens": "^4.0.0", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.24.1", "@contentful/rich-text-react-renderer": "^15.11.1", "@dnd-kit/core": "^6.0.8", @@ -44961,36 +45028,36 @@ "@contentful/f36-accordion": { "version": "file:packages/components/accordion", "requires": { - "@contentful/f36-collapse": "^4.41.1", - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-collapse": "^4.42.0", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" } }, "@contentful/f36-asset": { "version": "file:packages/components/asset", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" } }, "@contentful/f36-autocomplete": { "version": "file:packages/components/autocomplete", "requires": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-forms": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-forms": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-popover": "^4.41.1", - "@contentful/f36-skeleton": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-popover": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "@contentful/f36-utils": "^4.23.2", "downshift": "^6.1.12", "emotion": "^10.0.17" @@ -44999,21 +45066,21 @@ "@contentful/f36-badge": { "version": "file:packages/components/badge", "requires": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.25.0", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" } }, "@contentful/f36-button": { "version": "file:packages/components/button", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-spinner": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-spinner": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.24.1", "emotion": "^10.0.17" } @@ -45021,18 +45088,18 @@ "@contentful/f36-card": { "version": "file:packages/components/card", "requires": { - "@contentful/f36-asset": "^4.41.1", - "@contentful/f36-badge": "^4.41.1", - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-drag-handle": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-asset": "^4.42.0", + "@contentful/f36-badge": "^4.42.0", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-drag-handle": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-menu": "^4.41.1", - "@contentful/f36-skeleton": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-tooltip": "^4.41.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-menu": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-tooltip": "^4.42.0", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17", "truncate": "^3.0.0" } @@ -45189,47 +45256,47 @@ "@contentful/f36-collapse": { "version": "file:packages/components/collapse", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" } }, "@contentful/f36-components": { "version": "file:packages/forma-36-react-components", "requires": { - "@contentful/f36-accordion": "^4.41.1", - "@contentful/f36-asset": "^4.41.1", - "@contentful/f36-autocomplete": "^4.41.1", - "@contentful/f36-badge": "^4.41.1", - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-card": "^4.41.1", - "@contentful/f36-collapse": "^4.41.1", - "@contentful/f36-copybutton": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-datepicker": "^4.41.1", - "@contentful/f36-datetime": "^4.41.1", - "@contentful/f36-drag-handle": "^4.41.1", - "@contentful/f36-empty-state": "^4.41.1", - "@contentful/f36-entity-list": "^4.41.1", - "@contentful/f36-forms": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-accordion": "^4.42.0", + "@contentful/f36-asset": "^4.42.0", + "@contentful/f36-autocomplete": "^4.42.0", + "@contentful/f36-badge": "^4.42.0", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-card": "^4.42.0", + "@contentful/f36-collapse": "^4.42.0", + "@contentful/f36-copybutton": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-datepicker": "^4.42.0", + "@contentful/f36-datetime": "^4.42.0", + "@contentful/f36-drag-handle": "^4.42.0", + "@contentful/f36-empty-state": "^4.42.0", + "@contentful/f36-entity-list": "^4.42.0", + "@contentful/f36-forms": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-list": "^4.41.1", - "@contentful/f36-menu": "^4.41.1", - "@contentful/f36-modal": "^4.41.1", - "@contentful/f36-note": "^4.41.1", - "@contentful/f36-notification": "^4.41.1", - "@contentful/f36-pagination": "^4.41.1", - "@contentful/f36-pill": "^4.41.1", - "@contentful/f36-popover": "^4.41.1", - "@contentful/f36-skeleton": "^4.41.1", - "@contentful/f36-spinner": "^4.41.1", - "@contentful/f36-table": "^4.41.1", - "@contentful/f36-tabs": "^4.41.1", - "@contentful/f36-text-link": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-tooltip": "^4.41.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-list": "^4.42.0", + "@contentful/f36-menu": "^4.42.0", + "@contentful/f36-modal": "^4.42.0", + "@contentful/f36-note": "^4.42.0", + "@contentful/f36-notification": "^4.42.0", + "@contentful/f36-pagination": "^4.42.0", + "@contentful/f36-pill": "^4.42.0", + "@contentful/f36-popover": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-spinner": "^4.42.0", + "@contentful/f36-table": "^4.42.0", + "@contentful/f36-tabs": "^4.42.0", + "@contentful/f36-text-link": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-tooltip": "^4.42.0", + "@contentful/f36-typography": "^4.42.0", "@contentful/f36-utils": "^4.23.2", "@types/react": "16.14.22", "@types/react-dom": "16.9.14", @@ -47386,18 +47453,18 @@ "@contentful/f36-copybutton": { "version": "file:packages/components/copybutton", "requires": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-tooltip": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-tooltip": "^4.42.0", "emotion": "^10.0.17" } }, "@contentful/f36-core": { "version": "file:packages/core", "requires": { - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-tokens": "^4.0.2", "@emotion/core": "^10.1.1", "@emotion/is-prop-valid": "^1.2.0", "csstype": "^3.1.1", @@ -47418,13 +47485,13 @@ "@contentful/f36-datepicker": { "version": "file:packages/components/datepicker", "requires": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-forms": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-forms": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-popover": "^4.41.1", - "@contentful/f36-tokens": "^4.0.0", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-popover": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "date-fns": "^2.28.0", "emotion": "^10.0.17", "react-day-picker": "^8.3.5", @@ -47440,8 +47507,8 @@ "@contentful/f36-datetime": { "version": "file:packages/components/datetime", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "dayjs": "^1.11.5", "emotion": "^10.0.17" } @@ -47458,9 +47525,9 @@ "@contentful/f36-drag-handle": { "version": "file:packages/components/drag-handle", "requires": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.24.1", "emotion": "^10.0.17" } @@ -47468,34 +47535,34 @@ "@contentful/f36-empty-state": { "version": "file:packages/components/empty-state", "requires": { - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" } }, "@contentful/f36-entity-list": { "version": "file:packages/components/entity-list", "requires": { - "@contentful/f36-badge": "^4.41.1", - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-drag-handle": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-badge": "^4.42.0", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-drag-handle": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-menu": "^4.41.1", - "@contentful/f36-skeleton": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-menu": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" } }, "@contentful/f36-forms": { "version": "file:packages/components/forms", "requires": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17", "formik": "^2.2.9", "react-hook-form": "^7.15.0" @@ -47504,8 +47571,8 @@ "@contentful/f36-icon": { "version": "file:packages/components/icon", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17", "react-icons": "^4.4.0" } @@ -47519,22 +47586,31 @@ "emotion": "^10.0.17" } }, + "@contentful/f36-image": { + "version": "file:packages/components/image", + "requires": { + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-tokens": "^4.0.0", + "emotion": "^10.0.17" + } + }, "@contentful/f36-list": { "version": "file:packages/components/list", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" } }, "@contentful/f36-menu": { "version": "file:packages/components/menu", "requires": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-popover": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-popover": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "@contentful/f36-utils": "^4.23.2", "emotion": "^10.0.17" } @@ -47542,11 +47618,11 @@ "@contentful/f36-modal": { "version": "file:packages/components/modal", "requires": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "@types/react-modal": "^3.13.1", "emotion": "^10.0.17", "react-modal": "^3.16.1" @@ -47600,20 +47676,20 @@ "@contentful/f36-navlist": { "version": "file:packages/components/navlist", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" } }, "@contentful/f36-note": { "version": "file:packages/components/note", "requires": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "@emotion/serialize": "^1.1.1", "emotion": "^10.0.17" }, @@ -47650,12 +47726,12 @@ "@contentful/f36-notification": { "version": "file:packages/components/notification", "requires": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-text-link": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-text-link": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "@swc/helpers": "^0.4.14", "emotion": "^10.0.17", "react-animate-height": "^3.0.4" @@ -47674,32 +47750,32 @@ "@contentful/f36-pagination": { "version": "file:packages/components/pagination", "requires": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-forms": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-forms": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.0", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" } }, "@contentful/f36-pill": { "version": "file:packages/components/pill", "requires": { - "@contentful/f36-button": "^4.41.1", - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-drag-handle": "^4.41.1", + "@contentful/f36-button": "^4.42.0", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-drag-handle": "^4.42.0", "@contentful/f36-icons": "^4.23.2", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-tooltip": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-tooltip": "^4.42.0", "emotion": "^10.0.17" } }, "@contentful/f36-popover": { "version": "file:packages/components/popover", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.23.2", "@popperjs/core": "^2.11.5", "emotion": "^10.0.17", @@ -47709,28 +47785,28 @@ "@contentful/f36-skeleton": { "version": "file:packages/components/skeleton", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-table": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-table": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" } }, "@contentful/f36-spinner": { "version": "file:packages/components/spinner", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" } }, "@contentful/f36-table": { "version": "file:packages/components/table", "requires": { - "@contentful/f36-core": "^4.41.1", + "@contentful/f36-core": "^4.42.0", "@contentful/f36-icons": "^4.25.0", - "@contentful/f36-tokens": "^4.0.1", - "@contentful/f36-typography": "^4.41.1", + "@contentful/f36-tokens": "^4.0.2", + "@contentful/f36-typography": "^4.42.0", "emotion": "^10.0.17" }, "dependencies": { @@ -47750,8 +47826,8 @@ "@contentful/f36-tabs": { "version": "file:packages/components/tabs", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "@radix-ui/react-tabs": "^1.0.1", "emotion": "^10.0.17" }, @@ -47852,8 +47928,8 @@ "@contentful/f36-text-link": { "version": "file:packages/components/text-link", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" } }, @@ -47896,8 +47972,8 @@ "@contentful/f36-tooltip": { "version": "file:packages/components/tooltip", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.23.2", "@popperjs/core": "^2.11.5", "csstype": "^3.1.1", @@ -47908,8 +47984,8 @@ "@contentful/f36-typography": { "version": "file:packages/components/typography", "requires": { - "@contentful/f36-core": "^4.41.1", - "@contentful/f36-tokens": "^4.0.1", + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-tokens": "^4.0.2", "emotion": "^10.0.17" } }, @@ -47923,14 +47999,15 @@ "version": "file:packages/website", "requires": { "@codesandbox/sandpack-react": "^1.17.0", - "@contentful/f36-components": "^4.41.1", + "@contentful/f36-components": "^4.42.0", "@contentful/f36-docs-utils": "^4.0.2", - "@contentful/f36-empty-state": "^4.41.1", - "@contentful/f36-icon": "^4.41.1", + "@contentful/f36-empty-state": "^4.42.0", + "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.25.0", + "@contentful/f36-image": "^4.0.0-alpha.0", "@contentful/f36-multiselect": "^4.20.11", "@contentful/f36-navlist": "4.1.0-alpha.1", - "@contentful/f36-tokens": "^4.0.0", + "@contentful/f36-tokens": "^4.0.2", "@contentful/f36-utils": "^4.24.1", "@contentful/rich-text-react-renderer": "^15.11.1", "@contentful/rich-text-types": "^15.11.1", @@ -53641,6 +53718,16 @@ } } }, + "@testing-library/react-hooks": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz", + "integrity": "sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "react-error-boundary": "^3.1.0" + } + }, "@testing-library/user-event": { "version": "14.4.3", "dev": true, @@ -67098,6 +67185,15 @@ } } }, + "react-error-boundary": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5" + } + }, "react-fast-compare": { "version": "2.0.4", "dev": true diff --git a/package.json b/package.json index 8940ccc509..c0614e90da 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "@storybook/theming": "^6.5.10", "@testing-library/jest-dom": "5.16.1", "@testing-library/react": "12.1.5", + "@testing-library/react-hooks": "^8.0.1", "@testing-library/user-event": "14.4.3", "@types/jest": "^29.2.2", "@types/jest-axe": "3.5.4", diff --git a/packages/components/image/README.mdx b/packages/components/image/README.mdx new file mode 100644 index 0000000000..7a13aaf614 --- /dev/null +++ b/packages/components/image/README.mdx @@ -0,0 +1,41 @@ +--- +title: 'Image' +type: 'component' +status: 'alpha' +slug: /components/image/ +github: 'https://github.com/contentful/forma-36/tree/main/packages/components/image' +storybook: 'https://f36-storybook.contentful.com/?path=/story/components-image--overview' +typescript: ./src/Image.tsx +--- + +Image component that can handle showing a loading skeleton while the image is loading. + +## Import + +```jsx static=true +import { Image } from '@contentful/f36-image'; +``` + +## Examples + +### Basic example + +```jsx file=./examples/ImageBasicExample.tsx + +``` + +### Without a `src` + +The image component will render a loading skeleton matching the dimensions of the image if no `src` prop is passed. + +```jsx file=./examples/ImageWithoutSrcExample.tsx + +``` + +## Props (API reference) + + + +## Accessibility + +Make sure you pass the required `alt` prop. diff --git a/packages/components/image/examples/ImageBasicExample.tsx b/packages/components/image/examples/ImageBasicExample.tsx new file mode 100644 index 0000000000..3b7da9034f --- /dev/null +++ b/packages/components/image/examples/ImageBasicExample.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { Image } from '@contentful/f36-image'; + +export default function ImageBasicExample() { + return ( + An image saying "Everyone is welcome here" + ); +} diff --git a/packages/components/image/examples/ImageWithoutSrcExample.tsx b/packages/components/image/examples/ImageWithoutSrcExample.tsx new file mode 100644 index 0000000000..67072842bb --- /dev/null +++ b/packages/components/image/examples/ImageWithoutSrcExample.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Image } from '@contentful/f36-image'; + +export default function ImageBasicExample() { + return ( + An image saying "Everyone is welcome here" + ); +} diff --git a/packages/components/image/package.json b/packages/components/image/package.json new file mode 100644 index 0000000000..b30989ee98 --- /dev/null +++ b/packages/components/image/package.json @@ -0,0 +1,35 @@ +{ + "name": "@contentful/f36-image", + "version": "4.0.0-alpha.0", + "description": "Forma 36: Image component", + "scripts": { + "build": "tsup" + }, + "dependencies": { + "@contentful/f36-core": "^4.42.0", + "@contentful/f36-skeleton": "^4.42.0", + "@contentful/f36-tokens": "^4.0.0", + "emotion": "^10.0.17" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + }, + "license": "MIT", + "files": [ + "dist" + ], + "main": "dist/index.js", + "module": "dist/esm/index.js", + "types": "dist/index.d.ts", + "source": "src/index.ts", + "sideEffects": false, + "browserslist": "extends @contentful/browserslist-config", + "repository": { + "type": "git", + "url": "https://github.com/contentful/forma-36" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/components/image/src/Image.styles.ts b/packages/components/image/src/Image.styles.ts new file mode 100644 index 0000000000..4b424cb9a6 --- /dev/null +++ b/packages/components/image/src/Image.styles.ts @@ -0,0 +1,21 @@ +import { css } from 'emotion'; +import type { ImageProps } from './Image'; + +export const getImageStyles = ({ + height, + width, +}: Pick) => { + return { + image: ({ isLoaded }: { isLoaded: boolean }) => + css({ + display: isLoaded ? 'block' : 'none', + height: isLoaded ? height : 0, + opacity: isLoaded ? 1 : 0, + width: isLoaded ? width : 0, + }), + root: css({ + height, + width, + }), + }; +}; diff --git a/packages/components/image/src/Image.test.tsx b/packages/components/image/src/Image.test.tsx new file mode 100644 index 0000000000..48ebb484d5 --- /dev/null +++ b/packages/components/image/src/Image.test.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { render, screen, waitFor } from '@testing-library/react'; +import { useImageLoaded } from '@contentful/f36-core'; +import { Image } from './Image'; + +jest.mock('@contentful/f36-core', () => { + const originalModule = jest.requireActual('@contentful/f36-core'); + + return { + __esModule: true, + ...originalModule, + useImageLoaded: jest.fn(), + }; +}); + +describe('Image', () => { + const src = 'https://example.com/image.jpg'; + const alt = 'An image'; + const width = '400px'; + const height = '300px'; + + it('should render the image once loaded', async () => { + (useImageLoaded as jest.Mock).mockReturnValueOnce({ + loaded: true, + }); + + render({alt}); + const image = screen.getByAltText(alt); + expect(image).toBeInTheDocument(); + expect(image).toHaveAttribute('src', src); + }); + + it('should render the skeleton while loading', async () => { + (useImageLoaded as jest.Mock).mockReturnValueOnce({ + loaded: false, + }); + + render({alt}); + + expect( + screen.getByLabelText('Loading', { exact: false }), + ).toBeInTheDocument(); + }); + + it('should not render the skeleton once loaded', async () => { + (useImageLoaded as jest.Mock).mockReturnValueOnce({ + loaded: true, + }); + render({alt}); + const image = screen.getByAltText(alt); + + await waitFor(() => expect(image).toBeInTheDocument()); + expect(image).toHaveAttribute('src', src); + const skeleton = screen.queryByLabelText('Loading', { exact: false }); + expect(skeleton).not.toBeInTheDocument(); + }); +}); diff --git a/packages/components/image/src/Image.tsx b/packages/components/image/src/Image.tsx new file mode 100644 index 0000000000..d1561a900b --- /dev/null +++ b/packages/components/image/src/Image.tsx @@ -0,0 +1,63 @@ +import React, { ComponentPropsWithoutRef, forwardRef, type Ref } from 'react'; +import { cx } from 'emotion'; +import { + type CommonProps, + mergeRefs, + useImageLoaded, +} from '@contentful/f36-core'; +import { Skeleton } from '@contentful/f36-skeleton'; +import { getImageStyles } from './Image.styles'; + +export interface ImageProps + extends CommonProps, + Omit, 'onLoad'> { + /** + * Alt attribute to pass to the image element + */ + alt: string; + /** + * Height of the final image once loaded + */ + height: string; + /** + * Width of the final image once loaded + */ + width: string; +} + +function _Image( + { + className, + height, + src, + testId = 'cf-ui-image', + width, + ...otherProps + }: ImageProps, + forwardedRef: Ref, +) { + const styles = getImageStyles({ height, width }); + const { ref: imageRef, loaded: isImageLoaded, onLoad } = useImageLoaded(); + const isLoaded = Boolean(src && isImageLoaded); + + return ( +
+ {/* eslint-disable-next-line jsx-a11y/alt-text -- `alt` should be provided by the user */} + + {!isLoaded && ( + + + + )} +
+ ); +} + +export const Image = forwardRef(_Image); diff --git a/packages/components/image/src/index.ts b/packages/components/image/src/index.ts new file mode 100644 index 0000000000..80bb311d68 --- /dev/null +++ b/packages/components/image/src/index.ts @@ -0,0 +1,2 @@ +export { Image } from './Image'; +export type { ImageProps } from './Image'; diff --git a/packages/components/image/stories/Image.stories.tsx b/packages/components/image/stories/Image.stories.tsx new file mode 100644 index 0000000000..609dcb7215 --- /dev/null +++ b/packages/components/image/stories/Image.stories.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import type { Meta, Story } from '@storybook/react/types-6-0'; +import { Flex } from '@contentful/f36-core'; +import { SectionHeading } from '@contentful/f36-typography'; + +import { Image, type ImageProps } from '../src/Image'; + +export default { + component: Image, + title: 'Components/Image', +} as Meta; + +export const Overview: Story = () => { + return ( + <> + + + Basic + + + + + + + + + + Without a src + + + + + + + + ); +}; diff --git a/packages/core/src/hooks/index.ts b/packages/core/src/hooks/index.ts index c59ec74c85..f3e5aaf8fa 100644 --- a/packages/core/src/hooks/index.ts +++ b/packages/core/src/hooks/index.ts @@ -1,3 +1,4 @@ export { useId } from './useId'; export { useControllableState } from './useControllableState'; export type { UseControllableStateProps } from './useControllableState'; +export { useImageLoaded } from './useImageLoaded'; diff --git a/packages/core/src/hooks/useImageLoaded.test.ts b/packages/core/src/hooks/useImageLoaded.test.ts new file mode 100644 index 0000000000..ecb33dabd2 --- /dev/null +++ b/packages/core/src/hooks/useImageLoaded.test.ts @@ -0,0 +1,33 @@ +import { renderHook } from '@testing-library/react-hooks'; +import { useImageLoaded } from './useImageLoaded'; + +describe('useImageLoaded', () => { + it('should call the onLoad function when the image loads', async () => { + const onLoad = jest.fn(); + const mockImage = { + complete: false, + addEventListener: (event: string, callback: () => void) => { + if (event === 'load') { + setTimeout(() => { + mockImage.complete = true; + callback(); + }, 0); + } + }, + }; + const { result, waitForNextUpdate } = renderHook(() => + useImageLoaded({ onLoad }), + ); + + result.current.ref.current = mockImage as HTMLImageElement; + mockImage.addEventListener('load', result.current.onLoad); + + expect(onLoad).not.toHaveBeenCalled(); + expect(result.current.loaded).toBe(false); + + await waitForNextUpdate(); + + expect(onLoad).toHaveBeenCalledTimes(1); + expect(result.current.loaded).toBe(true); + }); +}); diff --git a/packages/core/src/hooks/useImageLoaded.ts b/packages/core/src/hooks/useImageLoaded.ts new file mode 100644 index 0000000000..cf03761b9d --- /dev/null +++ b/packages/core/src/hooks/useImageLoaded.ts @@ -0,0 +1,25 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; + +interface UseImageLoadedProps { + onLoad?: () => unknown; +} + +export function useImageLoaded({ + onLoad: onLoadProp, +}: UseImageLoadedProps = {}) { + const [loaded, setLoaded] = useState(false); + const ref = useRef(); + + const onLoad = useCallback(() => { + onLoadProp?.(); + setLoaded(true); + }, [onLoadProp]); + + useEffect(() => { + if (ref.current && ref.current.complete) { + onLoad(); + } + }, [onLoad]); + + return { ref, loaded, onLoad }; +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index c5be2505b4..3d117f4324 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -25,7 +25,7 @@ export type { StackProps } from './Stack'; export { ScreenReaderOnly } from './ScreenReaderOnly'; export type { ScreenReaderOnlyProps } from './ScreenReaderOnly'; -export { useControllableState, useId } from './hooks'; +export { useControllableState, useId, useImageLoaded } from './hooks'; export type { UseControllableStateProps } from './hooks'; export { mergeRefs } from './utils/mergeRefs'; export { getEntityStatusStyles } from './utils/getEntityStatusStyles'; diff --git a/packages/website/components/LiveEditor/ComponentSource.tsx b/packages/website/components/LiveEditor/ComponentSource.tsx index b4bb543e82..c9be2ec89a 100644 --- a/packages/website/components/LiveEditor/ComponentSource.tsx +++ b/packages/website/components/LiveEditor/ComponentSource.tsx @@ -13,6 +13,7 @@ import * as f36Components from '@contentful/f36-components'; import { Multiselect } from '@contentful/f36-multiselect'; import { NavList } from '@contentful/f36-navlist'; import * as f36utils from '@contentful/f36-utils'; +import { Image } from '@contentful/f36-image'; import { useForm, useController } from 'react-hook-form'; import { MdAccessAlarm } from 'react-icons/md'; import { Card, Button, CopyButton, Flex } from '@contentful/f36-components'; @@ -37,6 +38,7 @@ const liveProviderScope = { ...f36icons, ...f36Components, ...f36utils, + Image, // Remove when added to f36-components Multiselect, // Remove when added to f36-components NavList, // Remove when added to f36-components css, diff --git a/packages/website/components/Playground/SandpackRenderer.tsx b/packages/website/components/Playground/SandpackRenderer.tsx index 06e7e292ef..47c34daaeb 100644 --- a/packages/website/components/Playground/SandpackRenderer.tsx +++ b/packages/website/components/Playground/SandpackRenderer.tsx @@ -95,6 +95,7 @@ export function SandpackRenderer({ 'react-dom': '^17.0.0', 'react-scripts': '^4.0.0', '@contentful/f36-components': '^4.0.0', + '@contentful/f36-image': '^4.0.0', // Remove when added to f36-components '@contentful/f36-multiselect': '^4.0.0', // Remove when added to f36-components '@contentful/f36-navlist': '^4.1.0-alpha.0', // Remove when added to f36-components '@contentful/f36-tokens': '^4.0.0', diff --git a/packages/website/lib/api.ts b/packages/website/lib/api.ts index 0e78e40ba8..0a4967df7c 100644 --- a/packages/website/lib/api.ts +++ b/packages/website/lib/api.ts @@ -141,28 +141,35 @@ export async function getSingleArticleBySlug(slug, preview = false) { } export async function getAllArticles(preview = false) { - const entries = await fetchGraphQL( - `query { - kbAppArticleCollection(where: { slug_exists: true }) { - items { - ${ARTICLE_GRAPHQL_FIELDS} + try { + const entries = await fetchGraphQL( + `query { + kbAppArticleCollection(where: { slug_exists: true }) { + items { + ${ARTICLE_GRAPHQL_FIELDS} + } } - } - }`, - preview, - ); + }`, + preview, + ); - const articleEntries = extractArticleEntries(entries); + const articleEntries = extractArticleEntries(entries); - return articleEntries; + return articleEntries; + } catch (_error) { + return []; + } } export async function getSidebarLinksBySectionSlug( sectionSlug: string, preview = false, ) { - const entries = await fetchGraphQL( - `query { + let data; + + try { + const entries = await fetchGraphQL( + `query { sectionCollection( where: { slug_exists: true, slug: "${sectionSlug}" } limit: 1 @@ -197,10 +204,13 @@ export async function getSidebarLinksBySectionSlug( } } `, - preview, - ); + preview, + ); - const data = entries?.data?.sectionCollection?.items[0]; + data = entries?.data?.sectionCollection?.items[0]; + } catch (_error) { + // noop + } const prepareLink = (link: { slug: string; authProtected?: boolean }) => { // Changelog link is a special case because we don't want to prepend the section slug @@ -264,8 +274,9 @@ export async function getSidebarLinksBySectionSlug( } export async function getTopbarLinks(preview = false) { - const entries = await fetchGraphQL( - `query { + try { + const entries = await fetchGraphQL( + `query { navigationCollection(limit:1) { items { sys { @@ -284,11 +295,14 @@ export async function getTopbarLinks(preview = false) { } } }`, - preview, - ); + preview, + ); - const topbarLinks = - entries?.data?.navigationCollection?.items[0].sectionsCollection?.items; + const topbarLinks = + entries?.data?.navigationCollection?.items[0].sectionsCollection?.items; - return topbarLinks; + return topbarLinks; + } catch (_error) { + return []; + } } diff --git a/packages/website/package.json b/packages/website/package.json index 2b325abf5a..5465a0cb8a 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -15,6 +15,7 @@ "@contentful/f36-empty-state": "^4.42.0", "@contentful/f36-icon": "^4.42.0", "@contentful/f36-icons": "^4.25.0", + "@contentful/f36-image": "^4.0.0-alpha.0", "@contentful/f36-multiselect": "^4.20.11", "@contentful/f36-navlist": "4.1.0-alpha.1", "@contentful/f36-tokens": "^4.0.2", diff --git a/packages/website/utils/sidebarLinks.json b/packages/website/utils/sidebarLinks.json index 236c437df1..ca2f116470 100644 --- a/packages/website/utils/sidebarLinks.json +++ b/packages/website/utils/sidebarLinks.json @@ -38,6 +38,11 @@ "title": "Icons", "slug": "/components/icon/" }, + { + "title": "Image", + "slug": "/components/image/", + "status": "alpha" + }, { "title": "List", "slug": "/components/list/",