Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiDataGrid] Docs and autodocs #2449

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
8724183
Render out EuiDataGrid proptypes
chandlerprall Oct 8, 2019
1ba6319
Add pagination props to docs
chandlerprall Oct 10, 2019
da5e009
Merge branch 'feature/euidatagrid' into feature/euidatagrid-proptypes
chandlerprall Oct 17, 2019
46fb5de
Fill out all datagrid autodoc sections
chandlerprall Oct 17, 2019
dfc8b3a
remove debugger statement
chandlerprall Oct 18, 2019
dfee675
Update src/components/datagrid/data_grid_types.ts
chandlerprall Oct 18, 2019
81c9afa
words
snide Oct 18, 2019
04eb997
Merge remote-tracking branch 'upstream/feature/euidatagrid' into feat…
snide Oct 18, 2019
7cc1d19
docs start
snide Oct 18, 2019
10f887b
datatype renamed to schema, update docs
snide Oct 20, 2019
996f29a
docs, fix typo for fullscreen buton
snide Oct 20, 2019
6d8c646
core concepts
snide Oct 20, 2019
e3b86e2
better in memory explanation
snide Oct 20, 2019
b7224ed
custom schema example
snide Oct 20, 2019
e2e7cc8
provide a nice, documented snippet
snide Oct 20, 2019
d92dca3
typos
snide Oct 20, 2019
a00a228
don't show pagination when only one page
snide Oct 21, 2019
9ccf374
clean up styling, better docs for formatters
snide Oct 21, 2019
6530ecd
more docs cleanup
snide Oct 21, 2019
5864613
IE fix
snide Oct 21, 2019
3e567f5
IE fix again
snide Oct 21, 2019
b0ec82a
small cleanup of docs
snide Oct 21, 2019
4461722
describe how to disable expansion popovers
snide Oct 21, 2019
bfcf2ff
dark mode tweaks
snide Oct 21, 2019
5aaa8cb
Fix custom datatype sorting
chandlerprall Oct 21, 2019
82c4027
Update src-docs/src/views/datagrid/datagrid_example.js
chandlerprall Oct 21, 2019
ab3f7dd
Update src-docs/src/views/datagrid/datagrid_example.js
chandlerprall Oct 21, 2019
41c3026
Update src-docs/src/views/datagrid/datagrid_example.js
chandlerprall Oct 21, 2019
f83cbe8
Update src-docs/src/views/datagrid/datagrid_example.js
chandlerprall Oct 21, 2019
4dec561
Update src-docs/src/views/datagrid/datagrid_example.js
chandlerprall Oct 21, 2019
d08e15e
Update src-docs/src/views/datagrid/datagrid_example.js
chandlerprall Oct 21, 2019
9a8592e
Update src-docs/src/views/datagrid/datagrid_example.js
chandlerprall Oct 21, 2019
0bb88bc
Update src-docs/src/views/datagrid/datagrid_example.js
chandlerprall Oct 21, 2019
51c5d61
PR feedback
chandlerprall Oct 21, 2019
da50e8e
typo
chandlerprall Oct 21, 2019
4ea2868
feedback to break up docs
snide Oct 21, 2019
a8e6a6d
better cross linking and summary
snide Oct 21, 2019
1d3bf69
fix custom schema display
snide Oct 21, 2019
25f4d3a
Update src-docs/src/views/datagrid/datagrid_memory_example.js
chandlerprall Oct 22, 2019
49dbe5d
Update src-docs/src/views/datagrid/datagrid_memory_example.js
chandlerprall Oct 22, 2019
f7c17b7
Update src-docs/src/views/datagrid/datagrid_memory_example.js
chandlerprall Oct 22, 2019
76446f7
Update src-docs/src/views/datagrid/datagrid_schema_example.js
chandlerprall Oct 22, 2019
d14ec85
Update src-docs/src/views/datagrid/datagrid_memory_example.js
chandlerprall Oct 22, 2019
6e26f3b
Update src-docs/src/views/datagrid/datagrid_memory_example.js
chandlerprall Oct 22, 2019
3726be7
Update src-docs/src/views/datagrid/datagrid_memory_example.js
chandlerprall Oct 22, 2019
acfd3de
Updated some datagrid docs
chandlerprall Oct 22, 2019
2ba28a2
main dg example page feedback
snide Oct 22, 2019
3b0602e
Eui prefix all the things to be consistant. Adjust the data grid docs…
snide Oct 22, 2019
90dc785
rewrite intro based on feedback
snide Oct 22, 2019
b78ecae
more tweaking of words
snide Oct 22, 2019
41d81e2
rename toolbarDisplay->toolbarVisibility
snide Oct 23, 2019
69704fd
in memory docs reworked to four examples
snide Oct 23, 2019
18ab582
clean up core example
snide Oct 23, 2019
f3749f6
data grid styling snippets
snide Oct 23, 2019
1a023a1
fix prop list
snide Oct 23, 2019
6b6d45d
Minor grammar edits
Oct 23, 2019
ab504f3
Added isDetails prop to renderCellValue, reducing the use case for ex…
chandlerprall Oct 23, 2019
d0bd3d5
Merge branch 'feature/euidatagrid-proptypes' into cp/feature/euidatag…
chandlerprall Oct 23, 2019
833067e
Merge pull request #13 from cchaos/cp/feature/euidatagrid-proptypes
chandlerprall Oct 23, 2019
060ca87
fix docs renaming, fix css
snide Oct 23, 2019
c973a89
last docs edit seems fitting
snide Oct 23, 2019
26542d7
somewhat decent attempt at putting classnames on schemas
snide Oct 23, 2019
6183abf
Revert "somewhat decent attempt at putting classnames on schemas"
chandlerprall Oct 23, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 144 additions & 6 deletions scripts/babel/proptypes-from-ts-props/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,66 @@ function resolveArrayToPropTypes(node, state) {
}
}

