mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[SharedUX] Add custom branding to ExitFullScreenButton (#150620)
## Summary This PR replaces the Elastic logo with the custom logo in `ExitFullScreenButton` component. Without custom logo: <img width="185" alt="Screenshot 2023-02-13 at 12 49 59" src="https://user-images.githubusercontent.com/1937956/218451086-5cf3122b-a167-4b39-8311-1cead1f7afc5.png"> With custom logo: <img width="163" alt="Screenshot 2023-02-13 at 12 53 16" src="https://user-images.githubusercontent.com/1937956/218451270-db004b4a-b089-4963-9122-7d3f7b231372.png"> ### Checklist Delete any items that are not applicable to this PR. ~- [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)~ ~- [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials~ - [X] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [X] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [X] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) ~- [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~ - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) ~- [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers)~ ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
ea646dfe04
commit
868fc247a9
13 changed files with 99 additions and 5 deletions
|
@ -41,6 +41,54 @@ exports[`<ExitFullScreenButton /> with kibana services is rendered 1`] = `
|
|||
</div>
|
||||
`;
|
||||
|
||||
exports[`<ExitFullScreenButton /> with kibana services renders custom logo 1`] = `
|
||||
<div>
|
||||
<p
|
||||
aria-live="polite"
|
||||
class="emotion-euiScreenReaderOnly"
|
||||
>
|
||||
In full screen mode, press ESC to exit.
|
||||
</p>
|
||||
<button
|
||||
class="exitFullScreenButton"
|
||||
css="You have tried to stringify object returned from \`css\` function. It isn't supposed to be used directly (e.g. as value of the \`className\` prop), but rather handed to emotion so it can handle it (e.g. as value of \`css\` prop)."
|
||||
data-test-subj="exitFullScreenModeButton"
|
||||
>
|
||||
<span
|
||||
class="euiFlexGroup emotion-euiFlexGroup-s-flexStart-center-row"
|
||||
>
|
||||
<span
|
||||
class="euiFlexItem emotion-euiFlexItem-growZero"
|
||||
>
|
||||
<figure
|
||||
class="euiImageWrapper emotion-euiImageWrapper"
|
||||
>
|
||||
<img
|
||||
alt="customLogo"
|
||||
class="euiImage emotion-euiImage-customSize"
|
||||
src="imageSrcAsBase64encodedstring"
|
||||
style="max-width: 16px; max-height: 16px;"
|
||||
/>
|
||||
</figure>
|
||||
</span>
|
||||
<span
|
||||
class="euiFlexItem emotion-euiFlexItem-growZero"
|
||||
data-test-subj="exitFullScreenModeText"
|
||||
>
|
||||
Exit full screen
|
||||
</span>
|
||||
<span
|
||||
class="euiFlexItem emotion-euiFlexItem-growZero"
|
||||
>
|
||||
<span
|
||||
data-euiicon-type="fullScreenExit"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<ExitFullScreenButton /> with manual services is rendered 1`] = `
|
||||
<div>
|
||||
<p
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiIcon,
|
||||
EuiImage,
|
||||
useEuiTheme,
|
||||
makeHighContrastColor,
|
||||
} from '@elastic/eui';
|
||||
|
@ -37,7 +38,7 @@ const description = i18n.translate(
|
|||
/**
|
||||
* A presentational component that renders a button designed to exit "full screen" mode.
|
||||
*/
|
||||
export const ExitFullScreenButton = ({ onClick, className }: Props) => {
|
||||
export const ExitFullScreenButton = ({ onClick, className, customLogo }: Props) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { colors, size, border } = euiTheme;
|
||||
|
||||
|
@ -63,7 +64,11 @@ export const ExitFullScreenButton = ({ onClick, className }: Props) => {
|
|||
>
|
||||
<EuiFlexGroup component="span" responsive={false} alignItems="center" gutterSize="s">
|
||||
<EuiFlexItem component="span" grow={false}>
|
||||
<EuiIcon type="logoElastic" size="m" />
|
||||
{customLogo ? (
|
||||
<EuiImage src={customLogo} size={16} alt="customLogo" />
|
||||
) : (
|
||||
<EuiIcon type="logoElastic" size="m" />
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem component="span" grow={false} data-test-subj="exitFullScreenModeText">
|
||||
{text}
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
|
||||
import { ExitFullScreenButton } from './exit_full_screen_button';
|
||||
import { ExitFullScreenButtonKibanaProvider, ExitFullScreenButtonProvider } from './services';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
const componentServices = getExitFullScreenButtonServicesMock();
|
||||
const kibanaServices = getExitFullScreenButtonKibanaDependenciesMock();
|
||||
|
@ -103,6 +104,16 @@ describe('<ExitFullScreenButton />', () => {
|
|||
expect(kibanaServices.coreStart.chrome.setIsVisible).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
test('renders custom logo', () => {
|
||||
kibanaServices.coreStart.customBranding.customBranding$ = of({
|
||||
logo: 'imageSrcAsBase64encodedstring',
|
||||
});
|
||||
const component = kibanaMount(
|
||||
<ExitFullScreenButton onExit={jest.fn()} toggleChrome={false} />
|
||||
);
|
||||
expect(component.render()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('onExit', () => {
|
||||
const onExitHandler = jest.fn();
|
||||
let component: ReactWrapper;
|
||||
|
|
|
@ -13,6 +13,7 @@ import useMountedState from 'react-use/lib/useMountedState';
|
|||
|
||||
import type { ExitFullScreenButtonProps as Props } from '@kbn/shared-ux-button-exit-full-screen-types';
|
||||
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { ExitFullScreenButton as Component } from './exit_full_screen_button.component';
|
||||
import { useServices } from './services';
|
||||
|
||||
|
@ -22,8 +23,10 @@ import { useServices } from './services';
|
|||
*/
|
||||
export const ExitFullScreenButton = ({ onExit = () => {}, toggleChrome = true }: Props) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { setIsFullscreen } = useServices();
|
||||
const { setIsFullscreen, customBranding$ } = useServices();
|
||||
const isMounted = useMountedState();
|
||||
const customBranding = useObservable(customBranding$);
|
||||
const customLogo = customBranding?.logo;
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
if (toggleChrome) {
|
||||
|
@ -70,5 +73,5 @@ export const ExitFullScreenButton = ({ onExit = () => {}, toggleChrome = true }:
|
|||
z-index: 5;
|
||||
`;
|
||||
|
||||
return <Component css={buttonCSS} {...{ onClick }} />;
|
||||
return <Component css={buttonCSS} customLogo={customLogo} {...{ onClick }} />;
|
||||
};
|
||||
|
|
|
@ -43,6 +43,7 @@ export const ExitFullScreenButtonKibanaProvider: FC<ExitFullScreenButtonKibanaDe
|
|||
setIsFullscreen: (isFullscreen: boolean) => {
|
||||
services.coreStart.chrome.setIsVisible(!isFullscreen);
|
||||
},
|
||||
customBranding$: services.coreStart.customBranding.customBranding$,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
ExitFullScreenButtonKibanaDependencies,
|
||||
ExitFullScreenButtonServices,
|
||||
} from '@kbn/shared-ux-button-exit-full-screen-types';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Return a Jest mock of the services for the `ExitFullScreenButton` component.
|
||||
|
@ -17,6 +18,7 @@ import {
|
|||
export const getServicesMock = (): ExitFullScreenButtonServices => {
|
||||
return {
|
||||
setIsFullscreen: jest.fn(),
|
||||
customBranding$: of({}),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -29,6 +31,9 @@ export const getKibanaDependenciesMock = (): ExitFullScreenButtonKibanaDependenc
|
|||
chrome: {
|
||||
setIsVisible: jest.fn(),
|
||||
},
|
||||
customBranding: {
|
||||
customBranding$: of({}),
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@ import type {
|
|||
ExitFullScreenButtonProps as Props,
|
||||
ExitFullScreenButtonServices,
|
||||
} from '@kbn/shared-ux-button-exit-full-screen-types';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
type PropArguments = Pick<Props, 'toggleChrome'>;
|
||||
|
||||
|
@ -51,6 +52,7 @@ export class StorybookMock extends AbstractStorybookMock<
|
|||
setIsFullscreen: (isFullscreen: boolean) => {
|
||||
action('setIsFullscreen')(isFullscreen);
|
||||
},
|
||||
customBranding$: of({}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
*/
|
||||
|
||||
import { MouseEventHandler, HTMLAttributes } from 'react';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CustomBranding } from '@kbn/core-custom-branding-common';
|
||||
|
||||
/**
|
||||
* Abstract external services for this component.
|
||||
|
@ -14,6 +16,8 @@ import { MouseEventHandler, HTMLAttributes } from 'react';
|
|||
export interface Services {
|
||||
/** Function to invoke to set the application to full-screen mode */
|
||||
setIsFullscreen: (isFullscreen: boolean) => void;
|
||||
/** Observable that emits the value of custom branding, if set*/
|
||||
customBranding$: Observable<CustomBranding>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,6 +33,9 @@ export interface KibanaDependencies {
|
|||
chrome: {
|
||||
setIsVisible: (isVisible: boolean) => void;
|
||||
};
|
||||
customBranding: {
|
||||
customBranding$: Observable<CustomBranding>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -55,4 +62,6 @@ export interface ExitFullScreenButtonComponentProps
|
|||
extends Pick<HTMLAttributes<HTMLDivElement>, 'className'> {
|
||||
/** Handler to invoke when one clicks the button. */
|
||||
onClick: MouseEventHandler<HTMLButtonElement>;
|
||||
/** If set, custom logo is displayed instead of Elastic logo */
|
||||
customLogo?: string;
|
||||
}
|
||||
|
|
|
@ -9,5 +9,8 @@
|
|||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
],
|
||||
"kbn_references": [
|
||||
"@kbn/core-custom-branding-common",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -120,6 +120,7 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
|
|||
private dashboardSavedObjectService: DashboardSavedObjectService;
|
||||
private theme$;
|
||||
private chrome;
|
||||
private customBranding;
|
||||
|
||||
constructor(
|
||||
initialInput: DashboardContainerInput,
|
||||
|
@ -152,6 +153,7 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
|
|||
theme: { theme$: this.theme$ },
|
||||
},
|
||||
chrome: this.chrome,
|
||||
customBranding: this.customBranding,
|
||||
} = pluginServices.getServices());
|
||||
|
||||
this.initialSavedDashboardId = dashboardContainerInputIsByValue(this.input)
|
||||
|
@ -422,7 +424,9 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
|
|||
const { Wrapper: DashboardReduxWrapper } = this.reduxEmbeddableTools;
|
||||
ReactDOM.render(
|
||||
<I18nProvider>
|
||||
<ExitFullScreenButtonKibanaProvider coreStart={{ chrome: this.chrome }}>
|
||||
<ExitFullScreenButtonKibanaProvider
|
||||
coreStart={{ chrome: this.chrome, customBranding: this.customBranding }}
|
||||
>
|
||||
<KibanaThemeProvider theme$={this.theme$}>
|
||||
<DashboardReduxWrapper>
|
||||
<DashboardViewport />
|
||||
|
|
|
@ -16,5 +16,6 @@ export const customBrandingServiceFactory: CustomBrandingServiceFactory = () =>
|
|||
const pluginMock = coreMock.createStart();
|
||||
return {
|
||||
hasCustomBranding$: pluginMock.customBranding.hasCustomBranding$,
|
||||
customBranding$: pluginMock.customBranding.customBranding$,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -19,5 +19,6 @@ export const customBrandingServiceFactory: CustomBrandingServiceFactory = ({ cor
|
|||
const { customBranding } = coreStart;
|
||||
return {
|
||||
hasCustomBranding$: customBranding.hasCustomBranding$,
|
||||
customBranding$: customBranding.customBranding$,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,4 +10,5 @@ import type { CustomBrandingStart } from '@kbn/core-custom-branding-browser';
|
|||
|
||||
export interface DashboardCustomBrandingService {
|
||||
hasCustomBranding$: CustomBrandingStart['hasCustomBranding$'];
|
||||
customBranding$: CustomBrandingStart['customBranding$'];
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue