diff --git a/src/components/mark/mark.stories.tsx b/src/components/mark/mark.stories.tsx new file mode 100644 index 00000000000..65edfe8b197 --- /dev/null +++ b/src/components/mark/mark.stories.tsx @@ -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 type { Meta, StoryObj } from '@storybook/react'; + +import { EuiMark, EuiMarkProps } from './mark'; + +const meta: Meta = { + title: 'Utilities/EuiMark', + component: EuiMark, + // Component defaults + args: { + hasScreenReaderHelpText: true, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Playground: Story = { + args: { + children: 'Marked text', + }, +}; diff --git a/src/components/markdown_editor/markdown_editor.stories.tsx b/src/components/markdown_editor/markdown_editor.stories.tsx new file mode 100644 index 00000000000..32add3e8f3d --- /dev/null +++ b/src/components/markdown_editor/markdown_editor.stories.tsx @@ -0,0 +1,72 @@ +/* + * 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 { EuiMarkdownEditor, EuiMarkdownEditorProps } from './markdown_editor'; +import { + defaultParsingPlugins, + defaultProcessingPlugins, + defaultUiPlugins, +} from './plugins/markdown_default_plugins'; +import { MODE_EDITING, MODE_VIEWING } from './markdown_modes'; + +const initialContent = `## Hello world! + +Basic "GitHub flavored" markdown will work as you'd expect. + +The editor also ships with some built in plugins. For example it can handle checkboxes. Notice how they toggle state even in the preview mode. + +- [ ] Checkboxes +- [x] Can be filled +- [ ] Or empty + +It can also handle emojis! :smile: + +And it can render !{tooltip[tooltips like this](Look! I'm a very helpful tooltip content!)} +`; + +const meta: Meta = { + title: 'Editors & Syntax/EuiMarkdownEditor/EuiMarkdownEditor', + component: EuiMarkdownEditor, + // Component defaults + args: { + height: 250, + maxHeight: 500, + autoExpandPreview: true, + parsingPluginList: defaultParsingPlugins, + processingPluginList: defaultProcessingPlugins, + uiPlugins: defaultUiPlugins, + errors: [], + initialViewMode: MODE_EDITING, + dropHandlers: [], + }, +}; + +export default meta; +type Story = StoryObj; + +export const Playground: Story = { + args: { + value: initialContent, + }, +}; + +export const ViewMode: Story = { + args: { + value: initialContent, + initialViewMode: MODE_VIEWING, + }, +}; + +export const Errors: Story = { + args: { + value: initialContent, + errors: ['An error happened.', 'Woops, another error happened.'], + }, +}; diff --git a/src/components/markdown_editor/markdown_format.stories.tsx b/src/components/markdown_editor/markdown_format.stories.tsx new file mode 100644 index 00000000000..1092ffba1a7 --- /dev/null +++ b/src/components/markdown_editor/markdown_format.stories.tsx @@ -0,0 +1,71 @@ +/* + * 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 { + hideStorybookControls, + moveStorybookControlsToCategory, +} from '../../../.storybook/utils'; +import { EuiMarkdownFormat, EuiMarkdownFormatProps } from './markdown_format'; +import { + defaultParsingPlugins, + defaultProcessingPlugins, +} from './plugins/markdown_default_plugins'; +import { ALIGNMENTS } from '../text/text_align'; + +const initialContent = `## Hello world! + +Basic "GitHub flavored" markdown will work as you'd expect. + +The editor also ships with some built in plugins. For example it can handle checkboxes. Notice how they toggle state even in the preview mode. + +- [ ] Checkboxes +- [x] Can be filled +- [ ] Or empty + +It can also handle emojis! :smile: + +And it can render !{tooltip[tooltips like this](Look! I'm a very helpful tooltip content!)} +`; + +const meta: Meta = { + title: 'Editors & Syntax/EuiMarkdownEditor/EuiMarkdownFormat', + component: EuiMarkdownFormat, + argTypes: { + color: { control: { type: 'text' } }, + grow: { control: { type: 'boolean' } }, + textAlign: { + control: { type: 'radio' }, + options: [undefined, ...ALIGNMENTS], + }, + ...hideStorybookControls(['aria-label']), + }, + // Component defaults + args: { + textSize: 'm', + parsingPluginList: defaultParsingPlugins, + processingPluginList: defaultProcessingPlugins, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Playground: Story = { + // TODO: move this to the component level once utils are updated to fully support merged configs (#7583) + argTypes: { + ...moveStorybookControlsToCategory( + ['textAlign', 'color', 'grow'], + 'EuiText props' + ), + }, + args: { + children: initialContent, + }, +}; diff --git a/src/components/observer/mutation_observer/mutation_observer.stories.tsx b/src/components/observer/mutation_observer/mutation_observer.stories.tsx new file mode 100644 index 00000000000..51f7394b875 --- /dev/null +++ b/src/components/observer/mutation_observer/mutation_observer.stories.tsx @@ -0,0 +1,102 @@ +/* + * 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, { useState } from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { _EuiButtonColor } from '../../../themes/amsterdam/global_styling/mixins'; +import { EuiFlexGroup, EuiFlexItem } from '../../flex'; +import { EuiSpacer } from '../../spacer'; +import { EuiButton, EuiButtonEmpty } from '../../button'; +import { EuiPanel } from '../../panel'; +import { + EuiMutationObserver, + EuiMutationObserverProps, +} from './mutation_observer'; + +const meta: Meta = { + title: 'Utilities/EuiMutationObserver', + component: EuiMutationObserver, +}; + +export default meta; +type Story = StoryObj; + +const StatefulPlayground = ({ + onMutation, + ...rest +}: EuiMutationObserverProps) => { + const [lastMutation, setLastMutation] = useState('no changes detected'); + const [buttonColor, setButtonColor] = useState<_EuiButtonColor>('primary'); + const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']); + + const toggleButtonColor = () => { + setButtonColor(buttonColor === 'primary' ? 'warning' : 'primary'); + }; + + const addItem = () => { + setItems([...items, `Item ${items.length + 1}`]); + }; + + const handleOnMutation = ( + mutationRecords: MutationRecord[], + mutationObserver: MutationObserver + ) => { + const [{ type }] = mutationRecords; + setLastMutation( + type === 'attributes' ? 'button class name changed' : 'DOM tree changed' + ); + onMutation(mutationRecords, mutationObserver); + }; + + return ( + <> +

{lastMutation}

+ + + + + {(mutationRef) => ( +
+ + Toggle button color + + + + + + + +
    + {items.map((item) => ( +
  • {item}
  • + ))} +
+ + add item +
+
+
+
+ )} +
+ + ); +}; + +export const Playground: Story = { + render: (args) => , +}; diff --git a/src/components/observer/mutation_observer/mutation_observer.ts b/src/components/observer/mutation_observer/mutation_observer.tsx similarity index 100% rename from src/components/observer/mutation_observer/mutation_observer.ts rename to src/components/observer/mutation_observer/mutation_observer.tsx diff --git a/src/components/observer/resize_observer/resize_observer.stories.tsx b/src/components/observer/resize_observer/resize_observer.stories.tsx new file mode 100644 index 00000000000..f2baa73e127 --- /dev/null +++ b/src/components/observer/resize_observer/resize_observer.stories.tsx @@ -0,0 +1,93 @@ +/* + * 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, { useState } from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { EuiPaddingSize } from '../../../global_styling'; +import { EuiText } from '../../text'; +import { EuiCode } from '../../code'; +import { EuiSpacer } from '../../spacer'; +import { EuiButton, EuiButtonEmpty } from '../../button'; +import { EuiPanel } from '../../panel'; +import { EuiResizeObserver, EuiResizeObserverProps } from './resize_observer'; + +const meta: Meta = { + title: 'Utilities/EuiResizeObserver', + component: EuiResizeObserver, +}; + +export default meta; +type Story = StoryObj; + +const StatefulPlayground = ({ onResize, ...rest }: EuiResizeObserverProps) => { + const [paddingSize, setPaddingSize] = useState('s'); + const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']); + const [height, setHeight] = useState(0); + const [width, setWidth] = useState(0); + + const togglePaddingSize = () => { + setPaddingSize((paddingSize) => (paddingSize === 's' ? 'l' : 's')); + }; + + const addItem = () => { + setItems((items) => [...items, `Item ${items.length + 1}`]); + }; + + const handleOnResize = ({ + height, + width, + }: { + height: number; + width: number; + }) => { + setHeight(height); + setWidth(width); + onResize({ height, width }); + }; + + return ( + <> + +

+ + height: {height}; width: {width} + +

+
+ + + + + Toggle container padding + + + + + + {(resizeRef) => ( +
+ +
    + {items.map((item) => ( +
  • {item}
  • + ))} +
+ + add item +
+
+ )} +
+ + ); +}; + +export const Playground: Story = { + render: (args) => , +}; diff --git a/src/components/outside_click_detector/outside_click_detector.stories.tsx b/src/components/outside_click_detector/outside_click_detector.stories.tsx new file mode 100644 index 00000000000..4dbded25f6e --- /dev/null +++ b/src/components/outside_click_detector/outside_click_detector.stories.tsx @@ -0,0 +1,51 @@ +/* + * 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 { action } from '@storybook/addon-actions'; + +import { EuiText } from '../text'; +import { + EuiOutsideClickDetector, + EuiOutsideClickDetectorProps, +} from './outside_click_detector'; + +const meta: Meta = { + title: 'Utilities/EuiOutsideClickDetector', + component: EuiOutsideClickDetector, + argTypes: { + children: { control: { type: 'text' } }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Playground: Story = { + args: { + children: + // cast type here to ensure the control table and output are connected and useful + // TODO: remove once the control table can handle more complex types + 'Click anywhere outside of this text to trigger an alert' as unknown as any, + onOutsideClick: (e: Event) => { + action('onOutsideClick')(e); + window.alert('Clicked outside'); + }, + }, + render: ({ children, ...rest }: EuiOutsideClickDetectorProps) => { + const content = ( + +

{children}

+
+ ); + return ( + {content} + ); + }, +}; diff --git a/src/components/outside_click_detector/outside_click_detector.ts b/src/components/outside_click_detector/outside_click_detector.tsx similarity index 100% rename from src/components/outside_click_detector/outside_click_detector.ts rename to src/components/outside_click_detector/outside_click_detector.tsx