- Files and folders
- Partials
- Collapsible sidebar items
- Front matter
- Documeting components
- Custom components available
- Writing content
Code for the Elastic UI documentation site can be found in the packages/website
directory. The site is built with Docusaurus.
Documentation is written in Markdown.
Files are stored in the docs
folder and document files use MDX, thus the .mdx
file extension. This format allows writing React code alongside Markdown. It's also possible to import React code from .tsx
files, which is useful for more complex examples.
Check out the MDX syntax documentation here.
Tip
For formatting content always prefer using Markdown over React
The folder structure matches the navigation and content structure, similar to common static site builders like Jekyll. For instance, for editing the Components / Containers / Accordion page, the content will be found in the docs/components/containers/accordion.mdx
file.
Files and folder names must use kebab-case, unlike the EUI convention to use snake_case. This makes it easier to keep URLs consistent without having to override Docusaurus defaults in the front matter.
There are a few React components that can be used in .mdx
files without being imported. They are part of the MDX scope. Some of them, documented below, are:
The front matter is a section at the top of a Markdown file that contains metadata about the document. It's enclosed in triple dashes (---
) and written in YAML format.
A few important aspects of the document can be configured here:
id
(unique to the document)slug
(to customize the URL)sidebar_label
sidebar_position
title
(if different from the h1)description
Check the Docusaurus docs for a full list of fields.
To create a collapsible item in the sidebar, just add a folder in the file system containing one or more .mdx
files. In Docusaurus these are called category items, and they can be configured by adding a _category_.yml
file to the folder. By default the category label will be the folder name, this can be changed with the label
field in the _category_.yml
file. Other useful fields are position
and collapsed
.
It's possible to make a collapsible item be a document as well, though this is not recommended. Set the link
field to have type: doc
and id: <DOCUMENT_ID>
, with the id
from the document it should point to. If the id
is not explicitly set in the document file's front matter, it's the relative path starting from the docs
folder, without the file extension, e.g. docs/components/containers/accordion
.
Read more about category metadata and file structure in the Docusaurus docs.
Warning
Nesting items in the sidebar should be avoided when possible, deeply nested items can make the menu harder to use
All component pages should follow the following architecture:
- Intro
- Component: a bare-bones example of the component in its default form
- Usage (optional): examples of different states and use-cases
- Guidelines (optional): e.g. dos and don'ts
- Props
A document can be split into different files when content is too long, for easier editing.
Markdown files prefixed with an underscore will be ignored when generating the sidebar navigation. These hidden files can be imported and rendered in the main document.
For example, the document for the Modal page is containers/modal/index.mdx
:
containers/
modal/
_guidelines.mdx
_usage.mdx
index.mdx
Usage and Guidelines sections have their own file that can be imported:
import Usage from './_usage.mdx';
## Usage
<Usage />
## Guidelines
import Guidelines from './_guidelines.mdx';
<Guidelines />
Read more about importing Markdown files in the Docusaurus docs.
As previously mentioned, using Markdown is highly encouraged. It makes it easier for anybody to contribute to the documentation.
During the build step of the website, elements with a counterpart in EUI will be accordingly replaced, e.g. a link with EuiLink
, a inline code block with EuiCode
, etc.
Headings in Markdown are created with a hash symbol in a new line. The number of hashes will determine the heading level, #
for 1, ##
for 2, etc.
Important
Do not use heading levels for styling, use them to properly structure the document hierarchically
Markdown is the recommended syntax for creating links. Docusaurus will take care of rendering it correctly.
[This is a link](https://example.com)
To link between documents, use relative file paths, including the file extension, e.g. [EuiPanel](../containers/panel/index.mdx)
Read more about Markdown links in the Docusaurus docs.
The syntax for creating admonitions is wrapping a paragraph in three colons, e.g. :::
. The type of admonition and title can be defined after the first three colons. This will render EuiCallOut
.
:::info This is the title
Here's some content
:::
There are 5 types of admonitions supported, with icon and color respectively.
note
tip
info
accessibility
warning
danger
A code block or code snippet can be created by wrapping text in backticks, e.g. `code`.
For a simple one-liner, single backticks are enough. To create a multiline snippet or code block, use three backticks. For syntax highlighting, the language name can be added right after the first three backticks.
```html
<span>Hello World</span>
```
Code blocks can be used to generate live demos, where a React component that is exported in the snippet will be rendered on the page. To do that, append the word "interactive" after the language name, usually tsx
.
```tsx interactive
export default () => (
<div>Hello World</div>
)
```
More advanced usage with the Demo
component can be found right below.
When plain code blocks are not enough, the Demo
component can be used. It's available without being imported so it can be used straightaway.
Note
They're called "live" demos because the source code can be edited right there on the page and the preview will update
The benefits of the Demo
component over plain code blocks are mainly:
- that the scope of the demo can be extended with imports from the document, and already exposes all React and EUI exports, and
- it's possible to add a wrapper component for the preview and adjust the padding
children
- Atsx
code blockscope
- An object to extend the scope of the demo with additional propertiesisSourceOpen
- Whether the source code editor is open by default (false
)previewPadding
- Adjust the padding of the previewpreviewWrapper
- A wrapper component for the preview
Check the source code here.
Tip
Remember to wrap imports in ```mdx-code-block`
```mdx-code-block
import previewWrapper from './preview_wrapper.tsx';
```
<Demo previewWrapper={previewWrapper}>
```tsx
import React, { useState } from 'react';
import { EuiButton } from '@elastic/eui';
export default () => {
const [counter, setCounter] = useState<number>(0);
const updateCounter = () => setCounter(x => x + 1);
return (
<EuiButton onClick={updateCounter}>
Clicked {counter} times
</EuiButton>
)
}
```
</Demo>
The convention for creating full-screen examples, where the entire browser screen is needed to demo a certain component combination or pattern, is to create a Storybook story and link to it from the docs.
There's a StorybookLink
component that makes this easy and consistent, by handling the URL appropriately depending on the environment.
It's expected for the link to be preceded by a heading and a short description.
The story's id
can be found in the URL. It's the part after /index.html?path=/story/
.
## A heading for the example
Here it's explained what the examples represents.
```mdx-code-block
import { StorybookLink } from '@site/src/components';
```
<StorybookLink id="<STORY_ID>" />
The preferred way to display content in tables is by leveraging EuiBasicTable and not Markdown tables.
Just like with partials, the code for the table can be separated in its own file and imported into the MDX document where it'll be displayed. For example:
components/
my-component/
nice_table.tsx
index.mdx
nice_table.tsx
can export a component that renders EuiBasicTable:
import { css } from '@emotion/react';
import {
EuiBasicTable,
EuiBasicTableColumn,
// ...
} from '@elastic/eui';
export const NiceTable = () => {
const items = [
// ...
];
const columns = [
// ...
];
return <EuiBasicTable items={items} columns={columns} tableLayout="auto" />;
}
And then in index.mdx
the table can be rendered:
## A heading for the table
```mdx-code-block
import { NiceTable } from './nice_table';
```
<NiceTable />
For dos and don'ts sections there's a Guideline
component with the appropriate styles built-in. To display one next to the other, a EuiFlexGroup can be used:
<EuiFlexGroup gutterSize="m">
<Guideline type="do" text="Lorem ipsum dolor sit amet consectetur adipiscing elit.">
<div>Yep content</div>
</Guideline>
<Guideline type="dont" text="Quisque faucibus ex sapien vitae pellentesque sem placerat.">
<div>Nope content</div>
</Guideline>
</EuiFlexGroup>
children
- The content inside, can be other componentstype
-do
,dont
ordefault
text
- The actual guideline textpanelPadding
(optional) - To adjust the padding of the panelpanelStyle
(optional) - To further customize the panel styles
It's possible to embed a Figma file right into a page. The FigmaEmbed
component accepts a url
from a Figma file and a title
:
<FigmaEmbed url="https://www.figma.com/file/Uo8i…DX-0" title="Title of the embed" />
The Props table should always go last in a document. There is a PropTable
component available without being imported that will take the props information from the @elastic/eui-docgen
package in the definition
prop.
If more than one table is needed because the component has many exports, place one table after the other. It should look like this:
## Props
```mdx-code-block
import docgen from '@elastic/eui-docgen/dist/components/page';
```
<PropTable definition={docgen.EuiPage} />
<PropTable definition={docgen.EuiPageBody} />
<PropTable definition={docgen.EuiPageSidebar} />
To customize the table PropTable
also takes a headingLevel
prop (h1–h6) and a showTitle
boolean.