Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
af3d39c
feat: add mask editor (STU-313)
lag-of-death Jul 1, 2019
dd551a3
chore: rm yarn.lock and reinstall dependencies
lag-of-death Jul 3, 2019
cffc83b
style: address linting issue
lag-of-death Jul 3, 2019
790c4bf
feat: add "with mask controls" example to the stories
lag-of-death Jul 4, 2019
4eaaa90
fix: adjust padding
lag-of-death Jul 4, 2019
abc75db
feat: handle array and allOf [wip]
lag-of-death Jul 4, 2019
c5ab956
fix: toggle node
lag-of-death Jul 5, 2019
b4d1bca
feat: do not merge allOfs when in MaskEditor
lag-of-death Jul 5, 2019
aca6bdc
feat: add combiner name to its path
lag-of-death Jul 5, 2019
d3ce908
refactor: use a class instead of applying styles with style attr
lag-of-death Jul 5, 2019
3b560c6
chore: revert yarn.lock changes
lag-of-death Jul 5, 2019
9c5e9be
refactor: define SelectedPaths type
lag-of-death Jul 5, 2019
9cb785e
refactor: use React.ReactElement
lag-of-death Jul 5, 2019
8d822b7
refactor: use React.FunctionComponent for typing
lag-of-death Jul 5, 2019
7b49f17
refactor: rm TODO
lag-of-death Jul 5, 2019
485ca99
refactor: use tailwind class names
lag-of-death Jul 5, 2019
5ec1bd8
refactor: use MaskingProps type
lag-of-death Jul 5, 2019
7ac4db6
refactor: give "Apply/Update Mask" btn a better name (as a prop)
lag-of-death Jul 5, 2019
d7f5f6e
test: update test snapshots
lag-of-death Jul 5, 2019
74281d2
fix(render-schema): generate proper paths for arrays
P0lip Jul 10, 2019
e7e1624
refactor: move renderers to jse
Jul 10, 2019
2da8036
fix: general divider position issue
Jul 11, 2019
206202e
fix: divider spacing issue
Jul 11, 2019
1d2f58c
Merge branch 'master' of github.com:stoplightio/json-schema-viewer in…
Jul 11, 2019
da52f05
fix: remove unnecessary padding
Jul 11, 2019
bc1ae5d
fix: show "expand" caret (#38)
lag-of-death Jul 11, 2019
f56c95c
chore: update dependency
Jul 11, 2019
0175be6
chore: revert code artifact
Jul 11, 2019
bf334fe
chore: add a todo on useCallback and rowRenderer
lag-of-death Jul 11, 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
16 changes: 16 additions & 0 deletions src/__stories__/JsonSchemaViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { boolean, number, object, select, text, withKnobs } from '@storybook/add
import { storiesOf } from '@storybook/react';
import { JsonSchemaViewer } from '../components';

import { Checkbox } from '@stoplight/ui-kit';
import { JSONSchema4 } from 'json-schema';
import * as allOfSchemaResolved from '../__fixtures__/allOf/allOf-resolved.json';
import * as allOfSchema from '../__fixtures__/allOf/allOf-schema.json';
Expand Down Expand Up @@ -108,4 +109,19 @@ storiesOf('JsonSchemaViewer', module)
onGoToRef={action('onGoToRef')}
/>
</div>
))
.add('with rowRendererRight', () => (
<JsonSchemaViewer
rowRendererRight={() => (
<span style={{ position: 'relative', top: '5px' }}>
<Checkbox />
</span>
)}
name={text('name', 'my schema')}
schema={schema as JSONSchema4}
defaultExpandedDepth={number('defaultExpandedDepth', 2)}
expanded={boolean('expanded', false)}
hideTopBar={boolean('hideTopBar', false)}
onGoToRef={action('onGoToRef')}
/>
));
16 changes: 13 additions & 3 deletions src/components/JsonSchemaViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { runInAction } from 'mobx';
import * as React from 'react';

