diff --git a/src/plugins/shared_ux/public/components/index.ts b/src/plugins/shared_ux/public/components/index.ts
index 108b2f4b215484..c2f835b97ebde7 100644
--- a/src/plugins/shared_ux/public/components/index.ts
+++ b/src/plugins/shared_ux/public/components/index.ts
@@ -19,6 +19,12 @@ export const LazyExitFullScreenButton = React.lazy(() =>
}))
);
+export const LazySolutionToolbarButton = React.lazy(() =>
+ import('./toolbar/index').then(({ SolutionToolbarButton }) => ({
+ default: SolutionToolbarButton,
+ }))
+);
+
/**
* A `ExitFullScreenButton` component that is wrapped by the `withSuspense` HOC. This component can
* be used directly by consumers and will load the `LazyExitFullScreenButton` component lazily with
@@ -26,6 +32,13 @@ export const LazyExitFullScreenButton = React.lazy(() =>
*/
export const ExitFullScreenButton = withSuspense(LazyExitFullScreenButton);
+/**
+ * A `SolutionToolbarButton` component that is wrapped by the `withSuspense` HOC. This component can
+ * be used directly by consumers and will load the `LazySolutionToolbarButton` component lazily with
+ * a predefined fallback and error boundary.
+ */
+export const SolutionToolbarButton = withSuspense(LazySolutionToolbarButton);
+
/**
* The Lazily-loaded `NoDataViews` component. Consumers should use `React.Suspennse` or the
* `withSuspense` HOC to load this component.
diff --git a/src/plugins/shared_ux/public/components/toolbar/index.ts b/src/plugins/shared_ux/public/components/toolbar/index.ts
new file mode 100644
index 00000000000000..de15e73eaadeb0
--- /dev/null
+++ b/src/plugins/shared_ux/public/components/toolbar/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 { SolutionToolbarButton } from './solution_toolbar/button/primary';
diff --git a/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/__snapshots__/primary.test.tsx.snap b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/__snapshots__/primary.test.tsx.snap
new file mode 100644
index 00000000000000..1d7e3acb0b7628
--- /dev/null
+++ b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/__snapshots__/primary.test.tsx.snap
@@ -0,0 +1,78 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` is rendered 1`] = `
+
+
+
+
+
+
+
+
+
+`;
diff --git a/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.mdx b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.mdx
new file mode 100644
index 00000000000000..6693277b370ae5
--- /dev/null
+++ b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.mdx
@@ -0,0 +1,12 @@
+---
+id: sharedUX/Components/SolutionToolbarButton
+slug: /shared-ux/components/toolbar/solution_toolbar/button/primary
+title: Solution Toolbar Button
+summary: An opinionated implementation of the toolbar extracted to just the button.
+tags: ['shared-ux', 'component']
+date: 2022-02-17
+---
+
+> This documentation is in-progress.
+
+This button is a part of the solution toolbar component. This button has primary styling and requires a label. OnClick handlers and icon types are supported as an extension of EuiButtonProps. Icons are always on the left of any labels within the button.
diff --git a/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.stories.tsx b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.stories.tsx
new file mode 100644
index 00000000000000..56c15ec7749af9
--- /dev/null
+++ b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.stories.tsx
@@ -0,0 +1,41 @@
+/*
+ * 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 { Story } from '@storybook/react';
+import React from 'react';
+import { SolutionToolbarButton } from './primary';
+import mdx from './primary.mdx';
+
+export default {
+ title: 'Solution Toolbar Button',
+ description: 'A button that is a part of the solution toolbar.',
+ parameters: {
+ docs: {
+ page: mdx,
+ },
+ },
+ argTypes: {
+ iconType: {
+ control: {
+ type: 'radio',
+ expanded: true,
+ options: ['apps', 'logoGithub', 'folderCheck', 'documents'],
+ },
+ },
+ },
+};
+
+export const Component: Story<{
+ iconType: any;
+}> = ({ iconType }) => {
+ return ;
+};
+
+Component.args = {
+ iconType: 'apps',
+};
diff --git a/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.test.tsx b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.test.tsx
new file mode 100644
index 00000000000000..c2e5fd1ce7ab84
--- /dev/null
+++ b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.test.tsx
@@ -0,0 +1,41 @@
+/*
+ * 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 { mount as enzymeMount, ReactWrapper } from 'enzyme';
+import React from 'react';
+import { ServicesProvider, SharedUXServices } from '../../../../services';
+import { servicesFactory } from '../../../../services/mocks';
+
+import { SolutionToolbarButton } from './primary';
+
+describe('', () => {
+ let services: SharedUXServices;
+ let mount: (element: JSX.Element) => ReactWrapper;
+
+ beforeEach(() => {
+ services = servicesFactory();
+ mount = (element: JSX.Element) =>
+ enzymeMount({element});
+ });
+
+ afterEach(() => {
+ jest.resetAllMocks();
+ });
+
+ test('is rendered', () => {
+ const component = mount();
+
+ expect(component).toMatchSnapshot();
+ });
+ test('it can be passed a functional onClick handler', () => {
+ const mockHandler = jest.fn();
+ const component = mount();
+ component.simulate('click');
+ expect(mockHandler).toHaveBeenCalled();
+ });
+});
diff --git a/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.tsx b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.tsx
new file mode 100644
index 00000000000000..b99af852ed7e3d
--- /dev/null
+++ b/src/plugins/shared_ux/public/components/toolbar/solution_toolbar/button/primary.tsx
@@ -0,0 +1,23 @@
+/*
+ * 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 { EuiButton } from '@elastic/eui';
+import { EuiButtonPropsForButton } from '@elastic/eui/src/components/button/button';
+
+export interface Props extends Pick {
+ label: string;
+}
+
+export const SolutionToolbarButton = ({ label, ...rest }: Props) => {
+ return (
+
+ {label}
+
+ );
+};