function stripDoubleQuotes(value) {
return value.replace(/^"?(.*?)"?$/, '$1');
}

/**
* Converts an Omit<X, Y> type to resolveIdentifierToPropTypes(X) with Y removed
* @param node
* @param state
* @returns AST node representing matching proptypes
*/
function resolveOmitToPropTypes(node, state) {
const types = state.get('types');

const { typeParameters } = node;

if (typeParameters == null) return null;

const {
params: [sourceType, toRemove],
} = typeParameters;

const sourcePropTypes = getPropTypesForNode(sourceType, true, state);
// validate that this resulted in a shape, otherwise we don't know how to extract/merge the values
if (
!types.isCallExpression(sourcePropTypes) ||
!types.isMemberExpression(sourcePropTypes.callee) ||
sourcePropTypes.callee.object.name !== 'PropTypes' ||
sourcePropTypes.callee.property.name !== 'shape'
) {
return null;
}

const toRemovePropTypes = getPropTypesForNode(toRemove, true, state);
// validate that this resulted in a oneOf, otherwise we don't know how to use the values
if (
!types.isCallExpression(toRemovePropTypes) ||
!types.isMemberExpression(toRemovePropTypes.callee) ||
toRemovePropTypes.callee.object.name !== 'PropTypes' ||
toRemovePropTypes.callee.property.name !== 'oneOf'
) {
return null;
}

// extract the string values of keys to remove
const keysToRemove = new Set(
toRemovePropTypes.arguments[0].elements
.map(keyToRemove =>
types.isStringLiteral(keyToRemove) ? keyToRemove.value : null
)
.filter(x => x !== null)
);

// filter out omitted properties
sourcePropTypes.arguments[0].properties = sourcePropTypes.arguments[0].properties.filter(
({ key: { name } }) => keysToRemove.has(stripDoubleQuotes(name)) === false
);

return sourcePropTypes;
}