import { JSONSchema4 } from 'json-schema';
import { GoToRefHandler } from '../types';
import { GoToRefHandler, IExtendableRenderers } from '../types';
import { isSchemaViewerEmpty, renderSchema } from '../utils';
import { SchemaTree } from './SchemaTree';

export type FallbackComponent = React.ComponentType<{ error: Error | null }>;

export interface IJsonSchemaViewer {
export interface IJsonSchemaViewer extends IExtendableRenderers {
schema: JSONSchema4;
dereferencedSchema?: JSONSchema4;
style?: object;
Expand All @@ -22,6 +22,7 @@ export interface IJsonSchemaViewer {
hideTopBar?: boolean;
maxRows?: number;
onGoToRef?: GoToRefHandler;
mergeAllOf?: boolean;
FallbackComponent?: FallbackComponent;
}

Expand All @@ -33,7 +34,16 @@ export class JsonSchemaViewerComponent extends React.PureComponent<IJsonSchemaVi

this.treeStore = new TreeStore({
defaultExpandedDepth: this.expandedDepth,
nodes: Array.from(renderSchema(props.dereferencedSchema || props.schema, 0, { path: [] }, { mergeAllOf: true })),
nodes: Array.from(
renderSchema(
props.dereferencedSchema || props.schema,
0,
{ path: [] },
{
mergeAllOf: props.mergeAllOf === undefined ? true : props.mergeAllOf,
},
),
),
});
}

Expand Down
34 changes: 25 additions & 9 deletions src/components/SchemaRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,27 @@ import get = require('lodash/get');
import map = require('lodash/map');
import size = require('lodash/size');

import { GoToRefHandler, SchemaNodeWithMeta, SchemaTreeListNode } from '../types';
import { GoToRefHandler, IExtendableRenderers, SchemaNodeWithMeta, SchemaTreeListNode } from '../types';
import { isCombiner, isRef } from '../utils';
import { Types } from './';

export interface ISchemaRow {
export interface ISchemaRow extends IExtendableRenderers {
node: SchemaTreeListNode;
rowOptions: IRowRendererOptions;
onGoToRef?: GoToRefHandler;
toggleExpand: () => void;
}

const ICON_SIZE = 12;
const ICON_DIMENSION = 20;
const ROW_OFFSET = 7;

export const SchemaRow: React.FunctionComponent<ISchemaRow> = ({ node, rowOptions, onGoToRef }) => {
export const SchemaRow: React.FunctionComponent<ISchemaRow> = ({
node,
rowOptions,
onGoToRef,
rowRendererRight,
toggleExpand,
}) => {
const schemaNode = node.metadata as SchemaNodeWithMeta;
const { name, $ref, subtype, required } = schemaNode;

Expand Down Expand Up @@ -58,20 +64,22 @@ export const SchemaRow: React.FunctionComponent<ISchemaRow> = ({ node, rowOption
</div>
);

const combinerOffset = ICON_DIMENSION * node.level;
return (
<div className="px-2 flex-1 w-full">
<div onClick={toggleExpand} className="px-6 flex-1 w-full">
{/* Do not set position: relative. Divider must be relative to the parent container in order to avoid bugs related to this container calculated height changes. */}
<div
className="flex items-center text-sm relative"
className="flex items-center text-sm"
style={{
marginLeft: ICON_DIMENSION * node.level, // offset for spacing
marginLeft: combinerOffset,
}}
>
{node.canHaveChildren &&
node.level > 0 && (
<div
className="absolute flex justify-center cursor-pointer p-1 rounded hover:bg-darken-3"
style={{
left: ICON_DIMENSION * -1 + ROW_OFFSET / -2,
left: combinerOffset,
width: ICON_DIMENSION,
height: ICON_DIMENSION,
}}
Expand All @@ -85,7 +93,14 @@ export const SchemaRow: React.FunctionComponent<ISchemaRow> = ({ node, rowOption
)}

{schemaNode.divider && (
<div className="flex items-center w-full absolute" style={{ top: -9, height: 1 }}>
<div
className="flex items-center absolute"
style={{
top: 0,
height: 1,
width: `calc(100% - ${combinerOffset}px - 1.5rem)`,
}}
>
<div className="text-darken-7 dark:text-lighten-8 uppercase text-xs pr-2 -ml-4">{schemaNode.divider}</div>
<div className="flex-1 bg-darken-5 dark:bg-lighten-5" style={{ height: 1 }} />
</div>
Expand Down Expand Up @@ -171,6 +186,7 @@ export const SchemaRow: React.FunctionComponent<ISchemaRow> = ({ node, rowOption
) : (
requiredElem
)}
{rowRendererRight && <div className="ml-2">{rowRendererRight(node)}</div>}
</div>
</div>
);
Expand Down
31 changes: 19 additions & 12 deletions src/components/SchemaTree.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { TreeList, TreeListEvents, TreeStore } from '@stoplight/tree-list';
import { TreeList, TreeStore } from '@stoplight/tree-list';
import * as cn from 'classnames';
import { JSONSchema4 } from 'json-schema';
import { observer } from 'mobx-react-lite';
import * as React from 'react';

import { GoToRefHandler } from '../types';
import { GoToRefHandler, IExtendableRenderers, SchemaTreeListNode } from '../types';
import { SchemaRow } from './';

export interface ISchemaTree {
export interface ISchemaTree extends IExtendableRenderers {
treeStore: TreeStore;
schema: JSONSchema4;
className?: string;
Expand All @@ -24,19 +23,12 @@ const canDrag = () => false;
export const SchemaTree = observer<ISchemaTree>(props => {
const { hideTopBar, name, treeStore, maxRows, className, onGoToRef } = props;

treeStore.on(TreeListEvents.NodeClick, (e, node) => treeStore.toggleExpand(node));

const itemData = {
treeStore,
count: treeStore.nodes.length,
onGoToRef,
};

const rowRenderer = React.useCallback(
(node, rowOptions) => <SchemaRow node={node} rowOptions={rowOptions} {...itemData} />,
[itemData.count],
);

return (
<div className={cn(className, 'flex flex-col h-full w-full')}>
{name &&
Expand All @@ -50,9 +42,24 @@ export const SchemaTree = observer<ISchemaTree>(props => {
striped
maxRows={maxRows !== undefined ? maxRows + 0.5 : maxRows}
store={treeStore}
rowRenderer={rowRenderer}
rowRenderer={(node, rowOptions) => {
// TODO: add a React.useCallback to rerender only when either itemData.count or maskProps (to be found in studio) change

return (
<SchemaRow
toggleExpand={() => {
treeStore.toggleExpand(node);
}}
rowRendererRight={props.rowRendererRight}
node={node as SchemaTreeListNode}
rowOptions={rowOptions}
{...itemData}
/>
);
}}
canDrag={canDrag}
/>
{props.schemaControlsRenderer && props.schemaControlsRenderer()}
</div>
);
});
Expand Down
4 changes: 3 additions & 1 deletion src/components/__tests__/SchemaRow.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ describe('SchemaRow component', () => {
isExpanded: true,
};

const wrapper = shallow(shallow(<SchemaRow node={node as SchemaTreeListNode} rowOptions={rowOptions} />)
const wrapper = shallow(shallow(
<SchemaRow toggleExpand={() => null} node={node as SchemaTreeListNode} rowOptions={rowOptions} />,
)
.find(Popover)
.prop('content') as React.ReactElement);

Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { TreeListNode } from '@stoplight/tree-list';
import { Dictionary, JsonPath } from '@stoplight/types';
import { JSONSchema4, JSONSchema4TypeName } from 'json-schema';

export interface IExtendableRenderers {
rowRendererRight?: (node: SchemaTreeListNode) => React.ReactElement;
schemaControlsRenderer?: () => React.ReactElement;
}

export const enum SchemaKind {
Any = 'any',
String = 'string',
Expand Down