Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"esmodules",
"exportparts",
"kyleshockey",
"labelledby",
"prismjs",
"randombytes",
"rapidoc",
Expand Down
28 changes: 16 additions & 12 deletions src/components/api-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ export default class ApiRequest extends LitElement {
return keyed(id, html`
<div id="api-request-${id}"
class="api-request col regular-font request-panel ${(this.renderStyle === 'focused' || this.callback === 'true') ? 'focused-mode' : 'view-mode'}">
<div class=" ${this.callback === 'true' ? 'tiny-title' : 'req-res-title'} ">
${this.callback === 'true' ? 'CALLBACK REQUEST' : getI18nText('operations.request')}
<div class=" ${this.callback === 'true' ? 'tiny-title' : 'req-res-title'} " role="heading" aria-level="${this.renderStyle === 'focused' ? 3 : 4}">
${this.callback === 'true' ? getI18nText('operations.callback-request') : getI18nText('operations.request')}
</div>
<div>
${this.inputParametersTemplate('path')}
Expand Down Expand Up @@ -127,10 +127,10 @@ export default class ApiRequest extends LitElement {
}

const title = {
path: 'PATH PARAMETERS',
query: 'QUERY-STRING PARAMETERS',
header: 'REQUEST HEADERS',
cookie: 'COOKIES'
path: getI18nText('parameters.path'),
query: getI18nText('parameters.string'),
header: getI18nText('parameters.headers'),
cookie: getI18nText('parameters.cookies')
}[paramLocation];

const tableRows = [];
Expand Down Expand Up @@ -158,7 +158,7 @@ export default class ApiRequest extends LitElement {
return html`
<tr>
<td colspan="1" style="width:160px; min-width:50px; vertical-align: top">
<div class="param-name ${generatedParamSchema.deprecated ? 'deprecated' : ''}" style="margin-top: 1rem;">
<div class="param-name ${generatedParamSchema.deprecated ? 'deprecated' : ''}" style="margin-top: 1rem;" id="request-${paramName}-label">
${paramName}${!generatedParamSchema.deprecated && paramRequired ? html`<span style='color:var(--red);'>*</span>` : ''}
</div>
<div class="param-type" style="margin-bottom: 1rem;">
Expand All @@ -175,6 +175,7 @@ export default class ApiRequest extends LitElement {
<tag-input class="request-param"
autocomplete="on"
id = "request-param-${paramName}"
aria-labelledby = "request-${paramName}-label"
style = "width:100%;"
data-ptype = "${paramLocation}"
data-pname = "${paramName}"
Expand All @@ -190,6 +191,7 @@ export default class ApiRequest extends LitElement {
<textarea
autocomplete="on"
id = "request-param-${paramName}"
aria-labelledby = "request-${paramName}-label"
@input="${() => { this.computeCurlSyntax(); }}"
class = "textarea small request-param"
part = "textarea small textarea-param"
Expand Down Expand Up @@ -219,6 +221,7 @@ export default class ApiRequest extends LitElement {
<input type="${generatedParamSchema.format === 'password' ? 'password' : 'text'}" spellcheck="false" style="width:100%; margin-top: 1rem; margin-bottom: 1rem;"
autocomplete="on"
id="request-param-${paramName}"
aria-labelledby = "request-${paramName}-label"
@input="${() => { this.computeCurlSyntax(); }}"
placeholder="${generatedParamSchema.example || defaultVal || ''}"
class="request-param"
Expand Down Expand Up @@ -493,6 +496,7 @@ export default class ApiRequest extends LitElement {
@input="${() => { this.computeCurlSyntax(); }}"
class = "textarea request-body-param-user-input"
part = "textarea textarea-param"
aria-label = "${getI18nText('operations.request-body')}"
spellcheck = "false"
data-ptype = "${reqBody.mimeType}"
data-default = "${displayedBodyExample.exampleFormat === 'text' ? displayedBodyExample.exampleValue : JSON.stringify(displayedBodyExample.exampleValue, null, 8)}"
Expand Down Expand Up @@ -582,9 +586,9 @@ export default class ApiRequest extends LitElement {
${reqBodySchemaHtml || reqBodyDefaultHtml
? html`
<div class="tab-panel col" style="border-width:0 0 1px 0;">
<div class="tab-buttons row" @click="${(e) => { if (e.target.tagName.toLowerCase() === 'button') { this.activeSchemaTab = e.target.dataset.tab; } }}">
<button class="tab-btn ${this.activeSchemaTab === 'model' ? 'active' : ''}" data-tab="model" >${getI18nText('operations.model')}</button>
<button class="tab-btn ${this.activeSchemaTab !== 'model' ? 'active' : ''}" data-tab="body">${bodyTabNameUseBody ? getI18nText('operations.body') : getI18nText('operations.form')}</button>
<div class="tab-buttons row" role="group" @click="${(e) => { if (e.target.tagName.toLowerCase() === 'button') { this.activeSchemaTab = e.target.dataset.tab; } }}">
<button class="tab-btn ${this.activeSchemaTab === 'model' ? 'active' : ''}" aria-current="${this.activeSchemaTab === 'model'}" data-tab="model" >${getI18nText('operations.model')}</button>
<button class="tab-btn ${this.activeSchemaTab !== 'model' ? 'active' : ''}" aria-current="${this.activeSchemaTab !== 'model'}" data-tab="body">${bodyTabNameUseBody ? getI18nText('operations.body') : getI18nText('operations.form')}</button>
</div>
${html`<div class="tab-content col" style="display: ${this.activeSchemaTab === 'model' ? 'block' : 'none'}"> ${reqBodySchemaHtml}</div>`}
${html`<div class="tab-content col" style="display: ${this.activeSchemaTab === 'model' ? 'none' : 'block'}"> ${reqBodyDefaultHtml}</div>`}
Expand Down Expand Up @@ -620,7 +624,7 @@ export default class ApiRequest extends LitElement {
</div>` : ''
}
<div style="flex:1"></div>
${!hasResponse ? '' : html`<button class="m-btn" part="btn btn-outline" @click="${this.clearResponseData}">CLEAR RESPONSE</button>`}
${!hasResponse ? '' : html`<button class="m-btn" part="btn btn-outline" @click="${this.clearResponseData}">${getI18nText('operations.clear-response')}</button>`}
</div>
<div class="tab-panel col" style="border-width:0 0 1px 0;">
<div id="tab_buttons" class="tab-buttons row" @click="${(e) => {
Expand All @@ -629,7 +633,7 @@ export default class ApiRequest extends LitElement {
}}">
<br>
<div style="width: 100%">
<button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab = 'curl'>REQUEST</button>
<button class="tab-btn ${!hasResponse || this.activeResponseTab === 'curl' ? 'active' : ''}" data-tab = 'curl'>${getI18nText('operations.request')}</button>
${!hasResponse ? '' : html`
<button class="tab-btn ${this.activeResponseTab === 'response' ? 'active' : ''}" data-tab = 'response'>${getI18nText('operations.response')}</button>
<button class="tab-btn ${this.activeResponseTab === 'headers' ? 'active' : ''}" data-tab = 'headers'>${getI18nText('operations.response-headers')}</button>`
Expand Down
13 changes: 7 additions & 6 deletions src/components/api-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ export default class ApiResponse extends LitElement {
render() {
return html`
<div class="col regular-font response-panel ${this.renderStyle}-mode">
<div class=" ${this.callback === 'true' ? 'tiny-title' : 'req-res-title'} ">
${this.callback === 'true' ? 'CALLBACK RESPONSE' : getI18nText('operations.response')}
<div class=" ${this.callback === 'true' ? 'tiny-title' : 'req-res-title'} " role="heading" aria-level="${this.renderStyle === 'focused' ? 3 : 4}">
${this.callback === 'true' ? getI18nText('operations.callback-response') : getI18nText('operations.response')}
</div>
<div>
${this.responseTemplate()}
Expand Down Expand Up @@ -158,7 +158,7 @@ export default class ApiResponse extends LitElement {
this.headersForEachRespStatus[statusCode] = tempHeaders;
this.mimeResponsesForEachStatus[statusCode] = allMimeResp;
}
return html`<div class='row' style='flex-wrap:wrap'>
return html`<div class='row' style='flex-wrap:wrap' role="group">
${Object.keys(this.responses).map((respStatus) => html`
${respStatus === '$$ref' // Swagger-Client parser creates '$$ref' object if JSON references are used to create responses - this should be ignored
? ''
Expand All @@ -172,6 +172,7 @@ export default class ApiResponse extends LitElement {
this.selectedMimeType = undefined;
}
}}"
aria-current="${this.selectedStatus === respStatus}"
class='m-btn small ${this.selectedStatus === respStatus ? 'primary' : ''}'
part="btn--resp ${this.selectedStatus === respStatus ? 'btn-fill--resp' : 'btn-outline--resp'} btn-response-status"
style='margin: 8px 4px 0 0; text-transform: capitalize'>
Expand All @@ -194,9 +195,9 @@ export default class ApiResponse extends LitElement {
? ''
: html`
<div class="tab-panel col">
<div class="tab-buttons row" @click="${(e) => { if (e.target.tagName.toLowerCase() === 'button') { this.activeSchemaTab = e.target.dataset.tab; } }}" >
<button class="tab-btn ${this.activeSchemaTab === 'model' ? 'active' : ''}" data-tab='model'>${getI18nText('operations.model')}</button>
<button class="tab-btn ${this.activeSchemaTab !== 'model' ? 'active' : ''}" data-tab='body'>${getI18nText('operations.example')}</button>
<div class="tab-buttons row" role="group" @click="${(e) => { if (e.target.tagName.toLowerCase() === 'button') { this.activeSchemaTab = e.target.dataset.tab; } }}" >
<button class="tab-btn ${this.activeSchemaTab === 'model' ? 'active' : ''}" aria-current="${this.activeSchemaTab === 'model'}" data-tab='model'>${getI18nText('operations.model')}</button>
<button class="tab-btn ${this.activeSchemaTab !== 'model' ? 'active' : ''}" aria-current="${this.activeSchemaTab !== 'model'}" data-tab='body'>${getI18nText('operations.example')}</button>
<div style="flex:1"></div>
${Object.keys(this.mimeResponsesForEachStatus[status]).length === 1
? html`<span class='small-font-size gray-text' style='align-self:center; margin-top:8px;'> ${Object.keys(this.mimeResponsesForEachStatus[status])[0]} </span>`
Expand Down
22 changes: 20 additions & 2 deletions src/languages/en.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
export default {
translation: {
'menu': {
'menu': 'API Menu',
'filter': 'Filter',
'search': 'Search',
'overview': 'Overview',
'api-servers': 'API Servers',
'authentication': 'Authentication',
'operations': 'OPERATIONS',
'components': 'COMPONENTS',
'schemas': 'Schemas'
'schemas': 'Schemas',
'callbacks': 'CALLBACKS'
},
'headers': {
'api-servers': 'API SERVER',
Expand All @@ -23,6 +25,7 @@ export default {
'selected': 'SELECTED'
},
'authentication': {
'auth-header': 'Authorization header',
'no-api-key-applied': 'No API key applied',
'http-basic': 'HTTP Basic',
'http-basic-desc': 'Sends the <code>Authorization header</code> containing the token type <code>Basic</code> followed by the base64 encoded <code>username:password</code> string.',
Expand All @@ -31,10 +34,15 @@ export default {
'requires': 'Requires',
'http-basic-note': 'Base 64 encoded username:password',
'in-auth-header': 'in Authorization header',
'set': 'SET'
'set': 'SET',
'remove': 'REMOVE',
'clear': 'CLEAR ALL API KEYS',
'update': 'UPDATE',
'get': 'GET TOKEN'
},
'operations': {
'request': 'REQUEST',
'callback-request': 'CALLBACK REQUEST',
'request-body': 'REQUEST BODY',
'model': 'MODEL',
'body': 'BODY',
Expand All @@ -46,11 +54,21 @@ export default {
'response': 'RESPONSE',
'response-headers': 'RESPONSE HEADERS',
'example': 'EXAMPLE',
'webhook': 'WEBHOOK',
'deprecated': 'DEPRECATED',
'callback-response': 'CALLBACK RESPONSE',
'response-status': 'Response Status',
'fetch-fail': 'Failed to fetch (Check the browser network tab for more information.)',
'copy': 'Copy',
'copied': 'Copied'
},
'parameters': {
path: 'PATH PARAMETERS',
string: 'QUERY-STRING PARAMETERS',
headers: 'REQUEST HEADERS',
cookies: 'COOKIES',
samples: 'CODE SAMPLES'
},
'schemas': {
'collapse-desc': 'Collapse',
'expand-desc': 'Expand',
Expand Down
22 changes: 20 additions & 2 deletions src/languages/fr.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
export default {
translation: {
'menu': {
'menu': "Menu de l'API",
'filter': 'Filtre',
'search': 'Chercher',
'overview': 'Aperçu',
'api-servers': 'Serveur API',
'authentication': 'Authentification',
'operations': 'OPÉRATIONS',
'components': 'COMPOSANTS',
'schemas': 'Schémas'
'schemas': 'Schémas',
'callbacks': 'RAPPELS'
},
'headers': {
'api-servers': 'SERVEUR API',
Expand All @@ -23,6 +25,7 @@ export default {
'selected': 'CHOISI'
},
'authentication': {
'auth-header': "l'en-tête Authorization",
'no-api-key-applied': "Aucune clé d'API appliquée",
'http-basic': 'HTTP Basique',
'http-basic-desc': "Envoyez l'en-tête <code>Authorization contenant</code> le type <code>Basic</code> suivi d'un espace et d'une chaîne encodée en base64 de nom <code>d'utilisateur:mot</code> de passe",
Expand All @@ -31,10 +34,15 @@ export default {
'requires': 'Nécessite',
'http-basic-note': "un nom d'utilisateur/mot de passe encodé en base64",
'in-auth-header': "dans l'en-tête Authorization",
'set': 'DÉFINIR'
'set': 'DÉFINIR',
'remove': 'RETIRER',
'clear': 'EFFACER TOUTES LES CLÉS API',
'update': 'MISE À JOUR',
'get': 'OBTENIR UN JETON'
},
'operations': {
'request': 'REQUÊTE',
'callback-request': 'REQUÊTE DE RAPPEL',
'request-body': 'CORPS DE LA REQUÊTE',
'model': 'MODÈLE',
'body': 'CORPS',
Expand All @@ -44,13 +52,23 @@ export default {
'clear-response': 'VIDER LA RÉPONSE',
'execute': 'EXÉCUTER',
'response': 'RÉPONSE',
'callback-response': 'RÉPONSE DE RAPPEL',
'response-headers': 'EN-TÊTES DE LA RÉPONSE',
'example': 'EXEMPLE',
'webhook': 'WEBHOOK',
'deprecated': 'OBSOLÈTE',
'response-status': 'Statut de réponse',
'fetch-fail': "Échec d'obtenir (Consultez l'onglet Réseau de navigateur pour plus d'information.)",
'copy': 'Copier',
'copied': 'Copié'
},
'parameters': {
path: 'PARAMÈTRES DE CHEMIN',
string: 'PARAMÈTRES DE CHAÎNE DE REQUÊTE',
headers: 'EN-TÊTES DE REQUÊTE',
cookies: 'COOKIES',
samples: 'EXEMPLES DE CODES'
},
'schemas': {
'collapse-desc': 'Réduire',
'expand-desc': 'Agrandir',
Expand Down
15 changes: 12 additions & 3 deletions src/styles/input-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,21 @@ export default css`
.m-btn.small { padding:5px 12px; }
.m-btn.tiny { padding:5px 6px; }
.m-btn.circle { border-radius: 50%; }
.m-btn:hover {

.m-btn:hover,
.m-btn:focus-visible,
.m-btn.outline-primary:focus-visible {
color: var(--secondary-color);
border-color: var(--secondary-color);
}
.m-btn.primary:focus-visible {
color: var(--secondary-color);
background-color: var(--primary-color);
color: var(--primary-btn-text-color);
border-color: var(--secondary-color);
}
.m-btn.nav { border: 2px solid var(--secondary-color); }
.m-btn.nav:hover {
.m-btn.nav:hover,
.m-btn.nav:focus-visible {
background-color: var(--secondary-color);
}
.m-btn:disabled{
Expand Down
22 changes: 22 additions & 0 deletions src/styles/nav-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,37 @@ export default css`
background-color: var(--nav-hover-bg-color);
}

a:focus-visible,
section .nav-bar-path:focus-visible span {
outline:thin solid var(--secondary-color);
}
section .nav-bar-path:focus-visible span {
outline-offset: 2px;
}

.nav-bar-h1:focus-visible,
.nav-bar-h2:focus-visible,
.nav-bar-info:focus-visible, slot[name=nav-section]::slotted(*:focus-visible),
.nav-bar-tag:focus-visible,
.nav-bar-path:focus-visible,
.nav-bar-h1:hover,
.nav-bar-h2:hover,
.nav-bar-info:hover, slot[name=nav-section]::slotted(*:hover),
.nav-bar-tag:hover,
.nav-bar-path:hover {
outline: none;
color:var(--nav-hover-text-color);
background-color:var(--nav-hover-bg-color);
}

.nav-bar-h1.active:focus-visible,
.nav-bar-h2.active:focus-visible,
.nav-bar-info.active:focus-visible, slot[name=nav-section]::slotted(*.active:focus-visible),
.nav-bar-tag.active:focus-visible,
.nav-bar-path.active:focus-visible {
outline:thin solid var(--secondary-color);
}

.conditional-custom-section.custom-section::slotted(*) {
display: none;
}
Expand Down
10 changes: 9 additions & 1 deletion src/styles/tab-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export default css`
color: var(--light-fg);
background-color: transparent;
white-space: nowrap;
cursor: pointer;
outline:none;
font-family:var(--font-regular);
font-size:var(--font-size-small);
Expand All @@ -35,9 +34,18 @@ export default css`
color:var(--primary-color);
}

.tab-btn:not(.active) {
cursor: pointer;
}

.tab-btn:hover {
color:var(--primary-color);
}

.tab-btn:focus-visible {
color:var(--secondary-color);
}

.tab-content {
position:relative;
}
Expand Down
3 changes: 2 additions & 1 deletion src/templates/callback-template.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { html } from 'lit';
import { getI18nText } from '../languages/index.js';

/* eslint-disable indent */
export default function callbackTemplate(callbacks) {
return html`
<div class="api-request col regular-font request-panel ${this.renderStyle}-mode">
${Object.entries(callbacks).map((kv) => html`
<div class="${this.renderStyle}-request">
<div class="req-res-title">CALLBACKS</div>
<div class="req-res-title" role="heading" aria-level="3">${getI18nText('menu.callbacks')}</div>
<div class="table-title">${kv[0]}</div>
${Object.entries(kv[1]).map((pathObj) => html`
<div class="mono-font small-font-size" style="display:flex;">
Expand Down
Loading