Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ek-so authored Jul 31, 2024
2 parents 5204eeb + 1ff2db5 commit 6e51405
Show file tree
Hide file tree
Showing 33 changed files with 1,756 additions and 228 deletions.
599 changes: 599 additions & 0 deletions .yarn/patches/infima-npm-0.2.0-alpha.43-8d3b77b44d.patch

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"react-focus-lock": "2.9.5",
"@babel/core": "^7.21.8",
"jsdom": "24.1.0",
"@types/jsdom@npm:^20.0.0": "patch:@types/jsdom@npm%3A20.0.1#~/.yarn/patches/@types-jsdom-npm-20.0.1-5bb899e006.patch"
"@types/jsdom@npm:^20.0.0": "patch:@types/jsdom@npm%3A20.0.1#~/.yarn/patches/@types-jsdom-npm-20.0.1-5bb899e006.patch",
"infima@npm:0.2.0-alpha.43": "patch:infima@npm%3A0.2.0-alpha.43#~/.yarn/patches/infima-npm-0.2.0-alpha.43-8d3b77b44d.patch"
},
"packageManager": "[email protected]"
}
1 change: 1 addition & 0 deletions packages/docusaurus-theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@docusaurus/utils-validation": "^3.4.0",
"@elastic/datemath": "^5.0.3",
"@elastic/eui": "94.5.0",
"@elastic/eui-docgen": "workspace:^",
"@emotion/css": "^11.11.2",
"@emotion/react": "^11.11.4",
"@types/react-window": "^1.8.8",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Fragment, useMemo } from 'react';
import { EuiLink, EuiText } from '@elastic/eui';
import { ProcessedComponent } from '@elastic/eui-docgen';
import { extendedTypesInfo } from './extended_types_info';

export interface PropTableExtendedTypesProps {
definition: ProcessedComponent;
}

