diff --git a/docs/examples/search-by-params.html b/docs/examples/search-by-params.html new file mode 100644 index 00000000..cc4386f5 --- /dev/null +++ b/docs/examples/search-by-params.html @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + +
+
Search by Parameters
+
+ + +
+
+
+ + diff --git a/docs/list.html b/docs/list.html index a7d7246a..6ead9490 100644 --- a/docs/list.html +++ b/docs/list.html @@ -107,8 +107,8 @@
- -
+ +

How To Use

@@ -181,7 +181,7 @@

How To Use

-
+

Branding Ideas

@@ -236,7 +236,7 @@

Branding Ideas

Markdown headings in Navigation
- Optionally include markdown headings to navigation bar + Optionally include markdown headings to navigation bar
@@ -266,7 +266,7 @@

Branding Ideas

Code Samples
- Support for x-code-samples (vendor extension) in endpoint definition + Support for x-code-samples (vendor extension) in endpoint definition
@@ -319,7 +319,14 @@

Branding Ideas

Form Parameters - Dynamic
-
+
+ Search by Parameters +
+ true / false +
+
+ +

OAuth Setup

@@ -366,7 +373,7 @@

OAuth Setup

-
+

Performance Tips

@@ -384,7 +391,7 @@

Performance Tips

-
+

Mix HTML content

@@ -418,8 +425,8 @@

Mix HTML content

Collapsable tags with possibility to change load state (open/closed)
-
- + +
Play Ground diff --git a/src/components/dialog-box.js b/src/components/dialog-box.js new file mode 100644 index 00000000..17082268 --- /dev/null +++ b/src/components/dialog-box.js @@ -0,0 +1,65 @@ +import { html } from 'lit-html'; +import { LitElement } from 'lit-element'; + +import DialogBoxStyles from '@/styles/dialog-box-styles'; + +export default class DialogBox extends LitElement { + static get properties() { + return { + title: { type: String, attribute: 'title' }, + show: { type: Boolean, attribute: 'show' }, + }; + } + + static get styles() { + return [DialogBoxStyles]; + } + + connectedCallback() { + super.connectedCallback(); + if (!this.title) { this.title = 'Modal title'; } + + document.addEventListener('keydown', (e) => { + if (e.code === 'Escape') { + this.onClose(); + } + }); + } + + attributeChangedCallback(name, oldVal, newVal) { + if (oldVal !== newVal) { + if (name === 'title') { + this.title = newVal; + } + + if (name === 'show') { + this.show = newVal; + } + } + } + + render() { + return html` +
+
+
+

${this.title}

+ +
+
+ +
+
+
+ `; + } + + onClose() { + document.dispatchEvent(new CustomEvent('ondialogboxclose', { + bubbles: true, + composed: true, + })); + } +} + +customElements.define('dialog-box', DialogBox); diff --git a/src/rapidoc.js b/src/rapidoc.js index df4c5df3..19e6c5d5 100644 --- a/src/rapidoc.js +++ b/src/rapidoc.js @@ -22,7 +22,7 @@ import TabStyles from '@/styles/tab-styles'; import NavStyles from '@/styles/nav-styles'; import { - pathIsInSearch, invalidCharsRegEx, sleep, rapidocApiKey, + pathIsInSearch, findProperties, invalidCharsRegEx, sleep, rapidocApiKey, } from '@/utils/common-utils'; import ProcessSpec from '@/utils/spec-parser'; import mainBodyTemplate from '@/templates/main-body-template'; @@ -76,6 +76,7 @@ export default class RapiDoc extends LitElement { allowSpecUrlLoad: { type: String, attribute: 'allow-spec-url-load' }, allowSpecFileLoad: { type: String, attribute: 'allow-spec-file-load' }, allowSearch: { type: String, attribute: 'allow-search' }, + allowSearchByParams: { type: String, attribute: 'allow-search-by-params' }, allowServerSelection: { type: String, attribute: 'allow-server-selection' }, showComponents: { type: String, attribute: 'show-components' }, @@ -108,6 +109,7 @@ export default class RapiDoc extends LitElement { // Internal Attributes selectedContentId: { type: String }, + isSearchByPropertiesModalShow: { type: Boolean }, }; } @@ -349,6 +351,7 @@ export default class RapiDoc extends LitElement { this.responseAreaHeight = '300px'; } if (!this.allowTry || !'true, false,'.includes(`${this.allowTry},`)) { this.allowTry = 'true'; } + if (!this.allowSearchByParams || !'true, false,'.includes(`${this.allowSearchByParams},`)) { this.allowSearchByParams = 'false'; } if (!this.apiKeyValue) { this.apiKeyValue = '-'; } if (!this.apiKeyLocation) { this.apiKeyLocation = 'header'; } if (!this.apiKeyName) { this.apiKeyName = ''; } @@ -363,6 +366,7 @@ export default class RapiDoc extends LitElement { if (!this.showInfo || !'true, false,'.includes(`${this.showInfo},`)) { this.showInfo = 'true'; } if (!this.showComponents || !'true false'.includes(this.showComponents)) { this.showComponents = 'false'; } if (!this.infoDescriptionHeadingsInNavBar || !'true, false,'.includes(`${this.infoDescriptionHeadingsInNavBar},`)) { this.infoDescriptionHeadingsInNavBar = 'false'; } + if (!this.isSearchByPropertiesModalShow) { this.isSearchByPropertiesModalShow = false; } marked.setOptions({ highlight: (code, lang) => { @@ -538,6 +542,23 @@ export default class RapiDoc extends LitElement { this.matchPaths = ''; } + onSearchByPropertiesChange(e) { + this.matchProperties = findProperties(e.target.value.toLowerCase(), this.resolvedSpec.tags); + if (this.matchProperties) { + this.requestUpdate(); + } + } + + showSearchModal() { + this.isSearchByPropertiesModalShow = true; + this.requestUpdate(); + } + + hideSearchModal() { + this.isSearchByPropertiesModalShow = false; + this.requestUpdate(); + } + // Public Method async loadSpec(specUrl) { if (!specUrl) { @@ -691,6 +712,7 @@ export default class RapiDoc extends LitElement { } navEl.classList.add('active'); window.history.replaceState(null, null, `${window.location.href.split('#')[0]}#${targetElId}`); + this.hideSearchModal(); setTimeout(() => { this.isIntersectionObserverActive = true; }, 300); diff --git a/src/styles/dialog-box-styles.js b/src/styles/dialog-box-styles.js new file mode 100644 index 00000000..1f2c4e0d --- /dev/null +++ b/src/styles/dialog-box-styles.js @@ -0,0 +1,62 @@ +import { css } from 'lit-element'; + +export default css` + .dialog-box-overlay { + background-color: rgba(0, 0, 0, 0.4); + position: fixed; + z-index: 999; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + } + + .dialog-box { + background-color: white; + margin: 5% auto; + border: 1px solid #888; + width: 60vw; + border-radius: 5px; + } + + .dialog-box-header { + display: flex; + align-items: center; + border-bottom: 1px solid #e4e4e4; + padding: 1rem; + } + + .dialog-box-header button { + font-size: 1.5rem; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .5; + border: none; + background-color: white; + transition: all .2s; + border-radius: 2px; + } + + .dialog-box-header button:hover { + color: white; + background-color: var(--primary-color); + } + + .dialog-box-title { + flex-grow: 1; + } + + h4.dialog-box-title { + margin: 0; + padding: 0; + } + + .dialog-box-content { + padding: 1rem; + max-height: 80vh; + overflow: auto; + } +`; diff --git a/src/styles/input-styles.js b/src/styles/input-styles.js index 7562c480..419d8489 100644 --- a/src/styles/input-styles.js +++ b/src/styles/input-styles.js @@ -27,11 +27,16 @@ export default css` .m-btn.thin-border { border-width: 1px; } .m-btn.large { padding:8px 14px; } .m-btn.small { padding:5px 12px; } +.m-btn.tiny { padding:5px 6px; } .m-btn.circle { border-radius: 50%; } .m-btn:hover { background-color: var(--primary-color); color: var(--primary-color-invert); } +.m-btn.nav { border: 2px solid var(--nav-accent-color); } +.m-btn.nav:hover { + background-color: var(--nav-accent-color); +} .m-btn:disabled{ background-color: var(--bg3); color: var(--fg3); diff --git a/src/templates/header-template.js b/src/templates/header-template.js index 2db7cd43..efb00a75 100644 --- a/src/templates/header-template.js +++ b/src/templates/header-template.js @@ -49,6 +49,15 @@ export default function headerTemplate() {
` } + + ${(this.allowSearch === 'false' || this.allowSearchByParams === 'false' || 'read focused'.includes(this.renderStyle)) + ? '' + : html` + + ` + }
`; } diff --git a/src/templates/main-body-template.js b/src/templates/main-body-template.js index 3f704412..d38ec1fe 100644 --- a/src/templates/main-body-template.js +++ b/src/templates/main-body-template.js @@ -13,6 +13,7 @@ import componentsTemplate from '@/templates/components-template'; import contactInfoTemplate from '@/templates/contact-info-template'; import headerTemplate from '@/templates/header-template'; import navbarTemplate from '@/templates/navbar-template'; +import searchByPropertiesModalTemplate from '@/templates/search-by-properties-modal-template'; import SetTheme from '@/utils/theme'; import { isValidHexColor } from '@/utils/color-utils'; @@ -121,6 +122,8 @@ export default function mainBodyTemplate() { } + + ${this.allowSearchByParams === 'true' ? searchByPropertiesModalTemplate.call(this) : ''} `; diff --git a/src/templates/navbar-template.js b/src/templates/navbar-template.js index 508f7d3b..54bb1594 100644 --- a/src/templates/navbar-template.js +++ b/src/templates/navbar-template.js @@ -12,7 +12,7 @@ export default function navbarTemplate() { ${(this.allowSearch === 'false') ? '' : html` -
+
` } + ${this.allowSearchByParams === 'false' + ? '' + : html` +
+ +
+ ` + } ${html`