/**
* Converts an X[] type to PropTypes.arrayOf(X)
* @param node
Expand Down Expand Up @@ -160,9 +220,16 @@ function resolveIdentifierToPropTypes(node, state) {
types.identifier('PropTypes'),
types.identifier('node')
);

case 'JSXElementConstructor':
return types.memberExpression(
types.identifier('PropTypes'),
types.identifier('func') // this is more accurately `elementType` but our peerDependency version of prop-types doesn't have it
);
}

if (identifier.name === 'Array') return resolveArrayToPropTypes(node, state);
if (identifier.name === 'Omit') return resolveOmitToPropTypes(node, state);
if (identifier.name === 'MouseEventHandler')
return buildPropTypePrimitiveExpression(types, 'func');
if (identifier.name === 'Function')
Expand Down Expand Up @@ -356,10 +423,39 @@ function getPropTypesForNode(node, optional, state) {
propType = getPropTypesForNode(node.typeAnnotation, true, state);
break;

// Foo['bar']
case 'TSIndexedAccessType':
// verify the type of index access
if (types.isTSLiteralType(node.indexType) === false) break;

const indexedName = node.indexType.literal.value;
const objectPropType = getPropTypesForNode(node.objectType, true, state);

// verify this came out as a PropTypes.shape(), which we can pick the indexed property off of
if (
types.isCallExpression(objectPropType) &&
types.isMemberExpression(objectPropType.callee) &&
types.isIdentifier(objectPropType.callee.object) &&
objectPropType.callee.object.name === 'PropTypes' &&
types.isIdentifier(objectPropType.callee.property) &&
objectPropType.callee.property.name === 'shape'
) {
const shapeProps = objectPropType.arguments[0].properties;
for (let i = 0; i < shapeProps.length; i++) {
const prop = shapeProps[i];
if (prop.key.name === indexedName) {
propType = makePropTypeOptional(types, prop.value);
break;
}
}
}

break;

// translates intersections (Foo & Bar & Baz) to a shape with the types' members (Foo, Bar, Baz) merged together
case 'TSIntersectionType':
const usableNodes = node.types.filter(node => {
const nodePropTypes = getPropTypesForNode(node, true, state);
const usableNodes = [...node.types].filter(node => {
let nodePropTypes = getPropTypesForNode(node, true, state);

if (
types.isMemberExpression(nodePropTypes) &&
Expand All @@ -369,12 +465,12 @@ function getPropTypesForNode(node, optional, state) {
return false;
}

// validate that this resulted in a shape, otherwise we don't know how to extract/merge the values
// validate that this resulted in a shape or oneOfType, otherwise we don't know how to extract/merge the values
if (
!types.isCallExpression(nodePropTypes) ||
!types.isMemberExpression(nodePropTypes.callee) ||
nodePropTypes.callee.object.name !== 'PropTypes' ||
nodePropTypes.callee.property.name !== 'shape'
(nodePropTypes.callee.property.name !== 'shape' && nodePropTypes.callee.property.name !== 'oneOfType')
) {
return false;
}
Expand All @@ -384,7 +480,49 @@ function getPropTypesForNode(node, optional, state) {

// merge the resolved proptypes for each intersection member into one object, mergedProperties
const mergedProperties = usableNodes.reduce((mergedProperties, node) => {
const nodePropTypes = getPropTypesForNode(node, true, state);
let nodePropTypes = getPropTypesForNode(node, true, state);

// if this is a `oneOfType` extract those properties into a `shape`
if (
types.isCallExpression(nodePropTypes) &&
types.isMemberExpression(nodePropTypes.callee) &&
nodePropTypes.callee.object.name === 'PropTypes' &&
nodePropTypes.callee.property.name === 'oneOfType'
) {
const properties = nodePropTypes.arguments[0].elements
.map(propType => {
// This exists on a oneOfType which must be expressed as an optional proptype
propType = makePropTypeOptional(types, propType);

// validate we're working with a shape, otherwise we can't merge properties
if (
!types.isCallExpression(propType) ||
!types.isMemberExpression(propType.callee) ||
propType.callee.object.name !== 'PropTypes' ||
propType.callee.property.name !== 'shape'
) {
return null;
}

// extract all of the properties from this group and make them optional
return propType.arguments[0].properties.map(property => {
property.value = makePropTypeOptional(types, property.value);
return property;
});
})
.filter(x => x !== null)
.reduce((allProperties, properties) => {
return [...allProperties, ...properties];
}, []);

nodePropTypes = types.callExpression(
types.memberExpression(
types.identifier('PropTypes'),
types.identifier('shape')
),
[types.objectExpression(properties)]
);
}

// iterate over this type's members, adding them (and their comments) to `mergedProperties`
const typeProperties = nodePropTypes.arguments[0].properties; // properties on the ObjectExpression passed to PropTypes.shape()
Expand Down Expand Up @@ -1062,7 +1200,7 @@ function getPropTypesNodeFromAST(node, types) {
const buildPropTypes = babelTemplate('COMPONENT_NAME.propTypes = PROP_TYPES');

/**
* Called with a type definition and a React component node path, `processComponentDeclaration` translates that definiton
* Called with a type definition and a React component node path, `processComponentDeclaration` translates that definition
* to an AST of PropType.* calls and attaches those prop types to the component.
* @param typeDefinition
* @param path
Expand Down
49 changes: 49 additions & 0 deletions scripts/babel/proptypes-from-ts-props/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,28 @@ FooComponent.propTypes = {
};`);
});

it('understands JSXElementConstructor', () => {
const result = transform(
`
import React from 'react';
const FooComponent: React.SFC<{foo: JSXElementConstructor<any>}> = () => {
return (<div>Hello World</div>);
}`,
babelOptions
);

expect(result.code).toBe(`import React from 'react';
import PropTypes from "prop-types";

const FooComponent = () => {
return <div>Hello World</div>;
};

FooComponent.propTypes = {
foo: PropTypes.func.isRequired
};`);
});

});

describe('node propType', () => {
Expand Down Expand Up @@ -2051,6 +2073,33 @@ FooComponent.propTypes = {

});

describe('indexed property access', () => {
it('follows indexed properties', () => {
const result = transform(
`
import React from 'react';
interface Foo {
foo: () => {};
}
const FooComponent: React.SFC<{bar: Foo['foo']}> = () => {
return (<div>Hello World</div>);
}`,
babelOptions
);

expect(result.code).toBe(`import React from 'react';
import PropTypes from "prop-types";

const FooComponent = () => {
return <div>Hello World</div>;
};

FooComponent.propTypes = {
bar: PropTypes.func.isRequired
};`);
});
});

describe('supported component declarations', () => {

it('annotates React.SFC components', () => {
Expand Down
8 changes: 8 additions & 0 deletions src-docs/src/components/guide_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,11 @@ $guideZLevelHighest: $euiZLevel9 + 1000;
}
}
}

.euiDataGridRowCell--favoriteFranchise {
background: transparentize($color: #800080, $amount: .95) !important;
}

.euiDataGridHeaderCell--favoriteFranchise {
background: transparentize($color: #800080, $amount: .9) !important;
}
10 changes: 0 additions & 10 deletions src-docs/src/components/guide_section/_guide_section.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,3 @@
.guideSection__space {
height: $euiSizeL;
}

.guideSectionPropsTable {
width: auto;
min-width: 50%;

th,
td {
max-width: none;
}
}
31 changes: 16 additions & 15 deletions src-docs/src/components/guide_section/guide_section.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export class GuideSection extends Component {
const docgenInfo = Array.isArray(component.__docgenInfo)
? component.__docgenInfo[0]
: component.__docgenInfo;
const { _euiObjectType, description, props } = docgenInfo;
const { description, props } = docgenInfo;

if (!props && !description) {
return;
Expand Down Expand Up @@ -271,12 +271,7 @@ export class GuideSection extends Component {
return <EuiTableRow key={propName}>{cells}</EuiTableRow>;
});

const title =
_euiObjectType === 'type' ? (
<EuiCode id={componentName}>{componentName}</EuiCode>
) : (
<EuiText>{componentName}</EuiText>
);
const title = <span id={componentName}>{componentName}</span>;

let descriptionElement;

Expand All @@ -295,18 +290,23 @@ export class GuideSection extends Component {

if (rows.length) {
table = (
<EuiTable
className="guideSectionPropsTable"
compressed
key={`propsTable-${componentName}`}>
<EuiTable compressed key={`propsTable-${componentName}`}>
<EuiTableHeader>
<EuiTableHeaderCell>Prop</EuiTableHeaderCell>
<EuiTableHeaderCell style={{ Width: '20%' }}>
Prop
</EuiTableHeaderCell>

<EuiTableHeaderCell>Type</EuiTableHeaderCell>
<EuiTableHeaderCell style={{ width: '15%' }}>
Type
</EuiTableHeaderCell>

<EuiTableHeaderCell>Default</EuiTableHeaderCell>
<EuiTableHeaderCell style={{ width: '15%' }}>
Default
</EuiTableHeaderCell>

<EuiTableHeaderCell>Note</EuiTableHeaderCell>
<EuiTableHeaderCell style={{ width: '50%' }}>
Note
</EuiTableHeaderCell>
</EuiTableHeader>

<EuiTableBody>{rows}</EuiTableBody>
Expand Down Expand Up @@ -422,6 +422,7 @@ export class GuideSection extends Component {
<div className="guideSection" id={this.props.id}>
{chrome}
{this.renderContent()}
{this.props.extraContent}
</div>
);
}
Expand Down
15 changes: 13 additions & 2 deletions src-docs/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ import { ContextMenuExample } from './views/context_menu/context_menu_example';
import { CopyExample } from './views/copy/copy_example';

import { DataGridExample } from './views/datagrid/datagrid_example';
import { DataGridMemoryExample } from './views/datagrid/datagrid_memory_example';
import { DataGridSchemaExample } from './views/datagrid/datagrid_schema_example';
import { DataGridStylingExample } from './views/datagrid/datagrid_styling_example';

import { DatePickerExample } from './views/date_picker/date_picker_example';

Expand Down Expand Up @@ -312,6 +315,16 @@ const navigation = [
TabsExample,
].map(example => createExample(example)),
},
{
name: 'Tabular content',
items: [
DataGridExample,
DataGridMemoryExample,
DataGridSchemaExample,
DataGridStylingExample,
TableExample,
].map(example => createExample(example)),
},
cchaos marked this conversation as resolved.
Show resolved Hide resolved
{
name: 'Display',
items: [
Expand All @@ -320,7 +333,6 @@ const navigation = [
CallOutExample,
CardExample,
CodeExample,
DataGridExample,
DescriptionListExample,
DragAndDropExample,
EmptyPromptExample,
Expand All @@ -331,7 +343,6 @@ const navigation = [
LoadingExample,
ProgressExample,
StatExample,
TableExample,
TextExample,
TitleExample,
ToastExample,
Expand Down
Loading