export const PropTableExtendedTypes = ({ definition }: PropTableExtendedTypesProps) => {
const extendedTypes = useMemo(() => {
const types = definition.extends.filter(
(type) => extendedTypesInfo.hasOwnProperty(type.displayName),
);

if (types.every((type) => type.displayName.indexOf('HTMLAttributes') > -1)) {
const htmlAttributesIndex = types.findIndex((type) => type.displayName === 'HTMLAttributes');
if (htmlAttributesIndex > -1 && types.length > 1) {
types.splice(htmlAttributesIndex, 1);
}
}

return types;
}, [definition.extends]);

if (!extendedTypes.length) {
return null;
}

return (
<EuiText size="s">
Extends{' '}
{extendedTypes.map((type, index) => (
<Fragment key={index}>
<EuiLink href={extendedTypesInfo[type.displayName as keyof typeof extendedTypesInfo].url}>
{type.displayName}
</EuiLink>
{extendedTypes.length - 1 > index && ', '}
</Fragment>
))}
</EuiText>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export const extendedTypesInfo = {
// HTMLAttributes is removed from display if any of the following elements also exist
HTMLAttributes: {
name: 'HTMLElement',
url: 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement',
},
SelectHTMLAttributes: {
name: 'HTMLSelectElement',
url: 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement',
},
TextareaHTMLAttributes: {
name: 'HTMLTextAreaElement',
url: 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement',
},
InputHTMLAttributes: {
name: 'HTMLInputElement',
url: 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement',
},
AnchorHTMLAttributes: {
name: 'HTMLAnchorElement',
url: 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement',
},
ButtonHTMLAttributes: {
name: 'HTMLButtonElement',
url: 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PropTable } from './prop_table';
174 changes: 174 additions & 0 deletions packages/docusaurus-theme/src/components/prop_table/prop_table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import {
EuiBasicTable,
EuiMarkdownFormat,
EuiBasicTableColumn,
EuiTextColor,
EuiFlexGroup,
EuiCode,
UseEuiTheme,
EuiTitle,
useEuiMemoizedStyles, EuiLink,
} from '@elastic/eui';
import { ProcessedComponent, ProcessedComponentProp } from '@elastic/eui-docgen';
import { useCallback, useMemo } from 'react';
import { css } from '@emotion/react';
import { PropTableExtendedTypes } from './extended_types';

export interface PropTableProps {
definition: ProcessedComponent;
headingLevel?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
}

const getPropId = (prop: ProcessedComponentProp, componentName: string) => (
`${encodeURIComponent(componentName)}-prop-${prop.name}`
);

const getPropTableStyles = ({ euiTheme }: UseEuiTheme) => ({
propTable: css`
margin-block: ${euiTheme.size.xl};
`,
header: css`
// Increased specificity is needed here to override default
// content heading styles
&& h1,
&& h2,
&& h3,
&& h4,
&& h5,
&& h6 {
margin-block: 0;
}
`,
table: css`
vertical-align: top;
`,
propName: css`
font-family: ${euiTheme.font.familyCode};
font-weight: ${euiTheme.font.weight.semiBold};
`,
description: css`
p:first-child {
margin-block-start: 0;
}
`,
required: css`
font-family: ${euiTheme.font.familyCode};
color: ${euiTheme.colors.dangerText};
`,
type: css`
font-weight: ${euiTheme.font.weight.semiBold};
`,
tableNameLink: css`
display: none;
margin-inline-start: ${euiTheme.size.xs};
`,
tableRow: css`
scroll-margin-block-start: calc(var(--ifm-navbar-height) + 0.5rem);
&:hover .propLink {
display: inline-block;
}
`,
});

export const PropTable = ({
definition,
headingLevel: HeadingLevel = 'h3',
}: PropTableProps) => {
const styles = useEuiMemoizedStyles(getPropTableStyles);

const tableItems = useMemo<Array<ProcessedComponentProp>>(
() => Object.values(definition.props).sort(
(a, b) => +b.isRequired - +a.isRequired
),
[definition.props],
);

const columns = useMemo<Array<EuiBasicTableColumn<ProcessedComponentProp>>>(
() => ([
{
field: 'name',
name: 'Prop',
width: "150",
render(value: ProcessedComponentProp['name'], prop: ProcessedComponentProp) {
return (
<span css={styles.propName}>
{value}
<EuiLink
href={`#${getPropId(prop, definition.displayName)}`}
css={styles.tableNameLink}
className="propLink"
aria-label={`Direct link to the ${prop.name} prop`}
title={`Direct link to the ${prop.name} prop`}
>
#
</EuiLink>
</span>
);
},
},
{
field: 'description',
name: 'Description and type',
render(value: ProcessedComponentProp['description'], prop: ProcessedComponentProp) {
return (
<EuiFlexGroup direction="column" alignItems="flexStart" gutterSize="s">
{value?.trim() && (
<EuiMarkdownFormat css={styles.description}>{value}</EuiMarkdownFormat>
)}
{prop.type && (
<span css={styles.type}>
Type: {' '}
<EuiCode language="ts">
{prop.type.raw || prop.type.name}
</EuiCode>
</span>
)}
</EuiFlexGroup>
);
}
},
{
field: 'defaultValue',
name: 'Default value',
width: "120",
render(value: ProcessedComponentProp['defaultValue'], prop: ProcessedComponentProp) {
if (prop.isRequired && !value?.trim().length) {
return <EuiTextColor css={styles.required}>Required</EuiTextColor>
}

return value && <EuiCode>{value}</EuiCode>;
},
}
]),
[],
);

const rowProps = useCallback((item: ProcessedComponentProp) => ({
id: getPropId(item, definition.displayName),
css: styles.tableRow,
}), [definition.displayName]);

return (
<EuiFlexGroup
aria-label={`Component properties table for ${definition.displayName}`}
gutterSize="s"
direction="column"
css={styles.propTable}
>
<header css={styles.header}>
<EuiTitle size="m">
<HeadingLevel>{definition.displayName}</HeadingLevel>
</EuiTitle>
<PropTableExtendedTypes definition={definition} />
</header>
<EuiBasicTable
css={styles.table}
width="100%"
items={tableItems}
columns={columns}
rowProps={rowProps}
/>
</EuiFlexGroup>
);
};
24 changes: 23 additions & 1 deletion packages/docusaurus-theme/src/theme/DocRoot/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { css } from '@emotion/react';
import { useDocsSidebar } from '@docusaurus/theme-common/internal';
import useIsBrowser from '@docusaurus/useIsBrowser';
import BackToTopButton from '@theme-original/BackToTopButton';
import type { Props } from '@theme-original/DocRoot/Layout';
import DocRootLayoutSidebar from '@theme-original/DocRoot/Layout/Sidebar';
Expand All @@ -20,8 +21,29 @@ const styles = {
};

export default function DocRootLayout({ children }: Props): JSX.Element {
const isBrowser = useIsBrowser();
const sidebar = useDocsSidebar();
const [hiddenSidebarContainer, setHiddenSidebarContainer] = useState(false);

// Replicate browser hash scroll behavior to trigger it after the MDX content
// is rendered. Timeout = 0 should do the job here just fine as the effect
// will get executed at next render cycle when all elements are (hopefully)
// already in the DOM.
useEffect(() => {
if (!isBrowser) {
return;
}

if (window.location.hash) {
setTimeout(() => {
const element = document.getElementById(
window.location.hash.substring(1),
);
element?.scrollIntoView(true);
}, 0);
}
}, [isBrowser]);

return (
<div css={styles.docsWrapper}>
<BackToTopButton />
Expand Down
2 changes: 2 additions & 0 deletions packages/docusaurus-theme/src/theme/MDXComponents/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Badge } from '../../components/badge';
import { Icon } from '../../components/icon';
import { FigmaEmbed } from '../../components/figma_embed';
import { Demo, DemoSource } from '../../components/demo';
import { PropTable } from '../../components/prop_table';

const MDXComponents = {
...OriginalMDXComponents,
Expand All @@ -19,6 +20,7 @@ const MDXComponents = {
Icon,
Demo,
DemoSource,
PropTable,
};

export default MDXComponents;
2 changes: 2 additions & 0 deletions packages/eui-docgen/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
lib/
12 changes: 12 additions & 0 deletions packages/eui-docgen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# EUI component docs data generator

This package scans all `.ts(x)` source files in the [EUI](../eui) package and extracts prop type definitions to
JSON files which can be easily imported in the [website](../website) package and rendered as component prop table.

# Usage

## Build and generate prop type definitions

```bash
yarn build
```
31 changes: 31 additions & 0 deletions packages/eui-docgen/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@elastic/eui-docgen",
"version": "1.0.0",
"description": "",
"scripts": {
"clear": "rimraf dist/ lib/",
"generate": "ts-node src/main.ts",
"build": "tsc && yarn generate"
},
"repository": {
"type": "git",
"url": "https://github.com/tkajtoch/eui.git",
"directory": "packages/eui-docgen"
},
"private": true,
"dependencies": {
"glob": "^11.0.0",
"react-docgen-typescript": "^2.2.2",
"ts-node": "^10.9.2",
"typescript": "~5.5.4"
},
"devDependencies": {
"rimraf": "^6.0.1"
},
"files": [
"dist",
"lib"
],
"types": "./lib/index.d.ts",
"main": "./lib/index.d.ts"
}
Loading

0 comments on commit 6e51405

Please sign in to comment.