diff --git a/.buildkite/scripts/steps/storybooks/build_and_upload.ts b/.buildkite/scripts/steps/storybooks/build_and_upload.ts
index 3796076d0a3cd..75be5696dbca6 100644
--- a/.buildkite/scripts/steps/storybooks/build_and_upload.ts
+++ b/.buildkite/scripts/steps/storybooks/build_and_upload.ts
@@ -49,6 +49,7 @@ const STORYBOOKS = [
'ui_actions_enhanced',
'language_documentation_popover',
'unified_search',
+ 'random_sampling',
];
const GITHUB_CONTEXT = 'Build and Publish Storybooks';
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 7437653a92e5b..bfe6716b0d2c0 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -504,6 +504,7 @@ examples/portable_dashboards_example @elastic/kibana-presentation
examples/preboot_example @elastic/kibana-security @elastic/kibana-core
src/plugins/presentation_util @elastic/kibana-presentation
x-pack/plugins/profiling @elastic/profiling-ui
+x-pack/packages/kbn-random-sampling @elastic/kibana-visualizations
packages/kbn-react-field @elastic/kibana-data-discovery
x-pack/plugins/remote_clusters @elastic/platform-deployment-management
test/plugin_functional/plugins/rendering_plugin @elastic/kibana-core
diff --git a/.i18nrc.json b/.i18nrc.json
index 0b87f43d7da41..d3afda75dce51 100644
--- a/.i18nrc.json
+++ b/.i18nrc.json
@@ -75,6 +75,7 @@
"navigation": "src/plugins/navigation",
"newsfeed": "src/plugins/newsfeed",
"presentationUtil": "src/plugins/presentation_util",
+ "randomSampling": "x-pack/packages/kbn-random-sampling",
"reporting": "packages/kbn-reporting/common",
"savedObjects": "src/plugins/saved_objects",
"savedObjectsFinder": "src/plugins/saved_objects_finder",
diff --git a/package.json b/package.json
index 2a8b15fc2ca4e..ca0dab0ebd14f 100644
--- a/package.json
+++ b/package.json
@@ -511,6 +511,7 @@
"@kbn/preboot-example-plugin": "link:examples/preboot_example",
"@kbn/presentation-util-plugin": "link:src/plugins/presentation_util",
"@kbn/profiling-plugin": "link:x-pack/plugins/profiling",
+ "@kbn/random-sampling": "link:x-pack/packages/kbn-random-sampling",
"@kbn/react-field": "link:packages/kbn-react-field",
"@kbn/remote-clusters-plugin": "link:x-pack/plugins/remote_clusters",
"@kbn/rendering-plugin": "link:test/plugin_functional/plugins/rendering_plugin",
diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts
index e050926610259..bd21a80a0d6ff 100644
--- a/src/dev/storybook/aliases.ts
+++ b/src/dev/storybook/aliases.ts
@@ -44,6 +44,7 @@ export const storybookAliases = {
lists: 'x-pack/plugins/lists/.storybook',
observability: 'x-pack/plugins/observability/.storybook',
presentation: 'src/plugins/presentation_util/storybook',
+ random_sampling: 'x-pack/packages/kbn-random-sampling/.storybook',
security_solution: 'x-pack/plugins/security_solution/.storybook',
security_solution_packages: 'x-pack/packages/security-solution/storybook/config',
serverless: 'packages/serverless/storybook/config',
diff --git a/src/plugins/discover/public/application/context/context_app.tsx b/src/plugins/discover/public/application/context/context_app.tsx
index efd8992e48ca8..4686eadc50646 100644
--- a/src/plugins/discover/public/application/context/context_app.tsx
+++ b/src/plugins/discover/public/application/context/context_app.tsx
@@ -10,12 +10,7 @@ import React, { Fragment, memo, useEffect, useRef, useMemo, useCallback } from '
import './context_app.scss';
import classNames from 'classnames';
import { FormattedMessage } from '@kbn/i18n-react';
-import {
- EuiText,
- EuiPageContent_Deprecated as EuiPageContent,
- EuiPage,
- EuiSpacer,
-} from '@elastic/eui';
+import { EuiText, EuiPage, EuiPageBody, EuiSpacer } from '@elastic/eui';
import { cloneDeep } from 'lodash';
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
import { useExecutionContext } from '@kbn/kibana-react-plugin/public';
@@ -199,7 +194,12 @@ export const ContextApp = ({ dataView, anchorId, referrer }: ContextAppProps) =>
-
+
@@ -230,7 +230,7 @@ export const ContextApp = ({ dataView, anchorId, referrer }: ContextAppProps) =>
predecessorsStatus={fetchedState.predecessorsStatus.value}
successorsStatus={fetchedState.successorsStatus.value}
/>
-
+
)}
diff --git a/src/plugins/discover/public/application/doc/components/doc.tsx b/src/plugins/discover/public/application/doc/components/doc.tsx
index f507d2794184a..9bfea00a92fc2 100644
--- a/src/plugins/discover/public/application/doc/components/doc.tsx
+++ b/src/plugins/discover/public/application/doc/components/doc.tsx
@@ -8,13 +8,7 @@
import React, { useEffect, useRef } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
-import {
- EuiCallOut,
- EuiLink,
- EuiLoadingSpinner,
- EuiPageContent_Deprecated as EuiPageContent,
- EuiPage,
-} from '@elastic/eui';
+import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPage, EuiPageBody } from '@elastic/eui';
import type { DataView } from '@kbn/data-views-plugin/public';
import { i18n } from '@kbn/i18n';
import { getRootBreadcrumbs } from '../../../utils/breadcrumbs';
@@ -78,7 +72,7 @@ export function Doc(props: DocProps) {
values: { id: props.id },
})}
-
+
{reqState === ElasticRequestState.NotFoundDataView && (
)}
-
+
);
}
diff --git a/src/plugins/discover/public/application/doc/single_doc_route.tsx b/src/plugins/discover/public/application/doc/single_doc_route.tsx
index f3c53d4061b1e..ad50a508fc0ec 100644
--- a/src/plugins/discover/public/application/doc/single_doc_route.tsx
+++ b/src/plugins/discover/public/application/doc/single_doc_route.tsx
@@ -93,9 +93,5 @@ export const SingleDocRoute = () => {
);
}
- return (
-
-
-
- );
+ return ;
};
diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.scss b/src/plugins/discover/public/application/main/components/layout/discover_layout.scss
index 5cb1f54edfd2e..f3f552c76299f 100644
--- a/src/plugins/discover/public/application/main/components/layout/discover_layout.scss
+++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.scss
@@ -48,7 +48,12 @@ discover-app {
}
.dscPageContent--centered {
+ width: auto;
height: auto;
+ align-self: center;
+ margin-top: auto;
+ margin-bottom: auto;
+ flex-grow: 0;
}
.dscTable {
diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx
index 74118cf674dad..1dab027ca81fd 100644
--- a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx
+++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx
@@ -14,7 +14,7 @@ import {
EuiHideFor,
EuiPage,
EuiPageBody,
- EuiPageContent_Deprecated as EuiPageContent,
+ EuiPanel,
EuiSpacer,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@@ -374,19 +374,17 @@ export function DiscoverLayout({
data-test-subj="discoverNoResultsError"
/>
) : (
-
{mainDisplay}
-
+
)}
diff --git a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.tsx
index 8157e69fb91c1..dcb1d48b771c8 100644
--- a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.tsx
+++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar.tsx
@@ -9,12 +9,7 @@
import './discover_sidebar.scss';
import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
import { i18n } from '@kbn/i18n';
-import {
- EuiButton,
- EuiFlexGroup,
- EuiFlexItem,
- EuiPageSideBar_Deprecated as EuiPageSideBar,
-} from '@elastic/eui';
+import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiPageSidebar } from '@elastic/eui';
import { DataViewPicker } from '@kbn/unified-search-plugin/public';
import { type DataViewField, getFieldSubtypeMulti } from '@kbn/data-views-plugin/public';
import {
@@ -266,7 +261,7 @@ export function DiscoverSidebarComponent({
}
return (
-
-
+
);
}
diff --git a/test/functional/apps/visualize/group6/_tsvb_tsdb_basic.ts b/test/functional/apps/visualize/group6/_tsvb_tsdb_basic.ts
new file mode 100644
index 0000000000000..765c7a9d3ec4d
--- /dev/null
+++ b/test/functional/apps/visualize/group6/_tsvb_tsdb_basic.ts
@@ -0,0 +1,75 @@
+/*
+ * 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 expect from '@kbn/expect';
+
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ getPageObjects, getService }: FtrProviderContext) {
+ const { visualBuilder } = getPageObjects(['visualBuilder']);
+ const log = getService('log');
+ const kibanaServer = getService('kibanaServer');
+ const esArchiver = getService('esArchiver');
+ const testSubjects = getService('testSubjects');
+
+ describe('visual builder tsdb check', function describeIndexTests() {
+ before(async () => {
+ log.info(`loading sample TSDB index...`);
+ await esArchiver.load('test/functional/fixtures/es_archiver/kibana_sample_data_logs_tsdb');
+ log.info(`creating the TSDB data view...`);
+ await kibanaServer.importExport.load(
+ 'test/functional/fixtures/kbn_archiver/kibana_sample_data_logs_tsdb'
+ );
+ log.info(`setting the TSDB dataView as default...`);
+ await kibanaServer.uiSettings.replace({
+ defaultIndex: '90943e30-9a47-11e8-b64d-95841ca0c247',
+ });
+ });
+
+ after(async () => {
+ log.info(`removing the TSDB index...`);
+ await esArchiver.unload('test/functional/fixtures/es_archiver/kibana_sample_data_logs_tsdb');
+ log.info(`removing the TSDB dataView...`);
+ await kibanaServer.importExport.unload(
+ 'test/functional/fixtures/kbn_archiver/kibana_sample_data_logs_tsdb'
+ );
+ log.info(`unsetting the TSDB dataView default...`);
+ await kibanaServer.uiSettings.unset('defaultIndex');
+ });
+
+ beforeEach(async () => {
+ await visualBuilder.resetPage();
+ });
+
+ it('should render from a tsdb dataView regular fields with no issues', async () => {
+ await visualBuilder.selectAggType('Average');
+ await visualBuilder.setFieldForAggregation('bytes');
+ const isFieldForAggregationValid = await visualBuilder.checkFieldForAggregationValidity();
+ expect(isFieldForAggregationValid).to.be(true);
+ expect(await testSubjects.exists('visualization-error-text')).to.be(false);
+ });
+
+ it('should render from a tsdb dataView supported tsdb field type', async () => {
+ await visualBuilder.selectAggType('Average');
+ await visualBuilder.setFieldForAggregation('bytes_gauge');
+ const isFieldForAggregationValid = await visualBuilder.checkFieldForAggregationValidity();
+ expect(isFieldForAggregationValid).to.be(true);
+ expect(await testSubjects.exists('visualization-error-text')).to.be(false);
+ });
+
+ it('should show an error when using an unsupported tsdb field type', async () => {
+ await visualBuilder.selectAggType('Average');
+ await visualBuilder.setFieldForAggregation('bytes_counter');
+ // this is still returning true
+ const isFieldForAggregationValid = await visualBuilder.checkFieldForAggregationValidity();
+ expect(isFieldForAggregationValid).to.be(true);
+ // but an error should appear in visualization
+ expect(await testSubjects.exists('visualization-error-text')).to.be(true);
+ });
+ });
+}
diff --git a/test/functional/apps/visualize/group6/index.ts b/test/functional/apps/visualize/group6/index.ts
index 03027c7a31a8a..062f558625771 100644
--- a/test/functional/apps/visualize/group6/index.ts
+++ b/test/functional/apps/visualize/group6/index.ts
@@ -27,6 +27,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./_tag_cloud'));
loadTestFile(require.resolve('./_tsvb_markdown'));
loadTestFile(require.resolve('./_tsvb_table'));
+ loadTestFile(require.resolve('./_tsvb_tsdb_basic'));
loadTestFile(require.resolve('./_vega_chart'));
});
}
diff --git a/test/functional/fixtures/es_archiver/kibana_sample_data_logs_tsdb/data.json.gz b/test/functional/fixtures/es_archiver/kibana_sample_data_logs_tsdb/data.json.gz
new file mode 100644
index 0000000000000..7c358cfc48ac1
Binary files /dev/null and b/test/functional/fixtures/es_archiver/kibana_sample_data_logs_tsdb/data.json.gz differ
diff --git a/test/functional/fixtures/es_archiver/kibana_sample_data_logs_tsdb/mappings.json b/test/functional/fixtures/es_archiver/kibana_sample_data_logs_tsdb/mappings.json
new file mode 100644
index 0000000000000..19722e1df922b
--- /dev/null
+++ b/test/functional/fixtures/es_archiver/kibana_sample_data_logs_tsdb/mappings.json
@@ -0,0 +1,174 @@
+{
+ "type": "index",
+ "value": {
+ "aliases": {
+ },
+ "index": "kibana_sample_data_logstsdb",
+ "mappings": {
+ "_data_stream_timestamp": {
+ "enabled": true
+ },
+ "properties": {
+ "@timestamp": {
+ "type": "date"
+ },
+ "agent": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "bytes": {
+ "type": "long"
+ },
+ "bytes_counter": {
+ "time_series_metric": "counter",
+ "type": "long"
+ },
+ "bytes_gauge": {
+ "time_series_metric": "gauge",
+ "type": "long"
+ },
+ "clientip": {
+ "type": "ip"
+ },
+ "event": {
+ "properties": {
+ "dataset": {
+ "type": "keyword"
+ }
+ }
+ },
+ "extension": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "geo": {
+ "properties": {
+ "coordinates": {
+ "type": "geo_point"
+ },
+ "dest": {
+ "type": "keyword"
+ },
+ "src": {
+ "type": "keyword"
+ },
+ "srcdest": {
+ "type": "keyword"
+ }
+ }
+ },
+ "host": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "index": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "ip": {
+ "type": "ip"
+ },
+ "machine": {
+ "properties": {
+ "os": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "ram": {
+ "type": "long"
+ }
+ }
+ },
+ "memory": {
+ "type": "double"
+ },
+ "message": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "phpmemory": {
+ "type": "long"
+ },
+ "referer": {
+ "type": "keyword"
+ },
+ "request": {
+ "time_series_dimension": true,
+ "type": "keyword"
+ },
+ "response": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "tags": {
+ "fields": {
+ "keyword": {
+ "ignore_above": 256,
+ "type": "keyword"
+ }
+ },
+ "type": "text"
+ },
+ "timestamp": {
+ "path": "@timestamp",
+ "type": "alias"
+ },
+ "url": {
+ "time_series_dimension": true,
+ "type": "keyword"
+ },
+ "utc_time": {
+ "type": "date"
+ }
+ }
+ },
+ "settings": {
+ "index": {
+ "auto_expand_replicas": "0-1",
+ "mode": "time_series",
+ "number_of_replicas": "0",
+ "number_of_shards": "1",
+ "routing_path": "request",
+ "time_series": {
+ "end_time": "2023-06-28T09:17:00.283Z",
+ "start_time": "2023-03-28T09:17:00.283Z"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/functional/fixtures/kbn_archiver/kibana_sample_data_logs_tsdb.json b/test/functional/fixtures/kbn_archiver/kibana_sample_data_logs_tsdb.json
new file mode 100644
index 0000000000000..6d2c95fa0ac3d
--- /dev/null
+++ b/test/functional/fixtures/kbn_archiver/kibana_sample_data_logs_tsdb.json
@@ -0,0 +1,22 @@
+{
+ "attributes": {
+ "fieldFormatMap": "{\"hour_of_day\":{}}",
+ "name": "Kibana Sample Data Logs (TSDB)",
+ "runtimeFieldMap": "{\"hour_of_day\":{\"type\":\"long\",\"script\":{\"source\":\"emit(doc['timestamp'].value.getHour());\"}}}",
+ "timeFieldName": "timestamp",
+ "title": "kibana_sample_data_logstsdb"
+ },
+ "coreMigrationVersion": "8.8.0",
+ "created_at": "2023-04-27T13:09:20.333Z",
+ "id": "90943e30-9a47-11e8-b64d-95841ca0c247",
+ "managed": false,
+ "references": [],
+ "sort": [
+ 1682600960333,
+ 64
+ ],
+ "type": "index-pattern",
+ "typeMigrationVersion": "7.11.0",
+ "updated_at": "2023-04-27T13:09:20.333Z",
+ "version": "WzIxLDFd"
+}
\ No newline at end of file
diff --git a/tsconfig.base.json b/tsconfig.base.json
index 47391d9185f14..58eb34d40debd 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -1002,6 +1002,8 @@
"@kbn/presentation-util-plugin/*": ["src/plugins/presentation_util/*"],
"@kbn/profiling-plugin": ["x-pack/plugins/profiling"],
"@kbn/profiling-plugin/*": ["x-pack/plugins/profiling/*"],
+ "@kbn/random-sampling": ["x-pack/packages/kbn-random-sampling"],
+ "@kbn/random-sampling/*": ["x-pack/packages/kbn-random-sampling/*"],
"@kbn/react-field": ["packages/kbn-react-field"],
"@kbn/react-field/*": ["packages/kbn-react-field/*"],
"@kbn/remote-clusters-plugin": ["x-pack/plugins/remote_clusters"],
diff --git a/x-pack/packages/kbn-random-sampling/.storybook/main.js b/x-pack/packages/kbn-random-sampling/.storybook/main.js
new file mode 100644
index 0000000000000..cf33a3d9fbff0
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/.storybook/main.js
@@ -0,0 +1,16 @@
+/*
+ * 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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+const baseConfig = require('@kbn/storybook').defaultConfig;
+
+module.exports = {
+ ...baseConfig,
+ stories: ['../**/*.stories.mdx', ...baseConfig.stories],
+ typescript: {
+ reactDocgen: 'react-docgen-typescript',
+ },
+};
diff --git a/x-pack/packages/kbn-random-sampling/.storybook/preview.js b/x-pack/packages/kbn-random-sampling/.storybook/preview.js
new file mode 100644
index 0000000000000..2b39ca7220800
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/.storybook/preview.js
@@ -0,0 +1,13 @@
+/*
+ * 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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export const parameters = {
+ viewMode: 'docs',
+ previewTabs: {
+ canvas: { hidden: true },
+ },
+};
diff --git a/x-pack/packages/kbn-random-sampling/README.md b/x-pack/packages/kbn-random-sampling/README.md
new file mode 100755
index 0000000000000..9bff0e029527e
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/README.md
@@ -0,0 +1,10 @@
+# @kbn/random-sampling
+
+Contains all the components of Kibana's random sampling experience. Specifically:
+ - UI components for rendering the random sampling configuration;
+
+---
+
+## Development
+
+See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment.
diff --git a/x-pack/packages/kbn-random-sampling/index.ts b/x-pack/packages/kbn-random-sampling/index.ts
new file mode 100644
index 0000000000000..d9e9a6ea2576d
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { RandomSamplingSlider, RandomSamplingIcon } from './src';
+export type { RandomSamplingSliderProps, RandomSamplingIconProps } from './src';
diff --git a/x-pack/packages/kbn-random-sampling/jest.config.js b/x-pack/packages/kbn-random-sampling/jest.config.js
new file mode 100644
index 0000000000000..ea198cd7ad3bd
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/jest.config.js
@@ -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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+module.exports = {
+ preset: '@kbn/test',
+ rootDir: '../../..',
+ roots: ['/x-pack/packages/kbn-random-sampling'],
+ coverageDirectory: '/target/kibana-coverage/jest/x-pack/packages/kbn-random-sampling',
+ coverageReporters: ['text', 'html'],
+ collectCoverageFrom: ['/x-pack/packages/kbn-random-sampling/public/**/*.{ts,tsx}'],
+};
diff --git a/x-pack/packages/kbn-random-sampling/kibana.jsonc b/x-pack/packages/kbn-random-sampling/kibana.jsonc
new file mode 100644
index 0000000000000..963ef9add20b1
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/kibana.jsonc
@@ -0,0 +1,5 @@
+{
+ "type": "shared-browser",
+ "id": "@kbn/random-sampling",
+ "owner": "@elastic/kibana-visualizations",
+}
diff --git a/x-pack/packages/kbn-random-sampling/package.json b/x-pack/packages/kbn-random-sampling/package.json
new file mode 100644
index 0000000000000..d66789e69e3c5
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "@kbn/random-sampling",
+ "private": true,
+ "version": "1.0.0",
+ "license": "Elastic License 2.0"
+ }
\ No newline at end of file
diff --git a/x-pack/packages/kbn-random-sampling/src/__stories__/control_slider.stories.mdx b/x-pack/packages/kbn-random-sampling/src/__stories__/control_slider.stories.mdx
new file mode 100644
index 0000000000000..dff3556ea9d61
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/src/__stories__/control_slider.stories.mdx
@@ -0,0 +1,62 @@
+import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs/blocks';
+import { I18nProvider } from '@kbn/i18n-react';
+import { ControlSlider } from '../ui/slider_control'
+
+
+export const Template = (args) => ;
+
+
+
+
+# Overview
+
+The following control slider component has been designed to work as a shared component in Kibana:
+
+
+
+When the control slider is disabled an explanation tooltip is shown to the user:
+
+
+
+## Component props
+
+The component exposes the following properties:
+
+
diff --git a/x-pack/packages/kbn-random-sampling/src/__stories__/sampling_icon.stories.mdx b/x-pack/packages/kbn-random-sampling/src/__stories__/sampling_icon.stories.mdx
new file mode 100644
index 0000000000000..b30eaef920ef4
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/src/__stories__/sampling_icon.stories.mdx
@@ -0,0 +1,19 @@
+import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs/blocks';
+import { RandomSamplingIcon } from '../ui/icon/sampling_icon'
+
+
+
+# Overview
+The shared Random Sampling icon is the following
+
+
+
+## Component table props
+
+On top of common SVGElement props also the following props are supported by the component:
+
+
diff --git a/x-pack/packages/kbn-random-sampling/src/index.ts b/x-pack/packages/kbn-random-sampling/src/index.ts
new file mode 100755
index 0000000000000..f7cf156502a04
--- /dev/null
+++ b/x-pack/packages/kbn-random-sampling/src/index.ts
@@ -0,0 +1,12 @@
+/*
+ * 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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { RandomSamplingIcon, type RandomSamplingIconProps } from './ui/icon/sampling_icon';
+export {
+ ControlSlider as RandomSamplingSlider,
+ type ControlSliderProps as RandomSamplingSliderProps,
+} from './ui/slider_control';
diff --git a/x-pack/plugins/lens/public/datasources/form_based/sampling_icon.tsx b/x-pack/packages/kbn-random-sampling/src/ui/icon/sampling_icon.tsx
similarity index 96%
rename from x-pack/plugins/lens/public/datasources/form_based/sampling_icon.tsx
rename to x-pack/packages/kbn-random-sampling/src/ui/icon/sampling_icon.tsx
index 8241c1d86a5fc..aa3dc05d84cec 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/sampling_icon.tsx
+++ b/x-pack/packages/kbn-random-sampling/src/ui/icon/sampling_icon.tsx
@@ -4,6 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
+
import React from 'react';
interface CustomProps {
@@ -11,11 +12,9 @@ interface CustomProps {
titleId?: string;
}
-export function RandomSamplingIcon({
- title,
- titleId,
- ...props
-}: React.SVGProps & CustomProps) {
+export type RandomSamplingIconProps = React.SVGProps & CustomProps;
+
+export function RandomSamplingIcon({ title, titleId, ...props }: RandomSamplingIconProps) {
return (