Skip to content

Commit 32e8607

Browse files
cassernilott-ai
authored andcommitted
Feat/dark (#22)
* feat: darkmode * fix: tests * fix: allow passing in classname
1 parent 4dc6a5d commit 32e8607

File tree

10 files changed

+106
-56
lines changed

10 files changed

+106
-56
lines changed

src/__stories__/JsonSchemaViewer.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,17 @@ storiesOf('JsonSchemaViewer', module)
9191
hideTopBar={boolean('hideTopBar', false)}
9292
/>
9393
</Wrapper>
94+
))
95+
.add('dark', () => (
96+
<div style={{ height: '100vh' }} className="bp3-dark bg-gray-8">
97+
<Wrapper>
98+
<JsonSchemaViewer
99+
name={text('name', 'my stress schema')}
100+
schema={stressSchema as JSONSchema4}
101+
defaultExpandedDepth={number('defaultExpandedDepth', 2)}
102+
expanded={boolean('expanded', false)}
103+
hideTopBar={boolean('hideTopBar', false)}
104+
/>
105+
</Wrapper>
106+
</div>
94107
));

src/__stories__/_styles.scss

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
@import "~@stoplight/tree-list/styles/_tree-list.scss";
2-
@import "~@stoplight/ui-kit/styles/_ui-kit.scss";
1+
@import '../styles/json-schema-viewer';
2+
3+
@import '~@stoplight/tree-list/styles/_tree-list.scss';
4+
@import '~@stoplight/ui-kit/styles/_ui-kit.scss';

src/__stories__/utils/Wrapper.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react';
22

