diff --git a/demo/index.html b/demo/index.html
index ccd41077..0c4ccf2c 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -12,9 +12,11 @@
+
-
+
diff --git a/demo/main.css b/demo/main.css
index af3c136d..02ec91ec 100644
--- a/demo/main.css
+++ b/demo/main.css
@@ -105,6 +105,13 @@ nav {
box-sizing: border-box;
}
+nav iframe {
+ margin: 10px 0;
+ position: absolute;
+ right: 0;
+ top: 0;
+}
+
@media (min-width: 1000px) {
nav header {
position: absolute;
@@ -118,4 +125,8 @@ nav {
nav header {
display: none;
}
+
+ nav iframe {
+ display: none;
+ }
}
diff --git a/docs/redoc-vendor-extensions.md b/docs/redoc-vendor-extensions.md
index 5a6bee90..ab5d54ec 100644
--- a/docs/redoc-vendor-extensions.md
+++ b/docs/redoc-vendor-extensions.md
@@ -18,7 +18,7 @@ The information about API logo
| Field Name | Type | Description |
| :-------------- | :------: | :---------- |
| url | string | The URL pointing to the spec logo. MUST be in the format of a URL
-| backgroundColor | string | background color to be used. MUST be in [CSS color syntax](https://developer.mozilla.org/en/docs/Web/CSS/color) |
+| backgroundColor | string | background color to be used. MUST be RGB color in [hexadecimal format] (https://en.wikipedia.org/wiki/Web_colors#Hex_triplet)
###### x-logo example
@@ -30,7 +30,7 @@ json
"title": "Swagger Petstore",
"x-logo": {
"url": "https://rebilly.github.io/ReDoc/petstore-logo.png",
- "backgroundColor": "white"
+ "backgroundColor": "#FFFFFF"
}
}
}
@@ -42,7 +42,7 @@ info:
title: "Swagger Petstore"
x-logo:
url: "https://rebilly.github.io/ReDoc/petstore-logo.png"
- backgroundColor: "white"
+ backgroundColor: "#FFFFFF"
```
diff --git a/lib/common/components/DropDown/dropdown.js b/lib/common/components/DropDown/dropdown.js
new file mode 100644
index 00000000..7ce695f4
--- /dev/null
+++ b/lib/common/components/DropDown/dropdown.js
@@ -0,0 +1,37 @@
+'use strict';
+
+import {Component, EventEmitter, ElementRef} from 'angular2/core';
+import {CORE_DIRECTIVES} from 'angular2/common';
+import DropKick from 'Robdel12/DropKick';
+import 'Robdel12/DropKick/build/css/dropkick.css!css';
+
+@Component({
+ selector: 'dropdown',
+ events: ['change'],
+ template: `
+
+ `,
+ directives: [CORE_DIRECTIVES],
+ styleUrls: ['./lib/common/components/DropDown/dropdown.css']
+})
+@Reflect.metadata('parameters', [[ElementRef]])
+export class DropDown {
+ constructor(elem) {
+ this.change = new EventEmitter();
+ this.elem = elem.nativeElement;
+ }
+
+ ngAfterContentInit() {
+ this.inst = new DropKick(this.elem.firstElementChild, {autoWidth: true});
+ }
+
+ onChange(value) {
+ this.change.next(value);
+ }
+
+ destroy() {
+ this.inst.dispose();
+ }
+}
diff --git a/lib/common/components/DropDown/dropdown.scss b/lib/common/components/DropDown/dropdown.scss
new file mode 100644
index 00000000..d9d2ef4b
--- /dev/null
+++ b/lib/common/components/DropDown/dropdown.scss
@@ -0,0 +1,70 @@
+@import '../../styles/variables';
+
+$silver: #666D71;
+$background-silver: #EEEFEF;
+$border: darken($background-silver, 2%);
+
+:host {
+ .dk-select {
+ max-width: 100%;
+ font-family: $headers-font;
+ }
+
+ .dk-selected:after {
+ display: none;
+ }
+
+ // button
+
+ .dk-selected {
+ color: $silver;
+ border-color: $silver;
+ padding: 0.4em 0.9em 0.4em 0.4em;
+ border-radius: 0.4rem;
+ }
+
+ .dk-select-open-down .dk-selected {
+ border-radius: 0.4rem;
+ }
+
+ .dk-select-open-down .dk-selected, .dk-selected:focus, .dk-selected:hover {
+ border-color: $primary-color;
+ color: $primary-color;
+ }
+
+ // tick
+ .dk-selected:before {
+ border-top-color: $silver;
+ border-width: .35em .35em 0;
+ }
+
+ .dk-select-open-down .dk-selected:before,
+ .dk-select-open-up .dk-selected:before {
+ border-bottom-color: $primary-color;
+ border-width: 0 .35em .35em;
+ }
+
+ // items
+ .dk-select-multi:focus .dk-select-options,
+ .dk-select-open-down .dk-select-options,
+ .dk-select-open-up .dk-select-options {
+ border-color: $silver;
+ }
+
+ .dk-select-options {
+ margin-top: 0.2em;
+ border-radius: 0.4em;
+ }
+
+ .dk-option {
+ color: $black;
+ padding: 0.4em 0.4em;
+ &:hover {
+ background-color: $background-silver;
+ }
+ }
+
+ .dk-option-selected {
+ background-color: $background-silver;
+ }
+}
diff --git a/lib/components/JsonSchema/json-schema-lazy.js b/lib/components/JsonSchema/json-schema-lazy.js
index 8992cda9..47a98624 100644
--- a/lib/components/JsonSchema/json-schema-lazy.js
+++ b/lib/components/JsonSchema/json-schema-lazy.js
@@ -14,7 +14,7 @@ var cache = {};
@Component({
selector: 'json-schema-lazy',
- inputs: ['pointer', 'auto'],
+ inputs: ['pointer', 'auto', 'skipReadOnly'],
template: '',
directives: [CORE_DIRECTIVES]
})
@@ -38,7 +38,7 @@ export default class JsonSchemaLazy {
if (this.loaded) return;
if (this.pointer) {
this.dcl.loadNextToLocation(JsonSchema, this.elementRef).then((compRef) => {
- compRef.instance.pointer = this.pointer;
+ this.initComponent(compRef);
// trigger change detection
compRef.hostView.changeDetectorRef.detectChanges();
});
@@ -58,7 +58,7 @@ export default class JsonSchemaLazy {
// FIXME: get rid of dependency on selector
if ($element.querySelector('.discriminator-wrap')) {
this.dcl.loadNextToLocation(JsonSchema, this.elementRef).then((compRef) => {
- compRef.instance.pointer = this.pointer;
+ this.initComponent(compRef);
compRef.hostView.changeDetectorRef.markForCheck();
});
return;
@@ -68,13 +68,18 @@ export default class JsonSchemaLazy {
});
} else {
cache[this.pointer] = this.dcl.loadNextToLocation(JsonSchema, this.elementRef).then((compRef) => {
- compRef.instance.pointer = this.pointer;
+ this.initComponent(compRef);
compRef.hostView.changeDetectorRef.markForCheck();
return compRef;
});
}
}
+ initComponent(compRef) {
+ compRef.instance.pointer = this.pointer;
+ compRef.instance.skipReadOnly = this.skipReadOnly;
+ }
+
ngAfterViewInit() {
if (!this.auto) return;
this.loadCached();
diff --git a/lib/components/JsonSchema/json-schema.html b/lib/components/JsonSchema/json-schema.html
index e764f016..f633f901 100644
--- a/lib/components/JsonSchema/json-schema.html
+++ b/lib/components/JsonSchema/json-schema.html
@@ -22,24 +22,24 @@
{{prop._range}}
Required
-
+
{{enumItem.val | json}}
This field value determines the exact schema:
-
+
+
+
-
+
|
@@ -47,7 +47,8 @@
-
+
|
diff --git a/lib/components/JsonSchema/json-schema.js b/lib/components/JsonSchema/json-schema.js
index 05e964af..6e5687df 100644
--- a/lib/components/JsonSchema/json-schema.js
+++ b/lib/components/JsonSchema/json-schema.js
@@ -3,15 +3,15 @@
import {ElementRef} from 'angular2/core';
import {RedocComponent, BaseComponent, SchemaManager} from '../base';
-import {Tabs, Tab} from '../../common/components/Tabs/tabs';
+import {DropDown} from '../../common/components/DropDown/dropdown';
import JsonPointer from '../../utils/JsonPointer';
@RedocComponent({
selector: 'json-schema',
templateUrl: './lib/components/JsonSchema/json-schema.html',
styleUrls: ['./lib/components/JsonSchema/json-schema.css'],
- directives: [JsonSchema, Tabs, Tab],
- inputs: ['isArray', 'final', 'nestOdd', 'childFor']
+ directives: [JsonSchema, DropDown],
+ inputs: ['isArray', 'final', 'nestOdd', 'childFor', 'skipReadOnly']
})
@Reflect.metadata('parameters', [[SchemaManager], [ElementRef]])
export default class JsonSchema extends BaseComponent {
@@ -21,8 +21,9 @@ export default class JsonSchema extends BaseComponent {
this.final = false;
}
- selectDerived(subClass) {
- if (subClass.active) return;
+ selectDerived(subClassIdx) {
+ let subClass = this.schema.derived[subClassIdx];
+ if (!subClass || subClass.active) return;
this.schema.derived.forEach((subSchema) => {
subSchema.active = false;
});
@@ -62,7 +63,23 @@ export default class JsonSchema extends BaseComponent {
}
this.schema = schema;
- if (schema.derived.length) this.selectDerived(schema.derived[0]);
+ this.initDerived();
+ }
+
+ initDerived() {
+ if (!this.schema.derived.length) return;
+ let enumArr = this.schema.properties[this.schema.properties.length - 1].enum;
+ if (enumArr) {
+ let enumOrder = {};
+ enumArr.forEach((enumItem, idx) => {
+ enumOrder[enumItem.val] = idx;
+ });
+
+ this.schema.derived.sort((a, b) => {
+ return enumOrder[a.name] > enumOrder[b.name];
+ });
+ }
+ this.selectDerived(0);
}
prepareObjectPropertiesData(schema) {
@@ -74,7 +91,8 @@ export default class JsonSchema extends BaseComponent {
let discriminatorFieldIdx = -1;
let props = Object.keys(schema.properties).map((prop, idx) => {
let propertySchema = schema.properties[prop];
- let propPointer = JsonPointer.join(schema._pointer || this.pointer, ['properties', prop]);
+ let propPointer = propertySchema._pointer ||
+ JsonPointer.join(schema._pointer || this.pointer, ['properties', prop]);
propertySchema = JsonSchema.injectPropertyData(propertySchema, prop, propPointer);
// stop endless discriminator recursion
if (propertySchema._pointer === this.childFor) {
@@ -84,10 +102,12 @@ export default class JsonSchema extends BaseComponent {
propertySchema.isDiscriminator = (schema.discriminator === prop);
if (propertySchema.isDiscriminator) {
discriminatorFieldIdx = idx;
- propertySchema.enum = null;
}
return propertySchema;
});
+ if (this.skipReadOnly) {
+ props = props.filter(prop => !prop.readOnly);
+ }
// Move discriminator field to the end of properties list
if (discriminatorFieldIdx > -1) {
let discrProp = props.splice(discriminatorFieldIdx, 1);
@@ -205,5 +225,22 @@ const injectors = {
injectTo._range = range;
}
}
+ },
+ string: {
+ check: propertySchema => (propertySchema.type === 'string'),
+ inject: (injectTo, propertySchema = injectTo) => {
+ var range;
+ if (propertySchema.minLength && propertySchema.maxLength) {
+ range = `[ ${propertySchema.minLength} .. ${propertySchema.maxLength} ]`;
+ } else if (propertySchema.maxLength) {
+ range = '<= ' + propertySchema.maxLength;
+ } else if (propertySchema.minimum) {
+ range = '>= ' + propertySchema.minLength;
+ }
+
+ if (range) {
+ injectTo._range = range + ' characters';
+ }
+ }
}
};
diff --git a/lib/components/ParamsList/params-list.html b/lib/components/ParamsList/params-list.html
index faaf4a55..bdffe020 100644
--- a/lib/components/ParamsList/params-list.html
+++ b/lib/components/ParamsList/params-list.html
@@ -31,7 +31,7 @@
-
+
diff --git a/lib/components/base.js b/lib/components/base.js
index fd5a0ef4..2e7895bf 100644
--- a/lib/components/base.js
+++ b/lib/components/base.js
@@ -192,12 +192,19 @@ export class BaseComponent {
if (into.type === 'object' && subSchema.properties) {
into.properties || (into.properties = {});
Object.assign(into.properties, subSchema.properties);
+ Object.keys(subSchema.properties).forEach(propName => {
+ if (!subSchema.properties[propName]._pointer) {
+ subSchema.properties[propName]._pointer = subSchema._pointer ?
+ JsonPointer.join(subSchema._pointer, ['properties', propName]) : null;
+ }
+ });
}
if (into.type === 'object' && subSchema.required) {
into.required || (into.required = []);
into.required.push(...subSchema.required);
}
-
+ // don't merge _pointer
+ subSchema._pointer = null;
defaults(into, subSchema);
}
into.allOf = null;
diff --git a/package.json b/package.json
index 38e974ba..91fade42 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "redoc",
"description": "Swagger-generated API Reference Documentation",
- "version": "0.7.12",
+ "version": "0.7.13",
"repository": {
"type": "git",
"url": "git://github.com/Rebilly/ReDoc"
@@ -33,6 +33,7 @@
"jspm": {
"configFile": "system.config.js",
"dependencies": {
+ "Robdel12/DropKick": "github:Robdel12/DropKick@^2.1.7",
"angular2": "npm:angular2@^2.0.0-beta.12",
"es6-shim": "github:es-shims/es6-shim@^0.33.6",
"hint.css": "npm:hint.css@^2.2.1",
@@ -53,6 +54,11 @@
"core-js": "npm:core-js@^1.2.6",
"css": "github:systemjs/plugin-css@^0.1.18",
"systemjs/plugin-json": "github:systemjs/plugin-json@^0.1.0"
+ },
+ "overrides": {
+ "github:Robdel12/DropKick@2.1.7": {
+ "format": "global"
+ }
}
},
"devDependencies": {
diff --git a/system.config.js b/system.config.js
index 3a9ecf1d..dca27285 100644
--- a/system.config.js
+++ b/system.config.js
@@ -37,6 +37,7 @@ System.config({
},
map: {
+ "Robdel12/DropKick": "github:Robdel12/DropKick@2.1.7",
"angular2": "npm:angular2@2.0.0-beta.12",
"babel": "npm:babel-core@5.8.34",
"babel-runtime": "npm:babel-runtime@5.8.34",