mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Shared UX] Solution Avatar to package (#131579)
* [Shared UX] Solution Avatar to package * Fix imports * Fix snapshots
This commit is contained in:
parent
7d0db74f6a
commit
0b65d5b7e2
25 changed files with 450 additions and 109 deletions
|
@ -178,6 +178,7 @@
|
|||
"@kbn/securitysolution-utils": "link:bazel-bin/packages/kbn-securitysolution-utils",
|
||||
"@kbn/server-http-tools": "link:bazel-bin/packages/kbn-server-http-tools",
|
||||
"@kbn/server-route-repository": "link:bazel-bin/packages/kbn-server-route-repository",
|
||||
"@kbn/shared-ux-avatar-solution": "link:bazel-bin/packages/shared-ux/avatar/solution",
|
||||
"@kbn/shared-ux-button-exit-full-screen": "link:bazel-bin/packages/shared-ux/button/exit_full_screen",
|
||||
"@kbn/shared-ux-components": "link:bazel-bin/packages/kbn-shared-ux-components",
|
||||
"@kbn/shared-ux-link-redirect-app": "link:bazel-bin/packages/shared-ux/link/redirect_app",
|
||||
|
@ -666,6 +667,7 @@
|
|||
"@types/kbn__securitysolution-utils": "link:bazel-bin/packages/kbn-securitysolution-utils/npm_module_types",
|
||||
"@types/kbn__server-http-tools": "link:bazel-bin/packages/kbn-server-http-tools/npm_module_types",
|
||||
"@types/kbn__server-route-repository": "link:bazel-bin/packages/kbn-server-route-repository/npm_module_types",
|
||||
"@types/kbn__shared-ux-avatar-solution": "link:bazel-bin/packages/shared-ux/avatar/solution/npm_module_types",
|
||||
"@types/kbn__shared-ux-button-exit-full-screen": "link:bazel-bin/packages/shared-ux/button/exit_full_screen/npm_module_types",
|
||||
"@types/kbn__shared-ux-components": "link:bazel-bin/packages/kbn-shared-ux-components/npm_module_types",
|
||||
"@types/kbn__shared-ux-link-redirect-app": "link:bazel-bin/packages/shared-ux/link/redirect_app/npm_module_types",
|
||||
|
|
|
@ -109,6 +109,7 @@ filegroup(
|
|||
"//packages/kbn-ui-theme:build",
|
||||
"//packages/kbn-utility-types:build",
|
||||
"//packages/kbn-utils:build",
|
||||
"//packages/shared-ux/avatar/solution:build",
|
||||
"//packages/shared-ux/button/exit_full_screen:build",
|
||||
"//packages/shared-ux/link/redirect_app:build",
|
||||
],
|
||||
|
@ -203,6 +204,7 @@ filegroup(
|
|||
"//packages/kbn-ui-theme:build_types",
|
||||
"//packages/kbn-utility-types:build_types",
|
||||
"//packages/kbn-utils:build_types",
|
||||
"//packages/shared-ux/avatar/solution:build_types",
|
||||
"//packages/shared-ux/button/exit_full_screen:build_types",
|
||||
"//packages/shared-ux/link/redirect_app:build_types",
|
||||
],
|
||||
|
|
|
@ -42,6 +42,7 @@ NPM_MODULE_EXTRA_FILES = [
|
|||
RUNTIME_DEPS = [
|
||||
"//packages/kbn-i18n-react",
|
||||
"//packages/kbn-i18n",
|
||||
"//packages/shared-ux/avatar/solution",
|
||||
"//packages/shared-ux/link/redirect_app",
|
||||
"//packages/kbn-shared-ux-services",
|
||||
"//packages/kbn-shared-ux-storybook",
|
||||
|
@ -69,6 +70,7 @@ TYPES_DEPS = [
|
|||
"//packages/kbn-ambient-ui-types",
|
||||
"//packages/kbn-i18n-react:npm_module_types",
|
||||
"//packages/kbn-i18n:npm_module_types",
|
||||
"//packages/shared-ux/avatar/solution:npm_module_types",
|
||||
"//packages/shared-ux/link/redirect_app:npm_module_types",
|
||||
"//packages/kbn-shared-ux-services:npm_module_types",
|
||||
"//packages/kbn-shared-ux-storybook:npm_module_types",
|
||||
|
|
|
@ -98,23 +98,6 @@ export const KibanaPageTemplateSolutionNavLazy = React.lazy(() =>
|
|||
*/
|
||||
export const KibanaPageTemplateSolutionNav = withSuspense(KibanaPageTemplateSolutionNavLazy);
|
||||
|
||||
/**
|
||||
* The Lazily-loaded `KibanaSolutionAvatar` component. Consumers should use `React.Suspense` or
|
||||
* the withSuspense` HOC to load this component.
|
||||
*/
|
||||
export const KibanaSolutionAvatarLazy = React.lazy(() =>
|
||||
import('./solution_avatar').then(({ KibanaSolutionAvatar }) => ({
|
||||
default: KibanaSolutionAvatar,
|
||||
}))
|
||||
);
|
||||
|
||||
/**
|
||||
* A `KibanaSolutionAvatar` component that is wrapped by the `withSuspense` HOC. This component can
|
||||
* be used directly by consumers and will load the `KibanaPageTemplateSolutionNavAvatarLazy` component lazily with
|
||||
* a predefined fallback and error boundary.
|
||||
*/
|
||||
export const KibanaSolutionAvatar = withSuspense(KibanaSolutionAvatarLazy);
|
||||
|
||||
/**
|
||||
* The Lazily-loaded `NoDataViews` component. Consumers should use `React.Suspennse` or the
|
||||
* `withSuspense` HOC to load this component.
|
||||
|
|
|
@ -7,7 +7,7 @@ exports[`NoDataPage render 1`] = `
|
|||
<EuiText
|
||||
textAlign="center"
|
||||
>
|
||||
<KibanaSolutionAvatar
|
||||
<ForwardRef
|
||||
iconType="logoKibana"
|
||||
name="Analytics"
|
||||
size="xxl"
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
*/
|
||||
|
||||
import React, { useMemo, FunctionComponent } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { EuiLink, EuiSpacer, EuiText, EuiTextColor } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import classNames from 'classnames';
|
||||
import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution';
|
||||
|
||||
import { ElasticAgentCard } from './no_data_card';
|
||||
import { NoDataPageProps } from './types';
|
||||
import { KibanaSolutionAvatar } from '../../solution_avatar';
|
||||
|
||||
export const NoDataPage: FunctionComponent<NoDataPageProps> = ({
|
||||
solution,
|
||||
|
|
|
@ -178,7 +178,7 @@ exports[`KibanaPageTemplateSolutionNav renders with icon 1`] = `
|
|||
className="kbnPageTemplateSolutionNav"
|
||||
heading={
|
||||
<React.Fragment>
|
||||
<KibanaSolutionAvatar
|
||||
<ForwardRef
|
||||
className="kbnPageTemplateSolutionNavAvatar"
|
||||
iconType="logoElastic"
|
||||
name="Solution"
|
||||
|
@ -245,7 +245,7 @@ exports[`KibanaPageTemplateSolutionNav renders with icon 1`] = `
|
|||
}
|
||||
mobileTitle={
|
||||
<React.Fragment>
|
||||
<KibanaSolutionAvatar
|
||||
<ForwardRef
|
||||
className="kbnPageTemplateSolutionNavAvatar"
|
||||
iconType="logoElastic"
|
||||
name="Solution"
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
import './solution_nav.scss';
|
||||
|
||||
import React, { FunctionComponent, useState } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
EuiAvatarProps,
|
||||
EuiFlyout,
|
||||
|
@ -19,8 +18,9 @@ import {
|
|||
useIsWithinBreakpoints,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { KibanaSolutionAvatar } from '../../solution_avatar';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution';
|
||||
|
||||
import { KibanaPageTemplateSolutionNavCollapseButton } from './solution_nav_collapse_button';
|
||||
|
||||
export type KibanaPageTemplateSolutionNavProps = EuiSideNavProps<{}> & {
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
import { KibanaSolutionAvatar, KibanaSolutionAvatarProps } from './solution_avatar';
|
||||
|
||||
export default {
|
||||
title: 'Solution Avatar',
|
||||
description: 'A wrapper around EuiAvatar, specifically to stylize Elastic Solutions',
|
||||
};
|
||||
|
||||
type Params = Pick<KibanaSolutionAvatarProps, 'size' | 'name'>;
|
||||
|
||||
export const PureComponent = (params: Params) => {
|
||||
return <KibanaSolutionAvatar {...params} />;
|
||||
};
|
||||
|
||||
PureComponent.argTypes = {
|
||||
name: {
|
||||
control: 'text',
|
||||
defaultValue: 'Kibana',
|
||||
},
|
||||
size: {
|
||||
control: 'radio',
|
||||
options: ['s', 'm', 'l', 'xl', 'xxl'],
|
||||
defaultValue: 'xxl',
|
||||
},
|
||||
};
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* 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 './solution_avatar.scss';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { DistributiveOmit, EuiAvatar, EuiAvatarProps } from '@elastic/eui';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export type KibanaSolutionAvatarProps = DistributiveOmit<EuiAvatarProps, 'size'> & {
|
||||
/**
|
||||
* Any EuiAvatar size available, or `xxl` for custom large, brand-focused version
|
||||
*/
|
||||
size?: EuiAvatarProps['size'] | 'xxl';
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies extra styling to a typical EuiAvatar.
|
||||
* The `name` value will be appended to 'logo' to configure the `iconType` unless `iconType` is provided.
|
||||
*/
|
||||
export const KibanaSolutionAvatar = ({ className, size, ...rest }: KibanaSolutionAvatarProps) => {
|
||||
return (
|
||||
// @ts-ignore Complains about ExclusiveUnion between `iconSize` and `iconType`, but works fine
|
||||
<EuiAvatar
|
||||
className={classNames(
|
||||
'kbnSolutionAvatar',
|
||||
{
|
||||
[`kbnSolutionAvatar--${size}`]: size,
|
||||
},
|
||||
className
|
||||
)}
|
||||
size={size === 'xxl' ? 'xl' : size}
|
||||
iconSize={size}
|
||||
color="plain"
|
||||
iconType={`logo${rest.name}`}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
146
packages/shared-ux/avatar/solution/BUILD.bazel
Normal file
146
packages/shared-ux/avatar/solution/BUILD.bazel
Normal file
|
@ -0,0 +1,146 @@
|
|||
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 = "solution"
|
||||
PKG_REQUIRE_NAME = "@kbn/shared-ux-avatar-solution"
|
||||
|
||||
SOURCE_FILES = glob(
|
||||
[
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.scss",
|
||||
"src/**/*.mdx",
|
||||
"src/**/*.svg",
|
||||
],
|
||||
exclude = [
|
||||
"**/*.test.*",
|
||||
],
|
||||
)
|
||||
|
||||
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//classnames",
|
||||
"@npm//enzyme",
|
||||
"@npm//react",
|
||||
"@npm//url-loader",
|
||||
"//packages/kbn-i18n-react",
|
||||
"//packages/kbn-i18n",
|
||||
"//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//@storybook/addon-actions",
|
||||
"@npm//@types/classnames",
|
||||
"@npm//@types/enzyme",
|
||||
"@npm//@types/jest",
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/react",
|
||||
"//packages/kbn-ambient-ui-types",
|
||||
"//packages/kbn-i18n-react:npm_module_types",
|
||||
"//packages/kbn-i18n:npm_module_types",
|
||||
"//packages/kbn-shared-ux-utility: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",
|
||||
root_dir = "src",
|
||||
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"],
|
||||
)
|
||||
|
||||
pkg_npm(
|
||||
name = "npm_module",
|
||||
deps = [":" + PKG_DIRNAME],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build",
|
||||
srcs = [":npm_module"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm_types(
|
||||
name = "npm_module_types",
|
||||
srcs = SRCS,
|
||||
deps = [":tsc_types"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
tsconfig = ":tsconfig",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build_types",
|
||||
srcs = [":npm_module_types"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
26
packages/shared-ux/avatar/solution/README.mdx
Normal file
26
packages/shared-ux/avatar/solution/README.mdx
Normal file
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
id: sharedUX/Components/KibanaSolutionAvatar
|
||||
slug: /shared-ux/components/avatar-solution
|
||||
title: Solution Avatar
|
||||
summary: A wrapper around `EuiAvatar` tailored for use in Kibana solutions.
|
||||
tags: ['shared-ux', 'component']
|
||||
date: 2022-05-04
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
A wrapper around `EuiAvatar` tailored for use in Kibana solutions.
|
||||
|
||||
## Usage
|
||||
|
||||
If using for a known solution, (e.g. one whose logo is in EUI as `logoSomeSolution`), you can simply set the `name` prop:
|
||||
|
||||
```tsx
|
||||
<KibanaSolutionAvatar name="Kibana" size="xl" />
|
||||
```
|
||||
|
||||
If the name provided does not match a known solution, you *must* set the `iconType` prop:
|
||||
|
||||
```tsx
|
||||
<KibanaSolutionAvatar name="Hello World!" size="xl" iconType="logoElastic" />
|
||||
```
|
|
@ -5,5 +5,9 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
export { KibanaSolutionAvatar } from './solution_avatar';
|
||||
export type { KibanaSolutionAvatarProps } from './solution_avatar';
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/packages/shared-ux/avatar/solution'],
|
||||
};
|
8
packages/shared-ux/avatar/solution/package.json
Normal file
8
packages/shared-ux/avatar/solution/package.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "@kbn/shared-ux-avatar-solution",
|
||||
"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"
|
||||
}
|
|
@ -8,3 +8,12 @@ exports[`KibanaSolutionAvatar renders 1`] = `
|
|||
name="Solution"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`KibanaSolutionAvatar renders 2`] = `
|
||||
<EuiAvatar
|
||||
className="kbnSolutionAvatar"
|
||||
color="plain"
|
||||
iconType="logoElasticStack"
|
||||
name="Elastic Stack"
|
||||
/>
|
||||
`;
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
29
packages/shared-ux/avatar/solution/src/index.tsx
Normal file
29
packages/shared-ux/avatar/solution/src/index.tsx
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
import { withSuspense } from '@kbn/shared-ux-utility';
|
||||
|
||||
export type { KibanaSolutionAvatarProps } from './solution_avatar';
|
||||
|
||||
/**
|
||||
* The Lazily-loaded `KibanaSolutionAvatar` component. Consumers should use `React.Suspense` or
|
||||
* the withSuspense` HOC to load this component.
|
||||
*/
|
||||
export const KibanaSolutionAvatarLazy = React.lazy(() =>
|
||||
import('./solution_avatar').then(({ KibanaSolutionAvatar }) => ({
|
||||
default: KibanaSolutionAvatar,
|
||||
}))
|
||||
);
|
||||
|
||||
/**
|
||||
* A `KibanaSolutionAvatar` component that is wrapped by the `withSuspense` HOC. This component can
|
||||
* be used directly by consumers and will load the `KibanaPageTemplateSolutionNavAvatarLazy` component lazily with
|
||||
* a predefined fallback and error boundary.
|
||||
*/
|
||||
export const KibanaSolutionAvatar = withSuspense(KibanaSolutionAvatarLazy);
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
import { KibanaSolutionAvatar, IconTypeProps, KnownSolutionProps } from './solution_avatar';
|
||||
|
||||
export default {
|
||||
title: 'Solution Avatar',
|
||||
description: 'A wrapper around EuiAvatar, specifically to stylize Elastic Solutions',
|
||||
};
|
||||
|
||||
const argTypes = {
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['s', 'm', 'l', 'xl', 'xxl'],
|
||||
defaultValue: 'xxl',
|
||||
},
|
||||
};
|
||||
|
||||
type KnownSolutionParams = Pick<KnownSolutionProps, 'size' | 'name'>;
|
||||
|
||||
export const SolutionAvatar = (params: KnownSolutionParams) => {
|
||||
return <KibanaSolutionAvatar {...params} />;
|
||||
};
|
||||
|
||||
SolutionAvatar.argTypes = {
|
||||
name: {
|
||||
control: 'select',
|
||||
options: ['Cloud', 'Elastic', 'Kibana', 'Observability', 'Security', 'Enterprise Search'],
|
||||
defaultValue: 'Elastic',
|
||||
},
|
||||
...argTypes,
|
||||
};
|
||||
|
||||
type IconTypeParams = Pick<IconTypeProps, 'size' | 'name' | 'iconType'>;
|
||||
|
||||
export const IconTypeAvatar = (params: IconTypeParams) => {
|
||||
return <KibanaSolutionAvatar {...params} />;
|
||||
};
|
||||
|
||||
IconTypeAvatar.argTypes = {
|
||||
iconType: {
|
||||
control: 'select',
|
||||
options: [
|
||||
'logoCloud',
|
||||
'logoElastic',
|
||||
'logoElasticsearch',
|
||||
'logoElasticStack',
|
||||
'logoKibana',
|
||||
'logoObservability',
|
||||
'logoSecurity',
|
||||
'logoSiteSearch',
|
||||
'logoWorkplaceSearch',
|
||||
'machineLearningApp',
|
||||
'managementApp',
|
||||
],
|
||||
defaultValue: 'logoElastic',
|
||||
},
|
||||
name: {
|
||||
control: 'text',
|
||||
defaultValue: 'Solution Name',
|
||||
},
|
||||
...argTypes,
|
||||
};
|
|
@ -12,7 +12,9 @@ import { KibanaSolutionAvatar } from './solution_avatar';
|
|||
|
||||
describe('KibanaSolutionAvatar', () => {
|
||||
test('renders', () => {
|
||||
const component = shallow(<KibanaSolutionAvatar name="Solution" iconType="logoElastic" />);
|
||||
expect(component).toMatchSnapshot();
|
||||
const nameAndIcon = shallow(<KibanaSolutionAvatar name="Solution" iconType="logoElastic" />);
|
||||
expect(nameAndIcon).toMatchSnapshot();
|
||||
const nameOnly = shallow(<KibanaSolutionAvatar name="Elastic Stack" />);
|
||||
expect(nameOnly).toMatchSnapshot();
|
||||
});
|
||||
});
|
74
packages/shared-ux/avatar/solution/src/solution_avatar.tsx
Normal file
74
packages/shared-ux/avatar/solution/src/solution_avatar.tsx
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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 './solution_avatar.scss';
|
||||
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { DistributiveOmit, EuiAvatar, EuiAvatarProps, IconType } from '@elastic/eui';
|
||||
|
||||
import { SolutionNameType } from './types';
|
||||
|
||||
export type KnownSolutionProps = DistributiveOmit<EuiAvatarProps, 'size' | 'name' | 'iconType'> & {
|
||||
/**
|
||||
* Any EuiAvatar size available, or `xxl` for custom large, brand-focused version
|
||||
*/
|
||||
size?: EuiAvatarProps['size'] | 'xxl';
|
||||
name: SolutionNameType;
|
||||
};
|
||||
|
||||
export type IconTypeProps = DistributiveOmit<EuiAvatarProps, 'size' | 'name' | 'iconType'> & {
|
||||
/**
|
||||
* Any EuiAvatar size available, or `xxl` for custom large, brand-focused version
|
||||
*/
|
||||
size?: EuiAvatarProps['size'] | 'xxl';
|
||||
name?: string;
|
||||
iconType: IconType;
|
||||
};
|
||||
|
||||
const isKnown = (props: any): props is KnownSolutionProps => {
|
||||
return typeof props.iconType === 'undefined';
|
||||
};
|
||||
|
||||
export type KibanaSolutionAvatarProps = KnownSolutionProps | IconTypeProps;
|
||||
|
||||
/**
|
||||
* Applies extra styling to a typical EuiAvatar.
|
||||
* The `name` value will be appended to 'logo' to configure the `iconType` unless `iconType` is provided.
|
||||
*/
|
||||
export const KibanaSolutionAvatar = (props: KibanaSolutionAvatarProps) => {
|
||||
const { className, size, ...rest } = props;
|
||||
|
||||
// If the name is a known solution, use the name to set the correct IconType.
|
||||
// Create an empty object so `iconType` remains undefined or inherited from `props`.
|
||||
const icon: {
|
||||
iconType?: IconType;
|
||||
} = {};
|
||||
|
||||
if (isKnown(props)) {
|
||||
icon.iconType = `logo${props.name.replace(/\s+/g, '')}`;
|
||||
}
|
||||
|
||||
return (
|
||||
// @ts-ignore Complains about ExclusiveUnion between `iconSize` and `iconType`, but works fine
|
||||
<EuiAvatar
|
||||
className={classNames(
|
||||
'kbnSolutionAvatar',
|
||||
{
|
||||
[`kbnSolutionAvatar--${size}`]: size,
|
||||
},
|
||||
className
|
||||
)}
|
||||
size={size === 'xxl' ? 'xl' : size}
|
||||
iconSize={size}
|
||||
color="plain"
|
||||
{...rest}
|
||||
{...icon}
|
||||
/>
|
||||
);
|
||||
};
|
34
packages/shared-ux/avatar/solution/src/types.ts
Normal file
34
packages/shared-ux/avatar/solution/src/types.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Manual, exhaustive list at present. This was attempted dynamically using Typescript Template Literals and
|
||||
// the computation cost exceeded the benefit. By enumerating them manually, we reduce the complexity of TS
|
||||
// checking at the expense of not being dynamic against a very, very static list.
|
||||
//
|
||||
// The only consequence is requiring a solution name without a space, (e.g. `ElasticStack`) until it's added
|
||||
// here. That's easy to do in the very unlikely event that ever happens.
|
||||
export type SolutionNameType =
|
||||
| 'App Search'
|
||||
| 'Beats'
|
||||
| 'Business Analytics'
|
||||
| 'Cloud'
|
||||
| 'Cloud Enterprise'
|
||||
| 'Code'
|
||||
| 'Elastic'
|
||||
| 'Elastic Stack'
|
||||
| 'Elasticsearch'
|
||||
| 'Enterprise Search'
|
||||
| 'Logstash'
|
||||
| 'Maps'
|
||||
| 'Metrics'
|
||||
| 'Observability'
|
||||
| 'Security'
|
||||
| 'Site Search'
|
||||
| 'Uptime'
|
||||
| 'Webhook'
|
||||
| 'Workplace Search';
|
19
packages/shared-ux/avatar/solution/tsconfig.json
Normal file
19
packages/shared-ux/avatar/solution/tsconfig.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.bazel.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "target_types",
|
||||
"rootDir": "src",
|
||||
"stripInternal": false,
|
||||
"types": [
|
||||
"jest",
|
||||
"node",
|
||||
"react",
|
||||
"@kbn/ambient-ui-types"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
|
@ -23,7 +23,7 @@ import type { AppMountParameters, CoreStart } from '@kbn/core/public';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { KibanaPageTemplate, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { KibanaSolutionAvatar } from '@kbn/shared-ux-components';
|
||||
import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution';
|
||||
|
||||
import type { Space } from '../../common';
|
||||
import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../common/constants';
|
||||
|
|
|
@ -3204,6 +3204,10 @@
|
|||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/shared-ux-avatar-solution@link:bazel-bin/packages/shared-ux/avatar/solution":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/shared-ux-button-exit-full-screen@link:bazel-bin/packages/shared-ux/button/exit_full_screen":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
@ -6296,6 +6300,10 @@
|
|||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@types/kbn__shared-ux-avatar-solution@link:bazel-bin/packages/shared-ux/avatar/solution/npm_module_types":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@types/kbn__shared-ux-button-exit-full-screen@link:bazel-bin/packages/shared-ux/button/exit_full_screen/npm_module_types":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue