diff --git a/src/components/page_template/page_template.stories.tsx b/src/components/page_template/page_template.stories.tsx
index b97f43be46b..c53344e18ca 100644
--- a/src/components/page_template/page_template.stories.tsx
+++ b/src/components/page_template/page_template.stories.tsx
@@ -148,7 +148,4 @@ export const Playground: Story = {
},
},
},
- // using render() over args to ensure dynamic update on prop changes
- // Cee TODO: This doesn't appear to work for the `paddingSize` and `bottomBorder` props
- // render: ({ ...args }) => ,
};
diff --git a/src/components/resizable_container/resizable_container.stories.tsx b/src/components/resizable_container/resizable_container.stories.tsx
new file mode 100644
index 00000000000..9162db19b46
--- /dev/null
+++ b/src/components/resizable_container/resizable_container.stories.tsx
@@ -0,0 +1,209 @@
+/*
+ * 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 type { Meta, StoryObj } from '@storybook/react';
+import { faker } from '@faker-js/faker';
+
+import { enableFunctionToggleControls } from '../../../.storybook/utils';
+import { EuiText } from '../text';
+import {
+ EuiResizableContainer,
+ EuiResizableContainerProps,
+} from './resizable_container';
+
+faker.seed(42);
+
+const placeholderText = (
+ <>
+
{faker.lorem.sentences(5)}
+ {faker.lorem.sentences(5)}
+ {faker.lorem.sentences(5)}
+ >
+);
+
+const TwoColumns: EuiResizableContainerProps['children'] = (
+ EuiResizablePanel,
+ EuiResizableButton
+) => (
+ <>
+
+ {placeholderText}
+
+
+
+
+
+ {placeholderText}
+
+ >
+);
+
+const ThreeColumns: EuiResizableContainerProps['children'] = (
+ EuiResizablePanel,
+ EuiResizableButton
+) => (
+ <>
+
+ {placeholderText}
+
+
+
+
+
+ {placeholderText}
+
+
+
+
+
+ {placeholderText}
+
+ >
+);
+
+const WithMinSize: EuiResizableContainerProps['children'] = (
+ EuiResizablePanel,
+ EuiResizableButton
+) => (
+ <>
+
+
+ {placeholderText}
+ {placeholderText}
+ {placeholderText}
+
+
+
+
+
+
+
+ {placeholderText}
+ {placeholderText}
+ {placeholderText}
+
+
+ >
+);
+
+const SingleCollapsible: EuiResizableContainerProps['children'] = (
+ EuiResizablePanel,
+ EuiResizableButton
+) => (
+ <>
+
+
+ {placeholderText}
+ {placeholderText}
+ {placeholderText}
+
+
+
+
+
+
+
+ {placeholderText}
+ {placeholderText}
+ {placeholderText}
+
+
+ >
+);
+
+const MultiCollapsible: EuiResizableContainerProps['children'] = (
+ EuiResizablePanel,
+ EuiResizableButton
+) => (
+ <>
+
+
+ {placeholderText}
+ {placeholderText}
+ {placeholderText}
+
+
+
+
+
+
+
+ {placeholderText}
+ {placeholderText}
+ {placeholderText}
+
+
+
+
+
+
+
+ {placeholderText}
+ {placeholderText}
+ {placeholderText}
+
+
+ >
+);
+
+const meta: Meta = {
+ title: 'Layout/EuiResizableContainer/EuiResizableContainer',
+ component: EuiResizableContainer,
+ args: {
+ direction: 'horizontal',
+ },
+};
+enableFunctionToggleControls(meta, [
+ 'onPanelWidthChange',
+ 'onToggleCollapsed',
+ 'onResizeStart',
+ 'onResizeEnd',
+]);
+
+export default meta;
+type Story = StoryObj;
+
+export const Playground: Story = {
+ argTypes: {
+ children: {
+ control: 'select',
+ options: ['2 columns', '3 columns', 'With MinSize'],
+ description:
+ 'Select an option to show examples using EuiResizablePanel and EuiResizableButton',
+ mapping: {
+ '2 columns': TwoColumns,
+ '3 columns': ThreeColumns,
+ 'With MinSize': WithMinSize,
+ },
+ },
+ },
+ args: {
+ children: '2 columns' as unknown as any, // overwriting expected type to use children select control instead of function
+ style: { height: '50vh' },
+ },
+};
+
+export const CollapsiblePanels: Story = {
+ argTypes: {
+ children: {
+ control: 'radio',
+ options: ['Single', 'Multiple'],
+ description:
+ 'Select an option to show examples of EuiResizablePanel with mode={"collapsible" | "main"}. Click the resizable button element to collapse a column.',
+ mapping: {
+ Single: SingleCollapsible,
+ Multiple: MultiCollapsible,
+ },
+ },
+ },
+ args: {
+ children: 'Single' as unknown as any,
+ style: { height: '50vh' },
+ },
+};
diff --git a/src/components/resizable_container/resizable_panel.stories.tsx b/src/components/resizable_container/resizable_panel.stories.tsx
new file mode 100644
index 00000000000..a6525c37447
--- /dev/null
+++ b/src/components/resizable_container/resizable_panel.stories.tsx
@@ -0,0 +1,101 @@
+/*
+ * 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 type { Meta, StoryObj } from '@storybook/react';
+import { css } from '@emotion/react';
+import { faker } from '@faker-js/faker';
+
+import {
+ disableStorybookControls,
+ moveStorybookControlsToCategory,
+} from '../../../.storybook/utils';
+import { EuiResizableContainer } from './resizable_container';
+import { EuiResizablePanel, EuiResizablePanelProps } from './resizable_panel';
+
+faker.seed(42);
+
+const meta: Meta = {
+ title: 'Layout/EuiResizableContainer/EuiResizablePanel',
+ component: EuiResizablePanel,
+ argTypes: {
+ mode: {
+ control: 'radio',
+ description:
+ 'For use with collapsible panels. Will only be applied when used within EuiResizableContainer. View EuiResizableContainer stories for an example.',
+ options: [undefined, 'collapsible', 'main', 'custom'],
+ },
+ },
+ args: {
+ minSize: '0px',
+ scrollable: true,
+ hasShadow: false,
+ borderRadius: 'none',
+ color: 'transparent',
+ paddingSize: 'm',
+ wrapperPadding: 'none',
+ // for quicker/easier QA
+ grow: false,
+ hasBorder: false,
+ },
+};
+disableStorybookControls(meta, ['panelRef']);
+moveStorybookControlsToCategory(
+ meta,
+ [
+ 'color',
+ 'borderRadius',
+ 'grow',
+ 'hasBorder',
+ 'hasShadow',
+ 'paddingSize',
+ 'panelRef',
+ ],
+ 'EuiPanel props'
+);
+
+export default meta;
+type Story = StoryObj;
+
+export const Playground: Story = {
+ args: {
+ children: faker.lorem.sentences(5),
+ initialSize: 50,
+ },
+ render: ({ mode, children, ...rest }) => {
+ const placeholderMode =
+ mode === 'collapsible'
+ ? 'main'
+ : mode === 'main'
+ ? 'collapsible'
+ : 'custom';
+ return (
+
+ {(EuiResizablePanel, EuiResizableButton) => (
+ <>
+
+ {children}
+
+
+ {/* NOTE: using the second panel only to ensure functionality, visually not required */}
+
+ {children}
+
+ >
+ )}
+
+ );
+ },
+};
diff --git a/src/components/responsive/show_for.stories.tsx b/src/components/responsive/show_for.stories.tsx
new file mode 100644
index 00000000000..a96b276e7f3
--- /dev/null
+++ b/src/components/responsive/show_for.stories.tsx
@@ -0,0 +1,27 @@
+/*
+ * 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 type { Meta, StoryObj } from '@storybook/react';
+
+import { EuiShowFor, EuiShowForProps } from './show_for';
+
+const meta: Meta = {
+ title: 'Utilities/EuiShowFor',
+ component: EuiShowFor,
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Playground: Story = {
+ args: {
+ sizes: ['m', 'l', 'xl'],
+ children:
+ 'Try changing the Storybook viewport, or add or remove additional sizes, to see how it affects the visibility of this text.',
+ },
+};
diff --git a/src/components/search_bar/search_bar.stories.tsx b/src/components/search_bar/search_bar.stories.tsx
new file mode 100644
index 00000000000..cdce9bc461e
--- /dev/null
+++ b/src/components/search_bar/search_bar.stories.tsx
@@ -0,0 +1,157 @@
+/*
+ * 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 type { Meta, StoryObj } from '@storybook/react';
+
+import { enableFunctionToggleControls } from '../../../.storybook/utils';
+import { EuiButton } from '../button';
+import { EuiSearchBar, EuiSearchBarProps } from './search_bar';
+
+const tags = [
+ { name: 'marketing', color: 'danger' },
+ { name: 'finance', color: 'success' },
+ { name: 'eng', color: 'success' },
+ { name: 'sales', color: 'warning' },
+ { name: 'ga', color: 'success' },
+];
+
+const meta: Meta = {
+ title: 'Forms/EuiSearchBar/EuiSearchBar',
+ component: EuiSearchBar,
+ argTypes: {
+ toolsLeft: {
+ control: 'boolean',
+ description: 'Toogle the control to display an example for left tools',
+ mapping: {
+ true: Left tools button,
+ false: undefined,
+ },
+ },
+ toolsRight: {
+ control: 'boolean',
+ description: 'Toogle the control to display an example for right tools',
+ mapping: {
+ true: Right tools button,
+ false: undefined,
+ },
+ },
+ },
+};
+enableFunctionToggleControls(meta, ['onChange']);
+
+export default meta;
+type Story = StoryObj;
+
+export const Playground: Story = {
+ args: {
+ // setting up props for easier testing/QA
+ dateFormat: {},
+ defaultQuery: '',
+ query: '',
+ box: {
+ placeholder: 'Enter a search term or query...',
+ incremental: false,
+ schema: {
+ strict: true,
+ fields: {
+ type: {
+ type: 'string',
+ },
+ active: {
+ type: 'boolean',
+ },
+ status: {
+ type: 'string',
+ },
+ followers: {
+ type: 'number',
+ },
+ comments: {
+ type: 'number',
+ },
+ stars: {
+ type: 'number',
+ },
+ owner: {
+ type: 'string',
+ },
+ tag: {
+ type: 'string',
+ validate: (value: string) => {
+ if (value !== '' && !tags.some((tag) => tag.name === value)) {
+ throw new Error(
+ `unknown tag (possible values: ${tags
+ .map((tag) => tag.name)
+ .join(',')})`
+ );
+ }
+ },
+ },
+ },
+ },
+ },
+ filters: [
+ {
+ type: 'field_value_toggle_group',
+ field: 'status',
+ items: [
+ {
+ value: 'open',
+ name: 'Open',
+ },
+ {
+ value: 'closed',
+ name: 'Closed',
+ },
+ ],
+ },
+ {
+ type: 'is',
+ field: 'active',
+ name: 'Active',
+ negatedName: 'Inactive',
+ },
+ {
+ type: 'field_value_toggle',
+ name: 'Mine',
+ field: 'owner',
+ value: 'dewey',
+ },
+ {
+ type: 'field_value_toggle',
+ name: 'Popular',
+ field: 'followers',
+ value: 5,
+ operator: 'gt',
+ },
+ {
+ type: 'field_value_selection',
+ field: 'tag',
+ name: 'Tag',
+ multiSelect: 'or',
+ operator: 'exact',
+ cache: 10000, // will cache the loaded tags for 10 sec
+ options: () =>
+ new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(
+ tags.map((tag) => ({
+ value: tag.name,
+ view: tag.name,
+ }))
+ );
+ }, 2000);
+ }),
+ },
+ ],
+ // casting to any to allow for easier teasting/QA via toggle switch
+ toolsLeft: false as any,
+ toolsRight: false as any,
+ },
+};
diff --git a/src/components/search_bar/search_bar_filters.stories.tsx b/src/components/search_bar/search_bar_filters.stories.tsx
new file mode 100644
index 00000000000..e4897b9e223
--- /dev/null
+++ b/src/components/search_bar/search_bar_filters.stories.tsx
@@ -0,0 +1,96 @@
+/*
+ * 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 type { Meta, StoryObj } from '@storybook/react';
+
+import { enableFunctionToggleControls } from '../../../.storybook/utils';
+import { EuiHealth } from '../health';
+import {
+ EuiSearchBarFilters,
+ EuiSearchBarFiltersProps,
+} from './search_filters';
+import { Query } from './query';
+
+const tags = [
+ { name: 'marketing', color: 'danger' },
+ { name: 'finance', color: 'success' },
+ { name: 'eng', color: 'success' },
+ { name: 'sales', color: 'warning' },
+ { name: 'ga', color: 'success' },
+];
+
+const meta: Meta = {
+ title: 'Forms/EuiSearchBar/EuiSearchBarFilters',
+ component: EuiSearchBarFilters,
+};
+enableFunctionToggleControls(meta, ['onChange']);
+
+export default meta;
+type Story = StoryObj;
+
+export const Playground: Story = {
+ args: {
+ filters: [
+ {
+ type: 'field_value_toggle_group',
+ field: 'status',
+ items: [
+ {
+ value: 'open',
+ name: 'Open',
+ },
+ {
+ value: 'closed',
+ name: 'Closed',
+ },
+ ],
+ },
+ {
+ type: 'is',
+ field: 'active',
+ name: 'Active',
+ negatedName: 'Inactive',
+ },
+ {
+ type: 'field_value_toggle',
+ name: 'Mine',
+ field: 'owner',
+ value: 'dewey',
+ },
+ {
+ type: 'field_value_toggle',
+ name: 'Popular',
+ field: 'followers',
+ value: 5,
+ operator: 'gt',
+ },
+ {
+ type: 'field_value_selection',
+ field: 'tag',
+ name: 'Tag',
+ multiSelect: 'or',
+ operator: 'exact',
+ cache: 10000, // will cache the loaded tags for 10 sec
+ options: () =>
+ new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(
+ tags.map((tag) => ({
+ value: tag.name,
+ view: {tag.name},
+ }))
+ );
+ }, 2000);
+ }),
+ },
+ ],
+ // setting up props for easier testing/QA
+ query: Query.parse(''),
+ },
+};
diff --git a/src/components/search_bar/search_filters.tsx b/src/components/search_bar/search_filters.tsx
index 242624379e4..3b66d4228c2 100644
--- a/src/components/search_bar/search_filters.tsx
+++ b/src/components/search_bar/search_filters.tsx
@@ -13,7 +13,7 @@ import { EuiFilterGroup } from '../filter_group';
export type { SearchFilterConfig } from './filters';
-interface EuiSearchBarFiltersProps {
+export interface EuiSearchBarFiltersProps {
query: Query;
onChange: (query: Query) => void;
filters: SearchFilterConfig[];
diff --git a/src/components/side_nav/side_nav.stories.tsx b/src/components/side_nav/side_nav.stories.tsx
index 75e800ee4f9..d473c74c7fe 100644
--- a/src/components/side_nav/side_nav.stories.tsx
+++ b/src/components/side_nav/side_nav.stories.tsx
@@ -11,6 +11,7 @@ import type { Meta, StoryObj } from '@storybook/react';
import {
hideStorybookControls,
disableStorybookControls,
+ enableFunctionToggleControls,
} from '../../../.storybook/utils';
import { EuiIcon } from '../icon';
@@ -37,6 +38,7 @@ const meta: Meta = {
],
};
disableStorybookControls(meta, ['children']);
+enableFunctionToggleControls(meta, ['toggleOpenOnMobile']);
export default meta;
type Story = StoryObj;
diff --git a/src/components/spacer/spacer.stories.tsx b/src/components/spacer/spacer.stories.tsx
new file mode 100644
index 00000000000..3d8a18fd918
--- /dev/null
+++ b/src/components/spacer/spacer.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 React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+
+import { EuiText } from '../text';
+import { EuiSpacer, EuiSpacerProps } from './spacer';
+
+const meta: Meta = {
+ title: 'Layout/EuiSpacer',
+ component: EuiSpacer,
+ decorators: [
+ (Story) => (
+ <>
+
+ Observe the space created between this and the next text block.
+
+
+
+
+ Observe the space created between this and the previous text block.
+
+
+ >
+ ),
+ ],
+ args: {
+ size: 'l',
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Playground: Story = {};
diff --git a/src/components/stat/stat.stories.tsx b/src/components/stat/stat.stories.tsx
new file mode 100644
index 00000000000..ad0d37cbe74
--- /dev/null
+++ b/src/components/stat/stat.stories.tsx
@@ -0,0 +1,38 @@
+/*
+ * 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 type { Meta, StoryObj } from '@storybook/react';
+
+import { EuiStat, EuiStatProps } from './stat';
+
+const meta: Meta = {
+ title: 'Display/EuiStat',
+ component: EuiStat,
+ argTypes: {
+ title: { control: 'text' },
+ },
+ args: {
+ textAlign: 'left',
+ titleColor: 'default',
+ titleSize: 'l',
+ titleElement: 'p',
+ descriptionElement: 'p',
+ isLoading: false,
+ reverse: false,
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Playground: Story = {
+ args: {
+ title: '999,999',
+ description: 'description',
+ },
+};