Skip to content

[Epic] Simplify Documentation Code Examples for Copy-Paste Usage #9450

@JasonStoltz

Description

@JasonStoltz

Summary / Pitch

Target EUI release date(s): TBD
Related request: N/A

Transform EUI documentation examples from verbose, full-source-code displays into clean, copy-paste-ready snippets. Currently, users see 50-100+ lines of setup code when they just need 5-10 lines to use a component.

Context

EUI documentation examples currently display the complete source code required to make each interactive demo work, including:

  • React imports and state management
  • Configuration UI controls (switches, selects, etc.)
  • Layout wrappers (EuiFlexGroup, EuiSpacer, etc.)
  • Demo-specific logic that users don't need

This creates friction for developers who want to quickly copy component usage patterns.

Example:
https://eui.elastic.co/docs/components/navigation/buttons/button/

Image

Desired:

<EuiButton
  color="primary"
  fill={true}
  onClick={() => {}}
>
  Button label
</EuiButton>

Actual:

import React, { useState } from 'react';
import {
  EuiButton,
  EuiFlexGroup,
  EuiFlexItem,
  EuiSpacer,
  EuiSelect,
  EuiSwitch,
} from '@elastic/eui';
import { COLORS } from '@elastic/eui/es/components/button/button';

export default () => {
  const [disableButton, setDisableButton] = useState(false);
  const [fillButton, setFillButton] = useState(false);
  const [fullButton, setFullButton] = useState(false);
  const [smallButton, setSmallButton] = useState(false);
  const [withIconButton, setWithIconButton] = useState(false);

  // While `accentSecondary` is currently available on the component, it is likely to be removed
  // `neutral` and `risk` are only tentatively added but might be removed
  const filteredColors = COLORS.filter((name) => !['accentSecondary', 'neutral', 'risk'].includes(name));
  const buttonColorsOptions = filteredColors.map((name) => {
    return {
      value: name,
      text: name,
    };
  });

  const [buttonColor, setButtonColor] = useState(buttonColorsOptions[2].value);

  const onChangeButtonColor = (e) => {
    setButtonColor(e.target.value);
  };

  return(
    <div>
    <EuiFlexGroup
        gutterSize="m"
        alignItems="center"
        wrap={true}
      >
        <EuiFlexItem grow={false}>
          <EuiSelect
            prepend="Color"
            options={buttonColorsOptions}
            value={buttonColor}
            onChange={(e) => onChangeButtonColor(e)}
            compressed
            aria-label="Button colors"
          />
        </EuiFlexItem>
        <EuiFlexItem grow={false}>
          <EuiSwitch
            compressed
            label="Fill"
            checked={fillButton}
            onChange={() => setFillButton(!fillButton)}
          />
        </EuiFlexItem>
        <EuiFlexItem grow={false}>
          <EuiSwitch
            compressed
            label="Full width"
            checked={fullButton}
            onChange={() => setFullButton(!fullButton)}
          />
        </EuiFlexItem>
        <EuiFlexItem grow={false}>
          <EuiSwitch
            compressed
            label="Small"
            checked={smallButton}
            onChange={() => setSmallButton(!smallButton)}
          />
        </EuiFlexItem>
        <EuiFlexItem grow={false}>
          <EuiSwitch
            compressed
            label="With icon"
            checked={withIconButton}
            onChange={() => setWithIconButton(!withIconButton)}
          />
        </EuiFlexItem>
        <EuiFlexItem grow={false}>
          <EuiSwitch
            compressed
            label="Disabled"
            checked={disableButton}
            onChange={() => setDisableButton(!disableButton)}
          />
        </EuiFlexItem>
      </EuiFlexGroup>
      <EuiSpacer />
      <EuiButton
        color={buttonColor}
        disabled={disableButton}
        fill={fillButton}
        fullWidth={fullButton}
        size={smallButton ? 's' : 'm'}
        iconType={withIconButton ? 'discoverApp' : null}
        onClick={() => {}}
      >
        {!withIconButton ? 'Button' : 'Open in Discover'}
      </EuiButton>
    </div>
  );
};

For example, a simple EuiButton example shows ~100 lines of code when users only need:

<EuiButton
  color="primary"
  fill={true}
  onClick={() => {}}
>
  Button label
</EuiButton>

Example:
https://eui.elastic.co/docs/components/navigation/buttons/button/

User impact: Developers must manually extract the relevant component code from verbose examples, slowing adoption and increasing implementation errors.

Goals

  • Provide copy-paste-ready code snippets for all documentation examples
  • Maintain interactive demo functionality (configuration toggles, live preview)
  • Establish a scalable pattern for future documentation
  • (Optional) Retain full source code access for users who need implementation details

Out of scope

  • Changing the interactive demo functionality itself
  • Restructuring the documentation site architecture
  • Modifying component APIs or prop definitions

Scope Analysis

Metric Count
Total MDX documentation files 208
Interactive demos (<Demo> / <FlexDemo>) ~145
Total code blocks (all types) ~700+
Primary sections requiring updates components (55), utilities (53), dataviz (13)

High-impact examples to prioritize:

  • Navigation components (buttons, links, tabs)
  • Form components (inputs, selects, switches)
  • Layout components (flex, grid, panels)

Proposed Approach

  1. Modify Demo component to support snippet display
  2. Generate snippets using AI for all 145 interactive demos
  3. Manual review and refinement of generated snippets
  4. Documentation and contributor guidelines for future examples

POC:

  • Draft PR
  • The above POC used cursor to update an example from buttons and badges to show a dynamic snippet.
  • My assumption is that we could refine and extend that to cover all (or most) examples on the documentation website. If there are some that are too complex, then we can simply skip them for now and only show the more complex example code.

Image

Definition of Ready for Dev

  • PRD Ready
    • Link: {link}
  • Design Ready (UX for snippet vs. full source toggle)
    • Design issue: {link}
    • Design file: {link}
  • Estimated
  • Tasked

Definition of done

  • All ~145 interactive demos have copy-paste-ready snippets
  • Demo component updated to show snippets by default
  • Full source remains accessible via toggle
  • Contributor guidelines updated for adding snippets to new examples
  • Documentation site deployed with changes

Useful Links

  • Demo component implementation: packages/docusaurus-theme/src/components/demo/
  • Example documentation file: packages/website/docs/components/navigation/buttons/button.mdx

Risks

  • Snippet accuracy: AI-generated snippets may require significant manual review
  • Edge cases: Some demos (data grid, complex forms) may not reduce cleanly to simple snippets
  • Maintenance: Need process for keeping snippets synchronized with full examples
  • Dynamic props: Snippets need to reflect current toggle state, not just static defaults

Open Questions

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No fields configured for Epic.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions