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 @@
+
+
+
+
+
+
+
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`
+
+ `;
+ }
+
+ 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() {
}