33
export const Wrapper: React.FunctionComponent<React.HTMLAttributes<HTMLElement>> = ({ children, ...props }) => {
44
return (
5-
<div style={{ margin: '200px auto', width: '80vw' }}>
5+
<div style={{ padding: '200px auto' }}>
66
<div
77
// @ts-ignore
88
style={{

src/components/JsonSchemaViewer.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { TreeStore } from '@stoplight/tree-list';
2+
import * as cn from 'classnames';
23
import { runInAction } from 'mobx';
34
import * as React from 'react';
45
import ErrorBoundary, { ErrorBoundaryProps, FallbackProps } from 'react-error-boundary';
@@ -62,15 +63,24 @@ export class JsonSchemaViewerComponent extends React.PureComponent<IJsonSchemaVi
6263

6364
public render() {
6465
const {
65-
props: { emptyText = 'No schema defined', name, schema, expanded, defaultExpandedDepth, ...props },
66+
props: { emptyText = 'No schema defined', name, schema, expanded, defaultExpandedDepth, className, ...props },
6667
} = this;
6768

6869
// an empty array or object is still a valid response, schema is ONLY really empty when a combiner type has no information
6970
if (isSchemaViewerEmpty(schema)) {
7071
return <div>{emptyText}</div>;
7172
}
7273

73-
return <SchemaTree expanded={expanded} name={name} schema={schema} treeStore={this.treeStore} {...props} />;
74+
return (
75+
<SchemaTree
76+
className={cn('JsonSchemaViewer', className)}
77+
expanded={expanded}
78+
name={name}
79+
schema={schema}
80+
treeStore={this.treeStore}
81+
{...props}
82+
/>
83+
);
7484
}
7585
}
7686

src/components/SchemaRow.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,19 @@ export const SchemaRow: React.FunctionComponent<ISchemaRow> = ({ node, treeStore
3939
const validationCount = Object.keys(nodeValidations).length;
4040

4141
const requiredElem = (
42-
<span className={cn(required ? 'font-semibold' : 'text-darken-7')}>
42+
<span className={cn(required ? 'font-medium' : 'text-darken-7 dark:text-lighten-6')}>
4343
{required ? 'required' : 'optional'}
4444
{validationCount ? `+${validationCount}` : ''}
4545
</span>
4646
);
4747

4848
return (
49-
<div className="flex-1 flex items-center" style={{ marginLeft: ROW_OFFSET, marginRight: ROW_OFFSET }}>
49+
<div
50+
className="flex-1 flex items-center overflow-hidden"
51+
style={{ marginLeft: ROW_OFFSET, marginRight: ROW_OFFSET }}
52+
>
5053
<div
51-
className="flex flex-1 items-center text-sm leading-tight w-full h-full relative"
54+
className="flex flex-1 items-center text-sm leading-tight w-full h-full relative overflow-hidden"
5255
style={{
5356
marginLeft: ICON_DIMENSION * node.level, // offset for spacing
5457
}}
@@ -73,10 +76,13 @@ export const SchemaRow: React.FunctionComponent<ISchemaRow> = ({ node, treeStore
7376

7477
{schemaNode.divider && (
7578
<div className="flex items-center w-full absolute" style={{ top: -9, height: 1 }}>
76-
<div className="font-medium text-darken-7 pr-2 uppercase text-xs" style={{ marginLeft: -10 }}>
79+
<div
80+
className="font-medium text-darken-7 dark:text-lighten-7 pr-2 uppercase text-xs"
81+
style={{ marginLeft: -10 }}
82+
>
7783
{schemaNode.divider}
7884
</div>
79-
<div className="flex-1 bg-darken-5" style={{ height: 1 }} />
85+
<div className="flex-1 bg-darken-5 dark:bg-lighten-5" style={{ height: 1 }} />
8086
</div>
8187
)}
8288

@@ -88,17 +94,21 @@ export const SchemaRow: React.FunctionComponent<ISchemaRow> = ({ node, treeStore
8894
{type === '$ref' ? `[${$ref}]` : null}
8995
</Types>
9096

91-
{node.canHaveChildren && <span className="ml-2 text-darken-7">{`{${childrenCount}}`}</span>}
97+
{node.canHaveChildren && (
98+
<span className="ml-2 text-darken-7 dark:text-lighten-6">{`{${childrenCount}}`}</span>
99+
)}
92100

93101
{'pattern' in schemaNode && schemaNode.pattern ? (
94-
<span className="text-darken-7 ml-2">(pattern property)</span>
102+
<span className="text-darken-7 dark:text-lighten-6 ml-2">(pattern property)</span>
95103
) : null}
96104

97105
{description && (
98106
<Popover
99107
boundary="window"
100108
interactionKind="hover"
101-
target={<span className="ml-2 text-darken-7">{description}</span>}
109+
className="overflow-hidden JSV--Popover"
110+
targetClassName="overflow-hidden block"
111+
target={<div className="ml-2 text-darken-7 dark:text-lighten-6 truncate">{description}</div>}
102112
content={
103113
<div className="p-5" style={{ maxHeight: 500, maxWidth: 400 }}>
104114
<MarkdownViewer markdown={description} />

src/components/Type.tsx

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/components/Types.tsx

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
1+
import { Dictionary } from '@stoplight/types';
12
import cn from 'classnames';
23
import { JSONSchema4TypeName } from 'json-schema';
34
import * as React from 'react';
5+
46
import { ITreeNodeMeta, JSONSchema4CombinerName } from '../types';
5-
import { Type } from './Type';
67

8+
/**
9+
* TYPE
10+
*/
11+
export interface IType {
12+
type: JSONSchema4TypeName | JSONSchema4CombinerName | 'binary' | '$ref';
13+
subtype?: ITreeNodeMeta['subtype'];
14+
className?: string;
15+
}
16+
17+
export const Type: React.FunctionComponent<IType> = ({ className, children, type, subtype }) => {
18+
return (
19+
<span className={cn(className, PropertyTypeColors[type])}>
20+
{type === 'array' && subtype && subtype !== 'array' ? `array[${subtype}]` : type}
21+
22+
{children}
23+
</span>
24+
);
25+
};
26+
Type.displayName = 'JsonSchemaViewer.Type';
27+
28+
/**
29+
* TYPES
30+
*/
731
interface ITypes {
832
className?: string;
933
type?: JSONSchema4TypeName | JSONSchema4TypeName[] | JSONSchema4CombinerName | '$ref';
@@ -18,14 +42,14 @@ export const Types: React.FunctionComponent<ITypes> = ({ className, type, subtyp
1842
}
1943

2044
return (
21-
<div className={cn(className, 'truncate')}>
45+
<div className={cn(className, 'overflow-hidden')}>
2246
<>
2347
{type.map((name, i, { length }) => (
2448
<React.Fragment key={i}>
2549
<Type key={i} type={name} subtype={subtype} />
2650

2751
{i < length - 1 && (
28-
<span key={`${i}-sep`} className="text-darken-7">
52+
<span key={`${i}-sep`} className="text-darken-7 dark:text-lighten-6">
2953
{' or '}
3054
</span>
3155
)}
@@ -36,3 +60,22 @@ export const Types: React.FunctionComponent<ITypes> = ({ className, type, subtyp
3660
);
3761
};
3862
Types.displayName = 'JsonSchemaViewer.Types';
63+
64+
/**
65+
* HELPERS
66+
*/
67+
export const PropertyTypeColors: Dictionary<string, IType['type']> = {
68+
object: 'text-blue-6',
69+
any: 'text-blue-5',
70+
array: 'text-green-6',
71+
allOf: 'text-orange-5',
72+
oneOf: 'text-orange-5',
73+
anyOf: 'text-orange-5',
74+
null: 'text-orange-5',
75+
integer: 'text-red-7',
76+
number: 'text-red-7',
77+
boolean: 'text-red-4',
78+
binary: 'text-green-4',
79+
string: 'text-green-7',
80+
$ref: 'text-purple-6',
81+
};

src/components/__tests__/Type.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { shallow } from 'enzyme';
22
import 'jest-enzyme';
33
import * as React from 'react';
4-
import { IType, PropertyTypeColors, Type } from '../Type';
4+
import { IType, PropertyTypeColors, Type } from '../Types';
55

66
describe('Type component', () => {
77
it.each(Object.keys(PropertyTypeColors))('should handle $s type', type => {

src/components/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export * from './JsonSchemaViewer';
22
export * from './SchemaRow';
33
export * from './SchemaTree';
4-
export * from './Type';
54
export * from './Types';
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@import '~@stoplight/ui-kit/styles/common/theme';
2+
3+
.JsonSchemaViewer {
4+
.JSV--Popover {
5+
overflow: hidden;
6+
7+
.#{$ns}-popover-target {
8+
display: block !important;
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)