diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index f2bb1312c4365..253dd86879dda 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1026,6 +1026,10 @@ packages/shared-ux/button/exit_full_screen/types @elastic/kibana-global-experien
packages/shared-ux/card/no_data/impl @elastic/kibana-global-experience
packages/shared-ux/card/no_data/mocks @elastic/kibana-global-experience
packages/shared-ux/card/no_data/types @elastic/kibana-global-experience
+packages/shared-ux/file/image/impl @elastic/kibana-global-experience
+packages/shared-ux/file/image/mocks @elastic/kibana-global-experience
+packages/shared-ux/file/image/types @elastic/kibana-global-experience
+packages/shared-ux/file/util @elastic/kibana-global-experience
packages/shared-ux/link/redirect_app/impl @elastic/kibana-global-experience
packages/shared-ux/link/redirect_app/mocks @elastic/kibana-global-experience
packages/shared-ux/link/redirect_app/types @elastic/kibana-global-experience
diff --git a/examples/files_example/common/index.ts b/examples/files_example/common/index.ts
index 3ede97859f9df..29b2c97c9532e 100644
--- a/examples/files_example/common/index.ts
+++ b/examples/files_example/common/index.ts
@@ -6,7 +6,8 @@
* Side Public License, v 1.
*/
-import type { FileKind, FileImageMetadata } from '@kbn/files-plugin/common';
+import type { FileKind } from '@kbn/files-plugin/common';
+import type { FileImageMetadata } from '@kbn/shared-ux-file-image-types';
export const PLUGIN_ID = 'filesExample';
export const PLUGIN_NAME = 'Files example';
diff --git a/examples/files_example/public/imports.ts b/examples/files_example/public/imports.ts
index f21a30a390e60..797dbd6e3a608 100644
--- a/examples/files_example/public/imports.ts
+++ b/examples/files_example/public/imports.ts
@@ -14,7 +14,8 @@ export {
FilesContext,
type ScopedFilesClient,
FilePicker,
- Image,
} from '@kbn/files-plugin/public';
+export { FileImage as Image } from '@kbn/shared-ux-file-image';
+
export type { DeveloperExamplesSetup } from '@kbn/developer-examples-plugin/public';
diff --git a/package.json b/package.json
index ba63c4edf0400..724ec9b99ed92 100644
--- a/package.json
+++ b/package.json
@@ -385,6 +385,10 @@
"@kbn/shared-ux-card-no-data": "link:bazel-bin/packages/shared-ux/card/no_data/impl",
"@kbn/shared-ux-card-no-data-mocks": "link:bazel-bin/packages/shared-ux/card/no_data/mocks",
"@kbn/shared-ux-card-no-data-types": "link:bazel-bin/packages/shared-ux/card/no_data/types",
+ "@kbn/shared-ux-file-image": "link:bazel-bin/packages/shared-ux/file/image/impl",
+ "@kbn/shared-ux-file-image-mocks": "link:bazel-bin/packages/shared-ux/file/image/mocks",
+ "@kbn/shared-ux-file-image-types": "link:bazel-bin/packages/shared-ux/file/image/types",
+ "@kbn/shared-ux-file-util": "link:bazel-bin/packages/shared-ux/file/util",
"@kbn/shared-ux-link-redirect-app": "link:bazel-bin/packages/shared-ux/link/redirect_app/impl",
"@kbn/shared-ux-link-redirect-app-mocks": "link:bazel-bin/packages/shared-ux/link/redirect_app/mocks",
"@kbn/shared-ux-link-redirect-app-types": "link:bazel-bin/packages/shared-ux/link/redirect_app/types",
diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel
index 23b01b114cce2..17a515a5b04a0 100644
--- a/packages/BUILD.bazel
+++ b/packages/BUILD.bazel
@@ -333,6 +333,10 @@ filegroup(
"//packages/shared-ux/card/no_data/impl:build",
"//packages/shared-ux/card/no_data/mocks:build",
"//packages/shared-ux/card/no_data/types:build",
+ "//packages/shared-ux/file/image/impl:build",
+ "//packages/shared-ux/file/image/mocks:build",
+ "//packages/shared-ux/file/image/types:build",
+ "//packages/shared-ux/file/util:build",
"//packages/shared-ux/link/redirect_app/impl:build",
"//packages/shared-ux/link/redirect_app/mocks:build",
"//packages/shared-ux/link/redirect_app/types:build",
@@ -681,6 +685,9 @@ filegroup(
"//packages/shared-ux/button/exit_full_screen/mocks:build_types",
"//packages/shared-ux/card/no_data/impl:build_types",
"//packages/shared-ux/card/no_data/mocks:build_types",
+ "//packages/shared-ux/file/image/impl:build_types",
+ "//packages/shared-ux/file/image/mocks:build_types",
+ "//packages/shared-ux/file/util:build_types",
"//packages/shared-ux/link/redirect_app/impl:build_types",
"//packages/shared-ux/link/redirect_app/mocks:build_types",
"//packages/shared-ux/markdown/impl:build_types",
diff --git a/packages/shared-ux/card/no_data/mocks/tsconfig.json b/packages/shared-ux/card/no_data/mocks/tsconfig.json
index 4703a8ebf5e35..8ed0253743ff7 100644
--- a/packages/shared-ux/card/no_data/mocks/tsconfig.json
+++ b/packages/shared-ux/card/no_data/mocks/tsconfig.json
@@ -5,9 +5,9 @@
"emitDeclarationOnly": true,
"outDir": "target_types",
"types": [
- "jest",
"node",
- "react"
+ "react",
+ "jest"
]
},
"include": [
diff --git a/packages/shared-ux/file/image/impl/BUILD.bazel b/packages/shared-ux/file/image/impl/BUILD.bazel
new file mode 100644
index 0000000000000..95f8b36032d86
--- /dev/null
+++ b/packages/shared-ux/file/image/impl/BUILD.bazel
@@ -0,0 +1,148 @@
+load("@npm//@bazel/typescript:index.bzl", "ts_config")
+load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
+load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
+
+PKG_DIRNAME = "impl"
+PKG_REQUIRE_NAME = "@kbn/shared-ux-file-image"
+
+SOURCE_FILES = glob(
+ [
+ "**/*.ts",
+ "**/*.tsx",
+ "**/*.mdx",
+ ],
+ exclude = [
+ "**/*.config.js",
+ "**/*.mock.*",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/mocks/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+# In this array place runtime dependencies, including other packages and NPM packages
+# which must be available for this code to run.
+#
+# To reference other packages use:
+# "//repo/relative/path/to/package"
+# eg. "//packages/kbn-utils"
+#
+# To reference a NPM package use:
+# "@npm//name-of-package"
+# eg. "@npm//lodash"
+RUNTIME_DEPS = [
+ "@npm//@elastic/eui",
+ "@npm//react",
+ "@npm//classnames",
+ "@npm//@emotion/react",
+ "@npm//@emotion/css",
+ "//packages/shared-ux/file/util",
+ "//packages/kbn-shared-ux-utility",
+]
+
+# In this array place dependencies necessary to build the types, which will include the
+# :npm_module_types target of other packages and packages from NPM, including @types/*
+# packages.
+#
+# To reference the types for another package use:
+# "//repo/relative/path/to/package:npm_module_types"
+# eg. "//packages/kbn-utils:npm_module_types"
+#
+# References to NPM packages work the same as RUNTIME_DEPS
+TYPES_DEPS = [
+ "@npm//@elastic/eui",
+ "@npm//@types/jest",
+ "@npm//@types/node",
+ "@npm//@types/react",
+ "@npm//@types/classnames",
+ "//packages/kbn-ambient-ui-types",
+ "//packages/shared-ux/file/util:npm_module_types",
+ "//packages/shared-ux/file/image/types:npm_module_types",
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+jsts_transpiler(
+ name = "target_web",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+ web = True,
+ additional_args = [
+ "--copy-files",
+ "--quiet"
+ ],
+)
+
+ts_config(
+ name = "tsconfig",
+ src = "tsconfig.json",
+ deps = [
+ "//:tsconfig.base.json",
+ "//:tsconfig.bazel.json",
+ ],
+)
+
+ts_project(
+ name = "tsc_types",
+ args = ['--pretty'],
+ srcs = SRCS,
+ deps = TYPES_DEPS,
+ declaration = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node", ":target_web"],
+ package_name = PKG_REQUIRE_NAME,
+ visibility = ["//visibility:public"],
+)
+
+js_library(
+ name = "npm_module_types",
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"],
+ package_name = PKG_REQUIRE_NAME,
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm(
+ name = "npm_module",
+ deps = [":" + PKG_DIRNAME],
+)
+
+filegroup(
+ name = "build",
+ srcs = [":npm_module"],
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm(
+ name = "build_types",
+ deps = [":npm_module_types"],
+ visibility = ["//visibility:public"],
+)
diff --git a/packages/shared-ux/file/image/impl/README.mdx b/packages/shared-ux/file/image/impl/README.mdx
new file mode 100644
index 0000000000000..fac2086a4e51c
--- /dev/null
+++ b/packages/shared-ux/file/image/impl/README.mdx
@@ -0,0 +1,18 @@
+---
+id: sharedUX/Components/FileImage
+slug: /shared-ux/components/file-image
+title: File image
+description: Display images stored in Kibana files.
+tags: ['shared-ux', 'component', 'files']
+date: 2022-11-22
+---
+
+## Description
+
+A light wrapper around that introduces some "file-aware" functionality like displaying a [blurhash](https://blurha.sh/) before the final image loads.
+
+## Lazy loading
+
+It is a good practice to leverage the browser-native lazy loading of images. Depending on your use case, make sure that content can be loaded lazily where possible.
+
+For more information see the [loading attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading) for more information.
\ No newline at end of file
diff --git a/packages/shared-ux/file/image/impl/index.tsx b/packages/shared-ux/file/image/impl/index.tsx
new file mode 100644
index 0000000000000..957ba6b990590
--- /dev/null
+++ b/packages/shared-ux/file/image/impl/index.tsx
@@ -0,0 +1,10 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export { Image as FileImage } from './src/image';
+export type { Props as FileImageProps } from './src/image';
diff --git a/packages/shared-ux/file/image/impl/kibana.jsonc b/packages/shared-ux/file/image/impl/kibana.jsonc
new file mode 100644
index 0000000000000..93a4709c14bca
--- /dev/null
+++ b/packages/shared-ux/file/image/impl/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/shared-ux-file-image",
+ "owner": "@elastic/kibana-global-experience",
+ "runtimeDeps": [],
+ "typeDeps": []
+}
diff --git a/packages/shared-ux/file/image/impl/package.json b/packages/shared-ux/file/image/impl/package.json
new file mode 100644
index 0000000000000..9b45e313c4194
--- /dev/null
+++ b/packages/shared-ux/file/image/impl/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@kbn/shared-ux-file-image",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "browser": "./target_web/index.js",
+ "license": "SSPL-1.0 OR Elastic License 2.0",
+ "types": "./target_types/index.d.ts"
+}
diff --git a/src/plugins/files/public/components/image/image.stories.tsx b/packages/shared-ux/file/image/impl/src/image.stories.tsx
similarity index 92%
rename from src/plugins/files/public/components/image/image.stories.tsx
rename to packages/shared-ux/file/image/impl/src/image.stories.tsx
index 15967437d0849..762d5407b441a 100644
--- a/src/plugins/files/public/components/image/image.stories.tsx
+++ b/packages/shared-ux/file/image/impl/src/image.stories.tsx
@@ -9,14 +9,14 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
-import { getImageMetadata } from '../util';
+import { getImageMetadata } from '@kbn/shared-ux-file-util';
+import { getImageData as getBlob, base64dLogo } from '@kbn/shared-ux-file-image-mocks';
import { Image, Props } from './image';
-import { getImageData as getBlob, base64dLogo } from './image.constants.stories';
const defaultArgs: Props = { alt: 'test', src: `data:image/png;base64,${base64dLogo}` };
export default {
- title: 'components/Image',
+ title: 'files/Image',
component: Image,
args: defaultArgs,
decorators: [
diff --git a/src/plugins/files/public/components/image/image.tsx b/packages/shared-ux/file/image/impl/src/image.tsx
similarity index 96%
rename from src/plugins/files/public/components/image/image.tsx
rename to packages/shared-ux/file/image/impl/src/image.tsx
index d538ad2308040..59dc56d4ddc15 100644
--- a/src/plugins/files/public/components/image/image.tsx
+++ b/packages/shared-ux/file/image/impl/src/image.tsx
@@ -9,10 +9,10 @@
import React from 'react';
import { useState } from 'react';
import { EuiImage, EuiImageProps } from '@elastic/eui';
+import type { FileImageMetadata } from '@kbn/shared-ux-file-image-types';
+import { getBlurhashSrc } from '@kbn/shared-ux-file-util';
import classNames from 'classnames';
import { css } from '@emotion/react';
-import type { FileImageMetadata } from '../../../common';
-import { getBlurhashSrc } from '../util';
export type Props = { meta?: FileImageMetadata } & EuiImageProps;
diff --git a/src/plugins/files/public/components/image/index.ts b/packages/shared-ux/file/image/impl/src/index.ts
similarity index 100%
rename from src/plugins/files/public/components/image/index.ts
rename to packages/shared-ux/file/image/impl/src/index.ts
diff --git a/packages/shared-ux/file/image/impl/tsconfig.json b/packages/shared-ux/file/image/impl/tsconfig.json
new file mode 100644
index 0000000000000..dad7279f0e301
--- /dev/null
+++ b/packages/shared-ux/file/image/impl/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "types": [
+ "node",
+ "jest",
+ "react",
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ "**/*.tsx",
+ ]
+}
diff --git a/packages/shared-ux/file/image/mocks/BUILD.bazel b/packages/shared-ux/file/image/mocks/BUILD.bazel
new file mode 100644
index 0000000000000..0c25ef25839ae
--- /dev/null
+++ b/packages/shared-ux/file/image/mocks/BUILD.bazel
@@ -0,0 +1,127 @@
+load("@npm//@bazel/typescript:index.bzl", "ts_config")
+load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
+load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
+
+PKG_DIRNAME = "mocks"
+PKG_REQUIRE_NAME = "@kbn/shared-ux-file-image-mocks"
+
+SOURCE_FILES = glob(
+ [
+ "**/*.ts",
+ ],
+ exclude = [
+ "**/*.config.js",
+ "**/*.mock.*",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/mocks/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+# In this array place runtime dependencies, including other packages and NPM packages
+# which must be available for this code to run.
+#
+# To reference other packages use:
+# "//repo/relative/path/to/package"
+# eg. "//packages/kbn-utils"
+#
+# To reference a NPM package use:
+# "@npm//name-of-package"
+# eg. "@npm//lodash"
+RUNTIME_DEPS = [ ]
+
+# In this array place dependencies necessary to build the types, which will include the
+# :npm_module_types target of other packages and packages from NPM, including @types/*
+# packages.
+#
+# To reference the types for another package use:
+# "//repo/relative/path/to/package:npm_module_types"
+# eg. "//packages/kbn-utils:npm_module_types"
+#
+# References to NPM packages work the same as RUNTIME_DEPS
+TYPES_DEPS = [
+ "@npm//@types/node",
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+jsts_transpiler(
+ name = "target_web",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+ web = True,
+)
+
+ts_config(
+ name = "tsconfig",
+ src = "tsconfig.json",
+ deps = [
+ "//:tsconfig.base.json",
+ "//:tsconfig.bazel.json",
+ ],
+)
+
+ts_project(
+ name = "tsc_types",
+ args = ['--pretty'],
+ srcs = SRCS,
+ deps = TYPES_DEPS,
+ declaration = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node", ":target_web"],
+ package_name = PKG_REQUIRE_NAME,
+ visibility = ["//visibility:public"],
+)
+
+js_library(
+ name = "npm_module_types",
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"],
+ package_name = PKG_REQUIRE_NAME,
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm(
+ name = "npm_module",
+ deps = [":" + PKG_DIRNAME],
+)
+
+filegroup(
+ name = "build",
+ srcs = [":npm_module"],
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm(
+ name = "build_types",
+ deps = [":npm_module_types"],
+ visibility = ["//visibility:public"],
+)
diff --git a/packages/shared-ux/file/image/mocks/README.md b/packages/shared-ux/file/image/mocks/README.md
new file mode 100644
index 0000000000000..c05a289f6aee5
--- /dev/null
+++ b/packages/shared-ux/file/image/mocks/README.md
@@ -0,0 +1,3 @@
+# @kbn/shared-ux-card-no-data-mocks
+
+TODO
diff --git a/packages/shared-ux/file/image/mocks/index.ts b/packages/shared-ux/file/image/mocks/index.ts
new file mode 100644
index 0000000000000..6337cc0044596
--- /dev/null
+++ b/packages/shared-ux/file/image/mocks/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export { base64dLogo, getImageData } from './src';
diff --git a/packages/shared-ux/file/image/mocks/kibana.jsonc b/packages/shared-ux/file/image/mocks/kibana.jsonc
new file mode 100644
index 0000000000000..bb4d6a6acca4e
--- /dev/null
+++ b/packages/shared-ux/file/image/mocks/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/shared-ux-file-image-mocks",
+ "owner": "@elastic/kibana-global-experience",
+ "runtimeDeps": [],
+ "typeDeps": []
+}
diff --git a/packages/shared-ux/file/image/mocks/package.json b/packages/shared-ux/file/image/mocks/package.json
new file mode 100644
index 0000000000000..02f631e8257ea
--- /dev/null
+++ b/packages/shared-ux/file/image/mocks/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@kbn/shared-ux-file-image-mocks",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "browser": "./target_web/index.js",
+ "license": "SSPL-1.0 OR Elastic License 2.0",
+ "types": "./target_types/index.d.ts"
+}
\ No newline at end of file
diff --git a/src/plugins/files/public/components/image/image.constants.stories.tsx b/packages/shared-ux/file/image/mocks/src/index.ts
similarity index 100%
rename from src/plugins/files/public/components/image/image.constants.stories.tsx
rename to packages/shared-ux/file/image/mocks/src/index.ts
diff --git a/packages/shared-ux/file/image/mocks/tsconfig.json b/packages/shared-ux/file/image/mocks/tsconfig.json
new file mode 100644
index 0000000000000..88aabf570de07
--- /dev/null
+++ b/packages/shared-ux/file/image/mocks/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "extends": "../../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "types": [
+ "node",
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ ]
+}
diff --git a/packages/shared-ux/file/image/types/BUILD.bazel b/packages/shared-ux/file/image/types/BUILD.bazel
new file mode 100644
index 0000000000000..d328c3c4fc76a
--- /dev/null
+++ b/packages/shared-ux/file/image/types/BUILD.bazel
@@ -0,0 +1,59 @@
+load("@npm//@bazel/typescript:index.bzl", "ts_config")
+load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
+load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
+
+PKG_DIRNAME = "types"
+PKG_REQUIRE_NAME = "@kbn/shared-ux-file-image-types"
+
+SRCS = glob(
+ [
+ "*.d.ts",
+ ]
+)
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+# In this array place runtime dependencies, including other packages and NPM packages
+# which must be available for this code to run.
+#
+# To reference other packages use:
+# "//repo/relative/path/to/package"
+# eg. "//packages/kbn-utils"
+#
+# To reference a NPM package use:
+# "@npm//name-of-package"
+# eg. "@npm//lodash"
+RUNTIME_DEPS = [
+]
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = SRCS + NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS,
+ package_name = PKG_REQUIRE_NAME,
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm(
+ name = "npm_module",
+ deps = [":" + PKG_DIRNAME],
+)
+
+filegroup(
+ name = "build",
+ srcs = [":npm_module"],
+ visibility = ["//visibility:public"],
+)
+
+alias(
+ name = "npm_module_types",
+ actual = ":" + PKG_DIRNAME,
+ visibility = ["//visibility:public"],
+)
diff --git a/packages/shared-ux/file/image/types/README.md b/packages/shared-ux/file/image/types/README.md
new file mode 100644
index 0000000000000..6bef9e4caac23
--- /dev/null
+++ b/packages/shared-ux/file/image/types/README.md
@@ -0,0 +1,3 @@
+# @kbn/shared-ux-link-redirect-app-types
+
+TODO
diff --git a/packages/shared-ux/file/image/types/index.d.ts b/packages/shared-ux/file/image/types/index.d.ts
new file mode 100644
index 0000000000000..0635982d12a75
--- /dev/null
+++ b/packages/shared-ux/file/image/types/index.d.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+/**
+ * Set of metadata captured for every image uploaded via the file services'
+ * public components.
+ */
+export interface FileImageMetadata {
+ /**
+ * The blurhash that can be displayed while the image is loading
+ */
+ blurhash?: string;
+ /**
+ * Width, in px, of the original image
+ */
+ width: number;
+ /**
+ * Height, in px, of the original image
+ */
+ height: number;
+}
diff --git a/packages/shared-ux/file/image/types/kibana.jsonc b/packages/shared-ux/file/image/types/kibana.jsonc
new file mode 100644
index 0000000000000..c337cfd460355
--- /dev/null
+++ b/packages/shared-ux/file/image/types/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/shared-ux-link-redirect-app-types",
+ "owner": "@elastic/kibana-global-experience",
+ "runtimeDeps": [],
+ "typeDeps": []
+}
diff --git a/packages/shared-ux/file/image/types/package.json b/packages/shared-ux/file/image/types/package.json
new file mode 100644
index 0000000000000..66726e55b51fe
--- /dev/null
+++ b/packages/shared-ux/file/image/types/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "@kbn/shared-ux-link-redirect-app-types",
+ "private": true,
+ "version": "1.0.0",
+ "license": "SSPL-1.0 OR Elastic License 2.0"
+}
\ No newline at end of file
diff --git a/packages/shared-ux/file/image/types/tsconfig.json b/packages/shared-ux/file/image/types/tsconfig.json
new file mode 100644
index 0000000000000..f566d00dd2704
--- /dev/null
+++ b/packages/shared-ux/file/image/types/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "extends": "../../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "types": [
+ "rxjs",
+ "@types/react",
+ ]
+ },
+ "include": [
+ "*.d.ts"
+ ]
+}
diff --git a/packages/shared-ux/file/util/BUILD.bazel b/packages/shared-ux/file/util/BUILD.bazel
new file mode 100644
index 0000000000000..e7aeb058410b9
--- /dev/null
+++ b/packages/shared-ux/file/util/BUILD.bazel
@@ -0,0 +1,138 @@
+load("@npm//@bazel/typescript:index.bzl", "ts_config")
+load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
+load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
+
+PKG_DIRNAME = "util"
+PKG_REQUIRE_NAME = "@kbn/shared-ux-file-util"
+
+SOURCE_FILES = glob(
+ [
+ "**/*.ts",
+ "**/*.tsx",
+ "**/*.mdx",
+ ],
+ exclude = [
+ "**/*.config.js",
+ "**/*.mock.*",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/mocks/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+# In this array place runtime dependencies, including other packages and NPM packages
+# which must be available for this code to run.
+#
+# To reference other packages use:
+# "//repo/relative/path/to/package"
+# eg. "//packages/kbn-utils"
+#
+# To reference a NPM package use:
+# "@npm//name-of-package"
+# eg. "@npm//lodash"
+RUNTIME_DEPS = [
+ "@npm//jest",
+ "@npm//blurhash",
+]
+
+# In this array place dependencies necessary to build the types, which will include the
+# :npm_module_types target of other packages and packages from NPM, including @types/*
+# packages.
+#
+# To reference the types for another package use:
+# "//repo/relative/path/to/package:npm_module_types"
+# eg. "//packages/kbn-utils:npm_module_types"
+#
+# References to NPM packages work the same as RUNTIME_DEPS
+TYPES_DEPS = [
+ "@npm//@types/jest",
+ "@npm//blurhash",
+ "//packages/shared-ux/file/image/types:npm_module_types",
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+jsts_transpiler(
+ name = "target_web",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+ web = True,
+ additional_args = [
+ "--copy-files",
+ "--quiet"
+ ],
+)
+
+ts_config(
+ name = "tsconfig",
+ src = "tsconfig.json",
+ deps = [
+ "//:tsconfig.base.json",
+ "//:tsconfig.bazel.json",
+ ],
+)
+
+ts_project(
+ name = "tsc_types",
+ args = ['--pretty'],
+ srcs = SRCS,
+ deps = TYPES_DEPS,
+ declaration = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node", ":target_web"],
+ package_name = PKG_REQUIRE_NAME,
+ visibility = ["//visibility:public"],
+)
+
+js_library(
+ name = "npm_module_types",
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node", ":target_web", ":tsc_types"],
+ package_name = PKG_REQUIRE_NAME,
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm(
+ name = "npm_module",
+ deps = [":" + PKG_DIRNAME],
+)
+
+filegroup(
+ name = "build",
+ srcs = [":npm_module"],
+ visibility = ["//visibility:public"],
+)
+
+pkg_npm(
+ name = "build_types",
+ deps = [":npm_module_types"],
+ visibility = ["//visibility:public"],
+)
diff --git a/packages/shared-ux/file/util/README.mdx b/packages/shared-ux/file/util/README.mdx
new file mode 100644
index 0000000000000..6471ddec90d6c
--- /dev/null
+++ b/packages/shared-ux/file/util/README.mdx
@@ -0,0 +1,12 @@
+---
+id: sharedUX/Components/FileUtilities
+slug: /shared-ux/components/util
+title: File component utilities
+description: Common utilities used by shared UX file components.
+tags: ['shared-ux', 'utilities', 'files']
+date: 2022-11-22
+---
+
+## Description
+
+A set of utilities used by shared UX file components for working with files.
diff --git a/packages/shared-ux/file/util/index.ts b/packages/shared-ux/file/util/index.ts
new file mode 100644
index 0000000000000..25ce4d9f13cbb
--- /dev/null
+++ b/packages/shared-ux/file/util/index.ts
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export {
+ fitToBox,
+ getBlurhashSrc,
+ getImageMetadata,
+ isImage,
+ type ImageMetadataFactory,
+} from './src';
diff --git a/packages/shared-ux/file/util/jest.config.js b/packages/shared-ux/file/util/jest.config.js
new file mode 100644
index 0000000000000..6ca3cc46f0eb6
--- /dev/null
+++ b/packages/shared-ux/file/util/jest.config.js
@@ -0,0 +1,14 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+module.exports = {
+ preset: '@kbn/test',
+ rootDir: '../../../..',
+ roots: ['/packages/shared-ux/file/util'],
+ verbose: true,
+};
diff --git a/packages/shared-ux/file/util/kibana.jsonc b/packages/shared-ux/file/util/kibana.jsonc
new file mode 100644
index 0000000000000..ef30839a63640
--- /dev/null
+++ b/packages/shared-ux/file/util/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/shared-ux-file-util",
+ "owner": "@elastic/kibana-global-experience",
+ "runtimeDeps": [],
+ "typeDeps": []
+}
diff --git a/packages/shared-ux/file/util/package.json b/packages/shared-ux/file/util/package.json
new file mode 100644
index 0000000000000..91b5fbb765173
--- /dev/null
+++ b/packages/shared-ux/file/util/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@kbn/shared-ux-file-util",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "browser": "./target_web/index.js",
+ "license": "SSPL-1.0 OR Elastic License 2.0",
+ "types": "./target_types/index.d.ts"
+}
diff --git a/packages/shared-ux/file/util/src/image_metadata.test.ts b/packages/shared-ux/file/util/src/image_metadata.test.ts
new file mode 100644
index 0000000000000..d91b9be36f6bb
--- /dev/null
+++ b/packages/shared-ux/file/util/src/image_metadata.test.ts
@@ -0,0 +1,57 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { fitToBox } from './image_metadata';
+describe('util', () => {
+ describe('fitToBox', () => {
+ test('300x300', () => {
+ expect(fitToBox(300, 300)).toMatchInlineSnapshot(`
+ Object {
+ "height": 120,
+ "width": 120,
+ }
+ `);
+ });
+
+ test('300x150', () => {
+ expect(fitToBox(300, 150)).toMatchInlineSnapshot(`
+ Object {
+ "height": 60,
+ "width": 120,
+ }
+ `);
+ });
+
+ test('4500x9000', () => {
+ expect(fitToBox(4500, 9000)).toMatchInlineSnapshot(`
+ Object {
+ "height": 120,
+ "width": 60,
+ }
+ `);
+ });
+
+ test('1000x300', () => {
+ expect(fitToBox(1000, 300)).toMatchInlineSnapshot(`
+ Object {
+ "height": 36,
+ "width": 120,
+ }
+ `);
+ });
+
+ test('0x0', () => {
+ expect(fitToBox(0, 0)).toMatchInlineSnapshot(`
+ Object {
+ "height": 0,
+ "width": 0,
+ }
+ `);
+ });
+ });
+});
diff --git a/packages/shared-ux/file/util/src/image_metadata.ts b/packages/shared-ux/file/util/src/image_metadata.ts
new file mode 100644
index 0000000000000..f19abcf14c053
--- /dev/null
+++ b/packages/shared-ux/file/util/src/image_metadata.ts
@@ -0,0 +1,111 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import bh from 'blurhash';
+import type { FileImageMetadata } from '@kbn/shared-ux-file-image-types';
+
+export function isImage(file: { type?: string }): boolean {
+ return Boolean(file.type?.startsWith('image/'));
+}
+
+export const boxDimensions = {
+ width: 120,
+ height: 120,
+};
+
+/**
+ * Calculate the size of an image, fitting to our limits see {@link boxDimensions},
+ * while preserving the aspect ratio.
+ */
+export function fitToBox(width: number, height: number): { width: number; height: number } {
+ const offsetRatio = Math.abs(
+ Math.min(
+ // Find the aspect at which our box is smallest, if less than 1, it means we exceed the limits
+ Math.min(boxDimensions.width / width, boxDimensions.height / height),
+ // Values greater than 1 are within our limits
+ 1
+ ) - 1 // Get the percentage we are exceeding. E.g., 0.3 - 1 = -0.7 means the image needs to shrink by 70% to fit
+ );
+ return {
+ width: Math.floor(width - offsetRatio * width),
+ height: Math.floor(height - offsetRatio * height),
+ };
+}
+
+/**
+ * Get the native size of the image
+ */
+function loadImage(src: string): Promise {
+ return new Promise((res, rej) => {
+ const image = new window.Image();
+ image.src = src;
+ image.onload = () => res(image);
+ image.onerror = rej;
+ });
+}
+
+/**
+ * Extract image metadata, assumes that file or blob as an image!
+ */
+export async function getImageMetadata(file: File | Blob): Promise {
+ const imgUrl = window.URL.createObjectURL(file);
+ try {
+ const image = await loadImage(imgUrl);
+ const canvas = document.createElement('canvas');
+ // blurhash encoding and decoding is an expensive algorithm,
+ // so we have to shrink the image to speed up the calculation
+ const { width, height } = fitToBox(image.width, image.height);
+ canvas.width = width;
+ canvas.height = height;
+ const ctx = canvas.getContext('2d');
+ if (!ctx) throw new Error('Could not get 2d canvas context!');
+ ctx.drawImage(image, 0, 0, width, height);
+ const imgData = ctx.getImageData(0, 0, width, height);
+ return {
+ blurhash: bh.encode(imgData.data, imgData.width, imgData.height, 4, 4),
+ width: image.width,
+ height: image.height,
+ };
+ } catch (e) {
+ // Don't error out if we cannot generate the blurhash
+ return undefined;
+ } finally {
+ window.URL.revokeObjectURL(imgUrl);
+ }
+}
+
+export type ImageMetadataFactory = typeof getImageMetadata;
+
+export function getBlurhashSrc({
+ width,
+ height,
+ hash,
+}: {
+ width: number;
+ height: number;
+ hash: string;
+}): string {
+ const smallSizeImageCanvas = document.createElement('canvas');
+ const { width: blurWidth, height: blurHeight } = fitToBox(width, height);
+ smallSizeImageCanvas.width = blurWidth;
+ smallSizeImageCanvas.height = blurHeight;
+
+ const smallSizeImageCtx = smallSizeImageCanvas.getContext('2d')!;
+ const imageData = smallSizeImageCtx.createImageData(blurWidth, blurHeight);
+ imageData.data.set(bh.decode(hash, blurWidth, blurHeight));
+ smallSizeImageCtx.putImageData(imageData, 0, 0);
+
+ // scale back the blurred image to the size of the original image,
+ // so it is sized and positioned the same as the original image when used with an `` tag
+ const originalSizeImageCanvas = document.createElement('canvas');
+ originalSizeImageCanvas.width = width;
+ originalSizeImageCanvas.height = height;
+ const originalSizeImageCtx = originalSizeImageCanvas.getContext('2d')!;
+ originalSizeImageCtx.drawImage(smallSizeImageCanvas, 0, 0, width, height);
+ return originalSizeImageCanvas.toDataURL();
+}
diff --git a/packages/shared-ux/file/util/src/index.ts b/packages/shared-ux/file/util/src/index.ts
new file mode 100644
index 0000000000000..9e0dccc6c3365
--- /dev/null
+++ b/packages/shared-ux/file/util/src/index.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export { getImageMetadata, isImage, fitToBox, getBlurhashSrc } from './image_metadata';
+export type { ImageMetadataFactory } from './image_metadata';
diff --git a/packages/shared-ux/file/util/tsconfig.json b/packages/shared-ux/file/util/tsconfig.json
new file mode 100644
index 0000000000000..47ad657279cbb
--- /dev/null
+++ b/packages/shared-ux/file/util/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "types": [
+ "jest",
+ "node",
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ "**/*.tsx",
+ ]
+}
diff --git a/packages/shared-ux/page/no_data/mocks/BUILD.bazel b/packages/shared-ux/page/no_data/mocks/BUILD.bazel
index eaeec70938a64..52b1806936a2d 100644
--- a/packages/shared-ux/page/no_data/mocks/BUILD.bazel
+++ b/packages/shared-ux/page/no_data/mocks/BUILD.bazel
@@ -47,7 +47,7 @@ NPM_MODULE_EXTRA_FILES = [
# eg. "@npm//lodash"
RUNTIME_DEPS = [
"@npm//react",
- "@npm//@storybook/addon-actions",
+ "@npm//@storybook/addon-actions",
"//packages/shared-ux/card/no_data/mocks",
"//packages/shared-ux/storybook/mock",
]
diff --git a/src/plugins/files/common/index.ts b/src/plugins/files/common/index.ts
index 16a7d03775e86..05d32a0645a0d 100755
--- a/src/plugins/files/common/index.ts
+++ b/src/plugins/files/common/index.ts
@@ -23,7 +23,6 @@ export type {
FileSavedObject,
BaseFileMetadata,
FileShareOptions,
- FileImageMetadata,
FileUnshareOptions,
BlobStorageSettings,
UpdatableFileMetadata,
diff --git a/src/plugins/files/common/types.ts b/src/plugins/files/common/types.ts
index 247340c583ea6..370be9028317c 100644
--- a/src/plugins/files/common/types.ts
+++ b/src/plugins/files/common/types.ts
@@ -559,22 +559,3 @@ export interface FilesMetrics {
*/
countByExtension: Record;
}
-
-/**
- * Set of metadata captured for every image uploaded via the file services'
- * public components.
- */
-export interface FileImageMetadata {
- /**
- * The blurhash that can be displayed while the image is loading
- */
- blurhash?: string;
- /**
- * Width, in px, of the original image
- */
- width: number;
- /**
- * Height, in px, of the original image
- */
- height: number;
-}
diff --git a/src/plugins/files/public/components/file_picker/components/file_card.tsx b/src/plugins/files/public/components/file_picker/components/file_card.tsx
index 8e5730a9745ac..148f77736bfe1 100644
--- a/src/plugins/files/public/components/file_picker/components/file_card.tsx
+++ b/src/plugins/files/public/components/file_picker/components/file_card.tsx
@@ -12,8 +12,9 @@ import numeral from '@elastic/numeral';
import useObservable from 'react-use/lib/useObservable';
import { EuiCard, EuiText, EuiIcon, useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';
-import { FileImageMetadata, FileJSON } from '../../../../common';
-import { Image } from '../../image';
+import { FileImage as Image } from '@kbn/shared-ux-file-image';
+import type { FileImageMetadata } from '@kbn/shared-ux-file-image-types';
+import { FileJSON } from '../../../../common';
import { isImage } from '../../util';
import { useFilePickerContext } from '../context';
diff --git a/src/plugins/files/public/components/file_picker/file_picker.stories.tsx b/src/plugins/files/public/components/file_picker/file_picker.stories.tsx
index 573f321ebcf4c..e0de316d60b24 100644
--- a/src/plugins/files/public/components/file_picker/file_picker.stories.tsx
+++ b/src/plugins/files/public/components/file_picker/file_picker.stories.tsx
@@ -9,10 +9,11 @@
import React from 'react';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { action } from '@storybook/addon-actions';
-import type { FileJSON, FileImageMetadata } from '../../../common';
+import { base64dLogo } from '@kbn/shared-ux-file-image-mocks';
+import type { FileImageMetadata } from '@kbn/shared-ux-file-image-types';
+import type { FileJSON } from '../../../common';
import { FilesClient, FilesClientResponses } from '../../types';
import { register } from '../stories_shared';
-import { base64dLogo } from '../image/image.constants.stories';
import { FilesContext } from '../context';
import { FilePicker, Props as FilePickerProps } from './file_picker';
diff --git a/src/plugins/files/public/components/index.ts b/src/plugins/files/public/components/index.ts
index e4470d4a58be7..87354bd934f32 100644
--- a/src/plugins/files/public/components/index.ts
+++ b/src/plugins/files/public/components/index.ts
@@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
-export { Image, type ImageProps } from './image';
export { UploadFile, type UploadFileProps } from './upload_file';
export { FilePicker, type FilePickerProps } from './file_picker';
export { FilesContext } from './context';
diff --git a/src/plugins/files/public/components/util/image_metadata.ts b/src/plugins/files/public/components/util/image_metadata.ts
index b1faed7b294b8..891448b99bbbe 100644
--- a/src/plugins/files/public/components/util/image_metadata.ts
+++ b/src/plugins/files/public/components/util/image_metadata.ts
@@ -7,7 +7,7 @@
*/
import * as bh from 'blurhash';
-import type { FileImageMetadata } from '../../../common';
+import type { FileImageMetadata } from '@kbn/shared-ux-file-image-types';
export function isImage(file: { type?: string }): boolean {
return Boolean(file.type?.startsWith('image/'));
diff --git a/src/plugins/files/public/index.ts b/src/plugins/files/public/index.ts
index 2d07fa06b8a4e..dc36b4d29d25a 100644
--- a/src/plugins/files/public/index.ts
+++ b/src/plugins/files/public/index.ts
@@ -17,8 +17,6 @@ export type {
} from './types';
export {
FilesContext,
- Image,
- type ImageProps,
UploadFile,
type UploadFileProps,
FilePicker,
diff --git a/src/plugins/files_management/public/components/file_flyout.tsx b/src/plugins/files_management/public/components/file_flyout.tsx
index 93339edae5000..05f77ea69af41 100644
--- a/src/plugins/files_management/public/components/file_flyout.tsx
+++ b/src/plugins/files_management/public/components/file_flyout.tsx
@@ -23,7 +23,7 @@ import {
import numeral from '@elastic/numeral';
import type { FileJSON } from '@kbn/files-plugin/common';
import type { FunctionComponent } from 'react';
-import { Image } from '@kbn/files-plugin/public';
+import { FileImage as Image } from '@kbn/shared-ux-file-image';
import React from 'react';
import { i18nTexts } from '../i18n_texts';
import { useFilesManagementContext } from '../context';
diff --git a/tsconfig.base.json b/tsconfig.base.json
index 8d2fb8125c1cb..a1d756709ee16 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -654,6 +654,14 @@
"@kbn/shared-ux-card-no-data-mocks/*": ["packages/shared-ux/card/no_data/mocks/*"],
"@kbn/shared-ux-card-no-data-types": ["packages/shared-ux/card/no_data/types"],
"@kbn/shared-ux-card-no-data-types/*": ["packages/shared-ux/card/no_data/types/*"],
+ "@kbn/shared-ux-file-image": ["packages/shared-ux/file/image/impl"],
+ "@kbn/shared-ux-file-image/*": ["packages/shared-ux/file/image/impl/*"],
+ "@kbn/shared-ux-file-image-mocks": ["packages/shared-ux/file/image/mocks"],
+ "@kbn/shared-ux-file-image-mocks/*": ["packages/shared-ux/file/image/mocks/*"],
+ "@kbn/shared-ux-link-redirect-app-types": ["packages/shared-ux/file/image/types"],
+ "@kbn/shared-ux-link-redirect-app-types/*": ["packages/shared-ux/file/image/types/*"],
+ "@kbn/shared-ux-file-util": ["packages/shared-ux/file/util"],
+ "@kbn/shared-ux-file-util/*": ["packages/shared-ux/file/util/*"],
"@kbn/shared-ux-link-redirect-app": ["packages/shared-ux/link/redirect_app/impl"],
"@kbn/shared-ux-link-redirect-app/*": ["packages/shared-ux/link/redirect_app/impl/*"],
"@kbn/shared-ux-link-redirect-app-mocks": ["packages/shared-ux/link/redirect_app/mocks"],
diff --git a/yarn.lock b/yarn.lock
index d0192a4719a7b..a1e85461a3915 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3901,6 +3901,22 @@
version "0.0.0"
uid ""
+"@kbn/shared-ux-file-image-mocks@link:bazel-bin/packages/shared-ux/file/image/mocks":
+ version "0.0.0"
+ uid ""
+
+"@kbn/shared-ux-file-image-types@link:bazel-bin/packages/shared-ux/file/image/types":
+ version "0.0.0"
+ uid ""
+
+"@kbn/shared-ux-file-image@link:bazel-bin/packages/shared-ux/file/image/impl":
+ version "0.0.0"
+ uid ""
+
+"@kbn/shared-ux-file-util@link:bazel-bin/packages/shared-ux/file/util":
+ version "0.0.0"
+ uid ""
+
"@kbn/shared-ux-link-redirect-app-mocks@link:bazel-bin/packages/shared-ux/link/redirect_app/mocks":
version "0.0.0"
uid ""