diff --git a/.vscode/settings.json b/.vscode/settings.json index e8ec85a9..2abc10dd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "esmodules", "exportparts", "kyleshockey", + "labelledby", "prismjs", "randombytes", "rapidoc", diff --git a/src/components/api-request.js b/src/components/api-request.js index a50a2176..ba4f3ff7 100644 --- a/src/components/api-request.js +++ b/src/components/api-request.js @@ -79,8 +79,8 @@ export default class ApiRequest extends LitElement { return keyed(id, html`
-
- ${this.callback === 'true' ? 'CALLBACK REQUEST' : getI18nText('operations.request')} +
+ ${this.callback === 'true' ? getI18nText('operations.callback-request') : getI18nText('operations.request')}
${this.inputParametersTemplate('path')} @@ -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 = []; @@ -158,7 +158,7 @@ export default class ApiRequest extends LitElement { return html` -
+
${paramName}${!generatedParamSchema.deprecated && paramRequired ? html`*` : ''}
@@ -175,6 +175,7 @@ export default class ApiRequest extends LitElement { -
- - +
+ +
${html`
${reqBodySchemaHtml}
`} ${html`
${reqBodyDefaultHtml}
`} @@ -620,7 +624,7 @@ export default class ApiRequest extends LitElement {
` : '' }
- ${!hasResponse ? '' : html``} + ${!hasResponse ? '' : html``}

- + ${!hasResponse ? '' : html` ` diff --git a/src/components/api-response.js b/src/components/api-response.js index 43e88862..c62af743 100644 --- a/src/components/api-response.js +++ b/src/components/api-response.js @@ -103,8 +103,8 @@ export default class ApiResponse extends LitElement { render() { return html`
-
- ${this.callback === 'true' ? 'CALLBACK RESPONSE' : getI18nText('operations.response')} +
+ ${this.callback === 'true' ? getI18nText('operations.callback-response') : getI18nText('operations.response')}
${this.responseTemplate()} @@ -158,7 +158,7 @@ export default class ApiResponse extends LitElement { this.headersForEachRespStatus[statusCode] = tempHeaders; this.mimeResponsesForEachStatus[statusCode] = allMimeResp; } - return html`
+ return html`
${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 ? '' @@ -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'> @@ -194,9 +195,9 @@ export default class ApiResponse extends LitElement { ? '' : html`
-
- - +
+ +
${Object.keys(this.mimeResponsesForEachStatus[status]).length === 1 ? html` ${Object.keys(this.mimeResponsesForEachStatus[status])[0]} ` diff --git a/src/languages/en.js b/src/languages/en.js index 0b173e4f..3acd69c2 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1,6 +1,7 @@ export default { translation: { 'menu': { + 'menu': 'API Menu', 'filter': 'Filter', 'search': 'Search', 'overview': 'Overview', @@ -8,7 +9,8 @@ export default { 'authentication': 'Authentication', 'operations': 'OPERATIONS', 'components': 'COMPONENTS', - 'schemas': 'Schemas' + 'schemas': 'Schemas', + 'callbacks': 'CALLBACKS' }, 'headers': { 'api-servers': 'API SERVER', @@ -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 Authorization header containing the token type Basic followed by the base64 encoded username:password string.', @@ -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', @@ -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', diff --git a/src/languages/fr.js b/src/languages/fr.js index 9fad4469..241ac56f 100644 --- a/src/languages/fr.js +++ b/src/languages/fr.js @@ -1,6 +1,7 @@ export default { translation: { 'menu': { + 'menu': "Menu de l'API", 'filter': 'Filtre', 'search': 'Chercher', 'overview': 'Aperçu', @@ -8,7 +9,8 @@ export default { 'authentication': 'Authentification', 'operations': 'OPÉRATIONS', 'components': 'COMPOSANTS', - 'schemas': 'Schémas' + 'schemas': 'Schémas', + 'callbacks': 'RAPPELS' }, 'headers': { 'api-servers': 'SERVEUR API', @@ -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 Authorization contenant le type Basic suivi d'un espace et d'une chaîne encodée en base64 de nom d'utilisateur:mot de passe", @@ -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', @@ -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', diff --git a/src/styles/input-styles.js b/src/styles/input-styles.js index 83a99776..b55abe8f 100644 --- a/src/styles/input-styles.js +++ b/src/styles/input-styles.js @@ -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{ diff --git a/src/styles/nav-styles.js b/src/styles/nav-styles.js index fe18e598..748235a9 100644 --- a/src/styles/nav-styles.js +++ b/src/styles/nav-styles.js @@ -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; } diff --git a/src/styles/tab-styles.js b/src/styles/tab-styles.js index df124aaf..2efe1c04 100644 --- a/src/styles/tab-styles.js +++ b/src/styles/tab-styles.js @@ -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); @@ -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; } diff --git a/src/templates/callback-template.js b/src/templates/callback-template.js index dc87e635..2d619001 100644 --- a/src/templates/callback-template.js +++ b/src/templates/callback-template.js @@ -1,4 +1,5 @@ import { html } from 'lit'; +import { getI18nText } from '../languages/index.js'; /* eslint-disable indent */ export default function callbackTemplate(callbacks) { @@ -6,7 +7,7 @@ export default function callbackTemplate(callbacks) {
${Object.entries(callbacks).map((kv) => html`
-
CALLBACKS
+
${getI18nText('menu.callbacks')}
${kv[0]}
${Object.entries(kv[1]).map((pathObj) => html`
diff --git a/src/templates/code-samples-template.js b/src/templates/code-samples-template.js index f73c96e5..e9bbdeab 100644 --- a/src/templates/code-samples-template.js +++ b/src/templates/code-samples-template.js @@ -1,9 +1,10 @@ import { html } from 'lit'; +import { getI18nText } from '../languages/index.js'; /* eslint-disable indent */ export default function codeSamplesTemplate(xCodeSamples) { return html` -
CODE SAMPLES
+
${getI18nText('parameters.samples')}
-
- ${xCodeSamples.map((v, i) => html``)} +
+ ${xCodeSamples.map((v, i) => html``)}
${xCodeSamples.map((v, i) => { // We skip the first line because it could be there is no padding there, but padding on the next lines which needs to be removed diff --git a/src/templates/components-template.js b/src/templates/components-template.js index 5e4d4e78..9a823219 100644 --- a/src/templates/components-template.js +++ b/src/templates/components-template.js @@ -74,7 +74,7 @@ export default function componentsTemplate() { const componentInfo = getComponentInfo(component.componentKeyId); return html`
-
${componentInfo.name}
+
${componentInfo.name}
${unsafeHTML(`
${toMarkdown(componentInfo.description ? componentInfo.description : '')}
`)}
diff --git a/src/templates/endpoint-template.js b/src/templates/endpoint-template.js index b95655d0..38afbb12 100644 --- a/src/templates/endpoint-template.js +++ b/src/templates/endpoint-template.js @@ -6,6 +6,7 @@ import codeSamplesTemplate from './code-samples-template.js'; import callbackTemplate from './callback-template.js'; import { pathSecurityTemplate } from './security-scheme-template.js'; import { getCurrentElement, pathIsInSearch, replaceState, toMarkdown } from '../utils/common-utils.js'; +import { getI18nText } from '../languages/index.js'; function toggleExpand(path) { if (path.expanded) { @@ -43,13 +44,13 @@ export function expandCollapseComponent(component) { function endpointHeadTemplate(path) { return html` -
${path.method}
+
${path.method}
${this.usePathInNavBar ? html`
${path.path.split('/').filter(t => t.trim()).map(t => html`/${t}`)}
` : html`
${path.summary || path.shortSummary}
` } - ${path.isWebhook ? html` (Webhook) ` : ''} + ${path.isWebhook ? html` (${getI18nText('operations.webhook')}) ` : ''}
`; @@ -64,10 +65,10 @@ function endpointBodyTemplate(path) {
${this.usePathInNavBar - ? path.summary ? html`
${path.summary}
` : path.shortSummary !== path.description ? html`
${path.shortSummary}
` : '' + ? path.summary ? html`
${path.summary}
` : path.shortSummary !== path.description ? html`
${path.shortSummary}
` : '' : html`
- ${path.isWebhook ? html` WEBHOOK ` : ''} + ${path.isWebhook ? html`${getI18nText('operations.webhook')}` : ''} ${path.method}  ${path.path.split('/').filter(t => t.trim()).map(t => html`/${t}`)}
` @@ -132,7 +133,7 @@ export default function endpointTemplate() {